(defblog exordium) Emacs and Lisp musings

My fancy Zsh prompt

I switched from bash to zsh a few years ago and I am never looking back. It has awesome tab completion: for example cd doc/sh/pl becomes cd Documents/shared/planning. It also expands git commands and branches, environment variables and other things. It has extended file globbing which provides a good replacement for find. If you spend a lot of time in the shell, you should really give zsh a try.

Whatever shell you use, it’s worth spending a few minutes configuring your prompt. The prompt is something you will see literally thousands of times a day. So why not make it useful?

Here is mine. First, let’s open a new shell in the home directory:

zsh prompt

Simple and to the point. ~ sweet ~! Let’s go into some directory:

zsh prompt

It displays the path, from the home directory, with the current directory displayed in bold (“planning”). To keep the prompt short, we only display the last 3 subdirectories:

zsh prompt

And now let’s move into a git repo:

zsh prompt

The prompt displays the path starting at the root of the repo (“org”), and also the current branch in green (“master”). Now let’s move into a subdirectory in the same repo:

zsh prompt

The root of the repo is highlighted (“org”), and the current directory is displayed in bold like before. We could also display something indicating if the repo is clean or if it has uncommitted changes, but I prefer to keep it simple.

The colors are from the Tomorrow Night theme, which also happens to be the default theme in Exordium.

Here is the code (in ~/.zshrc):

# Zsh options
setopt prompt_subst
autoload -U colors && colors

# Colors
BLACK=$'\033[0m'
GREEN=$'\033[38;5;148m'
BLUE=$'\033[38;5;117m'
DARK_BLUE='\033[38;5;4m'

current_git_branch() {
    git rev-parse --abbrev-ref HEAD 2> /dev/null | sed -e 's/\(.*\)/(\1)/g'
}

current_directory() {
    PROMPT_PATH=""
    CURRENT=`dirname ${PWD}`
    if [[ $CURRENT = / ]]; then
        PROMPT_PATH=""
    elif [[ $PWD = $HOME ]]; then
        PROMPT_PATH=""
    else
        GIT_REPO_PATH=$(git rev-parse --show-toplevel 2>/dev/null)
        if [[ -d $GIT_REPO_PATH ]]; then
            # We are in a git repo. Display the root in color, then the path
            # starting from the root.
            if [[ $PWD -ef $GIT_REPO_PATH ]]; then
                # We are at the root of the git repo.
                PROMPT_PATH=""
            else
                # We are not at the root of the git repo.
                BASE=$(basename $GIT_REPO_PATH)
                GIT_ROOT="%{$fg_bold[red]%}%{$DARK_BLUE%}${BASE}%{$reset_color%}"
                REAL_PWD=$PWD:A
                PATH_TO_CURRENT="${REAL_PWD#$GIT_REPO_PATH}"
                PATH_TO_CURRENT="%{$BLUE%}${PATH_TO_CURRENT%/*}%{$reset_color%}"
                PROMPT_PATH="${GIT_ROOT}${PATH_TO_CURRENT}/"
            fi
        else
            # We are not in a git repo.
            PATH_TO_CURRENT=$(print -P %3~)
            PATH_TO_CURRENT="%{$BLUE%}${PATH_TO_CURRENT%/*}%{$reset_color%}"
            PROMPT_PATH="${PATH_TO_CURRENT}/"
        fi
    fi
    echo "${PROMPT_PATH}%{$reset_color%}%{$fg_bold[red]%}%{$BLUE%}%1~%{$reset_color%}"
}

export PROMPT=$'$(current_directory) %{$GREEN%}$(current_git_branch)%{$BLACK%}%# '

Notice the function current_git_branch: this is the fastest way I have found to get the name of the branch. The trick is to make the execution of the prompt as fast as possible, since it gets executed every time you hit Enter.

Org mode part 2

This is the second article in a series about Emacs Org mode. It assumes that you read the first one.

