Emacs Redux

Return to the Essence of Text Editing

A Peek at Emacs 24.4: Smarter Show-paren-mode

| Comments

Some time ago I wrote about highlighting matching delimiters with show-smartparens-mode. In Emacs 24.4, the built-in show-paren-mode is capable of highlighting more complex paired delimiters as well (like do/end in Ruby for instance). There is one limitation to show-paren-mode (compared to show-smartparens-mode) - it requires that the major mode, that it’s used together with (e.g. ruby-mode), is implemented in terms of the new(ish) SMIE (Simple Minded Indentation Engine). SMIE has been around since 23.3, but hasn’t seen much adoption until quite recently. Prior to Emacs 24.4 very few built-in modes were using it (and just about no third-party major modes). In Emacs 24.4, however, a lot of modes were updated to use SMIE (like ruby-mode), so you’ll be able to enjoy the show-paren-mode improvement with them.

Here’s a glimpse of the enhanced show-paren-mode in action:

Long term, I still think that betting on smartparens-mode is a good idea, but if you prefer to stick with built-in modes - show-paren-mode is now more capable than ever.

A Peek at Emacs 24.4

| Comments

Emacs 24.4 is now feature frozen and its release is (probably) just a few months away at this point. This makes it a good time to start talking about some of the exciting and not so exciting changes that will be introduced in it.

Emacs 24.4 is a special for me, since it’s the first Emacs release to which I contributed code. On a related note - I’ve tracked its development much closer than I used to in previous years and I feel I have lots of interesting things to share with you.

In a series of smallish posts I’ll highlight some of the many new features that are coming in 24.4. Keep in mind that since we’re talking about unreleased code, there’s the chance of changes in the final version of 24.4.

By the way, if you’re looking for a brief overview of what to expect in Emacs 24.4 you might have a look at Mickey Petersen’s article on the subject.

The first article in the series will be arriving momentarily!

Articles in the Series

P.S. Emacs 24.4 is fairly stable at this point, so can start using it today. I’ve been using it exclusively for about half an year now and I’ve rarely come across any issues whatsoever. If you’re a Prelude user - it is 24.4 compatible.

A Crazy Productivity Boost: Remap Return to Control

| Comments

People have always complained about the awkward positioning of the two Control keys on modern keyboards. That’s a fact! Effective Emacs usage is heavily dependent on the Control keys (yep, both of them). That’s also a fact!

A great many Emacs users remap the infrequently used CapsLock key to Control to alleviate partially the problem with the accessibility of the control keys. That, while useful, is not sufficient for the optimal typing experience, since that way you’re breaking the key symmetry on both sides of your keyboard. Also - your right pinky has to go much further than your left one, while you’re typing. Many people seem to be using only the left Control and I guess they’re not particularly bothered by this, but touch typists like me are generally quite bothered by such things.

A much better idea would be to leverage a little knows capability of keyboard input systems and map the Return key to Control only when it’s held down (it will behave like a normal Return key in all other situations). This sounds a bit crazy, but please bear with me for a while.

This radical approach has several advantages. First and foremost - it’s much easier to hit Return with your right pinky than it is to hit the regular right Control (especially if you’re using a US layout keyboard - these have long single row Return keys, compared to the short 2 row Returns found on European keyboards). Second, if you’ve already remapped CapsLock to Control (like you should have done) you’re getting a pretty symmetrical mapping on the opposite side of your keyboard. Last, but not least - it’s a great option for people using compact keyboards with no left Control key.

Obviously you’ll need some keyboard remapping software to make this trick work. OSX users can use KeyRemap4MacBook to do that. In its settings look up the Change Return section and under it Return to Control_R (+ When you type Return only, send Return). As far as I know this remapping can be done on GNU/Linux systems with xcape (though I haven’t checked that myself), but I have no idea if it’s a viable option for Windows users.

All in all - remapping Return to Control should be a big productivity win for some (the touch typists) of you and should make your right pinky’s life easier.

Highlight Matching Delimiters With Smartparens

| Comments

Some time ago I wrote about highlighting matching parentheses with show-paren-mode. This is definitely useful, but it’s kind of restrictive, since parentheses are just a specific kind of paired delimiter. Single and double quotes are also paired delimiters (at least in most programmming languages). In the Ruby programmming language, for instance, do and end also constitute paired delimiter.

smartparens offers extremely customizable handling of paired delimiters and comes with an extra minor mode called show-smartparens-mode to highlight them. This mode totally replaces show-paren-mode and language specific modes like hirb (which highlights Ruby blocks).

Assuming you’re already using smartparens, enabling show-smartparens-mode is trivial:

1
(show-smartparens-global-mode +1)

Here’s a glimpse of it in action:

In Prelude show-paren-mode was replaced by show-smartparens-mode some time ago.

Instant Access to Your Shell Init File

| Comments

A while ago I showed you a way to instantly edit your Emacs init file. Today we’ll adapt the original idea for shell init files like .bashrc and .zshrc. The code required is fairly short and simple:

1
2
3
4
5
6
7
8
9
(defun find-shell-init-file ()
  "Edit the shell init file in another window."
  (interactive)
  (let* ((shell (car (reverse (split-string (getenv "SHELL") "/"))))
         (shell-init-file (cond
                           ((string-equal "zsh" shell) ".zshrc")
                           ((string-equal "bash" shell) ".bashrc")
                           (t (error "Unknown shell")))))
    (find-file-other-window (expand-file-name shell-init-file (getenv "HOME")))))

The shell init file is deduced from your SHELL env variable. While there are different shell init files for most shell (e.g. .bash_profile, .zshenv, .zprofile), here we’re assuming you’re using the most commonly used files. find-file-other-window will open the file in a window adjacent to the one you’re currently in.

1
(global-set-key (kbd "C-c S") 'find-shell-init-file)

find-shell-init-file is available in Prelude(but with a prelude- prefix).

Removing/Altering Key Bindings From Minor Mode Keymaps

| Comments

Often minor modes don’t respect standard keybinding conventions and use some user reserved keys (like C-c a). Occasionally two minor modes would have conflicting keybindings or a minor mode would keybindings conflicting with a major mode. I guess you can imagine similar problems. Dealing with them is fairly straight-forward - we have to either unbind or rebind the offending binding:

1
2
3
4
5
;; remove keybinding
(define-key minor-mode-map (kbd "C-c c") nil)

;; change keybinding
(define-key minor-mode-map (kbd "C-c c") (kbd "C-c C-c"))

Generally speaking you can use define-key to alter the keymap of a major mode as well, but those are rarely offenders when it comes to picking appropriate keybindings for their keymaps.

Normally you’d want to invoke the above code right after the related minor (or major) mode is loaded:

1
2
(eval-after-load "minor-mode"
  '(define-key minor-mode-map (kbd "C-c c") nil))

Making a minor mode have different keymaps in different major modes is tricky, but possible. Here’s an example that disables some keybindings in the minor prelude-mode, that are conflicting with the major org-mode:

1
2
3
4
5
6
7
8
9
10
11
(defun my-org-mode-hook ()
  (let ((oldmap (cdr (assoc 'prelude-mode minor-mode-map-alist)))
        (newmap (make-sparse-keymap)))
    (set-keymap-parent newmap oldmap)
    (define-key newmap (kbd "C-c +") nil)
    (define-key newmap (kbd "C-c -") nil)
    (make-local-variable 'minor-mode-overriding-map-alist)
    (push `(prelude-mode . ,newmap) minor-mode-overriding-map-alist))
)

(add-hook 'org-mode-hook 'my-org-mode-hook)

Dired Jump

| Comments

Most Emacs users know that they can start dired (Emacs’s file browser) with M-x dired or C-x d. That would display a prompt in the minibuffer asking which directory to open with dired (the current directory will be suggested as a default).

More often than not you’ll probably want dired to display the directory of file you’re currently editing. You might even want to have the cursor positioned over that very same file in the dired buffer. There’s a cool command that does exactly that - dired-jump. To use it you have to first load the built-in library dired-x:

1
(require 'dired-x)

You can run the command with C-x C-j (M-x dired-jump). No prompts, no wasted time. You’re instantly teleported to the currently edited file’s position in a dired buffer.

This command works out-of-the-box in Prelude.

A Proper Replacement for Flet

| Comments

The popular flet macro was deprecated in Emacs 24.3 and replaced with two similar macros - cl-flet and cl-letf.

flet was used to temporarily override function definitions. This was an analogue of a dynamically scoped let that operates on the function cell of symbols rather than their value cell.

The ability to dynamically rebind a functions was very useful for stubbing purposes in unit tests (you do write unit tests, don’t you?).

1
2
3
(flet ((projectile-project-root () "/path/to/project")
       (projectile-project-name () "project"))
  ...)

projectile-project-root and projectile-project-name are impure functions (they depend on the current directory) and testing functions that use them internally would normally be problematic. However, flet gives us the ability to override their actual definitions in our tests. flet’s official replacement cl-flet is lexically bound and this is no longer possible with it.

Fortunately Nic Ferrier created a true drop-in flet replacement (with some extra magic baked in) - noflet. If you’re missing flet, I suggest you to give noflet a try.

Version Checks

| Comments

Often the code you’re writing would be depending on the version of some external tool (say git) or Emacs itself. Version checks in Emacs are pretty easy - just use the built-in functions version=, version<= or version=.

Let’s illustrate this with an example. Prelude requires at least GNU Emacs 24.1 to run and on startup it performs the following check:

1
2
(when (version< emacs-version "24.1")
  (error "Prelude requires at least GNU Emacs 24.1"))

Simple and effective. The version functions are pretty smart and recognize most popular version formats correctly. Note that version string “1” is equal to “1.0”, “1.0.0”, “1.0.0.0”, etc. That is, the trailing “.0”s are insignificant. Also, version string “1” is higher (newer) than “1pre”, which is higher than “1beta”, which is higher than “1alpha”. Also, “-CVS” and “-NNN” are treated as alpha versions.

If you’re writing an Emacs package you can also add an explicit Emacs version dependency in the packge metadata:

1
;; Package-Requires: ((emacs "24.1"))

That way users of older Emacsen would not see a version of your package targeting newer Emacsen.

Search Youtube

| Comments

Some time ago I showed you how to do Google queries from Emacs. The approach used in that articles is pretty generic and can be used for the creation of various similar commands. Let’s create a command that searches in YouTube:

1
2
3
4
5
6
7
8
9
(defun youtube ()
  "Search YouTube with a query or region if any."
  (interactive)
  (browse-url
   (concat
    "http://www.youtube.com/results?search_query="
    (url-hexify-string (if mark-active
                           (buffer-substring (region-beginning) (region-end))
                         (read-string "Search YouTube: "))))))

This command will display the query results in your default browser.

I’d suggest binding the command to C-c y if you plan to use it regularly.

1
(global-set-key (kbd "C-c y") 'youtube)

youtube is available in Prelude(but with a prelude- prefix).