Using TAB to complete and indent
I’m not a too fast typist, but emacs’ dabbrev-expand makes even me fly. Ok, not as fast as a hawk, but maybe like a quail.
So it wouldn’t be a bad idea to bind dabbrev-expand to the TAB key, if indenting wasn’t such an important command when programming.
Because I didn’t want to choose between pestilence and cholera, I wrote this function:
(defun th-complete-or-indent (arg)
"If preceding character is a word character and the following
character is a whitespace or non-word character, then
`dabbrev-expand', else indent according to mode."
(interactive "*P")
(cond ((and
(= (char-syntax (preceding-char)) ?w)
(looking-at (rx (or word-end (any ".,;:#=?()[]{}")))))
(require 'sort)
(let ((case-fold-search t))
(dabbrev-expand arg)))
(t
(indent-according-to-mode))))
Bind this function to the TAB key. Then TAB completes the current word with dabbrev-expand. But if you a not at the end of a word, it will indent according to the current major mode instead.
Never touched dabbrev, always used pabbrev (which shows some preview of a possible completion; see http://homepages.cs.ncl.ac.uk/phillip.lord/download/emacs/pabbrev.el). Thought about using your code with pabbrev, until I noticed it already seems to do something similar.
Schimmi
December 2, 2006 at 9:22 pm
I’ve read the description and it sounds really interesting. One thing which I think is a bit inconvenient is that it openes a separate buffer on the secont TAB hit, so that you can choose another possible completion. Simply cycling through all completions sounds faster. Anyway, I really should give it a try.
Tassilo Horn
December 2, 2006 at 9:51 pm
Hmmmm… doesn’t emacs have some kind of overlays or something where you can overlay text over a buffer? I think I remember reading about it in passing in the elisp manual, but maybe I’m smoking crack. Anyway, if it does, you could get it do be all visual-studio-esque by presenting the possibilities in an overlay of some sort…
But, it seems like cycling through is the best behavior to me, if the overlay thing doesn’t work…
Paul Huff
December 5, 2006 at 3:11 am
This is really cool, but it causes problems for me in the minibuffer. When using tab with ido-find-file, it tries to look up abbreviations instead of completing from the list of suggestions ido gives. My elisp skills are very weak. Is there a way I could bind th-tab-or-indent only when I’m NOT in the minibuffer? Thanks!
Nate
December 12, 2006 at 4:48 pm
@Nate:
th-tab-or-indent is meant to be bound in a mode specific manner, not globally. E.g. if you want to use it while programmng in C/C++, add this to your ~/.emacs.
(add-hook 'c++-mode-hook(lambda ()
(local-set-key "\C-i" 'th-complete-or-indent)))
(add-hook 'c-mode-hook
(lambda ()
(local-set-key "\C-i" 'th-complete-or-indent)))
Tassilo Horn
December 12, 2006 at 5:34 pm
Thanks! Works great now.
Nate
December 12, 2006 at 6:18 pm
Quick question: this looks great, but I enabled it on my system and added it as a python-mode-hook, but now auto-indenting seems broken. If I now type
for i in [1,2,3]:
the next line is not automatically indented. Am I doing something wrong? Is there a way to preserve auto-indentation while getting tab-dabbrev completions?
Fernando
January 5, 2007 at 7:08 am
Hi Fernando,
I cannot confirm your problems.
(add-hook 'python-mode-hook(lambda ()
(local-set-key "\C-i" 'th-complete-or-indent)
(local-set-key (kbd "RET") 'newline-and-indent)))
works as expected here…
Tassilo Horn
January 5, 2007 at 1:38 pm
I’m using Xemacs 21.4.20. I’m getting an undefined on (rx). any idea what to do about this? I’ve done some digging, I think it’s a regxp function…
Armen
January 5, 2007 at 4:05 pm
Hi Armen,
yeah, `rx’ is a macro for constructing regular expressions in emacs 22. Try replacing the rx-sexp with an equivalent regexp:
(rx (or word-end (any ".,;:#=?()[]{}")))stands for the regular expression\\(?:\\>\\|\\(?:[].,;:#=?()[{}]\\)\\).Tassilo Horn
January 5, 2007 at 4:34 pm
This makes my life so much better….
Armen
January 5, 2007 at 4:59 pm
Thanks! I have no clue, but I can’t reproduce it again either. I was probably tired last night and made a silly mistake.
In any case, your reply prompted me to test again, and it’s fine now.
Fantastic enhancement, since TAB is completely hardwired in my muscle memory by now.
Thanks again for your help and this little snippet.
Fernando
January 5, 2007 at 7:20 pm
Another alterative can be found on Ryan McGeary’s Blog: http://www.emacsblog.org/2007/03/12/tab-completion-everywhere/
Tassilo Horn
March 12, 2007 at 8:36 pm
Peace people
We love you
HelloWorld
April 28, 2007 at 2:18 pm
Hi.
Good design, who make it?
naisioxerloro
November 28, 2007 at 3:42 pm
@naisioxerloro: What? `rx’? rx.el is written by Gerd Moellmann.
Tassilo Horn
November 28, 2007 at 4:20 pm
Thanks, I tried pabbrev mode out, but i feel dabbrev does a better job and binding it to the tab key makes life heavenly.
Jacob
May 15, 2009 at 2:21 am