19 May 2015
More checkdoc
goodness
If you're doing some Elisp coding, you should definitely check out the
built-in checkdoc
command. Too bad it's (was) interactive-only. With
a small modification, I've made it suitable for batch.
You can check out how I did it in the
avy (or
lispy) repository. Here's my
compile
target in the Makefile:
emacs ?= emacs
compile:
$(emacs) -batch -l targets/avy-init.el
And here are the contents of avy-init.el:
(add-to-list 'load-path default-directory)
(mapc #'byte-compile-file '("avy.el"))
(require 'avy)
(require 'checkdoc)
(with-current-buffer (find-file "avy.el")
(checkdoc-current-buffer t))
I made compile
target a dependency of the all
target, so with a
single make
I can:
- run the tests
- check for compiler warnings
- check for
checkdoc
style warnings
compile
over ansi-term
There's no reason to use ansi-term
(or an external shell) over
compile
in this case. Using M-x compile
(or actually
M-x helm-make) I
can navigate to any compilation or style warning or failed test from
the *compilation*
buffer.
For the lazy, it's possible to jump to errors with a mouse, but
navigating errors is a breeze with this Hydra:
(defhydra hydra-error (global-map "M-g")
"goto-error"
("h" first-error "first")
("j" next-error "next")
("k" previous-error "prev")
("v" recenter-top-bottom "recenter")
("q" nil "quit"))
There is also
ace-link-compilation, but I
tend not to use it often.
I make good use of one of the coolest compilation-mode
features:
pressing g will restart the compilation process.
Outro
Check out the new feature, I think it's really cool. Another incentive
to try is that lately the
emacs trunk has been
extremely stable: I'm on Emacs25 almost all the time now, since it
feels a lot faster.
Here are my aliasing settings:
$ which newemacs
/usr/local/bin/newemacs
$ readlink -f `which newemacs`
/home/oleh/git/gnu-emacs/src/emacs
To run the tests with newemacs
instead of emacs
(since that's the
one for which checkdoc
works in batch), use M-x setenv
-> emacs
-> newemacs
.
17 May 2015
I have a fondness for Emacs commands and key bindings that you can
get for free. Here, by "free" I mean customizations that don't
require you to change your old workflow (i.e. unbind your old
bindings), but still get the new workflow with comfortable bindings.
- For free (almost physical) keys, see my post on
xmodmap.
- See the last post
to see how you can get window manipulation commands "for free" when
you call
ace-window
.
- With hydra, you can define
lightweight minor modes for almost free or even completely free key
bindings.
- With lispy, you get list
manipulation bindings (single letters, no less) for free when your
point is positioned at a list boundary, or when the region is
active.
- With worf, you get heading
navigation and manipulation bindings, also single-letter, when your
point is at a heading or markup start.
Today, I describe a recent addition to
avy: when you call avy-goto-line
and decide that you don't want to use avy-keys
to select a line on
screen, and you want to select a line by number, you can just enter
that number.
avy-goto-line
will recognize that you entered a digit, and forward
to goto-line
with that digit already pre-entered. So basically there's no disadvantage to doing this:
(global-set-key (kbd "M-g g") 'avy-goto-line)
Even if you use the avy
method zero times, you lose no efficiency
when compared with regular goto-line
, you just get a pretty
light-show with each call:
You can customize a lot of things in avy
, for instance the keys or
the way the overlays are displayed. See the
new wiki page on
customization for more info.
13 May 2015
I kind of forgot to tag the 0.8.0
release on Github, so it's been a
whole 3 months since the last release. In this post, I'll only
describe the newest exciting feature in more detail, see
the archive for
older
posts
on
ace
window.
New Features
Display the window decision chars in the mode line
Enable ace-window-display-mode
for this. This gives you the
advantage of always being aware which window corresponds to which
char.
New defcustom: aw-ignore-current
This is off by default. When t, ace-window
will ignore
selected-window
.
Allow to switch the window action midway
Ace-window has many commands available, like:
ace-select-window
ace-delete-window
ace-swap-window
- ...
But did you wish sometimes when you called ace-select-window
that
you should have called ace-delete-window
? In the old way, you would
cancel ace-select-window
with C-g and call
ace-delete-window
.
With the new way, you can, just press x followed by the
decision char. All keys are customizable through aw-dispatch-alist
.
(defvar aw-dispatch-alist
'((?x aw-delete-window " Ace - Delete Window")
(?m aw-swap-window " Ace - Swap Window")
(?n aw-flip-window)
(?v aw-split-window-vert " Ace - Split Vert Window")
(?b aw-split-window-horz " Ace - Split Horz Window")
(?i delete-other-windows " Ace - Maximize Window")
(?o delete-other-windows))
"List of actions for `aw-dispatch-default'.")
The strings beside each command are important: they are used to update
the mode line when you press a char. They also mean that a window
should be selected using aw-keys
for the corresponding command. If
there's no string, the command is just called straight away, with no
arguments. To reiterate, for each entry without a string, its command
will be called immediately, and for others the window will be selected
first.
Also, take note of aw-flip-window
. Suppose the you have a lot (say
7) windows, but you only want to cycle between the most recent
two. You can do so with n, with no need to press the
decision char.
I call this feature "the dispatch". The dispatch normally happens when:
- you're prompted for
aw-keys
- you press a char that isn't in
aw-keys
- there's an entry in
aw-dispatch-alist
for this char
If you want to skip step 1 always (since, by default, you're not
prompted for aw-keys
when you have 2 or less windows), use:
(setq aw-dispatch-always t)
Be careful though, setting this means that you'll always have to
select a window with aw-keys
, even if there are only two. This is a
large toll on the muscle memory. On the other hand, even with one
window, assuming you've bound ace-window
to M-p, you get:
split-window-vertically
on M-p v
split-window-horizontally
on M-p b
delete-other-windows
on M-p o
What's also nice is that these commands scale with the amount of
windows: if you have only one window, you get no prompt for M-p
v, so it acts just like C-x 2. But if you have more
windows, you don't have to select the window that you want to split
beforehand: you can select it after you decided to issue a split
operation.
See the wiki for a nice
customization setup by @joedicastro.
Outro
Give the new feature a try. The jump in utility between the new and
old ace-window
, I feel, is of the same magnitude as the jump between
other-window
and ace-window
. However, it doesn't come for free and
the muscle memory needs to be readjusted slightly.
Big thanks to all who contributed, especially to @joedicastro.
08 May 2015
This package contains the library on which ace-window and
ace-link now depend, as well as a multitude of navigation
commands.
Intro
Yes, they used to depend on ace-jump-mode, hence the
ace
in their names, but as I added features to my packages over time, it became harder to compose
features because of ace-jump-mode
inflexibility.
Don't get me wrong, ace-jump-mode
is a fine standalone package, and if you're using it only for
jumping to chars, there are few reasons for you to make the switch. However, if you're interested in
the new and juicy features, such as:
- jumping to word starts
- jumping to sub-word starts
- jumping to line beginnings or endings
- copying and moving lines
with most of the features coming in -0
, -1
, or -2
flavor, or if you're interested in building
an ace-jump-mode
-based package, then you should consider avy.
The leading chars flavor
All of the commands provided are about jumping to visible characters, and possibly doing some stuff.
Since usually there are a lot of these visible characters, it's advantageous to first narrow them
somewhat. So each command can be divided into two phases: the narrowing phase and the decision phase.
There are 3 variations of the narrowing phase:
The -0
flavor, e.g. avy-goto-word-0
or avy-goto-line
doesn't narrow at all. The advantage
that there's minimum context switching (no narrowing phase, only decision phase). The disadvantage
is that the number of candidates in the decision phase can be quite large.
The -1
flavor, e.g. avy-goto-word-1
or avy-goto-char
narrows by the first character of the
thing. The disadvantage is the context switch: first you call the command, then you switch context
to scan and input the leading char, then you switch context to scan and input the decision chars.
The advantage is less candidates in the decision phase.
The -2
flavor is my favorite avy-goto-char-2
: it reads two consecutive chars, instead of
just one. This doesn't impact the narrowing phase too much, since inputting two consecutive chars
isn't much more than just one. But it greatly decreases the number of candidates in the decision
phase. The small amount of candidates allows me to use this setting for the decision:
(setq avy-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
That's only 9 decision chars, all of them on the home row.
The decision char overlay flavors
Once again, there are three, here are their corresponding defcustom
s:
(defcustom avy-goto-char-style 'pre
"Method of displaying the overlays for `avy-goto-char' and `avy-goto-char-2'."
:type '(choice
(const :tag "Pre" pre)
(const :tag "At" at)
(const :tag "Post" post)))
(defcustom avy-goto-word-style 'pre
"Method of displaying the overlays for `avy-goto-word-0' and `avy-goto-word-0'."
:type '(choice
(const :tag "Pre" pre)
(const :tag "At" at)
(const :tag "Post" post)))
If you're used to ace-jump-mode
, the corresponding style is at
, which displays the overlay at
the target position, one character at a time. I don't like this style most of the time, I prefer
pre
which is more similar to vim-easymotion
: it will display the full char path at once, before
the target position. This results in less feedback and more efficiency, in my opinion.
Outro
Give the new package a try, it's already been pretty active the last few days, with bugs being fixed
and new features appearing, thanks to all who contributed.
If you want to see some screenshots, there are plenty at the
repository page, and also in an earlier
post.
Finally, the package in on MELPA, so it's convenient to install. The only hassle is to decide where to bind all these commands.
02 May 2015
This is a feature-packed release with a lot of cool things like:
- Partial completion on TAB
- Resume the last completion session with
ivy-resume
- Multi-tier regex matching
The detailed release notes follow.
Fixes
Glob expansion in rgrep
While completing file names, ivy expands the file name to
full. Unfortunately, rgrep
uses read-file-name-internal
and isn't
receptive to globs being expanded with the current directory. A
work-around this is to use the generic strategy when ivy is in
trouble:
- enter the input text as if there was no completion.
- exit with C-u C-j (forwards to
ivy-immediate-done
).
ivy-immediate-done
is currently unbound by default. If you want, you
can bind it in your config like this:
(define-key ivy-minibuffer-map (kbd "C-c C-d") 'ivy-immediate-done)
Exclude a couple more modes from font-lock
This time, they are jabber-chat-mode
and elfeed-search-mode
.
Fix a flag in swiper-query-replace
You can launch a query replace with M-q from swiper.
Avoid sorting org-refile
candidates
By default, ivy completion candidates are sorted with
string-lessp
. The sorting can be customized with
ivy-sort-functions-alist
. While refiling, the natural order is
actually best, so the sorting is turned off in that case.
Reset to the first candidate when switching directories
With ivy-mode
you can select a file anywhere on your file system by
switching directories repeatedly with C-j
(ivy-alt-done
). After moving to a new directory, the point should be
on the first candidate.
Fixup the face order
All this time there was an issue with the face order swapping between
1 and 2 groups. This is now fixed. Also, I've made
swiper-match-face-4
inherit from isearch-fail
. It's important to
have all 4 faces be different.
Don't error on bad regex
When the current input is a bad regex, just display no candidates and
continue. Don't throw an error.
New Features
Use // instead of / to move to root
While completing file names, you can enter // to move to
the root directory. This change was necessary in order to make it
possible to enter e.g. /sudo:
or /ssh:
.
Host completion for /sudo:
and /ssh:
This feature is a bit flaky for now. But it works well on my
machine. It should get better after a few bug reports. You can start
the completion right after the method, e.g. /ssh:
RET, or
after method+user, e.g. /ssh:oleh@
RET.
Respect confirm-nonexistent-file-or-buffer
If you set confirm-nonexistent-file-or-buffer
to t (it's nil by
default), you'll have to confirm when you create a new file or buffer
with ivy.
Highlight remote buffers with ivy-remote
face
Just some extra polish to make things look nicer. The buffers to which
you're connected through TRAMP will be highlighted with the new
ivy-remote
face.
Change the prompt for match-required
interactions
Sometimes, the Emacs functions that call completion specify to it that
a match is required, i.e. you can't just type in some random stuff -
you have to select one of the candidates given to you. In that case
ivy will appropriately change the prompt like this:
Improve the candidate selection while using history
While completing, you press M-p to select the previous
input. This update tries to select not just the first candidates that
matches, but the actual previous candidate that you selected before.
Use alpha compositing to add ivy-current-match-face
This is only relevant for when the completion candidates have custom
face backgrounds. But in that case, the minibuffer looks a lot nicer.
Add partial completion
Press TAB to do call ivy-partial-or-done
to complete the
current thing to the largest possible prefix. When called twice in a
row, it's the same as C-j, i.e. it will finish the
completion.
Improve completion of hidden buffers
In Emacs, hidden buffer names start with a space. To see them all,
press a single space while completing buffers in ivy-mode
. You can
toggle between hidden and non-hidden buffers by editing the first
space in your input query. Remember that with ivy-mode
the
minibuffer is a proper editable area, so C-a works properly
(unlike in isearch
or ido-mode
).
Allow to quote spaces while matching
Spaces are wild while matching - they serve as group
boundaries. However, sometimes it would be useful to quote them. From
now on, you can quote N
consecutive spaces by inputting N+1
consecutive spaces.
Add multi-tier regex matching
This is actually a really cool feature, so if you're paying attention
to any section, let it be this one.
User side
For example, I cloned
boost-1.58.0
and called counsel-git
, which is like a find-file
for all files in
a git repository at once.
- Initially, it gives 45919 candidate files.
- With input "utility", there are 234 candidates.
- With input "utility hpp", there are 139 candidates.
Now, the interesting part. If I want to exclude anything with "hpp" in
it, I change the input to "utility !hpp" (with M-b !) to
get 95 candidates (95=234-139, it checks out). I could exclude some
more:
- with input "utility !hpp cpp" there are 57 candidates.
- with input "utility !hpp cpp ipp" there are 46 candidates.
- I can unify the regex to "utility ![hic]pp" and also get 46 candidates.
- exclude htm with "utility ![hic]pp htm" to get only 17 candidates.
You can use this strategy anywhere, not just for git file. For example, in describe-function
or swiper
.
Elisp side
You can customize ivy-re-builders-alist
to make ivy-mode
complete
in the way that you like. The alist dispatches on the collection
type, so you can have one completion strategy for buffers, another for
files and still another for everything else.
Each function on the alist should turn the string input into a string
regex. So the simplest one would be regexp-quote
. If you want to use
multi-tier matching, the function should instead return a list of
regexps of two types:
- the ones that should match (will be joined by
and
).
- the ones that should not match (will be joined by
or
).
Add ivy-resume
This feature is still a bit of a work-in-progress. But it allows you
to resume the last completion to the point before you entered
RET or C-g etc. It only works for features that
specifically passed :action
to ivy-read
. You could resume other
features, but nothing would be done when you select the candidate,
since ivy-completing-read
has no idea what the function that called
it was going to do with the result.
Currently, you can resume:
counsel-describe-variable
counsel-describe-function
lispy-goto
swiper
Here's how I've bound it in my config:
(global-set-key (kbd "C-c C-r") 'ivy-resume)
(global-set-key [f6] 'ivy-resume)
The ivy-resume
feature adds occur
-like functionality to swiper
.
Calling ivy-resume
is like switching to the *Occur*
buffer.
Outro
Big thanks to all who contributed, especially
@tsdh and
@zhaojiangbin.
If you're considering to switch from ido-mode
to ivy-mode
, now is
a good time, since the most glaring gaps have now been filled. You can
find some up-to-date info on the
swiper wiki. I switched the
page syntax from markdown to org-mode, but Github makes the headings
way to big. So it might be easier to clone the wiki and view the org
files in Emacs:
git clone https://github.com/abo-abo/swiper.wiki.git