Skip to content

Instantly share code, notes, and snippets.

@ssaavedra
Last active November 18, 2016 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssaavedra/05623f608ea5cebdb1fa5a1a6f100f74 to your computer and use it in GitHub Desktop.
Save ssaavedra/05623f608ea5cebdb1fa5a1a6f100f74 to your computer and use it in GitHub Desktop.
How to use Emacs to write CLIR files

This is a Beginners Guide to writing CAVI-ART's CLIR files using Emacs, for people who has never used Emacs.

Introduction to Emacs

Emacs is a editor very leaned to using the keyboard as the primary input method. Thus, most commands on Emacs can be entered through the keyboard, although most can also be entered through the toolbar with the mouse.

Prerequirements

Emacs 24.4 or Emacs 25.

Key "chords"

Most commands on emacs take more than one keystroke. So, for example, save is Ctrl.+S in most editors. In Emacs, it's Ctrl.+x, Ctrl.+s.

In Emacs literature, you'll find that key chords like that are abbreviated as C-x C-s. C- means Control+following key. The space means that the two combinations must be pressed, one after the other (the space bar is noted SPC to avoid confusion).

M-x is the same but with the Meta key. The Meta key depends on your X11 implementation, but on Linux it is usually the Alt key. In keyboard without a Meta key you can press ESC to achieve the same effect. Thus, M-x and ESC x will have the same effect.

Meta-x

M-x is the main key binding of Emacs. It takes you to the minibuffer, a magical place where you can send commands to the editor.

Installing packages

Emacs (24+) comes with a set of utilities called package.el, which implement a sort of package management system for Emacs, in order to download stuff to better enhance and improve the Emacs editor.

There is a free software repository configured by default called GNU ELPA, which contains software that is accepted by GNU to be part of Emacs.

We will install paredit-mode, a mode to edit files with balanced parentheses.

For that, we'll invoke the package manager list, with M-x package-list-packages RET (that is, M-x, followed by those letters --you can autocomplete with TAB--, and then the Return key to send the command).

That should download the latest indices for ELPA. You can search in the list with C-s paredit RET. When you find the one, go to it and press install with the mouse (or with the keyboard, select it to be installed with i and then execute the installation with x).

Exiting the editor

If that was already too much Emacs for today, you can always exit the editor with C-x C-c. If that does not happen (because maybe Emacs is waiting for your input on something else), you can tell Emacs to abort everything it is asking you with C-g C-g C-g (one should be enough, three is the most number of times you will need it).

Using Emacs on clir files

By default, Emacs does not know anything about a .clir extension. Thus, it will open the file in fundamental-mode, which is a rather rudamentary mode for editing plain text.

We want to use lisp-mode in order to gain the indentation knowledge of Emacs for indenting parentesized code.

Thus, we enable lisp-mode by typing M-x lisp-mode RET.

Emacs knows about something called file-local variables, and you can instruct Emacs to open a file with a certain mode from the file itself.

So, you can add a comment to your file with the following content:

;; Local Variables:
;; mode: lisp
;; End:

You can also instruct Emacs to add this for you (when you are already in lisp-mode) by typing M-x add-file-local-variable RET mode RET lisp-mode RET.

You also have to enable paredit-mode by typing M-x paredit-mode RET.

Once you have paredit-mode enabled you should see "Paredit" on the bottom of the screen (that is called the modeline). If you type that again, it will disappear. If you ever have a disbalanced parenthesis, paredit should not be enabled in order for you to fix the typo.

Paredit

Paredit automatically balances parenthesis and double quotes on lisp modes. You can never insert accidentally a closing parenthesis without a corresponding opening one (and when opening a parenthesis, paredit closes it already for you).

You can navigate to after the parenthesis by typing it, as you would naturally if paredit wasn't there, but it will take care for you not to add additional parenthesis.

It takes a moment to get used to it.

Try for example in an empty buffer to type the following:

(Well, first, type in M-x lisp-mode RET M-x paredit-mode RET)

( h e l l o , SPC w o r l d ). You will find out that Emacs highlights the closing parenthesis but the cursor point just goes over it without typing anything, as if you pressed the right arrow on the keyboard. That is the behaviour you should expect.

Loading paredit automatically on lisp mode

You can paste the following in your ~/.emacs to instruct Emacs to always load paredit-mode when entering lisp-mode.

(autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t)
(add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode)
(add-hook 'lisp-mode-hook #'enable-paredit-mode)

Indentation

In Lisp-mode Emacs indents nodes automatically depending on how nested they are on the parentheses.

The default modes are ok enough, but for CLIR, let expressions do not hold the same indentation pattern as in Common Lisp, and thus you should paste the following in your ~/.emacs file:

(put 'letfun 'lisp-indent-function
     '((&whole 4 &rest (&whole 1 &lambda 4 &body)) &body))

;; Default for LISP (uncomment and eval to undo the effect)
;; (put 'let 'lisp-indent-function '((&whole 4 &rest (&whole 1 1 2)) &body))

(put 'asserts 'lisp-indent-function '(4 &body))

(put 'let 'lisp-indent-function
     '((&whole 4 &rest (&whole 1 &lambda 2 &body)) 6 &body))

(put 'define 'common-lisp-indent-function
     '(4 &lambda &lambda &body))

When you want to re-indent a CLIR file (or any file in Emacs), press M-q. The text will reflow to its intended place.

Also, pressing TAB will indent the current line to where it is expected, according to how the previous line (but if the previous line is not correctly-indented it will not escalate to fix that).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment