Emacs Redux

Return to the Essence of Text Editing

Smarter Navigation to the Beginning of a Line

| Comments

In Emacs there are two essential commands when you have to go the beginning of a line - move-beginning-of-line(bound to C-a) and back-to-indentation(bound to M-m). The first takes you to the first column of a line and the latter takes you the first non-whitespace character on a line.

Generally, I find back-to-indentation more useful, but occasionally it makes sense to go to the real beginning of a line as well. What doesn’t make sense is to have to think all the time what command is the most appropriate in a particular situation. Wouldn’t it be great if C-a initially took you to the first non-whitespace char(as back-to-indentation does) on a line, and if pressed again took you to the actual beginning of the line? It would be! Let’s get it done:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
(defun smarter-move-beginning-of-line (arg)
  "Move point back to indentation of beginning of line.

Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and
the beginning of the line.

If ARG is not nil or 1, move forward ARG - 1 lines first.  If
point reaches the beginning or end of the buffer, stop there."
  (interactive "^p")
  (setq arg (or arg 1))

  ;; Move lines first
  (when (/= arg 1)
    (let ((line-move-visual nil))
      (forward-line (1- arg))))

  (let ((orig-point (point)))
    (back-to-indentation)
    (when (= orig-point (point))
      (move-beginning-of-line 1))))

;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
                'smarter-move-beginning-of-line)

The command will keep toggling between the first non-whitespace char and the beginning of the line when invoked.

Here’s a visual example(| is the cursor):

1
2
3
4
5
6
7
8
This is a short example
    text|
    # pressing C-a once
   |text
    # pressing C-a again
|   text
    # pressing C-a again
   |text

This functionality could also be implemented with defadvice, but I tend to avoid their use.

smarter-move-beginning-of-line is part of Prelude.

P.S. The credit for this tip goes to Sebastian Wiesner.

Delete Whitespace Around Point

| Comments

One task that often pops when editing text or code is the need to remove some extra whitespace around the point(the cursor). Emacs has your back!

First, we have the command delete-horizontal-space(bound to M-\) - it deletes all spaces and tabs around the point. With a prefix argument(C-u M-\) the command deletes only the whitespace before the point.

One similar, although a bit less known, command is just-one-space(bound to M-SPC) - it deletes all spaces and tabs around the point, leaving just one space (or N spaces if you supply N as a prefix argument like C-4 M-SPC). If N is negative, the command deletes newlines as well, leaving -N spaces.

One minor snafu with just-one-space is that M-SPC is a no-go on OSX since just about everyone uses it for quick access to Spotlight or switching between languages. You might want to use a different keybinding like this one:

