Emacs Redux

Return to the Essence of Text Editing

Delete Selection on Insert

| Comments

It most text editors if you select a piece of text and press any key(that’s not bound to some command) the selection would be replaced by the character bound to the key(or deleted if you press Backspace). In Emacs things look differently - by default typed text is just inserted at point, regardless of any selection.

Of course, there is a way to change this:

1
(delete-selection-mode +1)

Now when transient-mark-mode is also enabled(it is enabled by default since Emacs 23) any typed text replaces the selection if the selection is active.

Personally I find this behavior more useful than the default one. That’s why it should be no surprise that delete-selection-mode is enabled by default in Prelude.

Kill Whole Line

| Comments

Let’s continue our exploration of the fascinating topic of killing lines. Apart from killing lines from the cursor to the end of the line(kill-line) and killing lines from the cursor back to the beginning of the line(kill-line with a 0 prefix argument) you can also kill entire lines with a single command - kill-whole-line.

The command is bound to C-S-Backspace by default and kills the line including its newline. With a prefix argument, it will kill that many lines starting from the current line. If the argument is negative it will kill that many lines backward plus the preceding newline. If the argument is 0, it will kill the current line but exclude the trailing newline. We can improve the command a bit by making it indentation aware(like we did for backward kill line in the previous post):

1
2
3
4
5
(defun smart-kill-whole-line (&optional arg)
  "A simple wrapper around `kill-whole-line' that respects indentation."
  (interactive "P")
  (kill-whole-line arg)
  (back-to-indentation))

Now we can rebind C-S-Backspace.

1
(global-set-key [remap kill-whole-line] 'smart-kill-whole-line)

remap is a pretty neat trick in its own right; maybe I’ll write a bit more about it in the future.

The smart-kill-whole-line command is available out-of-the-box in Prelude.

Kill Line Backward

| Comments

Emacs does not have a command backward-kill-line(which would kill the text from the point to the beginning of the line), but it doesn’t really need one anyways. Why so? Simple enough - invoking kill-line with a prefix argument 0 does exactly the same thing!

1
2
3
C-0 C-k
M-0 C-k
C-u 0 C-k

Take your pick! If you’d rather have a quicker way to do backward line killing you might consider rebinding C-Backspace or M-Backspace(both are bound to backward-word-kill by default). Personally I always do word killing with M-Backspace, so I favor rebinding C-Backspace.

1
2
3
(global-set-key (kbd "C-<backspace>") (lambda ()
                                        (interactive)
                                        (kill-line 0)))

This command can be further improved if killing backward factors the current indentation level:

1
2
3
4
(global-set-key (kbd "C-<backspace>") (lambda ()
                                        (interactive)
                                        (kill-line 0)
                                        (indent-according-to-mode)))

Thanks to Steve Purcell for suggesting a similar command in the comments.

The C-Backspace keybinding is available out-of-the-box in Prelude.

Display Visited File’s Path in the Frame Title

| Comments

I’m fond of seeing somewhere the full path to the file I’m currently editing(as opposed to just the file name displayed in modeline). Emacs’s frame title seems like a good place to display such information, since by default it doesn’t show anything interesting. Here’s how we can achieve this:

1
2
3
4
(setq frame-title-format
      '((:eval (if (buffer-file-name)
                   (abbreviate-file-name (buffer-file-name))
                 "%b"))))

The path will be displayed in an abbreviated manner(/home/bozhidar/ will be shortened to just ~/). If you’d like to see the expanded path just remove the abbreviate-file-name function invocation. If a buffer is not visiting a file, the buffer’s name would be displayed instead.

Prelude sets frame-title-format like this by default.

Recently Visited Files

| Comments

Emacs does not keep track of recently visited files by default. Sad, but true. On a more positive note - it has the feature(courtesy of recentf), but it’s simply not enabled out-of-the-box. Let’s see what we can do to change that:

1
2
3
4
(require 'recentf)
(setq recentf-max-saved-items 200
      recentf-max-menu-items 15)
(recentf-mode +1)

That wasn’t that hard. Now Emacs will keep track of the last 200 files we visited and will show the last 15 of them in the File->Open recent(this menu entry is added by recentf) menu. That’s it.

At this point you’re probably feeling let down. After all - who uses the menu bar in Emacs anyways? Fortunately there is also a command named recentf-open-files. Upon invoking it with M-x recentf-open-files you’ll be presented with a list of all recently visited files.

If you’re an ido user you might prefer to use some command based on it instead. Here’s one:

1
2
3
4
5
6
(defun recentf-ido-find-file ()
  "Find a recent file using ido."
  (interactive)
  (let ((file (ido-completing-read "Choose recent file: " recentf-list nil t)))
    (when file
      (find-file file))))

I’d suggest binding whichever command you prefer to either C-c f or C-x C-r (bound by default to the infrequently used find-file-read-only command):

1
(global-set-key (kbd "C-c f") 'recentf-ido-find-file)

As usual - both the command recentf-ido-find-file and its keybinding C-c f are available in Prelude(obviously recentf is enabled there out-of-the-box).

Prog-mode: The Parent of All Programming Modes

| Comments

You probably know that major modes in Emacs can derive(inherit) functionality from a parent major mode.

Emacs 24.1 introduced prog-mode - a new major mode from which all programming modes should be derived. All of the programming modes that come bundled with Emacs already inherit it(as do most actively maintained third-party modes). Having a common parent for all the programming modes allows us to do some pretty neat stuff - like setting common behavior for all of them. Here’s how we can enable spell-checking in comments:

1
(add-hook 'prog-mode-hook 'flyspell-prog-mode)

That’s all for now. We’ll discuss flyspell in more detail down the road.

Easter Eggs

| Comments

Emacs is packed with an insane amount of cool stuff. With Easter fast approaching (I’m an Orthodox Christian and ours is in the beginning of May this year) I cannot help but think of easter eggs(“secret” commands, inside jokes, etc). Let’s see if we can find some in Emacs!

Snake

M-x snake

Tetris

M-x tetris

Zone

M-x zone M-x zone-mode

Doctor

M-x doctor

Butterfly Mode

M-x butterfly (refer to this xkcd comics if you have no idea what this is)

Final Words

This was a short post(and not particularly instructive I guess), but I hope you’ve enjoyed it. Share in the comments section any Emacs easter eggs you know of, that I haven’t mentioned.

Delete File and Buffer

| Comments

From time to time(most often when I refactor code) I need to quickly(this removes dired from the equation) delete a file and kill 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-delete-file. Unfortunately the command does not act on the current file and will prompt you for a file to delete. 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
(defun delete-file-and-buffer ()
  "Kill the current buffer and deletes the file it is visiting."
  (interactive)
  (let ((filename (buffer-file-name)))
    (when filename
      (if (vc-backend filename)
          (vc-delete-file filename)
        (progn
          (delete-file filename)
          (message "Deleted file %s" filename)
          (kill-buffer))))))

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 D:

1
(global-set-key (kbd "C-c D")  'delete-file-and-buffer)

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

Move Current Line Up or Down

| Comments

While programming(at least in some languages) I often find myself wishing to drag the current line a couple lines up or down. Emacs does have the means to transpose (switch) lines (courtesy of the transpose-lines command bound to C-x C-t), but I find it unwieldy. That’s why I’ve built a couple of custom commands on top of it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(defun move-line-up ()
  "Move up the current line."
  (interactive)
  (transpose-lines 1)
  (forward-line -2)
  (indent-according-to-mode))

(defun move-line-down ()
  "Move down the current line."
  (interactive)
  (forward-line 1)
  (transpose-lines 1)
  (forward-line -1)
  (indent-according-to-mode))

Those are not the kind of commands you’ll want to invoke with M-x. Therefore I suggest binding them to something like C-S-up and C-S-down(these bindings are often used for the same purpose in other editors and IDEs):

1
2
(global-set-key [(control shift up)]  'move-line-up)
(global-set-key [(control shift down)]  'move-line-down)

Since this won’t work on OSX(Control+arrow is used by the window manager) I’d recommend the following alternative to OSX users:

1
2
(global-set-key [(meta shift up)]  'move-line-up)
(global-set-key [(meta shift down)]  'move-line-down)

Personally I’m not a fan of any keybindings that require me to move my hands off the home keyboard row, but I wasn’t able to come up with anything better. Suggestions are welcome!

As usual both commands(and both set of keybindings) are available in Prelude(but with prelude- prefices).

Highlight Current Line

| Comments

Just about every modern editor and IDE these days highlights the line you’re currently on, which I find extremely helpful. Emacs doesn’t do this out-of-the-box, but provides the means to do so - the built-in global minor mode global-hl-line-mode. To take it out for a spin just add the following line to your Emacs config:

1
(global-hl-line-mode +1)

In case you don’t like the highlighting color you can change it by adjusting the value of the hl-line-face face. Most decent color themes pick a pretty good value for it, so normally you should not bother changing it manually.

global-hl-line-mode is enabled out-of-the-box in Prelude.