18 Jan 2016
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.
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.
06 Jan 2016
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).
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.
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:
07 Dec 2015
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.
Use swiper
to replace each Markdown link with its title
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
!.
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.
Use basic Elisp to turn each bug reference into an Org-mode link
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.
30 Nov 2015
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:
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:
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.
04 Nov 2015
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:
- <f1> v (
counsel-describe-variable
) with input
function$
.
- 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.
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:
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.