- buffer
- The area containing text kinda like a tab in a browser
- point
- The cursor
- window
- A section of the emacs window containing text
- seperated by splits
- frame
- Dedicated Emacs Window (meaning your OS’s window)
- minibuffer
- Text area at the bottom of a frame
- mark
- The point where highlighted text starts
- the mark is set with
C-SPC
- the mark is set with
- region
- area between the point and the mark (often highlighted)
kill-region
(C-w) makes use of this
- Major Mode
- current programming language
- Minor Mode
- (enabled feature such as spellchecking)
- Calling functions
(defun my-add-function (num) (+ num 1)) (my-add-function 1)
2
Alternatively we can use funcall
(funcall 'my-add-function 1)
2
You can see that I put a quote before the my-add-function
This quote is basically a way to prevent evaluation of my-add-function
if we evaluated my-add-function it would look it up as if it was a variable.
To give the symbol my-add-function
it’s self we need to quote it.
Symbols are often used in place of where some languages would rely on a string.
I go into this a little more in my video LEARN EMACS LISP - Mostly The Strange Parts - YouTube
Evaluate each of these with C-x C-e
- numbers
- 1
- strings
- “hello”
- symbols
- ‘hello
- keywords
- :hello
- chars
- ?h
- true
- t
- false
- nil
- pairs (cons cell)
- (cons 1 2)
- lists
- (list 1 2 3)
Quote as in ’ tells Emacs not to evaluate the following expression
'(+ 1 2)
(+ 1 2)
We used quote to create the symbol above.
'i-am-a-symbol
i-am-a-symbol
for example if we evaluate (list 1 2)
we get (1 2)
Using quote we can prevent evaluation and skip the use of list
all together
'(1 2)
(1 2)
This is why you may hear people say that in lisp code is data
This can also be done for something like a cons cell to skip the use of cons
in (cons 1 2)
'(1 . 2)
Note that (1 . 2)
is how a cons cell is represented
In addition to the regular quote emacs has a special version of it called quasiquote which allows us to unquote and experession.
Here is a quick example
`(1 2 ,(+ 1 2))
Note that we use `
as quasiquote rather than '
and ,
to unquote
All commands you can use (seen with M-x
) are functions
They require the use of (interactive)
inside the functon to tell emacs
it can be used as a command.
(defun insert-numbers ()
"inserts an a sequence of numbers"
(interactive)
(insert "1 2 3"))
insert-numbers insert-numbers
These interactive functions can be accessed via a keybinding
The string at the top is simply for documentation purposes
To learn more about a function you can use
(describe-function 'insert-numbers)
This is also available via M-x
The most general way to bind a new key is using global-set-key
(global-set-key (kbd "C-S-s") 'insert-numbers) ;; control shift s
insert-numbers
kbd
here turns our string into something Emacs can convert into a key
If you are using a more modern Emacs you can skip the kbd
step by using
(keymap-global-set "C-S-s" 'insert-numbers)
insert-numbers
I will stick to the functions prefixed with keymap for now as they often you want keys to be set only for a specific mode
for example lets say we want a key that will insert an if statement in C
(defun c--insert-if ()
(interactive)
(insert "if () {\n}"))
(keymap-set c-mode-map "C-S-l" 'c--insert-if)
c–insert-if
Now if I open a C file
if () {
}
There is a corresponding map for basically every mode in Emacs simply
by following the name of the mode with -map
If I would like to learn more about a key I can use
(describe-key (kbd "C-S-s"))
Alternatively C-h k
then press the key it’s self
Since all function names are shared in Emacs packages prefix their functions with the name of the package as to avoid confusion and conflicting names
for example
org--newline
is a function used by org-mode to create a newline
the --
is to indicate it’s only meant to be used by org-mode internally
org-babel-tangle-file
On the other hand is intended to be used by anyone which is why there is only a single -
(if t
'it-was-true
'it-was-false)
it-was-true
(if nil
'it-was-true
'it-was-false)
it-was-false
As mentioned above we often use t
to mean true but really anything
other than nil
is considered true
(if 'this-is-true
'it-was-true
'it-was-false)
Often if
expressions can be difficult to read so when you only need to
handle when something is true we use when
(when t
'this-is-true)
If we want to handle the case that something is nil we use unless
(unless nil
'this-is-false)
this-is-false
Like in many other languages we can use and
, or
, and not
(and t nil)
(and t t)
(or t nil)
(not t)
In Elisp the last expression to be evaluated is returned.
While nice in most cases it can be a pain when we want to perform a
sequence of operations in an if
expression.
This is solved with progn
(if t
(progn
(message "print this in minibuffer")
'this-was-true)
'this-was-false)
this-was-true
This is another reason people tend to use when
and unless
Configuration of Emacs is often done via variables.
C-h v
M-x describe-variable
setq
setopt
(has extra features e.g. type checking)- These types come from defcustom
defvar
(For creating new variables)- e.g.
(defvar thing 1 "Just some thing")
- e.g.
- cons cells
- cons, car, and cdr
Recall the type cons cell (cons 1 2)
which is basically a pair in most other languages
Lists are actually constructed using cons cells
Chaining these pairs together we can create a list like so
(cons 1 (cons 2 nil))
As you can see a list is simply a chain of cons cells ending with nil
Each of these you can learn about using C-h f
or M-x describe-function
- cl-loop
- Probably the most familiar to those coming from other languages
(require 'cl-lib) ; Usually already required in your config anyways (cl-loop for i from 0 to 10 collect (* i i))
(0 1 4 9 16 25 36 49 64 81 100)
- I have a video that goes much deeper into it’s use
- while
(setq my/val 1) (setq my/truth t) (while my/truth (if (= my/val 10) (setq my/truth nil)) (message "%s" (setq my/val (1+ my/val))))
nil
- dotimes
(setq total nil) (dotimes (i 3) (setq total (cons total i))) total
- dolist
(setq total 0) (dolist (i '(1 2 3)) (setq total (+ total i))) total
6
- dotimes
One thing new comers often get confused by is hooks
A hook is a list of functions to run in a particular situation
(defun my-fun ()
(interactive)
;does something
(run-hooks 'my-fun-hook))
(add-hook 'my-fun-hook (lambda () (insert "3")))
(add-hook 'my-fun-hook (lambda () (insert "4")))
if you are coming from vim these are similar to autocommands but less finicky
One example usecase would be to change settings for a particular programming language
(add-hook 'emacs-lisp-mode-hook (lambda ()
(indent-tabs-mode -1)))
This means that whenever I open an emacs lisp file it will use spaces instead of tabs when I hit the TAB key
When you want a function local variable people usually use let
(defun what-is-2+2-5 ()
(let (
(four (+ 2 2))
(five 5)
)
(- four five)))
;; call this function
(what-is-2+2-5)