Emacs Redux

Return to the Essence of Text Editing

Locate

| Comments

locate is one extremely popular Unix command that allows you to search for files in a pre-built database.

One little know fact is that Emacs provides a wrapper around the command you can invoke with M-x locate. You’ll be prompted to enter a search string and you’ll be presented with a list of matching filenames from locate’s database. Many of dired keybindings are available in the results buffer (which will be using locate-mode major mode).

If you’d like you may change the command invoked by Emacs to supply the results by altering the locate-command variable. Here’s how you can start using OSX’s mdfind (the command-line interface to Spotlight) instead of locate:

1
(setq locate-command "mdfind")

Obviously any command that takes a string argument and returns a list of files would do here. In all likelihood you’ll never want to use anything other than the default locate command, though.

Boost Performance by Leveraging Byte-compilation

| Comments

Emacs’s Lisp interpreter is able to interpret two kinds of code: humanly readable code (stored in files with .el extension) and machine optimized code (called byte-compiled code), which is not humanly readable. Byte-compiled code runs faster than humanly readable code. Java or .NET developers should already be familiar with the concept of byte-code, since it’s pretty central on those platforms.

You can transform humanly readable code into byte-compiled code by running one of the compile commands such as byte-compile-file. The resulting byte-code is stored into .elc files. One can also byte-compile Emacs Lisp source files using Emacs in batch mode.

Here’s how you can compile everything in your .emacs.d folder:

1
emacs -batch -f batch-byte-compile ~/.emacs.d/**/*.el

Of course we can easily create an Emacs command that does the same thing:

1
2
3
4
(defun byte-compile-init-dir ()
  "Byte-compile all your dotfiles."
  (interactive)
  (byte-recompile-directory user-emacs-directory 0))

user-emacs-directory is an Emacs variable that points to your init dir (usually ~/.emacs.d on UNIX systems). This command will recompile even files that were already compiled before (meaning a file with the same name and the .elc extension instead of .el existed). You can try the new command with M-x byte-compile-init-dir.

You have to keep in mind that Emacs will load code from the .elc files if present alongside the .el files, so you’ll have to take steps to ensure you don’t have stale .elc files lying around. I’d suggest the following solution:

1
2
3
4
5
6
7
8
9
10
(defun remove-elc-on-save ()
  "If you're saving an elisp file, likely the .elc is no longer valid."
  (add-hook 'after-save-hook
            (lambda ()
              (if (file-exists-p (concat buffer-file-name "c"))
                  (delete-file (concat buffer-file-name "c"))))
            nil
            t))

(add-hook 'emacs-lisp-mode-hook 'remove-elc-on-save)

This code will make Emacs delete the some_file.elc file, every time the some_file.el file in the same folder is saved.

A couple of closing notes:

  • If you don’t have any custom computationally intensive defuns in your init directory - it probably doesn’t make sense to byte-compile it.

  • Packages installed via package.el will be automatically byte-compiled during the installation process.

The code presented here is part of Prelude. As a matter of fact Prelude will byte-compile itself during the installation process (if you used the installed script, that is). Prelude will also recompile itself when M-x prelude-update is invoked.

Eval and Replace

| Comments

Sometimes people tend to overlook how well Emacs and Emacs Lisp are integrated. Basically there is no limit to the places where you can evaluate a bit of Emacs Lisp and reap the associated benefits. From time to time I find myself editing something and thinking - “Hey, it’d be really great of I could just insert the result of some Emacs Lisp expression at point!” (my thoughts are pretty crazy, right?). Here’s a contrived example - I might have to enter somewhere the result of 1984 / 16. I can calculate that manually or I can fire up M-x calc and get the result, or I can play extra smart and devise the following command (which I did not actually devise - I’m pretty sure I saw it in someone else’s config a while back):

1
2
3
4
5
6
7
8
9
(defun eval-and-replace ()
  "Replace the preceding sexp with its value."
  (interactive)
  (backward-kill-sexp)
  (condition-case nil
      (prin1 (eval (read (current-kill 0)))
             (current-buffer))
    (error (message "Invalid expression")
           (insert (current-kill 0)))))

Let’s bind that to C-c e:

