WSU logo


College of Engineering & CS
Wright State University
Dayton, Ohio 45435-0001

CEG 333: Introduction to Unix

Prabhaker Mateti

Programming Emacs: Keybindings and Modes


In Emacs, every keypress runs a command, which calls a function written in the ELisp (or Emacs Lisp) programming language. Even the letter keys do their work by calling the self-insert-command function, which in turn tells Emacs to insert the last character typed into the buffer.

This makes Emacs extremely customizable. Keys can be rebound and functions reprogrammed while the editor runs, allowing almost any part of Emacs to be changed at will. New features can be written and toggled on and off with the push of a button.

To rebind a key for the current session, type M-x global-set-key. This will prompt for a key and the function it should call.

Features like keybindings are controlled by Emacs modes, of which there are two types. Major modes are for working with a specific task or type of file. The Text Mode invoked by opening .txt files and C++ Mode (introduced in week 5) are examples of this type. There are also minor modes, which add features like spell-checking, syntax highlighting, and mouse wheel operation, to name a few.

It is helpful to remember that many modes group their keybindings under a prefix, such as C-x r for commands dealing with rectangles or registers, C-x C-a for debugging commands, or C-x 4 for window management.

For example, like almost all other editors and word processors, Emacs has an overwrite feature which is toggled with the Insert key. Insert is bound to the overwrite-mode function. This function turns on a minor mode, which sets a global variable. When that variable is true, the parts of Emacs that deal with inserting text cause it to overwrite characters instead.

A major use of overwrite mode is to draw ASCII art diagrams. So suppose a user wants to draw a rectangle, with - and | for sides and + for corners. Overwrite mode makes this very convenient, because, mistakes don't need to be deleted, they can simply be "drawn over".

But suppose it is necessary to draw many rectangles. A user might define a macro as explained above, but then the rectangles couldn't be different sizes. The answer is beyond the scope of this class, but it's where Emacs really shines. The following ELisp example will draw rectangles of any size.

      (defun ceg333-draw-rectangle (h w)
        (interactive "*nHeight?
      nWidth? ")
        (let ((r h))
          (while (not (eq r 0))
            (let ((c (- w 2)))
      	(if (or (eq r h) (eq r 1))
      	    (progn
      	      (insert-char ?+ 1)
      	      (insert-char ?- c)
      	      (insert-char ?+ 1))
      	    (progn
      	      (insert-char ?| 1)
      	      (insert-char ?  c)
      	      (insert-char ?| 1)))
      	(newline))
            (setq r (1- r)))))
    

To run it, copy it into the Emacs scratch buffer, position the cursor after the last closing parenthesis, and press C-x C-e. The function can then be run with M-x ceg333-draw-rectangle.