- Dialect of the Lisp programming language
- Used by the Emacs text editor to implement most of the editing functionality
- Used to customize and extends emacs
Pretty much what makes emacs the programmer's editor
Pretty much what makes emacs the programmer's editor
Three parts
+ Some live examples in between
L
ots of I
rritating S
illy P
arentheses!
Or,
LIS
t P
rocessing
The syntax is entirely made up of lists, almost
every expression
being a function call.
ELISP> (+ 1 2) 3 ELISP> (concat "hello" ", " "world") "hello, world"
The first element of the list evaluated to a function and applied to the rest of the elements as arguments
set
and setq
can be used for top-level bindings
ELISP> (set 'a 20) 20 ELISP> (setq a 20) 20 ELISP> (setq b 30 c 40) 40
setq
is a more convenient version of set
which helps in two ways:
anything after semicolon is considered a comment (ie. ignored)
; i am inside a comment ;; i am also inside a comment (setq name "Vineet") ; me too a comment
t
, nil
foo
Symbols are interned
ELISP> foo *** Eval error *** Symbol's value as variable is void: foo ELISP> 'foo foo
ELISP> (setq p (cons 1 2)) (1 . 2) ELISP> (car p) 1 ELISP> (cdr p) 2
There are the most basic ones but there are many other primitive types
related to programming such as vector
, hash-table
etc. as well as
a few that are specific to emacs such as buffer
, frame
, window
etc.
ELISP> (1 2 3 4) ;; above will result in error ELISP> (list 1 2 3 4) (1 2 3 4) ELISP> '(1 2 3 4) (1 2 3 4) ELISP> '() ; empty list ELISP> (equal '() nil) t ELISP> (cons 1 '()) ELISP> (setq nums (cons 1 (cons 2 (cons 3 (cons 4 '()))))) (1 2 3 4) ELISP> (car nums) ; first 1 ELISP> (cdr nums) ; rest (2 3 4)
;; comparing numbers ELISP> (= 2 (+ 1 1)) t ;; checking for `same` objects ELISP> (eq 1 1) t ELISP> (eq 'a 'a) t ELISP> (eq "hi" "hi") nil ;; comparing objects with their content ELISP> (equal (list 1 2 3) (list 1 2 3)) t ;; checking for string equality ELISP> (string= "hi" (concat "h" "i")) t
ELISP> (if t "yes" "no") "yes" ELISP> (if (not t) "yes" "no") "no" ELISP> (when t "yes") "yes" ELISP> (cond ((> a b) 1) ((< a b) -1) ((= a b) 0))
ELISP> (setq a 10) 10 ELISP> (let ((a 5) (b (+ a 1)) (+ a b)) 16 ELISP> a 10
let*
can be used if subsequent bindings need to use previous ones.
Note: set
, setq
, if
, cond
, let
etc. are special forms and
not functions
ELISP> (progn (do-something) (do-something-else) (+ 1 2) (+ 3 4)) 7 ELISP>
usually code that uses progn
involves side effects to be carried out
in order.
ELISP> (defun greet (greeting name) "Optional docstring" (concat greeting ", " name)) greet ELISP> (greet "hello" "vineet") "hello, vineet" ELISP> ;; anonymous functions ELISP> ((lambda (x) (+ 1 x)) 3) 4
The result of the last expression of the function body is implicitly returned
ELISP> (defun g (f) (lambda (x) (funcall f x))) g ELISP> (funcall (g (lambda (x) (+ 1 x))) 10) *** Eval error *** Symbol's value as variable is void: f ELISP> (setq lexical-binding t) t ELISP> (defun g (f) (lambda (x) (funcall f x))) g ELISP> (funcall (g (lambda (x) (+ 1 x))) 10) 11
(defconst sphinx-doc-fun-regex "^\s*def \\([a-zA-Z0-9_]+\\)(\\(.*\\)):$") (defun sphinx-doc-fun-def (string) "Returns a pair of name of the function and list of the name of the arguments" (when (string-match sphinx-doc-fun-regex string) (list (match-string 1 string) (sphinx-doc-fun-args (match-string 2 string)))))
load-path
: list of paths where files to load are looked up
eager loading
: load
lazy loading
: autoload, "require"-ing provided features
buffer
, frame
, window
etc are editor related types
ELISP> (current-buffer) #<buffer *ielm*> ELISP> (bufferp (current-buffer)) t
Interactive functions can be called using M-x <function-name>
.
They can also be associated to keys bindings.
When we type out a key sequence, emacs calls the bounded function.
(defun some-function () (interactive) ...)
Evaluate the defun and then,
M-x some-function
Write the name of the current buffer with the message "Hi! You are viewing the '<buffer-name>' buffer" on the next line with an indent of 8 spaces and then move the cursor back to the earlier position
get the name of the current buffer
(defun buffer-greet () (interactive) (let ((name (buffer-name (current-buffer)))) (save-excursion (progn (next-line) (move-beginning-of-line 1) (insert " ") (insert (format "Hi! You are viewing the '%s' buffer" name))))))