Emacs is the greatest software that there is and obviously when it comes to text editors it is the one true editor. Fundamentally Emacs is actually REPL (Read-Eval-Print-Loop) for the Emacs Lisp and basically everything in it is programmable. For example when you type “a”, Emacs runs a function that prints “a” in your buffer. You can also change this function to anything you want (obviously not recommended, but possible).

This is not an introduction to the software Emacs itself. So I assume you have some basic knowledge of Emacs already and terminology of it (e.g. modes, buffers, frames etc.). This focuses more to the language behind Emacs called Emacs Lisp. This is also not going to cover everything in Emacs Lisp and is going to focus more on basics of the language.

Emacs Lisp derives from Lisp programming language so the syntax of Emacs Lisp is quite similar to other languages in the Lisp family. Most of the functionality in Emacs is written in this language, with the rest being written in C. Since the Emacs’ REPL nature you can write extensions in Emacs Lisp and run them directly in your Emacs session.

Obviously if you want to get started with programming in Emacs Lisp, you’ll want to install Emacs for that. Most Linux distributions provide Emacs in their own repositories.. Usually with the name of emacs. Emacs can also be downloaded from GNU Emacs website for other operating systems.

Evaluating Expressions in Emacs

Emacs can evaluate your expressions with the default keybinding C-x C-e (C = Ctrl) which calls eval-last-sexp. sexp is an ancient term for expressions in Lisp. In Emacs sexp is not limited to Lisp, but it can refer to any expression in any language.

Examples of sexp in Emacs:

(foo bar 42)
'(foo bar)
foobar
42
"foobar"

If you want to evaluate your expression go right at the end of it and press the keybinding C-x C-e. For example, if your expressions is (foo bar) place your cursor right after the closing parenthesis and eval the line with C-x C-e.

You can also evaluate all expressions in one buffer with command M-x eval-buffer (M = Meta/Alt/Option) which comes in handy when you’re configuring your Emacs configurations (.emacs, .emacs.el or .emacs.d/init.el), since with this command you can run all the commands in that file and see if it evaluates correctly without leaving Emacs.

Basic Emacs Lisp

In Emacs Lisp almost all expressions come inside parenthesis. This is very common in all the languages in Lisp family. When your functions and expressions get longer they’ll gather a lot of parenthesis in side them. So it can get quite hard to keep track of parentheses. But the more you code in Lisp, more prone you are to notice parenthesis imbalances.

Emacs Lisp files has the file extension of .el or .elc in which the latter one is compiled file. When you make a new file with the extension of .elin Emacs it should automatically recognize the file and change the major mode of Emacs to emacs-lisp-mode. If it doesn’t change that you can do it with the command M-x emacs-lisp-mode. But you can evaluate any Emacs Lisp command regardless of the mode if you want. Correct mode just brings different default settings that are useful when working with different languages.

Basic Calculations in Emacs Lisp

You can do simple calculations in Emacs Lisp by the following way:

(+ 2 2)

As you can see it is slightly different than regular math, but when you translate it to literal english it makes sense. This would then read “Add 2 to 2”.

When you evaluate that expression with C-x C-e when your cursor is at right after the closing parenthesis Emacs shows the answer to that calculation in its echo area. Echo area is the bottom buffer right below your mode-line. You should see something similar to this in your minibuffer when you evaluate that calculation:

