Throwing abbrevs into the mix
28 Dec 2014Currently, I'm using two methods for completing Elisp: company-mode
and helm-lisp-completion-at-point
. The latter is the cannon, the big
gun: it always gets the job done, but I don't want to shoot at
sparrows with it. So I only bring it out for hairy cases, like for
stuff that starts with LaTeX-
. Hence, the company-mode
. But too
often have I typed region-
only to find 7 candidates staring at me,
4 of them useless. Which prompted me to look for an additional
completion method.
Enter abbrevs
According to the manual,
A defined "abbrev" is a word which "expands", if you insert it, into some different text
Also,
Abbrevs can have "mode-specific" definitions, active only in one major mode
Sounds like something that could solve my problem with region-
commands:
rb -> region-beginning
re -> region-end
ra -> region-active-p
Also, obviously,
Abbrevs expand only when Abbrev mode, a buffer-local minor mode, is enabled
Add it to the mix:
(defun oleh-emacs-lisp-hook ()
(setq outline-regexp ";; ———")
(company-mode 1)
(abbrev-mode 1)
(set (make-local-variable 'company-backends)
'((company-elisp :with company-dabbrev-code)))
(yas-minor-mode-on)
(lispy-mode 1)
(auto-compile-mode 1))
Some data acquisition
I had the whole abbrev thing in the back of my mind until I saw a link
to the post
Abbrevs for the most frequent elisp symbols.
That's when I decided to act.
That post eventually links to a pastebin, where 1600 abbrevs are defined.
With my handy best extension
for best browser I've opened
the paste in Emacs best editor by just clicking the edit button
in the RAW Paste Data section.
I had to M-x emacs-lisp-mode
, since the file opened in
text-mode
. And boy, it's big. In lispy-mode
, I usually use
99j to navigate 99 sexps down and therefore to the end of
the list. Well, for this file even 999j wasn't enough.
I quickly tired of deleting one-by-one the each individual useless abbrev.
I mean:
ek -> echo-keystrokes,
when is that ever going to be useful? So I wrote this throw-away code:
(defun foobar ()
(interactive)
(lispy-mark-list 2)
(let ((str (read (lispy--string-dwim)))
count)
(other-window 1)
(goto-char (point-min))
(setq count (count-matches str))
(other-window 1)
(lispy-out-backward 1)
(deactivate-mark)
(if (< count 5)
(lispy-delete 1)
(message "%d" count))))
(local-set-key (kbd "C-.") 'foobar)
After switching to a two-pane window layout, with point in the
pastebin buffer, calling foobar
would count the amount of the abbrev
matches in
my most frequent elisp buffer.
If it was less than 5, the abbrev was auto-deleted, otherwise the
decision was up to me, as holding C-. would no longer
delete. In the end, there were only 56 abbrevs left out of 1600.
The final result
Here's what I have put into my abbrev_defs
:
(define-abbrev-table 'emacs-lisp-mode-abbrev-table
'(("sm" "string-match") ("mm" "major-mode")
("rb" "region-beginning") ("ca" "char-after")
("smd" "save-match-data") ("mb" "match-beginning")
("pm" "point-min") ("ir" "indent-region")
("sf" "search-forward") ("ci" "call-interactively")
("sn" "symbol-name") ("se" "save-excursion")
("scb" "skip-chars-backward") ("fc" "forward-char")
("ff" "find-file") ("fs" "forward-sexp")
("pa" "prefix-arg") ("re" "region-end")
("dc" "delete-char") ("ms" "match-string")
("tc" "this-command") ("dd" "default-directory")
("bc" "backward-char") ("rsf" "re-search-forward")
("snp" "substring-no-properties")
("bsnp" "buffer-substring-no-properties")
("lep" "line-end-position") ("bs" "buffer-substring")
("cc" "condition-case") ("ul" "up-list")
("bfn" "buffer-file-name") ("lb" "looking-back")
("tap" "thing-at-point") ("rm" "replace-match")
("fl" "forward-line") ("df" "declare-function")
("ntr" "narrow-to-region") ("dr" "delete-region")
("rsb" "re-search-backward") ("scf" "skip-chars-forward")
("wcb" "with-current-buffer") ("ie" "ignore-errors")
("gc" "goto-char") ("jos" "just-one-space")
("la" "looking-at") ("ow" "other-window")
("dk" "define-key") ("dm" "deactivate-mark")
("bod" "beginning-of-defun") ("sic" "self-insert-command")
("eol" "end-of-line") ("me" "match-end")
("nai" "newline-and-indent") ("cb" "current-buffer")
("atl" "add-to-list") ("rris" "replace-regexp-in-string")))