Giovanni's Diary > Programming > Emacs >
Emacs-lisp Exercises
Here is a collection of some emacs lisp exercises that I come up by myself when learning the syntax. Emacs lisp is quite a simple language, and It is very powerful because It integrates with emacs "natively". You can easily manage buffers, windows, keys and UI with ease, so I want to dedicate some time into this.
Basics
Define a variable a using setq
with the value "Hello World".
Variables are used to store the state such as the current
configuration of a package, so changing a variable's value
directly changes the configuration.
(setq a "Hello-World")
Lists are the most common data structures in lisp. To declare a
list, you need to prepend the white space separated elements
enclosed int parentheses ( )
with a '
character.
By default, a list does not evaluate It's element when the list
itself gets evaluated. To break this rule, you can use the `
character to represent a list that may be "escaped" with the ,
character.
'(1 2 3)
Functions
Sum two numbers together. You can use the +
function which
takes any number of arguments that are either numbers or markers.
To call a function, you surround the function name and Its
argument in parentheses (...)
.
(+ 1 2)
Call the message
function to write a message to the message
buffer. The message function works similarly to libc's printf.
To get information about function, you can call describe-function
from the minibuffer.
(message "Hello World")
Define a function to write hello and another to write bye to the
message buffer. Use defun
, followed by the function name,
arguments, and body.
(defun print-hello () (message "Hello World!")) (defun print-bye () (message "Bye bye!"))
Define a function that says either hello or bye depending on whether the number of iteration taken from the user is odd or even.
(defun hello-or-bye (iterations) (setq a iterations) (while (>= a 0) (if (= 0 (% a 2)) (print-hello) (print-bye)) (setq a (- a 1))))
Iteration
Define a function to iterate over a list supplied by the user and output to a buffer in another window.
(defun iterate-now (list) "Print elements of a list" (setq mybuff (generate-new-buffer "*my output*")) (while list (print (car list) mybuff) (setq list (cdr list))) (switch-to-buffer-other-window mybuff)) ;; Call that function ;;(iterate-now '(c c++ rust c3))
Custom types
Define a variable with defvar
.
(defvar food-list '(bread pasta pizza) "A list of Italian food")
Define a variable with defcustom.
(defgroup italian nil "Italian things") (defcustom city-list '("Rome" "Milan" "Trento") "A list of Italian cities" :group 'italian :type '(repeat string)) ;;(iterate-now city-list)
Define a function that returns true only if Its argument is a list of strings.
(require 'cl-lib) (defun is-string-list (obj) "Find out if the argument is a list of string" (and (listp obj) (cl-every #'stringp obj))) ;; Test the function (if (not (is-string-list city-list)) (message "upsie") (message "ok")) (if (is-string-list 123) (message "upsie 2") (message "ok"))
Of course, the language goes really deep and I barely scratched the surface. I will keep doing exercises until I feel satisfied.