Today we’ll talk a bit about literate programming. The idea is to write an Org mode document that includes snippets of code, and possibly the result of their execution as well. It kind of reverses the way you think about documenting code: instead of adding comments inside your program, you add your program’s code inside the documentation file. In the end the result is the same, you still get executable code.

Org mode includes a feature named Babel which allows for embedding code in any programming language you fancy. Let’s get started.

Enabling Babel

First, we need to make sure that Babel is enabled for a few other languages than ELisp (the only one by default). Add the following in your emacs configuration and evaluate it with M-C-x (or restart Emacs):

(org-babel-do-load-languages
 'org-babel-load-languages '((emacs-lisp . t)
                             (ruby . t)
                             (python . t)
                             (sh . t)))

Hello World

First open a new buffer literate.org, with this content:

#+TITLE: Literate Programming

#+begin_src python
def hello(str):
    return "Hello, " + str + "!"

return hello("Dude")
#+end_src

The #+TITLE directive is just to add a title to the Org file; it is not really needed. The other directives we use are #+begin_src and #+end_src which respectively introduce and close a code block for a particular language. Note that Emacs automatically applies the proper syntax highlighting.

Type C-c C-c to evaluate the code block under the point. After confirmation, Babel will insert a new block #+RESULTS with the result of the evaluation, like so:

Org-mode20

What happened here? Emacs forked a process to execute the code using Python, and got back the returned value, and inserted it into the buffer.

By default the result is the returned value i.e. the last expression that was executed, but you can also use the output of the program as the result with a directive like: #+begin_src python :result output. For example, evaluate the shell statement below, again using C-c C-c:

#+begin_src sh :results output
   echo "Hello $USER! Today is `date`"
#+end_src

Org-mode21

Calling code blocks

Babel also allows you to refer to code blocks from elsewhere in your document, by labeling each block with a name, using directive #+name. Let’s say we have some Ruby code to revert a string (yes, I know we could use the native reverse!):

#+name: reverse_str
#+begin_src ruby
def reverse_str(s)
  len = s.length
  reversed = ""
  for i in 1..len do
    reversed += s[-1*i]
  end
  return reversed
end

reverse_str(str)
#+end_src

We can now call this block. Note that we get the result of the block evaluation. So if you want to use the result of a function in the block, you also need to add the call to that function (see the last line).

To call the block, add a #+call directive referring to the block’s name and binding the input variable str, and type C-c C-c with the point onto it:

#+call: reverse_str(str="The Quick Brown Fox")

Org-mode22

More fun

Here is a more practical example to illustrate the power of Babel, using different languages to get the job done. This is actually similar to an iPython notebook.

Suppose I want to produce a report containing statistics about the words that are used in a collection of files. Assuming all these files are in the same directory (let’s say they are Markdown files), this shell script counts the number of unique words in each file:

