Emacs Lisp

Table of Contents

Dialect of Lisp used specifically to configure, extend, and program the GNU Emacs text editor

They are byte complied into .elc file, and native compiled into .eln file.

"TAB" is ^I and "<tab>" is tab key.

1. Definition

Symbol is an object that represent a variable or function. quote or ' wraps the variable as a symbol. It consists of four parts: name, value, function value, property list. They can be accessed with symbol-name, symbol-value, symbol-function, symbol-plist respectively.

  • fset sets the function value of the variable. It can be set to a raw function or a symbol as a indirection.
  • `(... ,a ...) backquote can be used to evaluate only certain part of expression.

Dynamically bound functions expands the scope when it is not bound locally, but lexically bound variable does not.

  • defvar makes the variable dynamically bound.
  • Lexical binding is preferred these days.
  • boundp checks if a symbol is bound to a value or void.
  • setf like setq but operates on any cell and variables.
  • (let ((var val), ...) (statement)) it binds local variable, dynamically on dynamic variable, lexically on free variable.
    • let* defines them sequencially
  • (defun name (arguments) "optional documentation" (interactive "optional-argument-passing-info") (body))
    • Function that is defined interactively with (interactive OPTION) is a command, which can be bound
  • (setq var val var val ...)
    • The variable is bound to the value.
    • The q is for quoted, which means the var does not need to be quoted
  • (defvar var val "optional documentation")
    • It marks the variable as special, so that it is always dynamically bound.
    • The variable is not overrode, and setq can change the value, it is seen globally
    • It allows doc string.
  • (provide 'PACKAGE) specified in the end of the package file. Later (require 'PACKAGE) is used to retrieve it.

Mode Simple mode defined as follow can be activated by M-x generic-mode

(define-generic-mode 'phits-mode
  '("#")         ;; comment character
  '("icntl")     ;; keywords
  '(("^\\[.*\\]" . 'font-lock-constant-face)) ;; font lock regex
  '("\\.inp\\'") ;; file extenstion
  nil            ;; list of functions to run
  "Genetic mode for phits input file")

(define-minor-mode MODE :init-value nil :lighter INDICATOR :global nil BODY) (defcustom var val "documentation" :type TYPE) it specify a variable that customize can control

2. Types

  • String "abc" , Vector [a b c] are array
  • Cons Cell
    • It consists of two parts car and cdr, that can contain value or reference. CAR and CDR - Wikipedia
    • cons or . form a cons cell out of two values.
    • list is a series of cons cell that reference the next cons cell and ends in nil
  • There are various types of data, such as #<buffer>, #<marker>, #<frame>. These are only represented in the printed representation, and not to be defined in this way.
  • The value can be a closure and it can be called with funcall
    • #' can be used to explicitly tell it to use the function value.
  • #1= and #1# can be used to create a reference and refer back to it.

3. Functions

3.1. Interactive Function

  • These are precisely the commands

Command is defined with (interactive OPSION) within the function defition.

The option can be nil, string, or lisp code. String option includes a sequence of code character and prompt string pairs separated by \n, with each user response assigned to the arguments of the function in order.

  • n number
  • s any string
    • the input is terminated by C-j or RET
  • c character
  • f filename
    • F file does not need to exist
  • b buffer name
    • B buffer does not need to exist
  • D directory
  • r region
    • take the start and end point of the region as the two argument.

The full list can be found here.

3.2. Build-in Functions

  • List
    • A list is a series of nodes (CAR CDR) -> (CAR CDR) -> ...
    • cdr can also be used to store value instead of the pointer to the next node, with (cons VAR1 VAR2) or equivalently (VAR1 . VAR2).
    • The reader reads the list and evaluate it if it is not quoted with (quote LIST) or equivalently 'LIST
    • (append LIST1 LIST2) produces the new concatenated list
    • Sequence Functions (GNU Emacs Lisp Reference Manual)
  • String
    • (concat STR1 STR2) concatenate into one string
    • (format FORMAT_STR VAR)
    • (substring STR START_INDEX [END_INDEX]) zero-based end-excluded substring.
  • Point
    • (point) return current point position
    • (goto-char NUM) move point to the position NUM
    • (forward-char &optional NUM), (backward-char &optional NUM) move point
    • (beginning-of-buffer), (end-of-buffer) move point
    • Common motion command, such as (forward-word), (forward-sentence) are also available.
    • (point-min), (point-max) return possible point position while taking narrowing into account
    • (save-excursion ...) save the point position, and allow point motions to be contained within the scope
  • Buffer
    • Get/Set Buffer
      • (current-buffer) get the current (editing) buffer
      • (get-buffer BUFFER-OR-NAME) get buffer by name
      • (get-file-buffer FILENAME) get buffer by file path
      • (get-buffer-create BUFFER-OR-NAME) get buffer while creating it when it does not exists.
      • (set-buffer BUFFER-OR-NAME) set current (editing) buffer to BUFFER
      • (with-current-buffer BUF ...) set the current buffer within the scope
      • (with-temp-buffer "CONTENT" ...) create a temporary buffer with given content
    • Buffer File
      • (buffer-file-name) the file path of the current buffer. It is nil if not applicable.
      • (find-file-noselect FILENAME) => BUF open a file into a buffer without displaying it
      • (save-buffer) save to buffer file
    • Buffer Text
      • (char-after NUM) return the character at the position
      • (thing-at-point THING &optional NO-PROPERTIES) the THING can be 'word, 'sentence, 'url and others
      • (search-forward STRING &optional BOUND NOERROR COUNT), (search-backward STRING) move the point after/before the (first) match
      • (buffer-substring START END) return string at the given range within current buffer
        • (buffer-substring-no-properties START END)
      • (insert STR) insert at point
      • (insert-file-contents-literally PATH)
      • (delete-region START END) delete the text within
  • Command
    • (this-command) return the object that represent the last executed command
  • External Command
    • (shell-command COMMAND)
      • xdg-open can be used to open a file externally.
    • (shell-command-to-string COMMAND) insert the result of shell command
    • (call-process ...)
    • (start-process ...)
  • Hook
    • (add-hook HOOK FUNCTION)
    • (run-hook-with-args-until-success HOOK &rest ARGS) runs hooks sequenctially until one of them returns t.
    • (with-eval-after-load PKG BODY)
  • Interactive
    • (y-or-n p PROMPT), (yes-or-no-p PROMPT) ask yes or no and return t or nil
    • (message STRING) echo in the minibuffer
  • (message "message" optional-format-vars) print message to the echo area
    • %s, %d can be used to format the string
  • (read-buffer PROMPT), (read-file-name PROMPT), (read-char &optional PROMPT)
  • -p is for predicate, and -q is for quoted.

4. Flow Control

5. Macro and Special Form

  • defmacro defines a macro that interprets expression differently, that it may not evaluate the expression.
  • Special form is similar to macro and it is often the language feature.
  • (progn EXPRESSIONS) execute the expressions in order

6. Packages

6.1. cl-lib

  • (cl-loop VAR_DEFINE(for, with, ...) BODY(if, repeat, collect, append, return, ...)

7. Byte Compilation

  • A lisp file from a package is byte compiled on installation. It needs to be recompiled via package-recompile to load the code.

8. History

The original Lisp came about in 1960 by John McCarthy. It diverged into several dialect in 1970s and unified with Common Lisp in 1980s. The ANSI standard was also established in 1990s.

It was a niche programming language among industry and academia and soon got outnumbered by other languages due to its low performance and lact of libraries. Java at work, Python at academia replaced them.

The Rise & Fall of LISP - Too Good For The Rest Of the World - YouTube

ch

9. References

Author: Jeemin Kim

Created: 2026-07-12 Sun 14:27