;
progn
: evaluate each statement in body sequentially and return value from last statement.
(1- x)
is same as (- x 1)
. Former form is considered better style.(shell-command "cmd")
(re-search-forward "^* The specific heading")
(insert "text")
(file-name-nondirectory arg)
: get filename and extension
(name)
is a function (as in name()
in C), but name
is a valuelet
is normal let, let*
is like letrec
(signal ..)
and (error ..)
: ways to indicate errors programmatically
Check value of a type:
(integerp v)
: return t
if v
is an integer(sequencep '(1 2)) ;; t
: check if value is a sequence
(sequencep (make-hash-table)) ;; nil
(hash-table-p v)
: hash tablesType conversions:
(+ 2 (string-to-number "3")) ;; 5
funcall f args
: calls function f
with args
as argumentsapply
takes args
as a list, but they are passed to f
as separate args(funcall '+ 2 3)
; 5
(apply '+ '(2 3))
; 5
https://www.gnu.org/software/emacs/manual/html_node/elisp/Point.html
(save-excursion)
Associated functions:
(point)
: current value of point in buffer(point-min)
/ (point-max)
: minimum/maximum accessible value of point in buffer(kill-ring)
??(kill-ring-max)
maximum size of kill ringSee:
Preceded by a ?
for syntax.
; ?a is like 'a' in C
?a
97
See:
mapcar
: map function over a sequence like listsseq-uniq
: Get unique elements in a list
(seq-uniq '(1 2 2 2 2)) ;; (1 2)
(nth idx lst)
: get n
-th element of lst
(nthcdr n lst)
: Like calling cdr
n
times on lst
(nth 0 '(0 1 2 3 4 5))
0
(nth 3 '(0 1 2 3 4 5))
3
(nthcdr 3 '(0 1 2 3 4 5))
(3 4 5)
(nthcdr 10 '(0 1 2 3 4 5))
nil
https://www.gnu.org/software/emacs/manual/html_node/eintr/nth.html
car
and cdr
–
car
: get head element of a listcdr
: get tail of a list(car '("a" "b" "c"))
; "a"
(car '(0 1 2))
; 0
(car '())
; nil
(cdr '("a" "b" "c"))
; ("b" "c")
(cdr '(0 1 2))
; (1 2)
(cdr '())
; nil
https://www.gnu.org/software/emacs/manual/html_node/eintr/car-_0026-cdr.html
string-width
'\n'
is not counted in this function(string-width "hi") ; 2
(string-width "\n") ; 0
(string ?a) ; "a"
(make-string <count> <char>)
(make-string 2 ?a) ; "aa"
(concat str1 str2)
string-join
(string-join '("hi " "how are" " you?")) ;; "hi how are you?"
(/ 3 2)
is 1(/ (float 3) 2)
is 1.5(/ 3 2.0)
is 1.5See:
If argument is char, return value is int for both downcase
and upcase
.
split-string
(split-string "1.2.3" "\\.")
; ("1" "2" "3")
(split-string "a-b c" "-")
; ("a" "b c")
defun foo () (5)
(foo) ;5
(defun fact (a) (cond
((= a 0) 1)
(t (* a
(fact (- a 1))
)
)))
(fact 5) ; 120
(defun gcd (a b)
(cond
((< a b) (gcd b a))
((= (% a b) 0) b)
(t (gcd b (% a b)))
))
(gcd 1000 10) ; 10
(atom 1) ; t
(atom (list 1 2)) ; nil
;; NOT WORKING
; find sqrt of a.
; x is starting value
; e is permissible error
(defun sqrt_nr (a x e)
(cond
((< (abs (- (* x x) a)) e) x)
(t (sqrt_nr a (* (/ 1 2) (+ x (/ a x))) e))
))
Functions:
—
In:
(pine cones numbers (1 2 3) color "blue")
it's like:
—
Examples:
"pine" "cones" "numbers" (1 2 3) "color" "blue"))
(setq-local myplist '(; ("pine" "cones" "numbers" (1 2 3) "color" "blue")
"vive" "la"))
(setq-local myplist (plist-put myplist ; ("pine" "cones" "numbers" (1 2 3) "color" "blue" "vive" "la")
(setq-local l myplist); ("pine" "cones" "numbers" (1 2 3) "color" "blue" "vive" "la")
4) 'foo)
(plist-get '(foo ; 4
(key . value)
(setq-local myalist"name" . "joe")
'(("age" . 50)
("planet" . "earth")))
(; (("name" . "joe") ("age" . 50) ("planet" . "earth"))
Functions:
(assq key alist)
: return element of alist whose car
is key
—
Folding over an alist (courtesy of chatgpt):
(require 'cl-lib)
(setq-local my-alist '((a . 1) (b . 2) (c . 3)))
((a . 1) (b . 2) (c . 3))
(cl-reduce (lambda (acc pair)
(+ acc (cdr pair))) ;; Accumulate the values (cdr of each pair)
my-alist
:initial-value 0)
; 6
make-hash-table
:test
argument specifies how hashing would be done:test
method is eql
#s(hash-table size 50 data (key1 val1) (key2 (val2)
hash-table data (key1 val1 key2 300))
#s(; #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data (key1 val1 key2 300 ...))
hash-table (key1 val1 key2 300))
#s(; #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ( ...))
300)
#s(key1 val1 key2 ; #s(key1 val1 key2 300)
Example usage:
make-hash-table)
(; #s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data ( ...))
hash-table size 30 data (key1 val1 key2 300))
#s(; #s(hash-table size 30 test eql rehash-size 1.5 rehash-threshold 0.8125 data (key1 val1 key2 300 ...))
hash-table size 30 data ("a" 10 "b" 20)))
(setq-local myht #s(; #s(hash-table size 30 test eql rehash-size 1.5 rehash-threshold 0.8125 data ("a" 10 "b" 20 ...))
gethash key table
puthash key table
remhash key table
clrhash table
: empty the hash tablemaphash function table
: in-place map over hashtablehash-table-keys table
: get all keys of hashtablehttps://www.gnu.org/software/emacs/manual/html_mono/elisp.html#Hash-Access
(hash-table-keys #s(hash-table data ("a" 1 "b" 2)))
; ("a" "b")
; No unique keys ???
(hash-table-keys #s(hash-table data ("a" 1 "b" 2 "a" 3)))
; ("a" "b" "a")
(hash-table-p #s("a" 1))
; nil
(hash-table-p #s(hash-table "a" 1))
; t
(hash-table-p (make-hash-table))
; t
https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#Text-Props-and-Strings
For example, the following means:
#("foo bar" 0 3 (face bold) 3 4 nil 4 7 (face italic))
Part of string | Slice | Property |
---|---|---|
"foo" | str[0: 3] | bold |
" " | str[3: 4] | NA |
"bar" | str[4: 7] | italic |
if
statement: (if (condition) (then-clause) (else-clause))
when
: like if
without elseunless
: like if
with only elseeq
-style equality ??
eq
for looking at internal structure ??See:
eq
(setq-local a 3)
(setq-local b 3)
(eq 'a 'a)
; t
(eq 'a 'b)
; nil
(eq 'a '3)
; nil
equal
(eq "2" "2")
; nil
(equal "2" "2")
; t
(equal 2 2)
; nil
Math functions:
abs
: absolute valuesqrt
: square roothttps://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html
Change the default behaviour of an existing function ('by giving some advice') rather than redefining the whole function.
First character of argument of (interactive)
.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Interactive-Codes.html
(interactive)
: function can be called with M-x
as well
(interactive "p")
mean?: See thisFunction | Description |
---|---|
read-char |
Reads a character. Returns int |
read-int |
Reads int |
read-string |
Reads string |
read-key |
|
read-char-choice |
|
yes-or-no-p |
Ask a yes/no answer |
y-or-n-p |
Ask a y/n answer |
dotimes
and dolist
dotimes (counter limit result) body
counter
starts from 0.body
is the loop bodyresult
.
nil
is returned.dolist
is looping on a list.
(dolist list-name
(operation list-elem)
is like the following python:
for list_elem in list_name:
operation(list_elem)
Use write-region
.
(write-region <string> nil <filename> 'append)
shell-command-to-string
: run a command and gets its output as a stringshell-command
: just run the command. Don't use its outputasync-shell-command
(message (shell-command-to-string "/bin/echo -n hello"))
; Output: hello
t
nil
or empty list(and t nil)
; nil
(or t nil)
; t
(if '() "T" "F")
; "F"
(if () "T" "F")
; "F"
M-x check-parens
See:
(current-time); (26423 47784 405993 901000)
(decode-time); (42 48 2 16 11 2024 6 nil 19800)
"%Y-%m-%d")
(format-time-string "2024-11-16"
"%Y-%m-%d" (decode-time))
(format-time-string "1970-01-07"
(decode-time); (59 6 3 16 11 2024 6 nil 19800)
(encode-time (decode-time)); (26423 48961)
"%Y-%m-%d" (encode-time (decode-time)))
(format-time-string ; "2024-11-16"
See:
car
: head of list
car
of empty list gives nil
cdr
: tail of listcar '(0 1 2 3))
(; 0
car nil)
(; nil
cdr '(0 1 2 3))
(; (1 2 3)
cdr (cdr '(0 1 2 3)))
(; (2 3)
nthcdr
repeats cdr
function n
timesnth 2 '(1 2 3))
(; 3
let
expressionsSee: https://www.gnu.org/software/emacs/manual/html_node/eintr/let.html
let
(let
((x 1)
(y 2))
(message (format "x=%d, y=%d" x y)))
; x=1, y=2
Each binding should be defined independent of the other.
Otherwise it will give error. For example:
(let
((x 1)
(y (+ x 2)))
(message (format "x=%d, y=%d" x y)))
; Debugger entered--Lisp error: (void-variable x)
; (+ x 2)
; (let ((x 1) (y (+ x 2))) (message (format "x=%d, y=%d" x y)))
; eval((let ((x 1) (y (+ x 2))) (message (format "x=%d, y=%d" x y))) t)
; eval-expression((let ((x 1) (y (+ x 2))) (message (format "x=%d, y=%d" x y))) nil nil 127)
; funcall-interactively(eval-expression (let ((x 1) (y (+ x 2))) (message (format "x=%d, y=%d" x y))) nil nil 127)
; call-interactively(eval-expression nil nil)
; command-execute(eval-expression)
let*
Unlike let
, bindings can be defined dependent on other values mentioned in the same let*
expression.
(let*
((x 1)
(y (+ x 2)))
(message (format "x=%d, y=%d" x y)))
; x=1, y=3
https://emacs.stackexchange.com/questions/42449/what-does-let-let-asterisk-mean-in-elisp
These functions update the kill ring. To just delete text without disturbing kill ring use functions that start with kill-
.
(copy-region-as-kill (point-min) (point-max))
(kill-region (point-min) (point-max))
https://www.gnu.org/software/emacs/manual/html_node/elisp/Kill-Functions.html
https://www.gnu.org/software/emacs/manual/html_node/elisp/Writing-to-Files.html
Handy to try out lisp snippets. Maybe in *scratch*
buffer.
M-x lisp-interaction-mode
C-j
: Evaluate last linehttps://www.gnu.org/software/emacs/manual/html_node/emacs/Lisp-Interaction.html
References:
May not be true for elisp.
#c(2 3)
means 2+3i
(directory-files "/foo" nil directory-files-no-dot-files-regexp)
https://www.gnu.org/software/emacs/manual/html_node/elisp/Contents-of-Directories.html