I'm trying to get tab complete within all open buffers and yasnippet to both work with the tab key. At the moment I can have one or the other. The following code is how I'm handling the yasnippet expand, but as I'm not a lisp programmer I cannot see the mistake here.
If it cannot expand the snippet I would like it to try and expand from the buffer.
;; Auto complete settings / tab settings
;; http://emacsblog.org/2007/03/12/tab-completion-everywhere/ <-- in the comments
(global-set-key [(tab)] 'smart-tab)
(defun smart-tab ()
"This smart tab is minibuffer compliant: it acts as usual in
the minibuffer. Else, if mark is active, indents region. Else if
point is at the end of a symbol, expands it. Else indents the
current line."
(interactive)
(if (minibufferp)
(unless (minibuffer-complete)
(dabbrev-expand nil))
(if mark-active
(indent-region (region-beginning)
(region-end))
(if (looking-at "\\_>")
(unless (yas/expand)
(dabbrev-expand nil))
(indent-for-tab-command)))))
First, I try to understand what the code does, and what you would like it does.
Your code
first checks
if the point is in the minibuffer
.
If so, then it tries to complete the minibuffer
else if the point is not in minibuffer
if some region is marked , it indents the region.
if no mark is active
, it checks to see if the point is at the end of some word
if so, it checks is yasnippet can expand.
if not, it tries to indent the current line
This is what your code does.
Your code fails due to yas/expand. This command does not return in case the expansion fails.
In case that this command fails, it checks the state of the variable yas/fallback-behavior
. If this variable has the value call-other-command
, as in your case, the failed yas expansion calls the command bound to the key kept in the variable yas/trigger-key
.
In your case , this variable is TAB
.
So: You are at the end of the word, You press TAB to complete it, this triggers the interactive smart-tab
, which calls yas/expand which in case it fails to expand calls the bound function of TAB
, and here is the infinite loop.
The Solution for your problem is to temporaily bound nil to yas/fallback-behavior
in this smart-tab
function.
Here is how to fix it:
(if (looking-at "\\_>")
(let ((yas/fallback-behavior nil))
(unless (yas/expand)
(dabbrev-expand nil)))
(indent-for-tab-command))