Table of Contents
- 1. common structures
- 2. Lisp - philosophy, patterns
- 3. features
- 4. symbols, special characters
- 5. terms
- 6. advanced terms
- 7. evaluation process and forms
- 8. dialects
- 9. types
- 10. char
- 11. strings
- 12. variables
- 13. control structures: sequencing, conditions, Iteration
- 14. functions
- 15. printing
- 16. Macros
- 17. regex
- 18. paths
- 19. Emacs Code Conventions
- 20. examples
- 21. USE CASES
- 22. Emacs Lisp
- 23. MELPA
- 24. errors handling
- 25. Error messages
- 26. Emacs API
- 27. Libraries - popular
- 28. links
;-- 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
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.
- 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
- .
- 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")
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
- funcall (function &rest arguments)
- apply (function &rest arguments) - last arg as list of args
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Argument-List.html
- funcall-interactively
(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.1. links
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
- \< \> 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
- All the variables should be let-bound; otherwise, you're altering global values.
- Code is not indented and hard to read. Normally, sexp indentation in Emacs is aggressive enough that it takes effort to make code look like this, rather than to make it right.
- Use when instead of if, progn.
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips.html
- https://github.com/bbatsov/emacs-lisp-style-guide
- C mostly https://www.gnu.org/prep/standards/standards.html
- https://www.math.utah.edu/docs/info/elisp_38.html
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.6. execute shell command
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:
- Use =lambda=s for local bindings and function calls, not for hooks or global variables.
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips.html
- https://github.com/bbatsov/emacs-lisp-style-guide
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
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 ? ?)
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.4.2. links
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
- Common Lisp the Language, 2nd Edition https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node1.html
- https://caiorss.github.io/Emacs-Elisp-Programming/Elisp_Programming.html