Recently I've discovered M-x ielm
(the Emacs self-REPL) and was pleasantly surprised that there's a working tab-completion in that mode. Say, I can start typing ecb-
, then hit TAB and ielm
will show me what functions are exposed by ECB. Very convenient for exploration!
However, when I start editing one of my 开发者_开发技巧*.el
files (in Emacs Lisp major mode), TAB no longer works as autocomplete and performs indentation, which I find unfortunate.
I tried to figure out how autocompletion works within ielm
in order to possibly transplant it into Emacs Lisp mode. However, apparently, autocompletion in ielm
uses comint-dynamic-complete
, which, as far as I understand, works only in comint
-based buffers. I guess, this means that I'm out of luck here.
So, well, how do I enable autocompletion for Emacs Lisp?
In recent versions of Emacs, you can use a little-known piece of built-in functionality which enables TAB completion:
(setq tab-always-indent 'complete)
(add-to-list 'completion-styles 'initials t)
With this setup, TAB
- which is usually bound to indent-for-tab-command
- first tries to adjust the indentation according to the mode's settings, but if the indentation is already correct, completion is triggered. This is usually the desired behavior, and IMHO works better than third-party plugins like smart-tab.
Note, however, that in some modes, TAB
is not bound to indent-for-tab-command
, so further rebinding is necessary for those modes, e.g. with smart-tab
. Also, when modes have "bounce indent" (e.g. python-mode
), this technique will also not work.
I find both indenting and completion helpful at times, so I have a function that chooses based on whether the last thing I did was inserting text or not:
(global-set-key [tab] 'indent-or-expand)
(defun indent-or-expand ()
"Either indent according to mode, or expand the word preceding point."
(interactive)
(if (or
(eq last-command 'self-insert-command)
(eq last-command 'dabbrev-expand))
(progn
(setq this-command 'dabbrev-expand)
(dabbrev-expand nil))
(indent-according-to-mode)))
You can probably use comint-dynamic-complete
instead of dabbrev
if you want, but I find that dabbrev
works great for emacs lisp - particularly when combined with completer.el
, which can expand even f-f-r-o
into find-file-read-only
.
精彩评论