Emacs Tips & Tricks
Power tools for Emacs users

January 2011
Geotechnical Software Services

This document is available at http://geosoft.no/development/emacs.html

Table of Content

    Basic Tips & Tricks
    File Finder
    Buffer Switcher
    Navigator
    Scroller
    Emacs for Programmers
    Emacs Links


Basic Tips & Tricks

Emacs initialization

When Emacs is launched, a specific initialization file is read. The initialization file can contain Emacs personal preferences like the functions and key bindings examples in this document. In addition it can contain default state settings for Emacs variables. Some examples are given below.

(setq default-frame-alist (append (list
  '(width  . 81)  ; Width set to 81 characters
  '(height . 40)) ; Height set to 60 lines
  default-frame-alist))

(setq inhibit-startup-message   t)   ; Don't want any startup message
(setq make-backup-files         nil) ; Don't want any backup files
(setq auto-save-list-file-name  nil) ; Don't want any .saves files
(setq auto-save-default         nil) ; Don't want any auto saving

(setq search-highlight           t) ; Highlight search object
(setq query-replace-highlight    t) ; Highlight query object
(setq mouse-sel-retain-highlight t) ; Keep mouse high-lightening

(set-face-background 'region "yellow") ; Set region background color
(set-background-color        "wheat3") ; Set emacs bg color

In the MS-Windows environment the initialization file should be called _EMACS and should be put in the root directory. In UNIX based systems the file should be called .emacs and should be put in the personal home directory.

Key bindings

For maximum typing and editing efficiency, as many keyboard keys as possible should be bound directly to Emacs functions. Some are already bound when Emacs is installed, but the great variety of keyboards and operating systems available makes it difficult for the Emacs team to pre bind functions in general.

To bind a function to a key, include a statement of the form

(global-set-key key-name 'function-name)

in the initialization file. key-name is either given as an actual name within brackets like [f1] for the F1 function key, or as "\C-q" or "\M-q" for a Control-key or Escape-key sequence respectively.

Remember that function that are not bound to a specific key or key sequence (actually this includes most functions) can always be accessed by typing

Esc-x function-name

This document gives many examples of possible Emacs key bindings. Since the name of the keys may differ between keyboards and operating systems, the following approach can be used to find the name of a specific key. Enter

Esc-x describe-key

and hit the key (or key combination) in question. This will reveal the name of the key as well as the function it is currently bound to.

Complete word

Emacs includes a very useful concept called complete word. Whenever in the minibuffer, it is always possible to hit the space bar to let Emacs try to complete the current input. This can save many key strokes and a lot of time.

For instance when looking for a file one can give one letter of a directory or a file name and, in case it is unique, Emacs will fill in the rest automatically. If it is not unique, Emacs will fill in as much as possible and return the different possible completions to let you choose between them.

The Emacs region

Emacs includes a powerful concept called a region. A region is like a marked area in a conventional word processor, but more useful in the way Emacs functions can be applied to it directly, for instance for sorting just a few lines of a file, or for printing a portion of a file.

A region is set implicitly by many Emacs functions, but can be set manually as well using Ctrl-Space. This specifies the current cursor position as one end of the region, called the mark. The cursor can then be moved around and its position will specify the other end of the region.

Cut, copy and paste key bindings

Based on the description of a region above, defining the common functions Cut, Copy and Paste on the region becomes very useful. The functions should be bound to keys for easy access, for instance like:

(global-set-key [f5] 'copy-region-as-kill) ; Copy
(global-set-key [f6] 'kill-region)         ; Cut
(global-set-key [f7] 'yank)                ; Paste

An element that is cut or copied this way is put into something called the kill-ring. Calling the yank function always pastes the last entry from the kill-ring. However, after the yank function as called, it is possible to replace the pasted text by the second last entry in the ring and so on by calling the yank-pop (by default boud to the Esc-y key) function repeatedly. In effect, all cut/copy operations of the session is registered, and are easily accessible through this simple sequence of key strokes.

Column handling

A feature that are missing in most editors and word processors is the possibility to cut/copy and paste a vertical region of a file. In Emacs this is simple. The column to cut or copy is marked as a region as described above. It can then be cut calling the function kill-rectangle and re-pasted by yank-rectangle

Navigation key bindings

These are the basic navigation keys. Many keyboard come with two sets of these keys, so each function is bound once for each key. Some of these functions are usually already bound when Emacs is installed.

(global-set-key [kp-home]  'beginning-of-buffer) ; [Home]
(global-set-key [home]     'beginning-of-buffer) ; [Home]
(global-set-key [kp-end]   'end-of-buffer)       ; [End]
(global-set-key [end]      'end-of-buffer)       ; [End]
(global-set-key [kp-prior] 'my-scroll-down)      ; [PgUp]
(global-set-key [prior]    'my-scroll-down)      ; [PgUp]
(global-set-key [kp-next]  'my-scroll-up)        ; [PgDn]
(global-set-key [next]     'my-scroll-up)        ; [PgDn]

Undo

Emacs has the most amazing undo facility. Anything you have typed since your session began is registered and can be undone. Since this obviously is a very useful function it should be bound directly to a key. Using the keypad [-] (subtraction) key for this purpose is convenient since it indicates the nature of the operation as well as being located so far away that it isn't easily accessed by accident.

(global-set-key [kp-subtract] 'undo) ; [Undo]

Insert/overwrite mode

By default Emacs run in insert mode. This state can be toggled with overwrite mode, and is best bound to the Insert key(s) on the keyboard.

(global-set-key [insert]    'overwrite-mode) ; [Ins]
(global-set-key [kp-insert] 'overwrite-mode) ; [Ins]

Goto line

To go to a specific line can be useful, especially when Emacs is used for programming. This common function can be bound to Ctrl-L by:

(global-set-key "\C-l" 'goto-line) ; [Ctrl]-[L]

Window splitting

The Emacs window can be split so that is can display two or more buffers at the same time. This can be useful when comparing two files, or when editing two files simultaneously. Functions for managing window splits:

(global-set-key [f2] 'split-window-vertically)
(global-set-key [f1] 'remove-split)

Frames

As well as displaying more than one buffer in a window, Emacs can also display more than one window (or frames as it is called in Emacs terminology). Creating and deleting frames can conveniently be done by binding the the functions as follows:

(global-set-key "\C-f" 'make-frame)   ; [Ctrl]-[F]
(global-set-key "\M-f" 'delete-frame) ; [ESC]-[F]

Getting information

Emacs contains lots of features and possibilities and it can be difficult to comprehend and utilize it all. However, Emacs comes with full documentation included. One of the more useful functions is apropos:

[ESC]-x apropos

This command prompts for a name or a concept and will return list of all functions or variables that relates to the entry given. This is a very useful approach for getting to know Emacs and the possibilities it contains.

Given an Emacs function or a variable it can sometimes be difficult to know exactly what it does. An explanation of a function or a variable can be obtained by:

[ESC]-x describe-function
[ESC]-x describe-variable

They will prompt for a name and return a comprehensive description of it.

Similarly, as described above

[ESC]-x describe-key

prompts for a key and returns the name of the key and the function it is currently bound to.


File Finder

This extension to the powerful Emacs complete-word facility is the major time saver for the frequent Emacs user. It is used within the find-file function and makes it possible to enter a given directory in the minibuffer by just entering a predefined two- to four letter sequence followed by the space key. Three different paths are given in the example below. The list can however be extended indefinetly.

(defun geosoft-parse-minibuffer ()
  ;; Extension to the complete word facility of the minibuffer
  (interactive)
  (backward-char 4)
  (setq found t)
  (cond
     ; local directories
     ((looking-at "..cd") (setq directory "c:/users/john/"))
     ((looking-at ".doc") (setq directory "c:/users/john/documents/"))
     ((looking-at "java") (setq directory "c:/users/john/src/java/"))
     (t (setq found nil)))
  (cond (found (beginning-of-line)
                (kill-line)
                (insert directory))
         (t     (forward-char 4)
                (minibuffer-complete))))

The function is made an extension to the minibuffer complete-word function by:

(define-key minibuffer-local-completion-map " " 'geosoft-parse-minibuffer)


Buffer Switcher

After a file has been loaded once, it is available in an Emacs buffer. Emacs is installed with lots of clever functions for fast retrieval of buffers. The function below is different however. It makes it possible to browse through the buffer list by single key-strokes only. It is also clever in its handling of the buffer stack in the way that the most frequent visited buffers (i.e. files) always are at the top of the stack.

(defvar LIMIT 1)
(defvar time 0)
(defvar mylist nil)

(defun time-now ()
   (car (cdr (current-time))))

(defun bubble-buffer ()
   (interactive)
   (if (or (> (- (time-now) time) LIMIT) (null mylist))
       (progn (setq mylist (copy-alist (buffer-list)))
          (delq (get-buffer " *Minibuf-0*") mylist)
          (delq (get-buffer " *Minibuf-1*") mylist)))
   (bury-buffer (car mylist))
   (setq mylist (cdr mylist))
   (setq newtop (car mylist))
   (switch-to-buffer (car mylist))
   (setq rest (cdr (copy-alist mylist)))
   (while rest
     (bury-buffer (car rest))
     (setq rest (cdr rest)))
   (setq time (time-now)))

The function is bound to a function key (for instance F4) by:

(global-set-key [f4] 'bubble-buffer)

When you are definitely done with a buffer (i.e. a file) it can be convinient to remove it from the buffer stack. To silently remove the current buffer from the stack (and retrieve the next one on the stack), bind the following function to the Ctrl-Del key.

(defun geosoft-kill-buffer ()
   ;; Kill default buffer without the extra emacs questions
   (interactive)
   (kill-buffer (buffer-name))
   (set-name))

Bind by:

(global-set-key [C-delete] 'geosoft-kill-buffer)
(global-set-key [C-kp-delete] 'geosoft-kill-buffer)


Navigator

For fast navigation within an Emacs buffer it is necessary to be able to move swiftly between words. The functions below change the default Emacs behavour on this point slightly, to make them a lot more usable.

Note the way that the underscore character is treated. This is convinient behaviour in programming. Other domains may have different requirements, and these functions should be easy to modify in this respect.

(defun geosoft-forward-word ()
   ;; Move one word forward. Leave the pointer at start of word
   ;; instead of emacs default end of word. Treat _ as part of word
   (interactive)
   (forward-char 1)
   (backward-word 1)
   (forward-word 2)
   (backward-word 1)
   (backward-char 1)
   (cond ((looking-at "_") (forward-char 1) (geosoft-forward-word))
         (t (forward-char 1))))

(defun geosoft-backward-word ()
   ;; Move one word backward. Leave the pointer at start of word
   ;; Treat _ as part of word
   (interactive)
   (backward-word 1)
   (backward-char 1)
   (cond ((looking-at "_") (geosoft-backward-word))
         (t (forward-char 1))))

Bind the functions to Ctrl-Left and Ctrl-Right with:

(global-set-key [C-right] 'geosoft-forward-word)
(global-set-key [C-left] 'geosoft-backward-word)


Scroller

Scrolling without moving the cursor can be achieved by the functions:

(defun scroll-down-keep-cursor ()
   ;; Scroll the text one line down while keeping the cursor
   (interactive)
   (scroll-down 1))

(defun scroll-up-keep-cursor ()
   ;; Scroll the text one line up while keeping the cursor
   (interactive)
   (scroll-up 1))

Bind the functions to the /-key and the *-key (on the numeric keypad) with:

(global-set-key [kp-divide] 'scroll-down-keep-cursor)
(global-set-key [kp-multiply] 'scroll-up-keep-cursor)


Emacs for Programmers

Modes

During editing Emacs can be set in different modes. The mode has some knowledge about the structure of the document the user is working on, and can assist on the organization, formatting and editing of this.

This is particularly helpful when Emacs is used for programming, since programming languages in general has rigid sets of restrictions regarding document structure. For instance, programming statements are normally indented according to specific rules, and if the mode know the rules, it can do the indentation for the user automatically.

There exists modes for all major and minor programming languages and most types of documents such as HTML, Perl scripts, shell scripts, Unix Makefiles, CSS etc. The mode is automatically set by Emacs based on the name or the extension of the file edited.

Color coding

A very useful feature is Emacs' ability to render text with different colors and fonts. Emacs packages for color coding analyse the structure of the text and color the text according to the structure. For instance can programming comments get one color, reserved words a different color, function definitions yet another and so on.

A popular color coding package that comes with the standard Emacs distribution is hilite. To use it, include the following statement in the initialization file:

(load "hilit19")

During editing, it is in general impossible for the color coding package to color the text since the structure of the edited part of the document may not yet be complete. Beacuase of this, it is handy to be able to refresh the color coding manually. This is done with the function hilit-highlight-buffer which can be bound to a key combination for convenience.

Including predefined element skeletons

Many of the text elements that are used in programming has a standard form based on common skeletons. The ability to include skeletons like these with a single keystroke can be very useful and time efficient.

For instance, declaration and documentation comments in Java follow the rules dictated by the javadoc automatic documentation system. A typical javadoc method comment will look something like this:

/**
 *
 * Returns the character at the specified index. An index
 * ranges from <code>0</code> to <code>length()-1&</code>
 *
 * @param       index of the desired character
 * @return      the desired character
 * @exeption    StringIndexOutOfRangeExeption
 *              if the index is not in the range <code>0</code>
 *              to <code>length()-1&</code>.
 * @see         java.lang.Character#charValue()
 */
public char charAt(int index) {
   ...
}

To create a skeleton that can be included directly into a java source file, include the following LISP function in the Emacs initialization file:

(defun javadoc-method-comment ()
  ;; Insert a javadoc method comment at the cursor position
  (interactive)
  (insert
"/**
 *
 *
 *
 *
 * @param
 * @return
 * @exeption
 * @see
 */
")/
  (previous-line 8)
  (end-of-line))

The function can be bound to a key by for instance:

(define-key java-mode-map [f9] 'javadoc-method-comment)

So hitting F9 will in effect include a javadoc method comment skeleton at the cursor position and move the cursor to the position within the comment where the description should start.

Along the same lines it is easy to predefine a large number of code elements, for instance while loops, if-then-else constructions, file headers etc. and make them available by single key strokes or key combinations.


Emacs Links