1
(global-set-key (kbd "C-c j") 'just-one-space)

Personally, of the two commands I find just-one-space the more useful.

In Prelude just-one-space is additionally bound to the kk keychord.

Instant Access to init.el

| Comments

One of the files Emacs users often edit is init.el(especially if they are having all of their configuration inside of it). It might be sensible then to develop a faster way to access init.el:

1
2
3
4
(defun find-user-init-file ()
  "Edit the `user-init-file', in another window."
  (interactive)
  (find-file-other-window user-init-file))

user-init-file holds the path to your init.el. For mine its value is /Users/bozhidar/.emacs.d/init.el. find-file-other-window will open the file in a window adjacent to the one you’re currently in.

Short and sweet! You might want to bind it to some keycombo:

1
(global-set-key (kbd "C-c I") 'find-user-init-file)

P.S. Thanks to Sebastian Wiesner for bringing this tip to my attention!

Whitespace Cleanup

| Comments

Good developers are very careful about the proper use of whitespace in their files - there should be no empty lines at the beginning of a file, no empty lines at the end of a file, no trailing whitespace, no mixture of tabs and spaces, etc.

Emacs, naturally, wants to help with every problem possible and provides a very nice solution in the form of the whitespace-cleanup command. It’s a much more powerful alternative to the older delete-trailing-whitespace command, that simply deletes trailing whitespace, and it’s aware of the whitespace-style variable, used by whitespace-mode.

It usually applies to the whole buffer, but in transient-mark-mode when the mark is active, it applies to the region. It also applies to the region when it is not in transient mark mode, the mark is active and C-u was pressed just before calling whitespace-cleanup interactively. There is also a similar command called whitespace-cleanup-region.

The problems cleaned up are (borrowed from the official documentation):

  1. Empty lines at beginning of buffer.

  2. Empty lines at end of buffer. If whitespace-style includes the value empty, remove all empty lines at beginning and/or end of buffer.

  3. 8 or more SPACEs at beginning of line. If whitespace-style includes the value indentation: replace 8 or more SPACEs at beginning of line by TABs, if indent-tabs-mode is non-nil; otherwise, replace TABs by SPACEs. If whitespace-style includes the value indentation::tab, replace 8 or more SPACEs at beginning of line by TABs. If whitespace-style includes the value indentation::space, replace TABs by SPACEs.

  4. SPACEs before TAB. If whitespace-style includes the value space-before-tab: replace SPACEs by TABs, if indent-tabs-mode is non-nil; otherwise, replace TABs by SPACEs. If whitespace-style includes the value space-before-tab::tab, replace SPACEs by TABs. If whitespace-style includes the value space-before-tab::space, replace TABs by SPACEs.

  5. SPACEs or TABs at end of line. If whitespace-style includes the value trailing, remove all SPACEs or TABs at end of line.

  6. 8 or more SPACEs after TAB. If whitespace-style includes the value space-after-tab: replace SPACEs by TABs, if indent-tabs-mode is non-nil; otherwise, replace TABs by SPACEs. If whitespace-style includes the value space-after-tab::tab, replace SPACEs by TABs. If whitespace-style includes the value space-after-tab::space, replace TABs by SPACEs.

It might be a good idea to add whitespace-cleanup to your before-save-hook so that every buffer would be cleaned up before it’s saved:

1
(add-hook 'before-save-hook 'whitespace-cleanup)

For programming languages that rely on tabs being tabs you should enable indent-tabs-mode (as noted above). Here’s an example for makefile-mode:

1
(add-hook 'makefile-mode-hook 'indent-tabs-mode)

Prelude adds whitespace-cleanup to before-save-hook by default.

Keep Backup and Auto-save Files Out of the Way

| Comments

Emacs has two helpful features, called auto-backup and auto-save(or at least I call them this way).

Auto-backup is triggered when you save a file - it will keep the old version of the file around, adding a ~ to its name. So if you saved the file foo, you’d get foo~ as well.

auto-save-mode auto-saves a file every few seconds or every few characters(both settings are configurable - auto-save-interval is set to 300 characters by default and auto-save-timeout is set to 30 seconds). The auto-save files have names like #foo# and are deleted automatically when you manually save a file.

Although the modes are definitely useful, many Emacs users find the extra files they create quite annoying(especially since they rarely resort to using them) and disable both feature to get rid of the pesky unwanted files:

1
2
3
;; disable auto-save and auto-backup
(setq auto-save-default nil)
(setq make-backup-files nil)

Even though I’ve never actually had any use of those backups, I still think it’s a bad idea to disable them(most backups are eventually useful). I find it much more prudent to simply get them out of sight by storing them in the OS’s tmp directory instead.

1
2
3
4
5
;; store all backup and autosave files in the tmp dir
(setq backup-directory-alist
      `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
      `((".*" ,temporary-file-directory t)))

Now they won’t annoy you constantly, but they will still be around if you need them. Some OSes delete everything in their tmp directories on restart, so if this worries you - consider using another directory.

Prelude keeps auto-backup and auto-save files in tmp by default.

Erase Buffer

| Comments

Some Emacs users find themselves wondering what’s the fastest way to erase the contents of a buffer. As you know, I’m fond of delete-selection-mode and I find the combination of C-x h (mark-whole-buffer) + inserting anything afterwards pretty potent.

Another pretty quick way to erase a buffer would be the built-in erase-buffer command. It’s disabled by default since it’s considered that beginners find it confusing(although I’m not sure why), so you’ll be prompted to enable it the first time you run M-x erase-buffer. Alternative you can simply put this snippet in your config:

1
2
;; enable erase-buffer command
(put 'erase-buffer 'disabled nil)

You should note that any narrowing restrictions would have no effect over erase-buffer and the buffer would be truly empty after invoking the command. Conversely - narrowing has an effect over mark-whole-buffer.

If you like the command you might want to bind it to some keybinding like C-c E:

1
(global-set-key (kbd "C-c E")  'erase-buffer)

Personally, I rarely need it, so I don’t bind it to anything.

The erase-buffer command is enabled by default in Prelude.

Rename File and Buffer

| Comments

A few weeks ago I wrote an article called “Delete file and buffer”. Today we’ll revisit the article in a way, by exploring a pretty similar topic - renaming of a file and its associated buffer. I’ve taken the liberty to use pretty much the same wording I used in the aforementioned post to spare me the effort of thinking up something original.


From time to time(most often when I refactor code) I need to quickly(this removes dired from the equation) rename a file and the buffer associated with it. Since most of the files I work with are under version control I can just use the tried and true M-x vc-rename-file. Unfortunately the command does not act on the current file and will prompt you for a file to rename. Looks like we need to create a simple wrapper around it to get the job done:

1
2
3
4
5
6
7
8
9
10
11
12
(defun rename-file-and-buffer ()
  "Rename the current buffer and file it is visiting."
  (interactive)
  (let ((filename (buffer-file-name)))
    (if (not (and filename (file-exists-p filename)))
        (message "Buffer is not visiting a file!")
      (let ((new-name (read-file-name "New name: " filename)))
        (cond
         ((vc-backend filename) (vc-rename-file filename new-name))
         (t
          (rename-file filename new-name t)
          (set-visited-file-name new-name t t)))))))

The wrapper is extra smart and will work on files that are not under version control as well! I’m pretty fond of commands that do what you mean instead of throwing errors. Now that we have this neat little command we should probably bind it to some each to press keys, like C-c r:

1
(global-set-key (kbd "C-c r")  'rename-file-and-buffer)

As usual both the command and its keybinding are available in Prelude.

Manage Processes With Proced

| Comments

One extremely cool (but little known) new feature in Emacs 23 was the addition of proced.

proced basically allows you to run top inside Emacs and monitor/control processes via it. Here’s how it looks in action:

Normally you’d use M-x proced to start the command, but as mentioned earlier I find it extremely useful and therefore I bind it to C-x p (inspired by dired’s C-x d):

1
(global-set-key (kbd "C-x p") 'proced)

See proced-mode(C-h f proced-mode) for a description of features available in Proced buffers.

Some of you might have noticed that the screenshot in the post is taken under GNOME, which is kind of strange considering I’m an OSX user. Unfortunately proced does not work on OSX(but perhaps surprisingly it works on Windows).

The C-x p keybinding works out-of-the box on Prelude.

Start Command or Switch to Its Buffer

| Comments

Few weeks ago I showed you a handy way to run term-mode. You might have noticed that it makes sense for many commands to be run in a similar manner. Here’s a quick example - I often like to jump between an Emacs Lisp source buffer and an ielm (interactive Emacs Lisp shell - M-x ielm) buffer to try out stuff. I could reuse the code I showed you for ansi-term to create a similar command called visit-ielm:

1
2
3
4
5
6
7
8
9
(defun visit-ielm ()
  "Create or visit a `ielm' buffer."
  (interactive)
  (if (not (get-buffer "*ielm*"))
      (progn
        (split-window-sensibly (selected-window))
        (other-window 1)
        (ielm))
    (switch-to-buffer-other-window "*ielm*")))

You might want to bind this to C-c C-z (a-la SLIME):

1
(define-key emacs-lisp-mode-map (kbd "C-c C-z") 'visit-ielm)

I don’t know about you, but I hate code repetition. Having that in mind we can factor out the duplication like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
(defun start-or-switch-to (function buffer-name)
  "Invoke FUNCTION if there is no buffer with BUFFER-NAME.
Otherwise switch to the buffer named BUFFER-NAME.  Don't clobber
the current buffer."
  (if (not (get-buffer buffer-name))
      (progn
        (split-window-sensibly (selected-window))
        (other-window 1)
        (funcall function))
    (switch-to-buffer-other-window buffer-name)))

(defun visit-term-buffer ()
  "Create or visit a terminal buffer."
  (interactive)
  (start-or-switch-to (lambda ()
                         (ansi-term (getenv "SHELL")))
                      "*ansi-term*"))

(defun visit-ielm ()
  "Switch to default `ielm' buffer.
Start `ielm' if it's not already running."
  (interactive)
  (prelude-start-or-switch-to 'ielm "*ielm*"))

Much better! We can now use start-or-switch-to to build any number of similar commands!

start-or-switch-to and visit-ielm are available in Prelude(but with a prelude- prefix).

P.S. If you’d like some nice SLIME-like code navigation command in emacs-lisp-mode you might check out elisp-slime-nav.

SLIME allows very convenient navigation to the symbol at point (using M-.), and the ability to pop back to previous marks (using M-,).

This plugin provides similar navigation for Emacs Lisp, supporting navigation to the definitions of variables, functions, libraries and faces.

Additionally, elisp-slime-nav provides a way to describe the symbol at point, whatever its type. As with slime-describe-symbol, this functionality is bound both to C-c C-d d and C-c C-d C-d by default.

It’s pretty useful if you hack Emacs Lisp yourselves. If you don’t hack Emacs Lisp (yet) you probably can do without it.

elisp-slime-nav comes bundled with Prelude.

Execute Commands Ninja-style With Key-chord-mode

| Comments

One of my bigger problems as an Emacs user is that there only so many good keybindings available. At some point you’re out of good options, but there are still plenty of commands you’d rather be able to execute faster than you’d be able to do with M-x command-name.

key-chord-mode to the rescue! It’s a pretty handy minor mode which allows you to bind commands to keys that should be pressed together or consecutively(with little time between the keystrokes - by default 0.3 seconds). This gives you some pretty good opportunities to increase your productivity. Assuming you’ve installed the mode somehow, you can start playing with it:

1
2
3
4
5
6
7
8
;; key chords
(require 'key-chord)

(key-chord-define-global "BB" 'iswitchb)
(key-chord-define-global "FF" 'find-file)
(key-chord-define-global "jk" 'beginning-of-buffer)

(key-chord-mode +1)

The examples above illustrate global key-chords. Major mode specific key chords are also available.

One should be careful about the key-chord he chooses - it should definitely be something you’re unlikely to type normally. This also means that if you’re writing in Emacs in several languages with common letters, key chords that make sense in say English, might not make sense in French (for instance). Luckily for me - I write almost exclusively in English or some programming language (and Bulgarian and English are nothing alike).

One other note - key chords don’t play very well with evil-mode(Emacs’s vim emulation layer) for obvious reasons. vim is kind of key-chord-mode’s principle inspiration. If you’re an evil-mode user you probably don’t need key-chord-mode anyways.

Prelude enables key-chord-mode out of the box and makes some creative use of it with jj and JJ (which I’d advise you try out if you didn’t know about them).