4 (#o4, #x4, ?\C-d)

In this minibuffer text you can see the answer of your expressions in integer then in parentheses that integer in octal, hexadecimal and char. So if you would evaluate #o4, #x4 or ?\C-d your minibuffer would yield the same answer.

You can also add multiple calculations together, for example:

(+ 2 (+ 5 6))

Inserting Text to Buffer

If you want to insert text in your current buffer you can do that by:

(insert "Hello, World!")

When you evaluate that line by C-x C-e it should print the the line Hello, World right after the closing parenthesis.

Variables and Formatting

You can set variables in Emacs Lisp with the functions set or setq. Difference between these two functions is that setq quotes the variable automatically whereas with set you need to quote it yourself. For example:

(set 'my-name "Topi")
(setq my-name "Topi")

These expressions are basically the same with the difference being that I had to quote the variable when using set. If I don’t do that evaluating that expression would yield an error in the echo area.

Before you use variables in Emacs Lisp you need to evaluate the expression for setting the variable. After that you can call that variable by simply evaluating the variable name:

my-name
=> "Topi"

With => I show what the evaluation prints in the echo area. You can also use these variables in any function:

(insert my-name)

That expression would print your set variable to your current buffer when evaluated.

You can also use variables with strings:

(insert "Hello " my-name)

You can also format your strings with or without variables:

(format "Hello %s!" "you")
=> "Hello you!"
(format "Hello %s!" my-name)
=> "Hello Topi!"

As you can see formatting syntax is similar to format syntax in many other language, e.g. C.

You can also print your formatted string easily by evaluating:

(insert (format "Hello %s!" my-name))

Quoting

Quoting a object in Lisp return the argument in written form without evaluating it. Quote is often used in Lisp programming and that is why it has easy syntax build in. To quote object you can do that by inserting apostrophe (‘) right before Lisp object.

E.g.

'foo
=> foo

'(+ 1 2)
=> (+ 1 2)

Quoting makes it possible to include constant symbols and lists in a program. Since these are not self-evaluating objects. When it comes to self-evaluating object, e.g. numbers, strings, vectors, quoting is not necessary.

Lists

Lisp’s name derives from list processing and originally the language was designed for easy manipulation of data strings. So lists play relatively big role on every Lisp language, including Emacs Lisp.

To set list to a variable write:

(setq list-of-names '("Eric" "Muddy" "Albert"))
=> "("Eric" "Muddy" "Albert")"

If you want to return the first element of the list:

(car list-of-names)
=> "Eric"

If you want to return all but the first element:

(cdr list-of-names)
=> ("Muddy" "Albert")

If you want to return the nth element from list:

(nth 1 list-of-names)
=> "Muddy

(nth 10 list-of-names)
=> nil

You can pop and push elements from and to the list. pop deletes the first element of the list and returns it (so you can set that element to a variable if so desired):

(pop list-of-names)
=> "Eric"

list-of-names
=> ("Muddy" "Albert")

push on the other hand pushes element to the beginning of the list:

(push "B.B." list-of-names)
=> ("B.B." "Muddy" "Albert")

Functions

Functions are very big part of most programming languages and same is true for Emacs Lisp. To define functions in Emacs Lisp you need to use defun for that.

E.g.

(defun hello ()
	(insert "Hello, World"))

This defines a functions called hello which doesn’t accept any arguments. To call this functions write:

(hello)

To define a function that accepts arguments write:

(defun cool-cat (name)
	(insert name " is a cool cat!\n"))

And to call this:

(cool-cat "Miles Davis")

This would then print Miles Davis is a cool cat! with new line printed at end of it (\n) to your current buffer.

You can combine first argument with the second argument with mapcar. For example:

(mapcar 'cool-cat list-of-names)

This would then call our cool-cat function with each name in our list. So the output would be:

B.B. is a cool cat!
Muddy is a cool cat!
Albert is a cool cat!

You can also evaluate multiple lines at once with progn:

(progn
  (insert "Hello World")
  (insert " and Hello you!"))

This would then insert:

Hello World and Hello you!

Local Variables

You can define local variables in Emacs Lisp with let. This allows you set different variables that are only used, for example, inside of a function. Here is a good example that shows the difference of setq and let:

(let ((x 3))
  (print x)      ; a
  (let ((x 89))
    (print x)    ; b
    (setq x 73)
    (print x))   ; c
  (print x))     ; d


3   ; a
89  ; b
73  ; c
3   ; d

You can also evaluate multiple lines at once when they are inside let, like I did in the last example:

(let ((local-name "Buddy"))
  (insert "Hello World")
  (insert " and Hello " local-name))

Notice that you can’t use the variable local-name outside of that call.

Often let might not work the way you intended if you use your variables that you set with setq inside it.

For example:

(setq y 2)
     => 2

(let ((y 1)
      (z y))
  (list y z))
    => (1 2)

As you can see this call uses the y that you set before let therefore it binds z to 2, even though you set your y to 1 inside let. If you would want to set z in this case to y value that was set inside of let, you need to use let* for that:

(setq y 2)
     => 2

(let* ((y 1)
       (z y))
  (list y z))
    => (1 1)

Keybindings in Emacs

Keybindings play a big part in Emacs since they can greatly enhance your workflow in it. You can set keybindings in your current session with M-x global-set-key key cmd or M-x local-set-key key cmd. Difference between global-set-key and local-set-key is that global-set-key sets key to all modes and buffers, whereas local-set-key sets is only to the current buffer and mode. These settings won’t stay if you exit your Emacs, so if you want these to stay it is recommended to put them inside your Emacs configuration file .emacs, .emacs.el or the recommended .emacs.d/init.el.

To set your keybindings in Emacs Lisp:

(global-set-key (kbd "key") 'cmd)

(local-set-key (kbd "key") 'cmd)

For example:

(global-set-key (kbd "C-h C-e") 'emacs-init-time)

After evaluation this binds C-h C-e to run command emacs-init-time, which tells you the boot time of your last Emacs boot.

Here you can also see use of prefix keymap, in this case C-h. These prefix keymaps allows you to link multiple keybindings together, like I did on the example above. These prefixes are C-x, C-c, C-h and C-x num, e.g. C-x 4. The last prefix is often used if you want to execute some command multiple times.

More examples on keybindings:

(global-set-key (kbd "C-c y") 'clipboard-yank)
(global-set-key (kbd "C-M-q") 'query-replace)
(global-set-key (kbd "<f5>") 'flyspell-mode)
(global-set-key (kbd "C-<f5>") 'linum-mode)
(global-set-key (kbd "C-<right>") 'forward-sentence)
(global-set-key (kbd "<mouse-2>") 'mouse-save-then-kill)

You can evaluate these bindings line by line or you can insert them in your Emacs configuration file, so they are evaluated when Emacs boots.

Hooks

You can write different mode specific configurations using hooks. Hooks are lists of functions that are called in specific occasions, e.g. when you open a file in some major mode.

For example:

(add-hook 'texinfo-mode-hook
		  (lambda ()
			(define-key texinfo-mode-map "\C-cp"
			  'backward-paragraph)
			(define-key texinfo-mode-map "\C-cn"
			  'forward-paragraph)))

This adds a hook that binds C-c p to backward-paragraph and C-c n to forward-paragraph when file is opened in texinfo-mode.

Lambda Expressions

In the previous example you can see a lambda expression. Lambda expressions are usually anonymous functions, which are often assigned as variable values or as arguments to functions. Lambda expressions are widely used in many programming language and especially in Lisp languages.

Simple lambda expression:

(lambda (a b c) (+ a b c))

You can then evaluate the lambda expression with funcall:

(funcall (lambda (a b c) (+ a b c))
		 1 2 3)

You can also use inner functions as arguments:

(funcall (lambda (a b c) (+ a b c))
		 1 (* 2 3) (- 5 4))

Another lambda example:

(lambda (x)
  "Return the hyperbolic cosine of X."
  (* 0.5 (+ (exp x) (exp (- x)))))
(funcall (lambda (x)
  "Return the hyperbolic cosine of 5."
  (* 0.5 (+ (exp x) (exp (- x)))))
		 5)

Further Readings

This was a short introduction to Emacs Lisp so you can get started in programming it. If you want to know something about any variable you can you press C-h v inside Emacs and read about the variable you want. Same can be done with functions with C-h f. If you want to know what some key combinations does you can press C-h k.

GNU Emacs has a great manual for Emacs Lisp and Emacs itself so I definitely recommend in reading those, if you want to dive into to the world of Emacs more. Those can found here:

If you’re interested about my Emacs configurations, you can find them at my GitHub.

Happy Hacking!