Programming Language Reference - EmacsLisp (draft)
23 Jun 2015In this post we explore the extension language for the powerful yet
very arcane ‘text editor’ emacs. Trying to keep track of various
features of emacs lisp along with useful extensions. The main
reference for his cheat sheet is the elisp manual which comes with you
installation of emacs. See (info "elisp")
The Emacs Lisp
Lisp Data Types
- Lisp
object
data maintained by lisp objects
belongs to at least one type- Fundamental types example
integer
float
cons
symbol
string
vector
hash-table
subr
byte-code function
buffer (editor specific types)
objects
know their types variables point to objects
Printed Representation and Read Syntax
- Format from Lisp printer
prin1
- printed representation also read syntax
- For certain objects dont have read syntax
- Start with
#<
- Example
invalid-read-syntax
if starts with#<
Comments
- start with
;
- continues till end of line
- discarded by
Lisp reader
#@COUNT
skips nextCOUNT
characters
Programmer Types
Integer Types
-536870912
to536870911
or2^29
to2^29 -1
- read syntax
- optional sign
- optinoal period at end
- For too large read as floating point number
Floating Point Type
Character Type
Symbol Type
:
denotes key workd symbol
Sequence Type
Cons Cell Type
Array Type
String Type
Vector Type
Char-Table Type
Bool-Vector Type
Hash Table Type
Function Type
Macro Type
Primitive Function Type
Byte-Code Type
Autoload Type
Programmer Types
####### Buffer Type
- The basic object of editing.
Marker Type
- A position in a buffer.
Window Type
- Buffers are displayed in windows.
Frame Type
- Windows subdivide frames.
Terminal Type
- A terminal device displays frames.
Window Configuration Type
- Recording the way a frame is subdivided.
Frame Configuration Type
- Recording the status of all frames.
Process Type
- A subprocess of Emacs running on the underlying OS.
Stream Type
- Receive or send characters.
Keymap Type
- What function a keystroke invokes.
Overlay Type
- How an overlay is represented.
Font Type
- Fonts for displaying text.
Numbers
Strings and Characters
Lists
Cons Cells
- How lists are made out of cons cells.
List-related Predicates
- Is this object a list? Comparing two lists.
List Elements
- Extracting the pieces of a list.
Building Lists
- Creating list structure.
List Variables
- Modifying lists stored in variables.
Modifying Lists
- Storing new pieces into an existing list.
Sets And Lists
- A list can represent a finite mathematical set.
Association Lists
- A list can represent a finite relation or mapping.
Sequences Arrays Vectors
Sequence Functions
- Functions that accept any kind of sequence.
Arrays
- Characteristics of arrays in Emacs Lisp.
Array Functions
- Functions specifically for arrays.
Vectors
- Special characteristics of Emacs Lisp vectors.
Vector Functions
- Functions specifically for vectors.
Char-Tables
- How to work with char-tables.
Bool-Vectors
- How to work with bool-vectors.
Rings
- Managing a fixed-size ring of objects.
Hash Tables
Creating Hash
- Functions to create hash tables.
Hash Access
- Reading and writing the hash table contents.
Defining Hash
- Defining new comparison methods.
Other Hash
- Miscellaneous.
Symbols
Evaluation
Control Structures
Sequencing
- Evaluation in textual order.
- Special form
progn
- execute A , B, C in order
- body of Function defines implicity
progn
- implicit in may control structures
progn
: evaluates all forms returns value of final formprog1
: This special form evaluates FORM1 and all of the FORMS, in textual order, returning the result of FORM1.prog2
: This special form evaluates FORM1, FORM2, and all of the following FORMS, in textual order, returning the result of FORM2.
Conditionals
if
,cond
,when
,unless
if condition then-form else-forms...
- chooses between
then-form
andelse-forms
based on conditionals - else has implicit
progn
- unexecuted branches are not executed
- chooses between
when condition then-forms...
- variant of
if
withoutelse-forms
- implicit progn for
then-forms
- variant of
unless condition forms...
- This is a variant of `if’ where there is no THEN-FORM:
cond clause...
cond
chooses among an arbitrary number of alternatives.- Each CLAUSE in the
cond
must be a list - The
CAR
of this list is theCONDITION
- If the value of CONDITION is non-
nil
,- the clause “succeeds”; then
cond
evaluates itsBODY-FORMS
, - the value of the last of
BODY-FORMS
becomes the value of thecond
- the clause “succeeds”; then
- Use
t
for default clause which always passes.
Combining Conditions
and
,or
,not
. #######not condition
- return
t
if condition isnil
andnil
otherwise #######and conditions...
- ensures each condition is
t
- short-circuits if any condition is
nil
####### or conditions...
- Requires at least one of the conditions to be true
- short cirquits on first non-
nil
condition - value returned is first non-
nil
- else returns nil
Iteration
####### while condition forms...
- while
non-nil
condition evaluation, evaluate forms in textual order - exit on
nil
condition orthrow
- support for
repeat
until loop available
####### dolist (var list [result]) body...
- execute body for each element of
list
var
hods the current element- returns value of
result
ornil
if result ommited
####### dotimes (var count [result]) body...
- evaluate body from
[0,count)
- return
result
Nonlocal Exits
- Transfer control from one point to another
- Unbind all variable bindings made by exited constructs
####### Catch and Throw
- Allow nonlocal exit on request
- throw when executed tranfers to corresponding catch
- second argument of throw is return value of
catch
- first argument used to find matching catch
eq
comparision - innermost matching catch takes precedence
- If binding constructs like
let
exited then variables get unbund throw
restores buffers and position saved bysave-restriction
throw
restores window selection saved bysave-window-excursion
lexical
nesting unnecessary only needs to be chronologically aftercatch
emacs-lisp
uses onlythrow
for non-local exits
####### catch tag body...
- extablishes a return point distinguished by tag
tag
can be anything butnil
- evaluate
body
in textual order - if corresponding
throw
executed, exit withthrow
second argument as value
####### throw tag value
- return to previously established
catch
- if multiple
tag
matches use innermost value
becomes value returned bycatch
####### Examples of Catch
- Using
catch
throw
to exit a double nested loop
Errors
Cleanups
Variables
-
Global Variables
- simplest definition
- Instantiate a variable throughout the lifetime of the system
- Gives x the value
(a b)
setq
special form- does not evaluate first argument
-
second argument evaluated and bound to first
- Constant Variables
- certain symbols that evaluate to themselves
nil
andt
-
:
symbols tarting with:
keywordp object
- object is symbol name starts with
:
- object is symbol name starts with
- Local Variables
- values which are scoped
- argument variables toa function
- only in effect during scope
- allows for nesting and superceding of values
- default scoping
dynamic scoping
dynamic scoping
current value is the most recent one created regardless oflexical placement
-
allows cusomtization of all variables in scope
let (bindings...) forms..
- sets up local bindings
- returns value of last form in
forms
binding
is either(val)
whereval
gets bound tonil
- or
(var value)
where variable is bound to value
let* (bindings...) forms...
- like let but binding available right after computation
- expression in next binding can represent previous binding
- Void Variables
- if symbol has unassigned value cell
- unassigned value cell not the same as
nil
assigned -
evaluating results in
void-variable
error makeunbound symbol
- empties out value cell making variable void
- return symbol
- if symbol has
dynamic local binding
unbinding only has effect over last shadowed local
boundp variable
- returns
t
ifvariable
is not voidnil
otherwise
- returns
- Defining Variables
defconst
,defvar
- signal intent of varable usagedefconst
used for signaling but emacs allows you to change value defined as constdefconst
unconditionally initializes a variabledefvar
initializes only if variable is originally void-
defcustom
defines a customizable variable (usesdefvar
internally) defvar symbol [value [doc-string]]
- defines
symbol
as a variable symbol
is not evaluated- variable marked as special always
dynamically bound
- if
symbol
already has a value then thevalue
is not even evaluated - if
symbol
has buffer local value thendefvar
acts on buffer-independent value - not current
(buffer-local)
binding C-M-x
eval-defun
force setting variable unconditionally without testing
- defines
defconst symbol value [doc-string]
- defines symbol and initializes it
- establishes global value for the symbol
- marked as
special
always dynamically bound - marks the variable as
risky
- sets the buffer independent value
- Tips for Defining
- Some naming conventions as follows (defined by suffix) :
-function
: defines functions-functions
: The value is a list of functions-hook
: variable is a hook-form
: The value is a form-forms
: The value is a list of forms-predicate
: The value is a predicate boolean expression-flag
: value significant only if not nil-program
: The value is a program name-command
: the value is a shell command-switches
: value is a list of command switches
- For complicated initializations put it all in a
defvar
- Some naming conventions as follows (defined by suffix) :
-
file reloading will initialize it the first time but not second time unless
C-M-x
is used -
Accessing Variables
symbaol-value symbol
- returns value in
symbol
value cell - value cell holds current (dynamic) value
- if variable is void throws
void-variable
error
- returns value in
- Setting Variables
setq [symbol form]...
- symbol given value result of form
- does not evaluate symbol
- argument gets automatically quoted
set symbol value
- puts
VALUE
in the value cell ofsymbol
- symbol is evaluated to obtain the symbol to set
- when dynamic binding is in effect same as
setq
- when variable is lexically bound
set
affectsdynamic value
setq
affects the currentlexical value
- puts
- Scoping Rules for Variable Bindings
- by default local bindings are
dynamic bindings
dynamic bindings
haveindefinite scope
dynamic bindings
havedynamic extent
lasts as long as binding construct(let
form) is being executedlexical bindings
optional support in emacslexical bindings
any reference to variable must be textually within binding constructlexical binding
chan haveindefinite extent
underclosures
where binding can live even after finshed execution of binding construct
- by default local bindings are
- Dynamic Binding
- variables binding is its current binding at during execution of Lisp program.
- The most recently-created dynamic local binding
- indefinite scope and synamic extent
- shown in example below
- Free reference in
getx
- within
let
takes onlet
’s binding forx
- outiside
takes global value of
x`
- Simple implementation
- Each symbol value cell has current
dynamic value
- new values assigned are recorded in a stack
- when binding construct (eg.
let
) finishes pops off old value from stack -
restores old value in value cell
- Proper Use of Dynamic Binding
- powerful since variables not textually defined can be used
- can make programs hard to understand
- keep it simple
- if no global definition use variables as a local variable in binding cosntruct
- else use
defvar
,defconst
ordefcustom
with variable documentation - see variable definition using
C-h v
- Lexical Binding
- Each binding construct defines a lexical environment
- specify symbols bound in construct
- when evaluator wants variable find first lexical environment
- lexical bindings can have indefinite extent.
- lexical environment can be “kept around” in “closure”
- closure created when named or anonymous function with lexical binding enabled.
- lexical environtment deined by let
x
locally bound- lambda expression automatically turned into a closure
- evaluation will increment
x
usingx
in stored lexical environment symbol-value
,boundp
andset
only retrieve and modify variables dynamic binding- code in body of
defun
anddefmacro
cannot reffer to surrounding lexical varaibles. - lexical variables not used as much
-
opportunities for optimization.
- lexical binding enabled if
buffer-local
variablelexical-binding
is notnil
lexical-binding
use lexical instead of dynamic binding but special variables still dynamically bound- must be set in the first line of the file
- eval has a
LEXICAL
argument that enables lexical bindings speical-variable-p SYMBOL
a special variable-
byte-compiler wll warn usage of free variables
-
Buffer Local Variables
- binding associated with a particular buffer
- binding in effect only when buffer is
current
- if variable set then new value set in
buffer-local
binding - ordinary binding called
default binding
- variable can have buffer local binding in some buffers
make-local-varaible
affects only current buffermake-variable-buffer-local
makes the variable local in all buffers and future bufferssetq-default
becomes the only way to change a variable made local to all buffers*WARNING*
iflet
has been used to shadow a buffer-local variable but current buffer has changed let binding wont be visible
- Creating and Deleting Buffer-Local Bindings
make-local-variable variable
- starts with original value of variable
- other buffers remain unaffected
- The value returned is
variable
- If variable is void it remains void
make-variable-buffer-local variable
-
File Local Variables
-
Directory Local Variables
-
Variable Aliases
- Variables with Restricted Values
Functions
Macros
Customization
Loading
Byte Compilation
Advising Function
Debugging
Read and Print
Minibuffers
Command Loop
Keymaps
Modes
Files
Buffers
Windows
Frames
Positions
Markers
Text
Searching and Matching
Syntax Tables
Processes
Suprocess Creation
Shell Arguments
Syncronous Processes
Asynchronous Processes
Deleting Processes
Process Information
Input to Processes
Signals to Processes
Display
System Interface
Summary
Unfortunately with great power comes great responsibility. Managing emacs can be something that requires great care and attention as well as requires openness to hacking at its internals. Perhaps this arcane editor is on its last legs or perhaps it is like a phoenix about to be reborn. Only time will be the judge.