Emacs Redux

Return to the Essence of Text Editing

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.

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.