Emacs Lisp Basics

This page is a short, practical, tutorial of Emacs Lisp the language.

To evaluate elisp code, for example, type (+ 3 4) , then move your cursor to after the closing parenthesis, then call eval-last-sexp 【 Ctrl + x Ctrl + e 】. Emacs will evaluate the lisp expression to the left of the cursor.

Or, you can select the lisp code, then Alt + x eval-region .

To find the doc string of a function, Alt + x describe-function 【 Ctrl + h f 】. (if the function name is under cursor, you don't need to type the name, just hit Enter .)

eval emacs lisp code basics. [see Evaluate Emacs Lisp Code]

To turn on syntax highlight, Alt + x emacs-lisp-mode .

Printing

( message "hi" ) ( message "Her age is: %d" 16) ( message "Her name is: %s" "Vicky" ) ( message "My list is: %S" ( list 8 2 3))

You can see the output in the buffer named “*Messages*”. You can switch to it by Alt + x view-echo-area-messages 【 Ctrl + h e 】.

[see Elisp: Print, Output]

[see Elisp: Format String]

Arithmetic

(+ 4 5 1) ( - 9 2) ( - 9 2 3) (* 2 3) (* 2 3 2) (/ 7 2) (/ 7 2.0) (% 7 4) ( expt 2 3)

WARNING: single digit decimal number such as 2. needs a zero after the dot, like this: 2.0 . For example, (/ 7 2.) returns 3, not 3.5.

( integerp 3.) ( floatp 3.) ( floatp 3.0)

Function names that end with a “p” often means it return either true or false. (The “p” stands for “predicate”) t means true; nil means false.

Convert Float/Integer

( float 3) ( truncate 3.3) ( floor 3.3) ( ceiling 3.3) ( round 3.4)

(info "(elisp) Numeric Conversions")

Convert String and Number

( string-to-number "3" ) ( number-to-string 3)

You can also use format to convert number to string. [see Elisp: Format String]

(info "(elisp) Numbers")

True, False

In elisp, the symbol nil is false, anything else is true. Also, nil is equivalent to the empty list () , so () is also false.

( if nil "yes" "no" ) ( if () "yes" "no" ) ( if '() "yes" "no" ) ( if ( list ) "yes" "no" )

By convention, the symbol t is used for true.

( if t "yes" "no" ) ( if 0 "yes" "no" ) ( if "" "yes" "no" ) ( if [] "yes" "no" )

There is no “boolean datatype” in elisp. Just remember that nil and empty list () are false, anything else is true.

Boolean Functions

Here's and and or .

( and t nil ) ( or t nil ) ( and t nil t t t t )

Comparing numbers:

(< 3 4) (> 3 4) (<= 3 4) (>= 3 4) (= 3 3) (= 3 3.00000000000000001) (/= 3 4)

Comparing strings:

( equal "abc" "abc" ) ( string-equal "abc" "abc" ) ( string-equal "abc" "Abc" ) ( string-equal "abc" 'abc)

For generic equality test, use equal . It tests if two values have the same datatype and value.

( equal 3 3) ( equal 3.0 3.0) ( equal 3 3.0) ( equal '(3 4 5) '(3 4 5)) ( equal '(3 4 5) '(3 4 "5" )) ( equal "e" "e" ) ( equal 'abc 'abc)

There's also the function eq , it returns t if the two args are the same Lisp object. This is usually not what you want. (eq "e" "e") returns nil .

To test for inequality, the /= is for numbers only, and doesn't work for strings and other lisp data. Use not to negate your equality test, like this:

( not (= 3 4)) (/= 3 4) ( not ( equal 3 4))

even, odd

(= (% n 2) 0) (= (% n 2) 1)

Variables

Global Variables

setq is used to set variables. Variables need not be declared, and is global.

( setq x 1) ( setq a 3 b 2 c 7)

Local Variables

To define local variables, use let . The form is:

(let ( var1 var2 …) body )

where body is (one or more) lisp expressions. The body's last expression's value is returned.

( let (a b) ( setq a 3) ( setq b 4) (+ a b) )

Another form of let is this:

(let (( var1 val1 ) ( var2 val2 ) …) body )

( let ((a 3) (b 4)) (+ a b) )

This form lets you set values to variable without using many setq in the body. This form is convenient if you just have a few simple local vars with known values.

(info "(elisp) Variables")

If Then Else

The form for “if” expression is:

(if test body )

or

(if test true_body false_body )

( if (< 3 2) 7 8 ) ( if (< 3 2) ( message "yes" ) )

(info "(elisp) Control Structures")

If you do not need a “else” part, you should use the function when instead, because it is more clear. The form is:

(when test expr1 expr2 …)

Its meaning is the same as

(if test (progn expr1 expr2 …))

Block of Expressions

Sometimes you need to group several expressions together as one single expression. This can be done with progn .

( progn ( message "a" ) ( message "b" )) ( message "a" ) ( message "b" )

The purpose of (progn …) is similar to a block of code {…} in C-like languages. It is used to group together a bunch of expressions into one single parenthesized expression. Most of the time it's used inside “if”.

( if something ( progn … ) ( progn … ) )

progn returns the last expression in its body.

( progn 3 4 )

(info "(elisp) Sequencing")

Loop

Most basic loop in elisp is with while .

(while test body )

, where body is one or more lisp expressions.

( setq x 0) ( while (< x 4) ( print ( format "number is %d" x)) ( setq x (1+ x)))

( let ((x 32)) ( while (< x 127) ( insert-char x) ( setq x (+ x 1))))

Usually it's better to use dolist or dotimes .

[see Elisp: Map List/Vector]

(info "(elisp) Iteration")

Break/Exit a Loop

Elisp: throw, catch

Sequence, List, Vector

Elisp: Sequence Type

Elisp: Vector

Elisp: List

Define a Function

Basic function definition is of the form:

(defun function_name ( param1 param2 …) " doc_string " body )

( defun myFunction () "testing" ( message "Yay!" ))

When a function is called, the last expression in the function's definition body is returned. (there's no “return statement”.)

(info "(elisp) Defining Functions")

Define a Command

A command is a function that emacs user can call by execute-extended-command 【 Alt + x 】.

When a function is also a command, we say that the function is available for interactive use.

To make a function available for interactive use, add (interactive) right after the doc string.

Evaluate the following code. Then, you can call it by execute-extended-command 【 Alt + x 】

( defun yay () "Insert “Yay!” at cursor position." ( interactive ) ( insert "Yay!" ))

(info "(elisp) Defining Commands")

Here is a function definition template that majority of elisp commands follow:

( defun myCommand () "One sentence summary of what this command do. More detailed documentation here." ( interactive ) ( let (localVar1 localVar2 …) ) )

See also: