(or emacs irrelevant)

Using Emacs as system-wide Rhythmbox interface

In an earlier post, I described how I've been managing Rhythmbox from Emacs. I've bound the entry point to C-S-o:

(global-set-key (kbd "C-S-o") 'counsel-rhythmbox)

Obviously, this entry point won't work while outside Emacs. Today, I'll describe how I've made it work everywhere. Everywhere on Ubuntu 14.04, that is, although a similar approach should work for other distributions.

Step 1: Make sure the Emacs server is running

Here's the relevant part of my init.el:

(require 'server)
(or (server-running-p) (server-start))

Using emacsclient is essential to avoiding the extra startup time: even a startup time of one second feels sluggish when all I need is to open a menu with a song playlist.

Step 2: Install the relevant X window tool

Initially, I only wrote a call to emacsclient, which resulted in the Emacs window gaining focus in the end. Then I thought it would be nice to give the focus back the original window after the end of selection, and raise it as well.

I wanted to do something with wmctrl, but I found that xdotool can do what I want in a simple way.

sudo apt-get install xdotool

Step 3: Write a shell script

#!/bin/bash
wnd_id="$(xdotool getwindowfocus)"
emacsclient --eval "(progn (x-focus-frame nil) (counsel-rhythmbox))"
xdotool windowfocus $wnd_id
xdotool windowraise $wnd_id

Here, (x-focus-frame nil) will raise the Emacs window and give the keyboard input focus. emacsclient will return as soon as I select something or press C-g. At that point the keyboard focus will be returned to whatever window had it when the script was invoked.

By the way, here's a cool configuration that automatically makes a file executable if it starts with #!.

(add-hook
 'after-save-hook
 'executable-make-buffer-file-executable-if-script-p)

Step 4: Bind the shell script to a key

Open this (possibly using gnome-control-center instead, if applicable):

unity-control-center keyboard

And add a new shortcut in Shortcuts/Custom Shortcuts. I've bound that one to C-S-o as well.

The final result

It's pretty convenient: as I'm scrolling something I'm reading in Firefox with j (via Firemacs), I can seamlessly press C-S-o moo RET to play "Sisters of the Moon", and continue scrolling the web page with j.

What's more, Emacs has very nice support for input methods with C-\ (toggle-input-method), so I can also quickly select Ukrainian-titled songs, while still keeping shortcuts like C-n and C-m (without having to switch the input method back).

The whole experience is similar to gnome-do/synapse, which I was using a few years back, except better because now it's in Emacs.

Better fuzzy matching support in Ivy

Recently, I wrote some code to add better highlighting for Ivy's fuzzy matcher. Here's a quick step-by-step to get an equivalent of flx-ido-mode working with Ivy.

Step 1: install the packages

M-x package-install - counsel and flx (MELPA should be configured).

Step 2: configure ivy-re-builders-alist

Here's the default setting:

(setq ivy-re-builders-alist
      '((t . ivy--regex-plus)))

The default matcher will use a .* regex wild card in place of each single space in the input. If you want to use the fuzzy matcher, which instead uses a .* regex wild card between each input letter, write this in your config:

(setq ivy-re-builders-alist
      '((t . ivy--regex-fuzzy)))

You can also mix the two regex builders, for example:

(setq ivy-re-builders-alist
      '((ivy-switch-buffer . ivy--regex-plus)
        (t . ivy--regex-fuzzy)))

The t key is used for all fall-through cases, otherwise the key is the command or collection name.

The fuzzy matcher often results in substantially more matching candidates than the regular one for similar input. That's why some kind of sorting is important to bring the more relevant matching candidates to the start of the list. Luckily, that's already been figured out in flx, so to have it working just make sure that the flx package is installed.

Step 3: optionally configure ivy-initial-inputs-alist

The ivy-initial-inputs-alist variable is pretty useful in conjunction with the default matcher. It's usually used to insert ^ into the input area for certain commands.

If you're going fuzzy all the way, you can do without the initial ^, and simply let flx (hopefully) sort the matches in a nice way:

(setq ivy-initial-inputs-alist nil)

The result

Here's how M-x counsel-M-x looks like now:

ivy-flx-highlight.png

Ivy-mode 0.7.0 is out

Intro

Ivy-mode is a completion method that's similar to Ido, but with emphasis on simplicity and customizability. Currently, there are two related packages on MELPA: swiper and counsel:

  • swiper provides an isearch replacement, using ivy-read for completion, as well as the basic ivy-mode.
  • counsel provides some extra commands that use ivy-read, like -M-x, -ag, -load-theme etc.

Release Notes

The release notes are available at the homepage as usual. There are 220 commits since the last release, which was on Aug 5, roughly 4 months ago. Slowly but surely, the contributors list has grown to 20 people, besides me. A few people even got their Emacs Copyright Assignment just to make large contributions. Statistically, Org-mode is probably the prime package that leads to the most CA, but I'm glad that Ivy is there as well, contributing in a small way.

The release notes are made in Org-mode, each new version is a level 1 heading. With time, hopefully, their parts will make their way into the manual, which is also in Org-mode.

In addition, I also export each new release notes to Markdown using pandoc, since that's what Github prefers.

Release Process

Since the release notes for 0.7.0 are huge, I don't embed them into the post, they're listed separately. You can go through them at your own pace, or wait until I make some highlights for each piece either or the blog or in the manual. The manual, by the way, is a work in progress but is already distributed in MELPA. Use C-h i followed by g (ivy) to read it. If you're new to reading the info pages, there's info on info in info format: use dg (info) to access it.

Today, I'll describe some cool stuff that I used to generate the Markdown notes from Changelog.org.

Org-mode's org-narrow-to-subtree

Since Changelog.org already has a 0.6.0 branch that I didn't want to see, I've narrowed the buffer to only the 0.7.0 branch. This is possible to do thanks to Emacs' narrowing feature and org-narrow-to-subtree. After this command, the buffer behaves as if the 0.6.0 branch isn't there and the only content is 0.7.0 branch. But if I perform any edits and save the file, everything that was hidden is still there.

As a shortcut, I'm using my worf to narrow faster. Pressing [ while worf-mode is active goes back to the current heading start. While at heading start, pressing alphanumeric keys calls commands instead of self-inserting:

  • N calls org-narrow-to-subtree,
  • W calls widen, which turns narrowing off.

There are, of course, many more commands and bindings in worf. Check it out if you like Org's Speed Keys feature, but feel like it could use more structure.

pandoc-mode

pandoc-mode is an Emacs interface to pandoc - a tool that allows to export documents from one format to another. The Elisp package is available in MELPA. And I installed pandoc-1.15.2-1-amd64.deb from its homepage with:

sudo dpkg -i pandoc-1.15.2-1-amd64.deb

After that, M-x pandoc-mode and I'm on easy street: C-c / calls pandoc-main-hydra/body:

  • Set the output format to Github-flavored Markdown with OG.
  • Set the input format to Org-mode with bIo.
  • Export with C-c / r.
  • View the resulting buffer with C-c / V.

Add table of contents to Markdown

I used M-x markdown-toc/generate-toc for this. The MELPA package markdown-toc provides this function. The resulting table of contents is a list with a bunch of links, which turned out to be dead, because of the way Github renders Markdown for releases.

Since swiper works with regexps, here's what I input to match each link:

\[\(.*?\)\](.*?)

This matches anything in brackets (non-greedy), followed by anything in parens; the bracket's content is captured in a group.

Then I press M-q (swiper-query-replace) and enter \1 as replacement - the first captured group. After this, I confirm each replacement with y or confirm them all at once with !.

Use rectangle-mark-mode to promote TOC one level

Since all entries in the TOC were children to a single 0.7.0 entry, I wanted to remove that entry and promote its children one level. This can be done with rectangle-mark-mode, bound by default to C-x SPC.

In my config, I use this instead:

(global-set-key (kbd "C-x SPC") 'hydra-rectangle/body)

Where, hydra-rectangle/body is provided by hydra-examples.el and is also described in an earlier post. I really liked the hydra-rectangle/body idea and use it all the time. Here's a key sequence I used to delete a 4x95 rectangle in order to promote the list items: C-x SPC 4l95jdo.

When copy-pasting from the commit log into Changelog.org, I quickly tired of putting the each issue link as e.g. [[https://github.com/abo-abo/swiper/issues/244][#244]]. So I wrote e.g. #244 instead, and used this code in the end to make the transformation:

(defun ora-quote-github-issues ()
  (interactive)
  (let ((base "https://github.com/abo-abo/swiper/issues/"))
    (goto-char (point-min))
    (while (re-search-forward "\\([^[]\\)#\\([0-9]+\\)" nil t)
      (replace-match
       (format "%s[[%s%s][#%s]]"
               (match-string 1)
               base
               (match-string 2)
               (match-string 2))))))

If anyone reading the blog wants to start with some basic Elisp, the above function is a nice intro to a lot of useful functions. And I expect that many people face this sort of automation scenario pretty often. I'm pretty sure that M-% query-replace-regexp could work here as well, but it's easier for me to just write out the code and save it for later.

Outro

Thanks to everyone who contributed issues, code and documentation. Enjoy the new release.

I move my s-expressions back and forth

Some people find lispy too weird and/or complex to try, quite possibly because of it's sort-of-modal key binding structure. Which is a shame, since out of 7k lines of lispy's code, only 500 lines do key bindings, the rest do all sorts of useful stuff, like sexp navigation/modification, outlines and REPL interaction.

In this post, I'll show a short example of using lispy's functions outside of lispy-mode, and compare it with the default approach.

Moving s-expressions while the point is anywhere

Using this simple hydra, and the key sequence C-c m sss www I got the following GIF:

hydra-lispy-move-1.gif

Doing the same lispy-way

To do it the lispy-way, I move the point before the list that I wish to operate on (with [ key), and press sss www to get the following GIF:

hydra-lispy-move-2.gif

The difference here is that no hydra is necessary in the second case, the key bindings come only from lispy-mode. But the first case will also work if lispy-mode is off.

Which way is better?

I think the second way is better, since it's faster and more clear, but you can decide for yourself. By the way, you can also move symbols, comments and sub-words (if that makes sense) with w and s, provided you mark them with a region first.

New feature in Ivy - ivy-occur

I've had an idea with this feature for quite some time, and only recently got to finally implement it. So here it goes: with ivy-occur, bound to C-c C-o while in the minibuffer, you can store almost Ivy any completion session in progress, and you can have as many of them as you like.

Example 1

This is where the command name originates from: swiper + ivy-occur = occur. You can store all of swiper's matching lines into a separate buffer. This doesn't give too much advantage over the good-old occur, the only thing is that you can use ivy-style regexps with wild spaces, and have an interactive preview beforehand. Having said that, it actually sounds pretty good!

Example 2

I press C-S-o, bound to counsel-rhythmbox, and enter u2. After pressing C-c C-o, bound to ivy-occur, the completion session is closed (effectively C-g), and a new buffer *ivy-occur counsel-rhythmbox "u2"* is generated with all songs that match u2.

As a reminder, counsel-rhythmbox has two actions: play (the default) and enqueue. In this new buffer, pressing RET or mouse-1 will call the play action (since it was active at the moment ivy-occur was called) for the current candidate. So I've effectively added a playlist functionality to counsel-rhythmbox through a generic command.

Note that it's very easy to identify a completion session by the command name and input. So I can distinguish e.g. *ivy-occur counsel-rhythmbox "u2"* and *ivy-occur counsel-rhythmbox "ัะบั€ั"*, and quickly select them with ivy-switch-buffer: just input rhy, usually only these two and similar buffers will match.

Example 3

Suppose I want to go through the documentation of all variables that end in -function. Easy:

  1. <f1> v (counsel-describe-variable) with input function$.
  2. C-c C-o (ivy-occur).

I get a new buffer named *ivy-occur cousnel-describe-variable "function$*" with 346 candidates. I can go through them at my own pace, possibly doing other completion stuff in between without disturbing my process. It's also convenient to navigate these buffers with swiper.

Example 4

Let's tweak the previous one. After inputting function$ I can press C-M-a (ivy-read-action) followed by d to select the definition action. Then again C-c C-o (ivy-occur). Pressing RET in the resulting buffer will take me to that variable's definition, instead of describing it as before. A similar thing could be done for counsel-rhythmbox to get the enqueue action in *ivy-occur* buffer, instead of play.

Example 5

This is an improvement to my workflow for quickly looking at a new package's features. This can be done with oge (lispy-goto-elisp-commands) from lispy, which scans the source for (interactive) tags and allows to jump to their definition.

It's a pretty cool optimization, compared to looking at all tags. For example, projectile currently has 375 top-level tags (functions and variables). But with lispy-goto-elisp-commands I only get 48 tags. And now I can have them in a convenient permanent list too.

ivy-occur-1.png

Alternatively, if projectile is already loaded, I can use counsel-M-x with input projectile-, followed by C-M-a d to select the definition action, followed by C-c C-o.

As a reminder of how it works, counsel-M-x is defined with a single action that calls the selected command. But then, I've also added this statement at top-level of counsel.el:

(ivy-set-actions
 'counsel-M-x
 '(("d" counsel--find-symbol "definition")))

This means that you can add as many actions as you like to ivy-read commands. And of course customize the binding and the hint, which are in this case d and definition respectively.

Limitations

Unfortunately, since the *ivy-occur* buffer needs to know the action to execute, it only works for commands that explicitly pass :action to ivy-read. For instance, it won't work for package-install with ivy-mode on: the buffer will be properly generated, but pressing RET won't install a package.

Fortunately, it's not hard to write a version that works:

(defun counsel-package-install ()
  (interactive)
  (ivy-read "Install package: "
            (delq nil
                  (mapcar (lambda (elt)
                            (unless (package-installed-p (car elt))
                              (symbol-name (car elt))))
                          package-archive-contents))
            :action (lambda (x)
                      (package-install (intern x)))
            :caller 'counsel-package-install))

Here's a buffer with a list of packages matching "ga"; pressing RET will install the selected package:

ivy-occur-2.png

Small note on key bindings

In the initial post, I wanted to bind ivy-occur to C-c o instead of C-c C-o. But I was reminded that C-c LETTER are reserved. I still think it's a better binding. If you agree, you can add it to your config:

(define-key ivy-minibuffer-map (kbd "C-c o") 'ivy-occur)

Additionally, ivy-occur is also available on C-o u, through the C-o hydra.

Outro

I think ivy-occur is a very powerful command that shouldn't be overlooked. Just as ivy-resume implements a sort of DEL or C-u key for completion, ivy-occur implements a convenient way to switch and store the completion context, a sort of C-x o or C-x b for completion.