1
(global-set-key (kbd "C-c e") 'eval-and-replace)

Now in the buffer I’m currently editing I can type (/ 1984 16) and press C-c e afterwards getting the result 124 replace the original expression. Pretty neat!

I’ll leave it up to you to think of more creative applications of the command.

This command is part of Prelude(it’s named prelude-eval-and-replace there).

Deleting Windows

| Comments

Every Emacs user knows that he can split the current window horizontally (with C-x 2) and vertically (with C-x 3) as much as he desires to. However, some Emacs users don’t know what to do with the extra windows they’ve created when they do not them.

To delete the selected window, type C-x 0 (delete-window). Once a window is deleted, the space that it occupied is given to an adjacent window (but not the minibuffer window, even if that is the active window at the time). Deleting the window has no effect on the buffer it used to display; the buffer continues to exist, and you can still switch to with C-x b or any other buffer navigation command.

C-x 4 0 (kill-buffer-and-window) is a stronger (and fairly unknown) command; it kills the current buffer and then deletes the selected window (basically it combines C-x k and C-x 0). Obviously it’s a good idea to use it on windows displaying buffers you’re no longer needing.

C-x 1 (delete-other-windows) deletes all the windows, except the selected one; the selected window expands to use the whole frame. (This command cannot be used while the minibuffer window is active; attempting to do so signals an error.) In the era of narrow screens I used that command fairly often when I needed to focus on a particular task. Now I keep my screen split in half vertically 99% of the time, but I still use C-x 1 from time to time when I’m about to resplit my screen in some uncommon way.

Windows displaying help buffers (generally created with commands like C-h ...) warrant a special mention. They can be deleted with a single keystroke - q. That would delete the help window altogether if it was created by the help command, or restore its original content if the window existing beforehand and was reused by the help command.

Open Line Above

| Comments

This post continues a topic that was introduced in smarter open-line few months back.

Often when editing code one wishes to open a line just above the current one, which is properly indented relative to the existing code, and position the cursor at its beginning. Such a feature is present in most IDEs, such as IntelliJ IDEA, Eclipse and NetBeans. It’s sometimes bound to Control+Shift+Enter. Last time I showed you how to implement a similar function called smart-open-line, this time will implement smart-open-line-above. Just add this snippet to your .emacs (or .emacs.d/init.el or whatever):

1
2
3
4
5
6
7
8
9
10
(defun smart-open-line-above ()
  "Insert an empty line above the current line.
Position the cursor at it's beginning, according to the current mode."
  (interactive)
  (move-beginning-of-line nil)
  (newline-and-indent)
  (forward-line -1)
  (indent-according-to-mode))

(global-set-key [(control shift return)] 'smart-open-line-above)

Evaluate the code (or restart Emacs) and you’ll be able to use M-x smart-open-line-above or Control+Shift+Enter (aka C-S-return).

Admittedly this keybinding kind of sucks, so here’s another option for you - M-o (used by default as the prefix for some font setting commands nobody ever uses) for smart-open-line and M-O for smart-open-line-above.

1
2
(global-set-key (kbd "M-o") 'smart-open-line)
(global-set-key (kbd "M-O") 'smart-open-line-above)

Another good option would be to fold the two commands into one and use a prefix argument to trigger the opening a new line above the current one.

This command is part of Prelude(it’s named prelude-smart-open-line-above there).

Using Emacs as a Database Client

| Comments

Most people that use Emacs are programmers - that’s a fact! Most programmers have to deal with relational databases - that’s also a fact!

Programmers often interact with the database they have to use via some dedicated client - be it a console or a GUI one. One fairly little known fact about Emacs is that it features a mode that wraps around terminal database clients, called SQLi. The mode allows you to interact with a relational database from the comfort of Emacs. Sure, you can run a terminal client like psql directly from ansi-term (for instance) as well - but if you’re using a client with no readline support (like the default clients for Oracle and DB2) you’ll certainly appreciate SQLi.

Let’s play a bit with SQLi. To create a PostgreSQL connection start by running M-x sql-postgres. You’ll be prompted for username, database, password and host and then you’ll be dropped in a buffer dedicated to the connection you’ve specified. Apart from being able to run all sorts of SQL in that buffer you’ll also be able to send to it SQL from .sql files you’re editing in Emacs.

Let’s see how you can do that in a bit more detail. First you have to associated an SQL file with a connection. While in some .sql file execute M-x sql-set-product and type postgres. Afterwards do M-x sql-set-sqli-buffer and select the name of the connection buffer you want to use (it’s probably called *SQL* if you have only one connection buffer). Now you’ll be able to use commands like sql-send-region (C-c C-r) from the .sql buffer and the code from the region will be executed in the associated connection buffer.

Have a look at the documentation of sql-mode for further details.

Continue a Comment on the Next Line

| Comments

When writing code from time to time we have to write comments as well. Most of the time programmers are using single-line comments, denoted by some special starting character(s), like #, //, etc. When you want to write a few lines of comments in Emacs you have two options:

Option A

  • Write the first line of the comment.
  • Go to the next line.
  • Insert the comment delimiter.
  • Continue writing the comment.

Option B (editor’s choice)

  • White the first line of the comment.
  • Press M-j (indent-new-comment-line).
  • Continue writing the comment on the second line.

The command breaks the line at point and indents the following line, continuing the comment if invoked within one. The indentation on the second line matches the indentation on the first line.

1
2
3
# first line
#     indented line|(we press `M-j` here)
#     |(we get here after pressing `M-j`)

This command is intended for styles where you write a comment per line, starting a new comment (and terminating it if necessary) on each line. If you want to continue one comment of the type /* */ across several lines, use C-j (newline-and-indent).

Outside of comments M-j behaves pretty much the same way as C-j.

Highlight Lines That Exceed a Certain Length Limit

| Comments

When you’re writing code you usually have to take into account the programming language’s convention for maximum line length. Most programming languages urge hackers to keep line length under 80 characters(although in recent years it has often been argued that such rules should be relaxed to 100-120 characters, given the state of current computer displays).

There are many ways to highlight lines that exceed a certain length in Emacs, but I find one to be particularly elegant - the use of the built-in whitespace-mode. Most people use whitespace-mode to visualize spaces, tabs and trailing whitespace, but it can actually do a bit more that that. Here’s the magic config:

1
2
3
4
5
(require 'whitespace)
(setq whitespace-line-column 80) ;; limit line length
(setq whitespace-style '(face lines-tail))

(add-hook 'prog-mode-hook 'whitespace-mode)

The above snippet will enable whitespace-mode only in major modes for programming. If you want to enable whitespace-mode everywhere you might want to do this instead:

1
(global-whitespace-mode +1)

whitespace-line-count determines that maximum line length; feel free to set this to whatever value suits you. whitespace-style determines what kind of stuff whitespace-mode is going to highlight. At this example we want to highlight only the part of lines exceeding the line length limit. Take a look at whitespace-style’s documentation for more details(C-h v RET whitespace-style).

Here’s the result:

It will probably come as no surprise that this functionality is enabled out-of-the-box in Prelude.

Joining Lines

| Comments

Often, while editing, you’ll want to compress a few lines into one. Here’s a simple example to illustrate the problem at hand. We want to convert this bit of Ruby code:

1
2
3
some_method(arg1,
            arg2,
            arg3)

into:

1
some_method(arg1, arg2, arg3)

Doing so is extremely easy. Just go to the last line in the first code block and press 3 times M-^ (delete-indentation, aliased also to join-line).

If you’re like me and like to join lines from top to bottom - go to the first line and press C-u M-^ three times. This works, but it is kind of hard to press C-u M-^ repeatedly, compared to just M-^. Let’s simplify this a bit:

1
2
3
4
(defun top-join-line ()
  "Join the current line with the line beneath it."
  (interactive)
  (delete-indentation 1))

Isn’t this a top way to join lines or what?

Since delete-indentation is bound both to M-^ it makes sense to use something like C-^ for the new command:

1
(global-set-key (kbd "C-^") 'top-join-line)

That’s mostly a personal preference I guess - feel free to use any other keycombo.

This command is part of Prelude(it’s named prelude-top-join-line there) and it’s bound to C-^ there.

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.