#+name: words
#+begin_src sh
  for F in /Users/phil/Documents/philippe-grenet.github.io/_posts/*.md
  do
     cat $F | tr -cs A-Za-z '\n' | tr A-Z a-z | sort | uniq -c | wc -l
  done
#+end_src

The result has multiple lines, one per file. Therefore it is stored into an Org table:

Org-mode23

Now let’s compute the standard deviation. We could follow up with another shell script, but it is easier to do this in ELisp. Add this block in the buffer:

#+begin_src elisp :var samples=words
(defun standard-deviation (samples)
  (let* ((samples    (mapcar #'car samples))
         (n          (length samples))
         (average    (/ (reduce #'+ samples) n))
         (deviations (mapcar #'(lambda (x)
                                 (expt (- x average) 2))
                             samples)))
    (sqrt (/ (reduce #'+ deviations) n))))

(standard-deviation samples))
#+end_src

The #+begin_src directive uses the :var keyword to bind the Lisp variable samples to the output of the words code block (which is the table above). In Lisp that samples variable will be set with a list of lists. Basically each row in the table is a sublist, and since the table has only one column the sublists only contain a single number, like this:

;; Value of 'sample':
'((55) (274) (560) (296) (650) (394) (253) (264))

If you evaluate the block with C-c C-c, you get the final result:

Org-mode24

You can of course re-run the report anytime you want. Once we have our report ready, Org mode is able to export it into plenty of different formats, choosing exactly what should be included and excluded. But that’s a discussion for another day.

Calc

If you are a programmer, there probably isn’t a day that goes by when you don’t need a calculator, for example for things like base conversion. After all, like Dijkstra said, programming is math.

Emacs includes a calculator, which is actually quite sophisticated. It is capable of both algebraic and symbolic calculations; it has a ton of functions and it can handle matrices or solve equations, if you need that sort of things. It can even create graphs if you have GnuPlot installed on your machine.

Here we will just review the basics. Check out the manual for more. There a nice Info manual embedded in Emacs which you can bring up using C-h i g (calc).

Start the calculator using M-x calc. It will show up at the bottom of the screen. Type q to quit. Once the calculator is started, you can hide and redisplay it using C-x * *.

RPN logic

Calc uses the RPN (Reverse Polish Notation) logic. Which is only fair, since Lisp uses the Polish notation! Anyway, if you are a fan of the HP calculators, you will be just at home.

Calc displays a stack of numbers. When you type a number, it accumulates in the stack. When you type an operator such as + or *, it operates on the last 2 numbers of the stack, and replaces those numbers with the result.

Give it a try: Type M-x calc, then the following:

  • 2 Enter
  • P (no need to press Enter)
  • 10 Enter

Org-mode1

The P inserts π. Now you have 3 numbers in the stack, and you can calculate the circumference of a circle of radius 10 (C = 2 π r). Press * once, the stack now shows 2 and 31.4159265359. Press * another time and you get a single number which is the result.

Because the dash key (-) is reserved for subtraction, you should use an underscore (_) to enter a negative number. Note that the calculator supports arbitrarily big numbers. If you want to challenge it, try calculating 2^200 (that’s 2 Enter, 200 Enter, then ^). The default precision is 12 but you can change it using p.

Type n to negate the last number, and TAB to flip the last 2 numbers. The delete key deletes the last number on the stack.

If you need to use complex numbers, enter them like (a,b). If you need fractions, enter them like 1:3 (1/3). You can also enter an algebraic expression directly by typing ' (the quote key) then your expression, such as 2 + (10 / 5). The result will be put on top of the stack.

Most functions use a single key. For example, type s for Sin, c for Cos, t for Tan, etc. The more complex commands are modal: they start with a prefix key, which leads to a prompt for the subcommand key. If you get lost, type ? and the mini-buffer will show you what is available.

If you make a mistake, type U to undo and D to redo. Of course this is Emacs, you have an infinite number of undos and redos. You can also reset the calculator using C-x * 0.

Base conversion

You can enter any number in the format base#number. Example: 16#FF is immediately converted to 255.

For the reverse, you need to set the output display mode. In this example, d r 16 followed by Enter sets the display to base 16. d r 2 sets it to binary. Set it to base 10 to get the default behaviour again.

Emacs Tips

In this short post we’ll review a few features of Emacs that are not well known, but really worth knowing.

Repeating commands

The simplest way to repeat a command is to type Control-a number, then the command. For example if I type C-6 C-0 ~ (that’s 6 then 0 with the Control key down, then the tilde character), I get a line with 60 tilde:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Another way is to use the universal argument: we saw how to write an interactive Lisp function that accepts a numeric argument in the previous article. forward-line is such a function; it goes down N lines (by default one line). For example C-u 1 0 DOWN (Control-u then 1 then 0 then the down arrow key) goes down 10 lines. You can do the same by calling the function explicitly with C-u 1 0 M-x forward-line.

Registers

Registers are used for saving temporary data in the current session. They can store positions or bookmarks, text, numbers etc. Registers have a name which is a letter or a number: a to z, A to Z (so case-sensitive) and 1 to 9, which gives you a total of 62 registers. That’s more than enough.

C-x r is the prefix for all register operations. Generally you type this prefix, then a key to specify what operation you want (e.g. save or read), then the register name which is one extra key.

Buffer positions

For example, open any file you have in one of your projects, go to some position in the file, and hit C-x r SPC a (where SPC is the space bar). This command stores the buffer position in register a. Now go to a different buffer such as the scratch buffer, and type C-x r j a: this command will jump back to the buffer and the position you just stored in register a.

Note that if you close the file and then retype the same command, Emacs will ask you if you want to reopen the file, and it will bring you back to the same position again. This can be useful if you want to keep bookmarks in a large project, for example if you keep going to the same files and bits within these files, but you don’t want to keep them open all the time.

You can view the content of register a with command M-x view-register then a at the prompt. It will show a window saying that this register stores a position in your buffer (note that the position is a number, which represents the offset from the beginning of the buffer). Type C-x 1, or q in the other window, to dismiss it.

Bookmarks

A bookmark is similar to a buffer position but with a twist: you give it a name and it is persisted between Emacs sessions. Note that bookmarks are not actually associated with registers, but they use the same C-x r prefix.

The command is C-x r m (mark) which prompts for a name. By default it proposes the current buffer name but you can choose whatever you want. You can view the list of bookmarks with C-x r l (list). Just click on a bookmark to jump to it. You can also jump to a bookmark with C-x r b (bookmark) which prompts for the name using auto-complete. The nice thing about bookmarks is that they are saved on the filesystem when you exit Emacs, and they are available when you restart it. You can also force save with M-x bookmark-save.

Text

Sometimes you want to save a snippet of text somewhere, so you can paste it later. One way is to use the kill ring: M-w to save the selected text (which is what Emacs calls the region), then C-y to paste. The kill ring saves all copy operations you have done so far, so if you want to paste the second previous thing you copied, type C-y followed by M-y (repeat M-y to go back in history).

Another way is to save the region in a register, which you do with something like C-x r s a (save in register a). Now if you want to insert the content of a register at the current point, type C-x r i a (insert the content of a).

Windows

This is less useful than the above, but you can also save a window configuration in a register. For example, split the screen horizontally with C-x 2, then split the current window vertically with C-x 3. You now have 3 windows displayed, which you can resize as you see fit.

Let’s save this layout in register a with C-r w a. Now dismiss all other windows than the current one using C-x 1. If you want to restore the layout, type C-r j a (it is the same key for jumping to a buffer position). Note that this only saves window configurations and not buffers content: if you close one of the buffers Emacs will not reopen it for you.

Summary

The table below summarizes the keys we just learned.

Key binding Description
C-x r SPC a Store the current position to register a.
C-x r j a Jump to the position stored in register a,
or restore the window positions stored in register a.
C-x r s a Save the selected region in register a.
C-x r i a Insert the text saved into register a.
C-x r w a Save window positions in register a.
C-x r m Save a bookmark.
C-x r b Go to a bookmark.
C-x r l List bookmarks.

Macros

Editing macros are a very powerful feature of Emacs. After all, Emacs stands for “Editing Macros” 1.

There are several keys for macros, but really you only need to remember two of them: F3 and F4. The first one records a new macro. The second one terminates the recording, if you were recording a macro; otherwise it executes the macro. If you make an mistake while recording a macro, hit C-g to abort, and start over.

Let’s take an example. Suppose I have this text:

the quick brown fox
jumps over
the lazy dog

Now suppose I want to make each line start with a capital letter and end with a period. I could edit the text manually because it is only 3 lines, but just imagine that it is much longer for argument’s sake, in order to make the use of a macro more compelling.

The way to do this with a macro is simple: fix the first line, while recording a macro. Then execute the macro N times, one time per remaining line. To record the macro do the following:

  • Move the cursor to the beginning (e.g. M-<).
  • F3 to start recording.
  • M-c to capitalize the first word (The).
  • C-e to go to the end of the line.
  • . to insert a period. Now the first line is good.
  • C-a to go to the beginning of the line (where we started), and the down arrow to go to the next line.

Now type F4 to stop recording. Then F4 again to run the macro on the second line. Then F4 again to run the macro on the 3rd line. You’re done!

The quick brown fox.
Jumps over.
The lazy dog.

You could also run the macro N times using Control-a number then F4, as we saw earlier. You can also apply the macro to a whole region by selecting the region and running M-x apply-macro-to-region-lines, which is neat.

If you want to see macros at their best (and incidentally Emacs beat Vim at its own game), check out this quick video:

The entire series of Emacs Rocks is worth watching.


That’s it for today. Lots more to come. Stay tuned!

  1. Note that Emacs editing macros have nothing to do with Lisp macros: one is a trick to save a sequence of keys and repeat it, the other is a Lisp function that executes twice, at compilation time and at run time.

ELisp crash course

This is the second article in a series about Lisp; it assumes you read the first one.

If you use Emacs but don’t know Lisp, you are missing a lot: Emacs is infinitely customizable with Emacs Lisp. This post is an introduction to ELisp, hopefully giving you enough basics to write useful functions. Today we will mostly focus on the language itself, as opposed to the gazillion of Emacs-specific APIs for editing text.

My goal is not to review every function of the language: it would take a book to do so. My goal instead is to give a good high-level overview of Elisp. If you find yourself looking for a function or variable, you can browse the Emacs elisp site or you can use M-x apropos which displays anything that matches a given string.

Let’s start with…

The Basic Types

Strings are double quoted and can contain newlines. Use backslash to escape double quotes:

"This is an \"Emacs verse\"
Forgive it for being so terse"

A string is a sequence of characters. The syntax for a character is ?x: question mark followed by character. Some need to be escaped, like for example ?\(, ?\) and ?\\.

There are many functions operating on strings, like for example:

(length "foo")              ; returns 3 (also works with lists)
(concat "foo" "bar" "baz")  ; returns a new string "foobarbaz"
(string= "foo" "foo")       ; string comparison
(substring "foobar" 0 3)    ; returns "foo"
(upcase "foo")              ; returns "FOO"

Note that none of these functions have any side effect, as it is the case with most functions in Lisp - they are pure functions. They create a new object and return it.

Integers have 29 bits of precision (I don’t know why) and doubles have 64 bits. Binary starts with “#b”, octal with “#o” and hexadecimal with “#x”.

The most useful data structure in Lisp is a list, but the language also has arrays, hash tables, and objects. An array is called a vector, and you can create one like so: [ "the" "answer" "is" 42]. Like lists, they can contain objects of various types. You use spaces to separate the values; comas are part of the Lisp syntax but they are used for something else as we will soon see.

Quote

The quote is a special character in the Lisp syntax that prevents an expression from being evaluated. For instance:

'a               ; => a
'(a b c)         ; => (a b c) equivalent to (list 'a 'b 'c)

The quote prevents the evaluation of the symbol “a” on the first line, and the list on the second line, otherwise they would be considered as a variable and a function call respectively.

The backquote is like a quote, except that any element preceded by a coma is evaluated. The backquote is very handy for defining macros, e.g. functions that generate code. For example:

`(1 ,(+ 1 1) 3)  ; => (1 2 3)

Variables

Lisp is a dynamically-typed language, like Ruby or Python and unlike Java or C++. You don’t need to declare the type of a variable, and a variable can hold objects of different types over time.

We already saw in the previous post how to declare a global variable with defvar and set it with setq. Another way to use variables is function parameters:

(defun add (x y)
  (+ x y))

(message "%s + %s = %s" 1 2 (add 1 2)) ; prints "1 + 2 = 3"

Here we define a function add with 2 arguments, which returns the sum of its arguments. Then we call it. message is an Emacs function similar to C’s printf: it prints a message in the mini-buffer and in the messages buffer1.

Every time you call add, Lisp creates new bindings to hold the values of x and y within the scope of the function call. A single variable can have multiple bindings at the same time; for example the parameters of a recursive function are rebound for each call of the function.

The let form declares local variables. The syntax is (let (variable*) body) where each variable is either a variable name, or a list (variable-name value). Variables declared with no value are bound to nil. For example:

(let ((x 1)
      y)
  (message "x = %s, y = %s" x y)) ; prints "x = 1, y = nil"

The scope of the variable bindings is the body of the let form. After the let, the variables refer to whatever, if anything, they referred to before the call to let. You can bind the same variable multiple times:

(defun foo (x)
  (message "x = %d" x)       ; x = 1
  (let ((x 2))
    (message "x = %d" x)     ; x = 2
    (let ((x 3))
      (message "x = %d" x))  ; x = 3
    (message "x = %d" x))    ; x = 2
  (message "x = %d" x))      ; x = 1

;; Check the Messages buffer to see the results
(foo 1)

Note that let binds variables in parallel and not sequentially. That means that you cannot declare a variable whose value depends on another variable declared in the same let. For example this is wrong:

(let ((x 1)
      (y (* x 10)))
  (message "x = %s, y = %s" x y)) ; error: variable x is void

There are two ways to fix the code above: you could use a second let within the first, or you could replace let with let*: it binds variables sequentially, one after the other. The key to understand that is to remember that the origin of Lisp is the Lamda Calculus, where everything is a function call. The first let form above is equivalent to calling an anonymous function like this:

;; equivalent to (let ((x 1) y) (message ...))
;; prints "x = 1, y = nil"
((lambda (x y)
   (message "x = %s, y = %s" x y))
 1 nil)

Here we define a lambda (anonymous) function with 2 arguments, and we call it with the values of the arguments. The syntax of a lambda is (lambda (arguments*) body), and we call it like any other function by putting it in a second pair of parentheses with the arguments.

The equivalent of a let* requires multiple function calls:

;; equivalent to (let* ((x 10) (y x)) (message ...))
;; prints "x = 1, y = 10"
((lambda (x)
   ((lambda (y)
      (message "x = %s, y = %s" x y))
    (* x 10)))
 1)

The first lambda binds x to 1 and the second lambda binds y to x * 10.

Conditions

In ELisp and Common Lisp, nil is used to mean false, and everything that is not nil is true, including the constant t which means true. Therefore a symbol is true, a string is true and a number is true (even 0). nil is the same as () and it is considered good taste to use the former when you mean false (or void) and the latter when you mean empty list. Note that Clojure and Scheme treat boolean logic differently: for them the empty list and false are different things.

Let’s start with simple boolean functions. not returns the negation of its argument, so that (not t) returns nil and vice versa. Like most functions in Lisp, and and or can take any number of arguments. and returns the value of the last argument that is true, or nil if it finds an argument that is not true. or returns the value of the first argument that is true, or nil if none of them are true. For example:

(and 0 'foo)      ; => 'foo => true
(and 0 nil 'foo)  ; => nil  => false
(or 0 nil 'foo)   ; => 0    => true

You can compare for equality using = for numbers, string= for strings or eq for same address in memory. There is also a generic equal function that tests if the objects are equal no matter what type they are, so that’s the only one you need to remember.

(if then else*) is a special form that is equivalent to C’s ternary operator ?:. It must have at least a then form and can only have one. It may have one or more else forms. It returns the value of the then form or the value of the last else form. For example:

(defun max (x y)
  (if (> x y) x y))

(max 1 2)  ; => 2

If you just want a then or an else, it is better to use when and unless because they can have multiple then or else forms. They return the value of the last form or nil. Here is an example:

;; Predicate (-p) testing if today is a Friday.
;; current-time-string returns a string like "Fri Jul 10 10:52:44 2015".
;; string-prefix-p is a predicate testing for a string prefix.
(defun today-is-friday-p ()
  (string-prefix-p "Fri" (current-time-string)))

(when (today-is-friday-p)
  (message "Yay Friday!")
  (message "I love Fridays"))

(unless (today-is-friday-p)
  (message "It's not Friday")
  (message "Oh well"))

Finally cond is like a super-charged version of C’s switch/case: it chooses between an arbitrary number of alternatives. Its arguments are a collection of clauses, each of them being a list. The car of the clause is the condition, and the cdr is the body to be executed if the condition is true (the body can have as many forms as you like). cond executes the body of the first clause for which the condition is true. For example:

(defun guess-what-type (x)
  "Guesses the type of x"
  (cond ((numberp x)
         (message "x is a number"))
        ((stringp x)
         (message "x is a string")
         (when (> (length x) 10)
           (message "It has more than 10 characters")))
        ((listp x)
         (message "x is a list"))
        ((symbolp x)
         (message "x is a symbol"))
        (t
         (message "I don't now what x is"))))

(guess-what-type 10)                ; x is a number
(guess-what-type "hello")           ; x is string
(guess-what-type '(a b))            ; x is a list
(guess-what-type nil)               ; x is a list
(guess-what-type 'foo)              ; x is a symbol
(guess-what-type :foo)              ; x is a symbol
(guess-what-type (current-buffer))  ; I don't know what x is

The code above uses predicates like numberp which returns t if the argument is a number. The function current-buffer returns a buffer object which is neither a number, string, list or symbol (it is an instance of a class). Notice the last clause: the condition is t which is obviously always true. This is the “otherwise” clause guaranteed to fire if everything else above has failed.

Loops

The simplest loop is a while:

(let ((i 10))
  (while (> i 0)
    (message "%d" i)
    (setq i (- i 1))))  ; you can also use macro (decf i)

dotimes takes a variable and a count, and sets the variable from 0 to count - 1:

(dotimes (i 5) (message "%d" i))

dolist takes a variable and a list, and sets the variable to each item in the list:

(dolist (i '(a b c)) (message "%s" i))

If you need anything more complicated, take a look at the documentation of the loop macro. This is a very powerful macro with lot of options that takes an (almost) English sentence as argument and generates what you mean. For example, a C “for” loop can be expressed like so:

(loop for i from 1 to 10
      do (message "i = %d" i))

Another example is the following code which iterates over a “plist” (property list) which is a collection like (key1 value1 key2 value2) using cddr to move by 2 items at a time and skipping the properties where the key is an even number:

(let ((l '(1 "one" 2 "two" 3 "three")))
  (loop for (key value) on l by #'cddr
        unless (evenp key)
        do (message "%d is %s in English" key value)))
;; 1 is one in English
;; 3 is three in English

Elisp also has exceptions, try/catch/finally and anything else you would expect.

Functions

Lisp uses several keywords for declaring arguments within a defun.

  • &optional introduces optional arguments, which if not specified are bound to nil. For example (defun foo (a b &optional c d) ...) makes c and d optional.
  • &rest takes all remaining arguments and concatenates them into a list. For example the signature of the list function is simply (&rest objects).
  • &key introduces a keyword argument, that is an optional argument specified by a keyword with a default value of your choice. For example:
(defun foo (&key (x 0) (y 0))
  (list x y))

(foo)            ; => (0 0)
(foo :x 1)       ; => (1 0)
(foo :y 2)       ; => (0 2)
(foo :x 1 :y 2)  ; => (1 2)

Functions are first class objects in Lisp. You can store them in a variable and call them later. For example:

(setq f #'list)       ; shortcut for (function list).
(funcall f 'a 'b 'c)  ; => (a b c)

The syntax #'foo is sugar for (function foo) which returns the definition of the function stored in symbol foo. It basically returns a pointer to the code. funcall calls the function with a given list of arguments. Note that Emacs is very tolerant and (setq f 'list) (e.g. setting f to the symbol “list”) will also work.

apply works like funcall but it applies the function to a list of arguments:

(apply #'+ '(1 2 3))  ; => 6

An interesting example of using apply is mapcar which applies a function to each element of a list and returns a list of the results:

(mapcar #'(lambda (x) (* 10 x))
        '(1 2 3))  ; => (10 20 30)

Interactive functions

Let’s use our fresh knowledge to do something useful.

Sometimes I want to include a separator in a comment, e.g. a sequence of dashes or tilde that fills up the rest of the line until the 80 character column (the fill-column variable defines that limit). For example, if I type “// Begin of test” I want a magic key to do this:

// Begin of test~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Elisp functions must be declared “interactive” if you want to call then using Meta-x or bind them to a key. You do this declaration by calling the interactive special form (it’s not a function) as the first form in the body of your function.

(defun insert-separator ()
  "Inserts a sequence of ~ at the end of the line, up to the
fill column"
  (interactive)
  (end-of-line)
  (let ((num-chars (- fill-column (current-column))))
    (dotimes (i num-chars)
      (insert ?~))))

;; Bind this function to C-c ~
(global-set-key [(control c)(~)] #'insert-separator)

end-of-line move the cursor to the end of the line, as you probably guessed. The let form calculates the number of characters to insert before it reaches the end of the line using the variable fill-column (which should be set to 79) and the current-column function which returns the cursor’s column number. The insert function inserts a character or string at the position of the cursor. Finally global-set-key binds the function to a key chord. Note that this is a simple implementation; it might be more efficient to create a string with n characters using (make-string num-chars ?~).

Let’s write another one. Suppose you work in an organization that has created its own code style, and suppose that said code style proclaims that lines longer than 80 characters are a cardinal sin. Believe me, such code styles do exist. So let’s write an interactive function that will find the next “long” line in the current buffer, from the position of the cursor. It could look like this2:

(defun goto-long-line (len)
  "Go to the first line that is at least LEN characters long.
Use a prefix arg to provide LEN.
Plain `C-u' (no number) uses `fill-column' as LEN."
  (interactive "P")
  (setq len (or len fill-column))
  (let ((start-line (line-number-at-pos))
        (len-found  0)
        (found      nil))
    (while (and (not found) (not (eobp)))
      (forward-line 1)
      (setq found (< len (setq len-found
                               (- (line-end-position) (point))))))
    (if found
        (when (called-interactively-p 'interactive)
          (message "Line %d: %d chars" (line-number-at-pos) len-found))
      ;; Compiler-happy equivalent to (goto-line start-line):
      (goto-char (point-min))
      (forward-line (1- start-line))
      (message "Not found"))))

This interactive function takes a numeric argument which is the max length of lines. The “P” string in the call to interactive specifies that we use an argument (in raw form; see the documentation of interactive for details). Either the user invokes this function with M-x goto-long-line, in which case the argument len is set to nil, or she invokes the function with C-u 7 9 M-x goto-long-line, in which case the argument len is set to 79 (for instance). The first setq line is used to set a default value to len: either it is the number that the user specified or it is the value of variable fill-column.

Without going into too much details, the rest of the code is a while loop until we have found a line or we reached the end of the buffer (predicate eobp). At each step we go down one line (forward-line) and we check the length of the line. Note that the Emacs function point returns the position of the cursor as an offset into the file (the current character number if you will). Our function is designed to be called both interactively and within a program, so it tests how we are called using predicate called-interactively-p before deciding to print a message or not. point-min returns the position of the first character in the buffer (should be 1) and goto-char goes to a given character position.

Note that sometimes the compiler complains when you call a function that is designed to be used interactively in your code (these functions are marked as such using a property). Usually the warning says you should use another function, supposedly more efficient because doing less tests.


That’s it for today. Lots more to come. Stay tuned!

  1. A right click in the mini-buffer pops up the message buffer. That’s a nice trick for debugging if you have a lot of traces.

  2. It is defined in Exordium.