New video demo - counsel-load-theme
23 Jun 2015Without further ado, here's the video link.
The code
(defun counsel--load-theme-action (x)
"Disable current themes and load theme X."
(condition-case nil
(progn
(mapc #'disable-theme custom-enabled-themes)
(load-theme (intern x))
(when (fboundp 'powerline-reset)
(powerline-reset)))
(error "Problem loading theme %s" x)))
;;;###autoload
(defun counsel-load-theme ()
"Forward to `load-theme'.
Usable with `ivy-resume', `ivy-next-line-and-call' and
`ivy-previous-line-and-call'."
(interactive)
(ivy-read "Load custom theme: "
(mapcar 'symbol-name
(custom-available-themes))
:action #'counsel--load-theme-action))
It looks almost trivial, the main idea is to disable all current
themes and load the new one. Additionally, try to reset the
powerline
, since it has to match the mode-line
face, which most
themes customize.
The Interface
The interface of ivy-read
is the same as the built-in
completing-read
in first two arguments. The difference is that it
also accepts a callback through the :action
argument. This callback
will make the completion engine aware of what needs to be done with
the completion result. The presence of the callback allows these completion engine features to work:
ivy-resume
will resume the last completion. Very useful if you change your mind on the candidate, or want to examine a related candidate.ivy-next-line-and-call
selects the next matching candidate and executes the callback for it.ivy-previous-line-and-call
selects the previous matching candidate and executes the callback for it.
I like to think of ivy-resume
as a DEL or
<left> for completion. As you can erase or go back
one character with the same DEL binding, regardless of the
last character inputted (a or B etc), in the
same way you can call the completion again with the same
<f6> binding, regardless of the command that required
completion (counsel-git-grep
or counsel-load-theme
or
counsel-load-library
etc). ivy-resume
isn't bound by default,
since it needs to be a global binding. I just use this in my config:
(global-set-key [f6] 'ivy-resume)
For the functions that execute the callback while changing the candidate, the idea is:
- C-M-n (
ivy-next-line-and-call
) corresponds to C-n (ivy-next-line
), - C-M-p (
ivy-previous-line-and-call
) corresponds to C-n (ivy-previous-line
).
I've also showed off a generic ivy
feature: M-j will yank
the word at point into the minibuffer. Think of it as the mirror of
C-w in isearch
. It could not be C-w, since I
like C-w being bound to kill-region
.
The command/insert mode split
Finally, I show off the equivalent
hydra-based modal selection
method. So instead of pressing C-M-n C-M-n C-M-n C-M-p
C-M-p, you can press the equivalent C-o c jjjkk.
Luckily, you don't need to remember a lot of bindings for this hydra
mode: just press C-o and read the hints. I'll just list the
exit points, since that's usually the more important stuff:
- To exit the "command-mode" completely, press o or the standard C-g.
- To exit the "command-mode" with the current candidate, press f or d.
- To exit the "command-mode" and once again edit the minibuffer, press i.
You might ask why f and d do the same. They
actually mirror C-j (ivy-alt-done
) and C-m
(ivy-done
). And if you ask what the difference between those two is,
the answer is that ivy-alt-done
will not exit the completion when
selecting directories during file name completion. It may be possible
to extend this to other types of completion where it makes sense to
select something but not to exit the minibuffer.
Outro
If you're using ivy-mode
, make sure to try the new features: the
action-using commands should work for any command that starts with
counsel-
. For other commands, like package-install
, you can only
select one candidate with C-m.
Also do try C-M-n with counsel-find-file
: you'll be able
to cycle through all files in a directory without exiting the
completion. Same goes for ivy-switch-buffer
, which should probably
be renamed to counsel-switch-buffer
for consistency.