Emacs Lisp Basics

By Xah Lee. Date: . Last updated: .

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-sexpCtrl+x Ctrl+e】. Emacs will evaluate the lisp expression to the left of the cursor.

Alternatively, you can select the lisp code, then call eval-region.

Alternatively, you can call ielm. It will start a interactive elisp command line interface.

To find the inline documentation of a function, call describe-functionCtrl+h f】.

eval emacs lisp basics 2015-09-17
eval emacs lisp basics. 〔➤see How to Evaluate Emacs Lisp Code

Printing

; printing
(message "hi")

; printing variable values
(message "Her age is: %d" 16)        ; %d is for number
(message "Her name is: %s" "Vicky")  ; %s is for string
(message "My list is: %S" (list 8 2 3))  ; %S is for any lisp expression

You can see the output in the buffer named “*Messages*”. You can switch to it by calling view-echo-area-messagesCtrl+h e】.

More detail: Emacs Lisp's print, princ, prin1, format, message.

Arithmetic Functions

(+ 4 5 1)     ;    ⇒ 10
(- 9 2)       ;    ⇒  7
(- 9 2 3)     ;    ⇒  4
(* 2 3)       ;    ⇒  6
(* 2 3 2)     ;    ⇒ 12
(/ 7 2)       ;    ⇒  3 (integer part of quotient)
(/ 7 2.0)     ;    ⇒  3.5
(% 7 4)       ;    ⇒  3 (mod, remainder)
(expt 2 3)    ;    ⇒ 8 (power; exponential)

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.

;; 3. is a integer, 3.0 is a float
(integerp 3.) ; returns t
(floatp 3.) ; returns nil
(floatp 3.0) ; returns t

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 String and Numbers

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

You can also use format to convert number to string. 〔➤see Emacs Lisp: print, princ, prin1, format, message

(info "(elisp) Numbers")

True, False

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

;; all the following are false. They all evaluate to “nil”
(if nil "yes" "no") ; ⇒ "no"
(if () "yes" "no") ; ⇒ "no"
(if '() "yes" "no") ; ⇒ "no"
(if (list) "yes" "no") ; ⇒ "no", because (list) eval to a empty list, same as ()

By convention, the symbol t is used for true.

(if t "yes" "no") ; ⇒ "yes"
(if 0 "yes" "no") ; ⇒ "yes"
(if "" "yes" "no") ; ⇒ "yes"
(if [] "yes" "no") ; ⇒ "yes". The [] is vector of 0 elements

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) ; ⇒ nil
(or t nil) ; ⇒ t

;; can take multiple args
(and t nil t t t t) ; ⇒ nil

Comparing numbers:

(< 3 4) ; less than
(> 3 4) ; greater than

(<= 3 4) ; less or equal to
(>= 3 4) ; greater or equal to

(= 3 3)   ; ⇒ t
(= 3 3.00000000000000001) ; ⇒ t

(/= 3 4) ; not equal. ⇒ t

Comparing strings:

;; compare string
(equal "abc" "abc") ; ⇒ t

;; dedicated function for comparing string
(string-equal "abc" "abc") ; ⇒ t

(string-equal "abc" "Abc") ; ⇒ nil. Case matters

;; can be used to compare string and symbol
(string-equal "abc" 'abc) ; ⇒ t

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

;; test if two values have the same datatype and value.

(equal 3 3) ; ⇒ t
(equal 3.0 3.0) ; ⇒ t

(equal 3 3.0) ; ⇒ nil. Because datatype doesn't match.

;; test equality of lists
(equal '(3 4 5) '(3 4 5))  ; ⇒ t
(equal '(3 4 5) '(3 4 "5")) ; ⇒ nil

;; test equality of strings
(equal "e" "e") ; ⇒ t

;; test equality of symbols
(equal 'abc 'abc) ; ⇒ t

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)) ; ⇒ t
(/= 3 4) ; ⇒ t. “/=” is for comparing numbers only

(not (equal 3 4)) ; ⇒ t. General way to test inequality.

even, odd

(= (% n 2) 0) ; test even

(= (% n 2) 1) ; test odd

Variables

Global Variables

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

(setq x 1) ; assign 1 to x
(setq a 3 b 2 c 7) ; assign 3 to a, 2 to b, 7 to c

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)
) ; returns 7

Another form of let is this: (let ((var1 val1) (var2 val2) …) body). Example:

(let ((a 3) (b 4))
 (+ a b)
) ; returns 7

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).

If you want a “else” part, the form is (if test true_body false_body).

Examples:

(if (< 3 2) (message "yes") ) ; does nothing. returns nil

(if (< 3 2) 7 8 ) ; returns 8

(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 this: (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"))
;; is equivalent to
(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”. For example:

(if something
    (progn ; true
    …
    )
    (progn ; else
    …
    )
)

progn returns the last expression in its body.

(progn 3 4 ) ; ⇒ 4

(info "(elisp) Sequencing")

Iteration

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 "yay %d" x))
  (setq x (1+ x)))

(info "(elisp) Iteration")

;; inserts Unicode chars 32 to 126
(let ((x 32))
  (while (< x 127)
    (ucs-insert x)
    (setq x (+ x 1))))

Break/Exit a Loop

Emacs Lisp: Exit Loop/Function, catch/throw

Sequence, List, Vector

Emacs Lisp: List vs Vector

Emacs Lisp: Vector

Emacs Lisp: List

Define a Function

Basic function definition is of the form:

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

Example:

(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-commandAlt+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-commandAlt+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 …)
    ; do something here …
    ;     ; last expression is returned
  )
)

See also:

Continue to:

Like it? Buy Xah Emacs Tutorial. Thanks.

or, buy something from my keyboard store.