Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

emacs - autocompletion in Emacs Lisp mode

Tags:

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?

like image 910
Eugene Burmako Avatar asked Aug 11 '11 08:08

Eugene Burmako


2 Answers

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.

like image 184
sanityinc Avatar answered Sep 20 '22 05:09

sanityinc


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.

like image 33
Kilian Foth Avatar answered Sep 21 '22 05:09

Kilian Foth