Table of Contents

;-- mode: Org; fill-column: 110;--

1. common structures

add "s" to every element of list "left-let":

(setq fin (mapcar (lambda (x) (cons s x)) left-let))

flatten list by one level

(apply 'append v)

all or every

(defun all (l) (cl-every #'identity l))

all or every nil

(defun allnil (l) (cl-every #'null l))

any t

(defun any (l) (cl-some #'identity l))

any nil

(defun anynil (l) (cl-some #'null l))

Apply map to every leaf of a tree like list

(defun maptree (f l)
"Apply map to every leaf of a list."
  (mapcar (lambda (x) (if (listp x)
                          (maptree f x)
                        ;; else
                        (funcall f x)
                        )) l))

Concatenate two lists

(setq c1 '(1 (2) 3 4))
(setq c2 '(1 2 3 (4)))
(print (seq-concatenate 'list c1 c2))

(defun add_one_to_another(c1 c2)
  (apply 'append (list c1 c2)))

(1 (2) 3 4 1 2 3 (4))

2. Lisp - philosophy, patterns

everything is list, space is items separrator

https://aartaka.me/lisp-design-patterns

3. features

https://www.tutorialspoint.com/lisp/index.htm https://www.gnu.org/software/emacs/manual/html_node/elisp/index.html

"Lots of Isolated Silly Parentheses" 1958 by John McCarthy

  • dynamic and strong typing, functional, reflective, meta
  • advanced object-oriented programming
  • prefix notation - operators are written before their operands
  • machine-independent, such as word length etc.
  • iterative design methodology, (easy extensibility ?)
  • allow updating the program dynamically
  • high level debugging
  • advanced object-oriented programming
  • convenient macro system?
  • expression-based ?
  • object-oriented condition system ?

4. symbols, special characters

(') is equal to (list) operator

"#"

(eq 'my-add #'my-add) -> t

can be used in front of a lambda expression indicating to the byte-compiler that the following expression can be byte compiled

used in the printed representation along with the left angle bracket (<) to indicate that the object printed is a description

":" A symbol whose name starts with a colon (‘:’) is called a “keyword symbol”. act as constants, and are normally used only by comparing an unknown symbol with a few specific alternatives 13.3.1

(print (list 1 2))
(print #'(1 2))

(1 2)

(1 2)

4.1. Steps for info:

  • F1 i or M-x info RET (open the info browser)
  • d m elisp RET (open the elisp manual)
  • I # RET (list the entries for # in the index)

4.2. meaning with Backquote (`) macroses

Backquote (`) and comma (,)

  • (`) character signals that in the expression that follows, every subexpression not preceded by a comma is to be quoted, and every subexpression preceded by a comma is to be evaluated.
(setq v1 2)
(setq e 2)
(setq v2 2)
(print `(progn (setq v1 ,@e) (setq ,v2 ,e)))
;;^ backquote   ^   ^         ^   ^ commas

(print '(
              progn (setq v1 e) `(setq ,v2 ,e)
                    ))

(progn (setq v1 . 2) (setq 2 2))

(progn (setq v1 e) `(setq ,v2 ,e))

Comma-splice (,@)

(setq v  '("oh boy"))
(print `(zap ,@v ,v))

(zap "oh boy" ("oh boy"))

Quote-comma (')

(defmacro explain-exp (exp)
  `(format "%s = %s" ',exp ,exp))
  ;;                 ^^

(print (explain-exp (+ 2 3)))


"(+ 2 3) = 5"

5. terms

must know:

  • whitespace and () - separators;
  • () = nil = atom and list
  • expressions = prefix notation = (+ 1 2)
  • special operators = (+, (list, (if. (lambda
  • anonymous function (lambda (arg) (+ arg 1) )
  • function (defun foo "optional comment" (a b c) (+ a b c))
  • function are case-insensitive
  • constants = Numbers, letter t, nil
  • true = t, false = nil
  • certain kinds of atom(arrays) can be separated into parts but not like lists,l
  • function names that end with a "p" often means it return true=t of false=nil = predicate

    terms:

  • are provided in various forms and representations
  • represent printed glyphs such as letters or text formatting operations
  • elemental entities, number symbols and strings (list 2 3), nil, (ab-a#221), ("asd asd")
  • are named data objects: + foo forward-line - atom type
  • sequence of atoms or lists in (), nil; unlist and unquote: (apply 'function '(12 23))
  • "asd" - arrays of characters
  • ;
  • any object meant to be evaluated (+ 3 4 1)
  • printed representation of both atoms and lists
  • '(+3 4 1) list without evaluation
  • first symbol in list (call)
  • translate lisp expression into another lisp expression
  • Arithmetic
    • +-*/%
    • (/ 7 2) ;3
    • (/7 2.0) ; 3.5
    • (expt 2 3) ; 2^3=8

6. advanced terms

forms - a data object meant to be evaluated as a program to produce one or more values (which are also data objects). One may request evaluation of any data object, but only certain ones are meaningful.

  • symbols and lists are meaningful forms:
    • 3, whose value is 3
    • (+ 3 4), whose value is 7
  • Meaningful forms may be divided into three categories:
    • self-evaluating forms, such as numbers
    • symbols, which stand for variables
    • lists, may be divided into:
      • special forms
      • macro calls
      • function calls.

7. evaluation process and forms

  • file to s-expressions
  • defines syntax of List forms that a built from s-expressions
  • determines which s-expressions are LISP forms.
  • Eval - Returns the result of evaluating an AutoLisp expression.
    • Syntax : (eval expr)
  • when you evaluate a function call form such as (car x), Emacs first evaluates the argument (the subform x). After evaluating the argument, Emacs executes the function (car)
  • Two tupes:
    • Self-Evaluating Forms '123 ⇒ 123, 123 ⇒ 123, (eval '123) => 123
    • Symbol Forms (setq a 123) (eval 'a) => 123, a => 123

LISP form could be:

  • An atom
  • An empty or non-list
  • Any list that has a symbol as its first element

Special Forms - is a primitive function specially marked so that its arguments are not all evaluated

7.1. Special Forms

and

see Combining Conditions catch

see Catch and Throw cond

see Conditionals condition-case

see Handling Errors defconst

see Defining Variables defvar

see Defining Variables function

see Anonymous Functions if

see Conditionals interactive

see Interactive Call lambda

see Lambda Expressions let let*

see Local Variables 2 or

see Combining Conditions prog1 prog2 progn

see Sequencing quote

see Quoting save-current-buffer

see Current Buffer save-excursion

see Excursions save-restriction

see Narrowing setq

see Setting Variables setq-default

see Creating Buffer-Local unwind-protect

see Nonlocal Exits while

see Iteration

8. dialects

https://en.wikipedia.org/wiki/Emacs_Lisp

  • Emacs Lisp or Elisp
  • Common Lisp - for javaVM too
  • Scheme - simple semantics and few different ways to form expressions. more minimalist design
  • Clojure is a recent dialect . mainly the Java virtual machine

8.1. TODO Common lisp vs Emacs Lisp

https://www.gnu.org/software/emacs/manual/html_node/cl/Porting-Common-Lisp.html

  • Case-insensitivity for symbols
    • Common LISP expressions are case-insensitive - cos 45 or COS 45 are same
    • Emacs lisp - case-sensitive

9. types

9.1. basic

everything atom or list

object - instance of type

Linked lists - one of Lisp's major data structures

s-expression or sexp - for code and data structure : (x y z) stands for (x . (y . (z . NIL)))

Constants:

  • Numbers
  • The letter t, that stands for logical true.
  • The value nil, that stands for logical false, as well as an empty list.

atom - is a number or symbol or string in double quotation marks.

symbol - string of contiguous character - can consist of any number of alphanumeric characters other than whitespace, open and closing parentheses, double and single quotes, backslash, comma, colon, semicolon and vertical bar. To use these characters in a name, you need to use escape character (\).

  • hello-from-tutorials-point
  • 123008907
  • hello
  • Block#221
  • abc123
  • +1
  • FOO ; A symbol named ‘FOO’, different from ‘foo’ for Emacs Lisp

list is a Linked lists is a sequence of atoms and/or other lists enclosed in parentheses.

  • Lists in Lisp are not a primitive data type they are built up from "cons cells"
  • "cons cells" - ordered pair - (CAR CDR)
  • each cell refers to the next one: CARs of the cons cells hold the elements of the list, and the CDRs are used to chain the list
  • CDR of the last cons cell in a list is ‘nil’
(setq bouquet '(rose violet buttercup))
     bouquet
      |
      |    --------------       ---------------       ----------------
      |   | car   | cdr  |     | car    | cdr  |     | car     | cdr  |
       -->| rose  |   o------->| violet |   o------->| butter- |  nil |
          |       |      |     |        |      |     | cup     |      |
           --------------       ---------------       ----------------

A string is a group of characters enclosed in double quotation marks. "Hello world!"

primitive types:

  • integer
  • float
  • cons
  • symbol
  • string
  • vector
  • hash-table
  • subr
  • byte-code function
  • record
  • plus several special types, such as buffer, that are related to editing

single inheritance?

single quote: (write '(* 2 3)) - atoms or lists literally and don't want them evaluated or treated as function calls.

  • Quoting - '123, (quote (+ 1 2))
  • Self-Evaluating Forms - evaluate to themselves '123 => 123 (eval '123) => 123

9.2. literals

(print 1e3)
(print 'this-a-symbol)
(print 'vector->list)
(print 'symbol?)

;; Pair / Cons Cell
(print '(a . b))
(print'(a . 2999))

(print "list")
(print'(+ 2 3 (3 4) (5 6 (+ 3 4)) 10 'a 'b "hello" ))

(print "vectors")
(print [1 2 3 4 (+ 1 2 3 54)])

9.3. Association Lists

(alist-get key alist &optional default remove testfn)

9.3.1. clist

values and the keys - may be any Lisp objects

;; Lists
(print '(10 203 40 "hello" () ("empty" 65)))

;; alist
(print '((a . b) (x . y) (2 . 3) (4 . (1 2 3 4 5))))

(print (cons 'a 'b))

(print (cons 'a (cons 'b (cons 'c nil))))

(setq
 vv
 (list
  (cons "aa" 23)
  (cons "bb" 24)
  (cons "cc" 33)))
(print vv)
(print (alist-get "aa" vv 999 nil 'string-equal))

;; get the value with key "bb". if not found, return 999. use string-equal for comparison
;; (print (alist-get "bb" xx 999 nil 'string-equal))

(("aa" . 23) ("bb" . 24) ("cc" . 33))

23
(let (clist)
  (setq clist
          (append (list (cons "sd" "asd"))
                  clist))
  (print clist)
    )

(("sd" . "asd"))

9.3.2. alist - Association Lists

(print '((a  b) (x  y) (2  3) (4  (1 2 3 4 5))))
(print (list (list 'a 'b) (list 'x 'y) (list 2 3) (list 2 '(1 2 3 4 5))))

9.3.3. plist - Property Lists

requires less parenthesis and it is more human readable

two types:

  • Text Properties.
  • Symbol Properties.
  1. Symbol Properties
    get symbol property
    get property from symbol. `eq' used, so any object is a legitimate property.
    put symbol property value
    .
    symbol-plist symbol
    .
  2. ex
    (print '(:key1 value1 :key2 value2 :key3 1002.23 :key4 (a b c d e)))
    (print '(
    :key1  value1
    :key2  value2
    :key3  value3
    :key4  (a b c d e )
    ))
    

9.3.4. functions

(setq dict '((pine . cones)
             (oak . acorns)
             (maple . seeds)))

(print dict)
;; Get a cell associated with a key
(print (assoc 'oak dict))
(print (assoc 'wrong dict))

(print (list
       (car (assoc 'oak dict))
       (cdr (assoc 'oak dict))
       ))
(print (car (assoc 'oak dict)))
;; Get all keys
(print (mapcar #'car dict))
;; Get all values
(print (mapcar #'cdr dict))

9.4. list operators

  • cons construct
  • car return first element of list
  • cdr return all elements of list except of first
  • list wrap to list ()
  • length/seq-length - get length
  • nthcdr n without first n elements
  • nth n get n element, starting from 0
  • last last element of list
  • reverse seq
  • append, nconc add elements to list
  • member, memq - check if there is memeber with equal or eq
  • push add element existing list
  • (setf (alist-get <key> <alist>) <value>)- replace element of list
  • copy-sequence/tree - make copy
  • reverse/nreverse - non destructive and destructive
  • seq-elt get element at index 0 - (len-1)
  • seq-drop [n:]
  • seq-take [:n]

9.4.1. init, append

(defvar cc nil)
(setq cc (cons "asd2" cc))
(print cc)

("asd2" "asd")

9.4.2. indexing

  • (assoc KEY ALIST &optional TESTFN) - value is actually the first element of ALIST whose car equals KEY
  • (assoc-string KEY LIST &optional CASE-FOLD) - for strings
(defconst sisheng-vowel-table
  '(("ā" "a" "ā" "á" "ǎ" "à")
    ("ē" "e" "ē" "é" "ě" "è")
    ("ī" "i" "ī" "í" "ǐ" "ì")
    ("ō" "o" "ō" "ó" "ǒ" "ò")
    ("ū" "u" "ū" "ú" "ǔ" "ù")
    ("ǖ" "v" "ǖ" "ǘ" "ǚ" "ǜ")
    ("üē" "ve" "üē" "üé" "üě" "üè")))

(print (assoc-string "üē" sisheng-vowel-table))

("üē" "ve" "üē" "üé" "üě" "üè")

9.4.3. cons, car, cdr

;; (print (cons 'pine '(fir oak maple)))
(print (list
 (cons 'pine '(fir oak maple))
 (car '(rose violet daisy buttercup))
 (cdr '(rose violet daisy buttercup))
 ))

((pine fir oak maple) rose (violet daisy buttercup))

9.4.4. nthcdr, nth, setcar, setcdr

(list
 (nthcdr 2 '(rose fir oak maple))
 (nth 2 '(rose fir oak maple))
 (nth 1 '(rose fir oak maple))
 )

setcar

(setq animals (list 'antelope 'giraffe 'lion 'tiger))
(print animals)
(print (setcar animals 'hippopotamus) )
(print animals)

setcdr

(setq animals (list 'antelope 'giraffe 'lion 'tiger))
(print animals)
(print (setcdr animals 'hippopotamus) )
(print animals)

9.4.5. length, nth, cl-position, car, cdr, cons, reverse, append, remove-if-not, null, delq, push, pop

(print (length '(1 2 3 4 5 6)))
;; nth element of a list
(print (list
(nth 0 '(0 1 2 3 4 5))
(nth 5 '(0 1 2 3 4 5))
(nth 10 '(0 1 2 3 4 5))
))

;; Position of list element (emacs 24.4 or later)
(print (cl-position 7 '(5 6 7 8)))

;; cdr - Removes first element of the list, returns the list tail.
(print  (cdr '(1 2 3 4 5)))
;; car - Returns the first list element
(print (car '(1 2 3 4 5)))
;; cons -  List constructor

(print (cons 10 '(1 2 3 4)))

;; reverse
(print (reverse '(1 2 3 4 5)))

;; append
(print (append '(1 "s") '( "a" "b" "c" "d")))

;; (print (remove-if-not (lambda (x) (> x 2))     '(1 2 3 4 5 6 7 8 9 10)))
(print (list
        (null '(1 2 3 4 5))
        (null '())
        (null nil)))

;; Drop the firsts n elements of a list
(print (nthcdr 2 '(1 2 3 4)))

;; Delete an element of a list
(print (delq 1 '(1 2 3 4)))
(print (delq '(5) '(1 2 (5) 3 4)))
(print (delete '(5) '(1 2 (5) 3 4)))

;; Convert Vector to List
(print (number-sequence 0 10 2))

;; Modify list variables.
(setq alist '(a b c d e))
(print (push 'f alist))
(print (pop alist))
(print alist)
(print "asd")

(f a b c d e)

f

(a b c d e)

"asd"

9.4.6. nconc

9.4.7. map

  • (mapcar function sequence)
  • (seq-some PRED SEQUENCE) - nil or first non-nil value returned by PRED.
(print (mapcar #'1+ [1 2 3]))

(2 3 4)
(setq properties '((a . 1)
                (b . 2)
                (c . 3)))
;; (print properties)
(seq-some (lambda (property) (print property)) properties)
(seq-some (lambda (property)
            (print (car property))
            (let
                  (print (car property)) )) ;; predicate for every property
                 properties)

(a . 1)

a

b

c

https://www.gnu.org/software/emacs/manual/html_node/elisp/Mapping-Functions.html

9.5. symbol type

is literal (not evaluated).

  • (symbolp sym) - Test if variable sym is a symbol
  • (symbol-name 'sym) - ;; Get symbol as string

Get value from a symbol

  • (symbol-value 'sym)
  • (symbol-function 'sym)
  • (symbol-plist 'sym)

Test if function is an elisp primitive

(subrp (symbol-function 'goto-char))
; Convert a symbol to string
(print (symbol-name 'wombat))
; Convert a String to Symbol
(print (intern "wombat"))

9.6. nil and t - special symbols that always evaluate to themselves

  • symbol nil has three separate meanings:
    • it is a symbol with the name ‘nil’;
    • it is the logical truth value false;
    • it is the empty list—the list of zero elements.
  • When used as a variable, nil always has the value nil.
  • we write () when we wish to emphasize that it means the empty list, and we write nil when we wish to emphasize that it means the truth value false.
    • (cons 'foo ()) ; Emphasize the empty list
    • (setq foo-flag nil) ; Emphasize the truth value false
  • non-nil value is considered to be true
  • t is the preferred way to represent the truth value true
  • The symbol t always has the value t.

;;; Everything that is not "nil" is true:

9.7. type conversion

(list
 (cl-coerce '(a b c) 'vector)
 (cl-coerce 7.2 'float)
 (cl-coerce "a" 'character)
 (format "%s" 33.2222)
)

; Number <-> String
(print (number-to-string 1000))
(print (string-to-number "200"))

; Symbol <-> String
(print (symbol-name 'my-symbol))
(print (symbol-name :my-symbol))
; String to Symbol
(print (intern "some-symbol"))

9.8. get type

(print (list
 (type-of "a")
 (type-of 7.2)
 (type-of 'type-of)
))

(print (equal 'buffer (type-of (current-buffer))))

9.9. Basic Types Predicate

Type Predicate Literal Description
Nil null nil '() Test if argument is nil
Number numberp 100, 200e3 Test if it is number.
String stringp "hello" Test if it is string
Symbol symbolp 'sym :keyworkd Test if it is a symbol.
Atom atom 'x "h" :key 200 Everything that is not a list or pair is an atom.
List listp '(1 2 x y) Test if it is a list
Pair consp '( a . 200) Test if it is a pair (cons cell)
Vector vectorp [1 200 'sym] Test if it is a vector
Object Predicate
Buffer bufferp
Window windowp
Frame framep
Process processp
(print (atom 10))
(print (null nil))

10. char

no way to distinguish integer from char.

  • get char at postion in string: (aref "foo" 0)
  • int/char to string: (char-to-string CHAR)
(equal 97 ?a ) ;; t
(equal 97 (string-to-char "a")) ;; t
(let (az)
  (dolist (h (number-sequence 97 122)) (setq az (cons (char-to-string h) az)) )
  (print az)
  )

("z" "y" "x" "w" "v" "u" "t" "s" "r" "q" "p" "o" "n" "m" "l" "k" "j" "i" "h" "g" "f" "e" "d" "c" "b" "a")

http://xahlee.info/emacs/emacs/elisp_char_datatype.html

11. strings

  • (format "notify-send –expire-time 5000 -i emacs '%s'" msg)
  • (substring "abcdefg" 0 3) ⇒ "abc"
  • (concat "abc" "-def") ⇒ "abc-def"
  • (split-string " two words ") ⇒ ("two" "words")
  • (length "abc");; 3
  • (string-to-number "3")
  • (number-to-string 3)
  • (format "%d" 3) ;; same as number-to-string but can also do format
  • endswith: (string-suffix-p "ending" a)
  • startswith: (string-prefix-p "beg" a)
  • compare string insensitive: (string-equal-ignore-case "a" "b")
  • replace substring: (defun string-replace (from-string to-string in-string)
  • split string: split-string (string &optional separators omit-nulls trim)
  • combine-and-quote-strings (strings &optional separator)
  • to characters: (split-string "abc" "" t) => ("a" "b" "c")

libs:

  • subr.el

links

11.1. ex

(print (mapconcat 'identity '("aaa" "bbb" "ccc") ","))
(print (split-string "aaa,bbb,ccc" ","))
(print (string-match "ce" "central park"))
(print (make-string 5 ?x))
; S-expression from String
(print (read-from-string
            "(
               (POINT1  (X  10.2323)  (Y   20.2323))
               (POINT2  (x  0.2)          (Y 923.23))
               (POINT3  (x -10.5)       (Y 78,23))
             )"))

(setq raw "(:x 10 :y 20 :z 30 :w \"hello world\")")
(print (read raw))
(print (plist-get (read raw) :x))

; Serialize a s-expression
(setq sexp '(:x 10 :y 20 :z 30 :w "hello world"))
(print (prin1-to-string sexp))

"aaa,bbb,ccc"

("aaa" "bbb" "ccc")

0

"xxxxx"

(((POINT1 (X 10.2323) (Y 20.2323)) (POINT2 (x 0.2) (Y 923.23)) (POINT3 (x -10.5) (Y 78 (\, 23)))) . 174)

(:x 10 :y 20 :z 30 :w "hello world")

10

"(:x 10 :y 20 :z 30 :w \"hello world\")"

12. variables

12.1. terms

a symbol with a value or a function definition attached to it. variable is a symbol that has a value, not function. use of a symbol as a variable is independent of its use as a function name.

scoping rule - default dynamic scoping - current binding as the innermost local binding, or the global binding if there is no local binding.

  • lexical scoping - .all Emacs Lisp source files and the scratch buffer use lexical scoping. ( can be enabled on a per-buffer basis. buffer-local variable ‘lexical-binding’ to a non-nil value. or ;; -- lexical-binding: t -- in library)

local

  • function arguments
  • local bindings

Generalized Variables - special places that accept assignment with setf. (setf (car a) b)

12.2. usage

12.2.1. global or global binding:

  • (setq x '(a b)) - evaluate only second, set global, replaces the variable
  • (setq-default [VAR VALUE]…) - If a variable is buffer-local, then setq sets its local value in the current buffer. setq-default sets the global default value.
  • (setf PLACE VAL PLACE VAL …) - macro
  • (set 'x '(a b)) - both evaluated first ( same effect as setq). Function.
  • defvar symbol [value [doc-string]] - global, announces your intention
    • (defvar bar 23 "The normal weight of a bar.")
    • for
      • it informs people that is intended to be used as a variable
      • it informs the Lisp system of this, optionally supplying an initial value and a documentation string.
      • it provides information to programming tools such as ‘etags’, allowing them to find where the variable was defined.
  • defconst symbol value [doc-string] - variant for constants, constant is not enforced, may be changed!
    • (defconst zsh-shell "/usr/bin/zsh")
  • setq-default - for buffer, macro: set-default
(defvar a 3)
(print a)
(defvar a 4) ;; second ignored
(print a)

3

3

12.2.2. reference

(setq a 3)
(setq v 'a)
(set v 2) ; v is evaluated first
(print a)

2

12.2.3. local:

  • setq-local - macro: ? + make-local-variable
  • let (bindings…) forms… - The local bindings set up by let will be in effect only within the body of forms.
    • bindigs - set of symbols, the order of bindings is unspecified.
    • value-forms - are evaluated in the order they appear and before binding any of the symbols to them.
    • return: value is the value of the last form in forms.
    • ex. (let ((x 2)(y 'b)(z 'c)) (print x))
  • let* - like let, but it binds each variable right after computing its local value, with order.
  • (boundp 'sym) - Test if variable is defined
  • symbolp Test if variable sym is a symbol
  • symbol-value - returns the value stored in SYMBOL’s value cell.
    • (symbol-value 'abracadabra)
  • defvar-local - buffer-local variable, macro: defvar + make-variable-buffer-local
  • buffer-local-value - get buffer-local variable from another buffer
  • setq-default
  • (setq-default left-margin-width 10 right-margin-width 8)
(defvar ssss (+ 1 1))
(print ssss)

2

12.3. Dynamic Scoping (Local Variables) and lexical scoping

  • (makunbound 'x) ; Void the local binding.
(print (let ((x 1) (y 10)) (+ (* 4 x) (* 5 y)) ))
;; (print x) ;; Symbol's value as variable is void: x
;; (print y)

Problem of dynamic scoping, that lexical scoping is fixing:

(defun getx ()
  x)            ; x is used free in this function.

(let ((x 1))    ; x is lexically bound.
  (getx)) ;; error→ Symbol's value as variable is void: x

12.4. Generalized Variables

setf [place form] …

aref
Return the element of ARRAY at index IDX. ARRAY: vector, a string, a char-table, a bool-vector, a record,

or a byte-code object.

car
first element of list
caar
(car (car
cadr
(car (cdr
cdr
second and left of list
cdar
(cdr (car
cddr
(cdr (cdr
elt
Return element of SEQUENCE at index N.
get
Return the value of SYMBOL’s PROPNAME property.
gethash
Look up KEY in TABLE and return its associated value.
nth
Return the Nth element of LIST.
nthcdr
Take cdr N times on LIST, return the result.
symbol-function
Return SYMBOL’s function definition, or nil if that is void.
symbol-plist
.
symbol-value
.

12.5. ex

z is bound to the old value of y, which is 2, not the new value of y, which is 1.

(setq y 2)
(let ((y 1) ;; define y
      (z y)) ;; define z
  (list y z)) ;; evaluate
(list y z) ;; error z is not defined
(let (aaa) (setq aaa 2) (list aaa))

13. control structures: sequencing, conditions, Iteration

13.1. conditions

  • cond (cond (test1 action1) (test2 action2) (condition body-forms…) … )
    • (condition body-forms…)
  • when (when (test-clause) (action1) (action2) … ) - alternative to if without else and requirement for (progn
  • if (if (test-clause) (then-action1) (else-action2))
  • case (case (keyform) ((key1) (action1 action2 …) ((key2) (action1 action2 …) ) … )
  • (not),
  • (and), If no arg yields nil, return the last arg’s value.
  • (or), (xor)
  • (unless cond - (when nil

13.1.1. test-clause

  • (null nil/t)
  • Comparison Operations
    • = Checks if the values of the operands are all equal or not, if yes then condition becomes true. (= A B) is not true.
    • /= Checks if the values of the operands are all different or not, if values are not equal then condition becomes true. (/= A B) is true.
    • > Checks if the values of the operands are monotonically decreasing. (> A B) is not true.
    • < Checks if the values of the operands are monotonically increasing. (< A B) is true.
    • >= Checks if the value of any left operand is greater than or equal to the value of next right operand, if yes then condition becomes true. (>= A B) is not true.
    • <= Checks if the value of any left operand is less than or equal to the value of its right operand, if yes then condition becomes true. (<= A B) is true.
    • max It compares two or more arguments and returns the maximum value. (max A B) returns 20
    • min It compares two or more arguments and returns the minimum value. (min A B) returns 10
  • Logical Operations
    • and
    • or
    • not
  • any: (not (cl-every 'null))
  • all:
  • (cl-every 'booleanp) ; nil or t
a b eq eql \= string= equal equalp
5 5 t t t error t t
5 5.0 nil t t error nil t
“a” “a” nil nil error t t t
“a” ‘a nil nil error t nil nil
a a t t error error t t
“a” “A” nil nil error nil nil t
(1 2) (1 2) nil nil error error t t

13.1.2. if else

(if (> 3 5)
  ;; if case
    (print "< 3 5")
  ;; else case
    (print ">= 3 5")
    (print "else again")
    )

; else if:
(if  (> 3 5) ; test-expression1
    (print "> 3 5") ; then-expression1
    (if (= 3 5) ; test-expression2
        (print "== 3 5") ; then-expression2
        (print "/= 3 5") ; else-expression2
      )
    )

;; ; else if 2:
(cond ( (= 1 0) ; test-expression1 ; if true - Any remaining clauses are ignored.
       (print "=x 1 0") ; then-expression1
       )
      ((>  3 3) ; test-expression2
       ; then-expression2
       (print "> 3 3")
       )
      (t (print "default") ; else-expression2 or default expression
       )
      )

13.1.3. comparison

;; Compare Numbers
(setq a 2)
(print (= 2 (+ a 1)))
(print (= 2 (+ 1 1)))

;; Compare Symbols and Numbers
(print (eq a 2))

;; Compare Elements of a List
(print (equal (list 1 2 3 4) (list 1 2 3 4)))

(print "Compare Strings")
(print (string= "hello" "hello"))


nil

t

t

t

"Compare Strings"

t

13.1.4. nil and empty

nil is equivalent to the boolean value false, there is no need to compare to it explicitly.

empty list is equivalent to nil

invert true to false: (null) or (not)

  • (null '()) => T
  • (null nil) => T
  • (null t) => NIL
  • (null 1) => NIL
(if nil
    (print 'true)
  'very-false)

13.1.5. cond

(cond
     (win (select-window win))
     (alive-p (switch-to-buffer last-buffer))
     (t (dired (cdr item))))

13.2. while

(setq num 0)
(while (< num 4)
  (print (format "Iteration %d." num))
  (setq num (1+ num))
  )

13.3. case

13.3.1. cl-case

(defun test-cl-case (operation x y)
  (cl-case operation
    (:mul (* x y))
    (:add (+ x y))
    (:sub (- x y))
    (:div (/ x y))
    (otherwise nil)))

(print (test-cl-case :mul 2 10))
(print (test-cl-case :sub 10 2))
(print (test-cl-case :add 10 2))
(print (test-cl-case :div 10 2))

13.3.2. pcase

(pcase "string here"
  ;; string
  ((and (pred stringp) msg)
   (message "%s" msg))

  ;; symbol
  ('success       (message "Done!"))
  ('would-block   (message "Sorry, can't do it now"))
  ('read-only     (message "The shmliblick is read-only"))
  ('access-denied (message "You do not have the needed rights"))

  ;; default
  (code           (message "Unknown return code %S" code)))

string here

13.4. loops

(cl-loop for n from 2 below 9 by 1
      do (print n))

2

3

4

5

6

7

8
(dolist (h (number-sequence 4 6))
        (print h)
)


4

5

6
(dolist (h '(a b c))
  (print h))
;; (dolist (h string("abc"))
;;   (print h))
(print (string-to-char "asd"))
(dotimes (i 3) (print i))
(do (variable-definition*)
    (end-test-form result-form*)
  statement*)

14. functions

14.1. progn

  • (progn BODY…) - Eval BODY forms sequentially and return value of last one.
  • prog1 for instance evaluates all expressions and returns the value of the first
  • prog2 evaluates all expressions and returns the value of the second

14.2. defun

  • defines the symbol name as a function with argument list args
  • Neither name nor args should be quoted.
  • The return value of defun is undefined.
  • Careful! defun redefines even primitive functions such as car without any hesitation or notification.
  • fmakunbound - undefine

(defun function-name (a &optional b &rest c) "optional-documentation…" (interactive argument-passing-info) (indent indent-spec) ; declare Form body…)

14.3. arguments

arguments can have clauses or markers: (required-vars… [&optional [optional-vars…]] [&rest rest-var])

  • &optional
  • &rest - list of arguemnts
(defun a (&optional v)
       (print v)
)
(a)

nil

https://www.gnu.org/software/emacs/manual/html_node/elisp/Argument-List.html

14.4. Function Calling

(print (funcall 'list '(1 2 3)))
(print (apply 'list '(1 2 3)))

((1 2 3))

(1 2 3)
(defun a (&optional v foo  c d &rest e)
       (interactive)
       (print (list v foo c d e)))
(a 1 2 3 4 5)
(defun b (&rest e)
       "function proxy"
       (interactive)
       (if (interactive-p)
           ;; (funcall-interactively 'a e)
           ;; (call-interactively 'a)
           (apply 'funcall-interactively 'a e)
         ;;else
         (apply 'a e))
  ;; (print e)
)
(print (vector (list 1 2 3 4) (list 1 2 3 4)))
(call-interactively 'a)
(call-interactively 'b)
(b 1 2 3 4 5)
(print "----")
(funcall-interactively 'a 1 2 3 4 5)
(funcall-interactively 'b 1 2 3 4 5)

(1 2 3 4 (5))

[(1 2 3 4) (1 2 3 4)]

(nil nil nil nil nil)

(nil nil nil nil nil)

(1 2 3 4 (5))

"----"

(1 2 3 4 (5))

(1 2 3 4 (5))
(defun averagenum (n1 n2 n3 n4)
  (/ ( + n1 n2 n3 n4) 4)
  )
(averagenum 2 3 4 10 )
;; 4


(setq f 'list)
;;     ⇒ list

(funcall f 'x 'y 'z)
  ;;   ⇒ (x y z)
(defun bar (n) (+ n 2))
(symbol-function 'bar)
;;     ⇒ (lambda (n) (+ n 2))

(fset 'baz 'bar)
  ;;   ⇒ bar

(symbol-function 'baz)
    ;; ⇒ bar

14.5. Named parameters:

To be able to supply arguments by name, we need to

  • declare them with &key <name>
  • we set them with :name <value>

Default values to key parameters:

  • &key (<name> <value>)
(defun hello (name &key happy)())
(hello "me" :happy t)

(defun hello (&optional name &key happy)())
(hello "me" :happy t)

14.6. lambda

  • A lambda expression, by itself, has no name; it is an anonymous function.
  • result is a closure object
  • they are more commonly associated with symbols to make named functions
  • A lambda form cannot be evaluated and it must appear only where LISP expects to find a function.

Macro: lambda args [doc] [interactive] body…

(lambda (x) (* x x)) ⇒ (lambda (x) (* x x))

14.6.1. Inline Functions

  • just like an ordinary function, except for one thing: when you byte-compile a call to the function the

function’s definition is expanded into the caller.

  • calls run faster
  • it reduces flexibility; if you change the definition of the function, calls already inlined still use the old definition until you recompile them.

defsubst name args [doc] [declare] [interactive] body…

14.6.2. Special Form: function function-object

  • returns function-object without evaluating it
  • it is similar to quote
  • function-object is a valid lambda expression, this has two effects
    • When the code is byte-compiled, function-object is compiled into a byte-code function object
    • When lexical binding is enabled, function-object is converted into a closure

All equal: (lambda (x) (* x x)) (function (lambda (x) (* x x))) #'(lambda (x) (* x x))

14.7. closure

A closure is a function that also carries a record of the lexical environment that existed when the function was defined. When it is invoked, any lexical variable references within its definition use the retained lexical environment.

Lambda macro or the function special form or the #' syntax (see Anonymous Functions), is automatically converted into a closure When lexical binding is enabled.

14.8. Interactive Functions

  • A Lisp function becomes a command when its body contains, at top level, a form that calls the special form `(interactive…)’.
  • This special form does nothing when executed, but its presence in the function definition indicates that interactive calling is permitted.
  • Its argument controls the reading of the function arguments in an interactive call.
  • In interactive function all arguments should be after &optional or &rest to be called with (call-interactively

(interactive &optional arg-descriptor &rest modes)

  • arg-descriptor: a string, sequence of elements separated by newlines
    • P - raw prefix
    • p - numeric prefix

(call-interactive mode) - will switch off mode if mode is on.

14.8.2. ex

(defun hello ()
       "Hello World and you can call it via M-x hello."
       (interactive)
       (print "Hello World!"))
(call-interactively 'hello)

"Hello World!"
(defun hello (&optional arg arg2)
       (interactive "P\np")
       ;; (print "%s" arg)
       (if  (eq arg2 4)
           (print "asd"))
       (print (list arg arg2 arg3))
)
(funcall-interactively 'hello '(1) 2 3)
(apply 'funcall-interactively 'hello '(nil 2))
;; use: C-u M-x hello

((1) 2 (3))

(nil 2 nil)

14.9. arguments

  • (lambda (a b c) (+ a b c)) - 3 arguments
  • keyword &optional before the optional arguments
  • To specify a list of zero or more extra arguments, include the keyword &rest before one final argument.
  • (a b &optional c d &rest e) - here c and d optional and e is a list

14.10. Functions with Property List argument

(defun make-shell-interface (&rest params)
  "
  Create a shell interface.

  Possible parameters:

    :name      Name of shell
    :type      ['sh, 'bash, ...]
    :path      Path to program
    :buffer    Name of buffer

  "
  (let
       ((name   (plist-get params :name ))
        (type   (plist-get params :type))
        (path   (plist-get params :path))
        (buffer (plist-get params :buffer)))
    (list
     (cons 'name buffer)
     (cons 'type type)
     (cons 'path path)
     (cons 'buffer buffer))))


(print (make-shell-interface :name "pylaucher" :path "/usr/bin/python" :type 'sh :buffer "pyshell"))
;; ((name . "pyshell")
;;  (type . sh)
;;  (path . "/usr/bin/python")
;;  (buffer . "pyshell"))

(print (make-shell-interface :name "pylaucher" :path "/usr/bin/python" :type 'sh))
(print (make-shell-interface :name "pylaucher" :path "/usr/bin/python" :type 'bash))
;; ((name)
;;  (type . bash)
;;  (path . "/usr/bin/python")
;;  (buffer))

;; ELISP> (make-shell-interface :name "pylaucher" :path "/usr/bin/python")
;; ((name)
;;  (type)
;;  (path . "/usr/bin/python")
;;  (buffer))

;; ELISP> (make-shell-interface :name "pylaucher" )
;; ((name)
;;  (type)
;;  (path)
;;  (buffer))

;; ELISP> (make-shell-interface  )
;; ((name)
;;  (type)
;;  (path)
;;  (buffer))

;; ELISP> (make-shell-interface :buffer "pyshell"  :path "/usr/bin/python" :type 'sh :name "pylaucher")
;; ((name . "pyshell")
;;  (type . sh)
;;  (path . "/usr/bin/python")
;;  (buffer . "pyshell"))

14.11. return

(info "(elisp) Nonlocal Exits").

  • Throw
  • block (info "(cl) Blocks and Exits")
  • cl-defun
  • defun*
(defun my-func ()
  "Simplistic `catch'/`throw' example."
  (catch 'my-early-return
    (when t
      (throw 'my-early-return "this is the short-circuit result of catch"))
    "this is the fallback result of catch"))

15. printing

  • print - Print a newline at end.
  • princ - does not add newline at end. intended to produce output that is readable by people
  • prin1 - does not add newline at end.
  • format
  • message - Print a Format String to the Messages Buffer.
  • insert - Instert string to current buffer, at cursor position.
(princ '("as" "asd"))
(print '("as" "asd"))
(pp '("as" "asd"))
(setq xbuff (generate-new-buffer "*my output*"))

(print "something" xbuff)

(switch-to-buffer xbuff )

16. Macros

  • expansion - Lisp expression which will in turn compute the value.

macro cannot be called with apply, mapcar and so on

(macroexpand - expands form, if it is a macro call. If the result is another macro call, it is expanded in turn, until something which is not a macro call results

(defmacro inc (var)
   (list 'setq var (list '1+ var)))
(setq x 2)
(defun z(c)
    (inc c))
(inc x)
(z 3)
(defmacro setq2 (v1 v2 e)
  (list 'progn (list 'setq v1 e) (list 'setq v2 e)))

(setq z 1)

(setq2 x y (+ z 3))

(defmacro setq2 (v1 v2 e)
  (list 'progn (list 'setq v1 e) (list 'setq v2 e)))

(print (macroexpand '(setq2 x y (+ x 2)) ) )

(progn (setq x (+ x 2)) (setq y (+ x 2)))

16.1. inline function

function’s definition is expanded into the caller

defsubst name args [doc] [declare] [interactive] body…

inline it as a compiler macro - more efficient.

define-inline name args [doc] [declare] body… ¶
  • (inline-quote expression) -
  • inline-letevals (bindings…) body… - This provides a convenient way to ensure that the arguments to an inlined function are evaluated exactly once, as well as to create local variables.
  • inline-const-p expression - Return non-nil if the value of expression is already known.
  • inline-const-val expression - Return the value of expression.
  • inline-error format &rest args - Signal an error, formatting args according to format.
(define-inline myaccessor (obj)
  (inline-letevals (obj)
    (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))

;; equal to:
(defsubst myaccessor (obj)
  (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2)))

17. regex

17.1. characters:

  • special
  • ordinary

normal escaping \[, for lisp: "\\[", also:"\n", "[ [:space:] ]"

17.2. commands

  • (looking-back "\n\\** ?" 2) - before point matches regular
  • (looking-at "" ) - after point matches regular
  • (rx …
(print (rx bol
  (zero-or-more blank)
  (one-or-more digit)
  ":"))

"^[[:blank:]]*[[:digit:]]+:"

17.3. special characters

  • . any character (but newline)
  • * previous character or group, repeated 0 or more time
  • + previous character or group, repeated 1 or more time
  • ? previous character or group, repeated 0 or 1 time
  • *?, +?, and ?? are non-greedy versions of *, +, and ?
  • ^ start of line
  • $ end of line
  • […] any character between brackets
  • [^..] any character not in the brackets
  • [a-z] any character between a and z
  • \ prevents interpretation of following special char
  • \| or
  • \w word constituent
  • \b word boundary
  • \sc character with c syntax (e.g. \s- for whitespace char)
  • \( \) start/end of group
  • \&lt; \&gt; start/end of word (faulty rendering: backslash + less-than and backslash + greater-than)
  • \_< \_> start/end of symbol
  • \` \' start/end of buffer/string
  • \1 string matched by the first group
  • \n string matched by the nth group
  • \{3\} previous character or group, repeated 3 times
  • \{3,\} previous character or group, repeated 3 or more times
  • \{3,6\} previous character or group, repeated 3 to 6 times
  • \= match succeeds if it is located at point

17.4. groups

C-u C-x = to display the category of the character under the cursor.

  • \ca ascii character
  • \Ca non-ascii character (newline included)
  • \cl latin character
  • \cg greek character
  • [:digit:] a digit, same as [0-9]
  • [:alpha:] a letter (an alphabetic character)
  • [:alnum:] a letter or a digit (an alphanumeric character)
  • [:upper:] a letter in uppercase
  • [:lower:] a letter in lowercase
  • [:graph:] a visible character
  • [:print:] a visible character plus the space character
  • [:space:] a whitespace character, as defined by the syntax table, but typically [ \t\r\n\v\f ], which includes the newline character
  • [:blank:] a space or tab character
  • [:xdigit:] an hexadecimal digit
  • [:cntrl:] a control character
  • [:ascii:] an ascii character
  • [:nonascii:] any non ascii character
  • \s- whitespace character
  • \sw word constituent
  • \s_ symbol constituent
  • \s. punctuation character
  • \s( open delimiter character
  • \s) close delimiter character
  • \s" string quote character
  • \s\ escape character
  • \s/ character quote character
  • \s$ paired delimiter
  • \s' expression prefix
  • \s< comment starter
  • \s> comment ender
  • \s! generic comment delimiter
  • \s| generic string delimiter
  • \W, \B, and \Sc match any character that does not match \w, \b, and \sc.
;; (print (string-match-p "^[:print:]+" "fsd"))
(print (string-match-p "^[[:print:]]$" "f"))
;; (print (string-match-p "^a+" "fsd"))

0

18. paths

default-directory - buffer-local variable with directory of current buffer file.

19. Emacs Code Conventions

  • M-x checkdoc.

19.1. variable name conventions

‘…-hook’ The variable is a normal hook (*note Hooks::).

‘…-function’ The value is a function.

‘…-functions’ The value is a list of functions.

‘…-form’ The value is a form (an expression).

‘…-forms’ The value is a list of forms (expressions).

‘…-predicate’ The value is a predicate—a function of one argument that returns non-‘nil’ for success and ‘nil’ for failure.

‘…-flag’ The value is significant only as to whether it is ‘nil’ or not. Since such variables often end up acquiring more values over time, this convention is not strongly recommended.

‘…-program’ The value is a program name.

‘…-command’ The value is a whole shell command.

‘…-switches’ The value specifies options for a command.

‘PREFIX–…’ The variable is intended for internal use and is defined in the file ‘PREFIX.el’. (Emacs code contributed before 2018 may follow other conventions, which are being phased out.)

‘…-internal’ The variable is intended for internal use and is defined in C code. (Emacs code contributed before 2018 may follow other conventions, which are being phased out.)

19.2. commands

  • (;) - comment on the same line
  • (;;) - comment on the new line

19.3. recommendation

20. examples

1s

 (list 1 2 (quote foo))
 (setq x (+ x 1)) = (incf x)


 ;;;; COMMENT-EXAMPLE function
 ;;; This function is useless
 ;;; except demonstrate comments.

 (defun asdas (x y)     ;X is anything
         ;; X is now not a list
         ((sumbolp x)


21. USE CASES

sort numbers:

  • (sort '(1 2 3) '(lambda (a b) (< a b)))
  • (sort '(2 4 7 3 9 1 5 4 6 3 8) #'<)

21.1. measure time of execution of any function

(defun my/time-call (time-call &rest args)
  (message "Ohai %s" args)
  (let ((start-time (float-time))
        (org-babel-python-command "/usr/bin/timeout 15 python")
        )
    (apply time-call args)
    (message "Call took %f seconds" (- (float-time) start-time)))
  )
(advice-add 'org-babel-python-evaluate-external-process :around #'my/time-call)

21.2. working with tabular data

Save to .org file

Name Math English Science
Alice A B C
Bob B A B
Charlie C A A
(mapc (lambda (student)
        (let ((name (car student))
              (math (nth 1 student))
              (english (nth 2 student))
              (science (nth 3 student)))
        (with-temp-buffer
          (insert (concat "Name: " name "\n"))
          (insert (concat "Math: " math "\nEnglish: " english "\nScience: " science "\n"))
          (write-region (point-min) (point-max) (concat name ".org"))
          ;; Export PDF
          ;; (find-file (concat name ".org"))
          ;; (org-latex-export-to-pdf)
          )))
      students)
(print "Operation finished.")

"Operation finished."
Wrote /home/u/tmp/Alice.org
Wrote /home/u/tmp/Bob.org
Wrote /home/u/tmp/Charlie.org

22. Emacs Lisp

  • introduction https://www.gnu.org/software/emacs/manual/html_mono/eintr.html
  • short http://ergoemacs.org/emacs/elisp_basics.html
  • function may reference local varibles in the scope it is called from, but not in the scope it was defined.
  • REPL mode: M-x ielm
  • cl.el
  • .elc - byte compiled code
  • (message "hi %d") ; %d number, %s string %S - lisp expression. - to buffer "Messages" C-h e
  • (if nil "yes" "no") ; "no" ; (), '(), (list)
  • (if t "yes" "no") ; "yes"; 0, "", [] - vector of 0 elements
  • (not (and (or (< (<= (>= (= (/= not equal. Comparing strings: (equal (string-equal
  • (equal - if same type and value
  • (eq - if same Lisp object

22.1. help

  • get help:
    • F1 f
    • F1 S - descrybe symbol

22.2. Keys:

  • <TAB> Indent line
  • M-C-\ Indent region
  • M-; Comment
  • C-x ; Set comment column
  • <ESC> <TAB> Completion for Symbol Names

Info:

  • C-h S Info documentation for symbol
  • M-x woman or man for operation system command, library function or system call.
  • C-h f Emacs Lisp functions
  • c-h v Emacs Lisp variable
  • C-x C-e eval-last-sexp - Evaluate the expression to the left of cursor.

22.3. Commands

  • C-M-x (eval-defun)
  • M-: (eval-expression)

22.4. ask user input

(if (y-or-n-p "Do it?")
    (progn
      ;; code to do something here
    )
  (progn
    ;; code if user answered no.
  )
)

22.5. suppress messages by function and subfunctions

(defun suppress-messages (old-fun &rest args) (cl-flet ((silence (&rest args1) (ignore))) (advice-add 'message :around #'silence) (unwind-protect (apply old-fun args) (advice-remove 'message #'silence)))) (advice-add 'server-execute :around #'suppress-messages)

22.7. defcustom

right way to set it in .emacs:

  • (setopt global-subword-mode t) if you have emacs 29 or later Wed
  • or (customize-set-variable global-subword-mode t)
(defcustom text-mode-hook nil
  "Normal hook run when entering Text mode and many related modes."
  :type 'hook ;; tells Emacs the kind of data to which text-mode-hook should be set and how to display the value in a Customization buffer.
  :options '(turn-on-auto-fill flyspell-mode) ;; keyword specifies a suggested list of values for the variable
  :group 'wp) ;;  in which group the variable is located.

# Emacs automaically manage this with M-x customize
(custom-set-variables  '(text-mode-hook '(turn-on-auto-fill text-mode-hook-identify)))

22.8. map

src/fns.c

(mapc FUNCTION SEQUENCE) Apply FUNCTION to each element of SEQUENCE for side effects only.

(mapcar FUNCTION SEQUENCE) Apply FUNCTION to each element of SEQUENCE, and make a list of the results.

(setq full-range '(1 2 3 4))
(setq re (mapcar (lambda (arg) (/ arg 2)) full-range))
(print re)

(0 1 1 2)

22.9. buffers

  • buffer-string - get buffer text as string with properties
  • (buffer-substring-no-properties (point-min) (point-max)
  • (buffer-name)

22.10. cl-loop

cl-macs.el

(cl-loop for handler in some_list until (condition-case …

22.11. convetions and style guide

comments:

  • ; - used at the end of line
  • ;; - used in code as separate line
  • ;;; We use them for comments that should be considered a heading by Outline minor mode.
  • on’t end headings with a colon : or any other punctuation.

naming:

  • Prefix unused local (lexically scoped) variables with _. (lambda (x _y) x)
  • – to denote private top-level definitions . projectile--private-fun
  • lowercas with - separator: some-var

functions:

22.12. testing

22.12.1. ERT: Emacs Lisp Regression Testing

build-in file:///usr/share/emacs/29.1/lisp/emacs-lisp/ert.el

  • C-h i m ert RET
  • $info ert
  1. ex
    (require 'ert)
    ;; (require 'tested-module)
    (ert-deftest csv-tests-end-of-field ()
      (with-temp-buffer
        (should (= (+ 1 2) 4)))
    )
    ;; execute test programmatically
    (ert-run-tests-interactively "csv-tests-end-of-field")
    
  2. links

23. MELPA

https://github.com/melpa/melpa

  • M-x package-recipe-mode
  • M-x package-build-current-recipie
  • fork https://github.com/melpa/melpa/
  • git clone own/melpa
  • git branch recipe
  • git checkout recipe
  • git cp ~/recipe own/melpa/recipies/
  • git add
  • git push

23.1. lint

M-x package-install package-lint

usage: package-lint-current-buffer

23.2. byte-compile

M-x byte-compile-file

24. errors handling

  • signals - exception
  • cleanup expressions - catch for exception
  • error symbol - describes what kind of error it is, and which describes also a list of condition name

unwind-protect - expressions to be evaluated in case of error.

condition-case - error handlers to recover control in case of error.

  • ignore-errors

24.1. condition case

condition-case var protected-form handlers

  • protected-form - body
  • handlers - (conditions body…) (conditions body…)
    • condition - condition name of t matches any condition.
(condition-case nil
    (load "asd")
  (error nil))

(condition-case nil
    (load "asd")
  ((debug error) nil))

(ignore-errors  (load "asd"))

24.2. catch and throw

  • catch tag body
  • throw tag value, value is used as the value to return from that catch.
(defun foo-outer ()
  (catch 'foo
    (foo-inner)
    )
)

(defun foo-inner ()
  (throw 'foo t))
(foo-outer)

25. Error messages

25.1. wrong-type-argument

(wrong-type-argument number-or-marker-p hello)

(+ 2 'hello)

symbol hello, not a number

Wrong type argument: listp, notmuch-show-save-part

https://www.gnu.org/software/emacs/manual/html_node/eintr/Wrong-Type-of-Argument.html

26. Emacs API

26.1. terms

  • Emacs Terminology Description
  • Point Cursor position, number of characters from beggining of the buffer to current cursor position.
  • Buffer Place where the user edit something. Not all buffers are bound to a file.
  • Mark Beginning of the selected area.
  • Region Selected area/ text
  • Frame The current window of emacs
  • Windows Each frame can be split in sections that Emacs documentation calls windows
  • Fill Word Wrap
  • Yank Copy
  • Kill Region Cut
  • Kill Ring Clipboard
  • Kill Buffer Close Buffer
  • Mode Line Status Bar
  • Font Locking Syntax Coloring

26.2. pointer

  • (point) - current position
  • (goto-char position)
  • (line-beginning-position &optional N) scan forward N - 1 lines first.
  • (beginning-of-line) - move cursor
  • (forward-line)
  • (next-line)

(count-lines ? ?)

http://xahlee.info/emacs/emacs/elisp_all_about_lines.html

26.3. buffers

  • (current-buffer)
  • (with-current-buffer BUFFER-OR-NAME &rest BODY) ;; Temporarily make a buffer current.
  • (set-buffer BUFFER-OR-NAME) - Make a buffer current. (but does not make it visible.) Return that buffer object. switch-to-buffer or pop-to-buffer.
  • (save-current-buffer &rest BODY) - Execute BODY, then restore the current buffer that is before this function call.
  • (with-temp-buffer &rest BODY) - Create a temporary buffer, and evaluate BODY, return the last expression.

http://xahlee.info/emacs/emacs/elisp_buffer_file_functions.html

26.3.1. create temp copy

(defun ss ()
  (let ((buffer (get-buffer-create " *temp*"))
        (orbuf (current-buffer))
        (p (point)))
    (save-excursion
      (with-current-buffer buffer
        (insert (with-current-buffer orbuf (buffer-string))) ;; insert text from orbuf to this
        (goto-char p)
        ;; now we are at the copy
        (print (point))
))))

26.4. temporary files

  • (make-temp-file) - This function creates a temporary file or directory and returns its name, and may insert text in it.
  • org-babel-temp-file - Create a temporary file
  • org-babel-process-file-name - Prepare NAME to be used in an external process and return new name
  • org-babel-eval-read-file - Return the contents of FILE as a string.
  • with-temp-file file body - evaluates the BODY forms with a temporary buffer as the current buffer; then, at the end, it writes the buffer contents into file FILE.
  • append-to-file - This function appends the contents of the region delimited by START and END in the current buffer to the end of file FILENAME.
  • write-region - This function writes the region delimited by START and END in the current buffer into the file specified by FILENAME. or write string.

Notes

  • ‘append-to-file’ and ‘write-region’ - Don’t use these functions to write to files that are being visited

26.4.1. ex

(make-temp-file
            (expand-file-name PREFIX
                              (or small-temporary-file-directory
                                  temporary-file-directory)))
(write-region <STRING> nil <FILENAME> 'append)
(defun my-append-string-to-file (s filename)
  (with-temp-buffer
    (insert s)
    (write-region (point-min) (point-max) filename t)))

26.5. lines

(count-lines (point-min) (point-max))

26.6. cleanup


(let ((buffer (get-buffer-create " *temp*")))
  (with-current-buffer buffer
    (unwind-protect
        (insert "asd")
      (kill-buffer buffer))))

https://www.gnu.org/software/emacs/manual/html_node/elisp/Cleanups.html

26.7. highlight character at point

(let ((ol (make-overlay (point) (1+ (point)))))
  (overlay-put ol 'face '(:background "dark red")))

26.8. modes

variables:

  • mode-name - name of current major mode: "Help"
  • major-mode - name of current major mode: help-mode
  • mode-line-buffer-identification

minor mode is buffer-local or global:

(local-variable-if-set-p 'show-paren-mode)

there's nothing stopping you giving a global mode a buffer-local value(to check really global):

(with-temp-buffer
  (local-variable-if-set-p 'show-paren-mode))

27. Libraries - popular

  • DamienCassou/hierarchy: Emacs library to create, query, navigate and display
  • magnars/dash.el: A modern list library for Emacs hierarchy structures

27.1. build in

  • seq.el
  • map.el

28. links

Created: 2024-03-03 Sun 09:51

Validate