First, I try to understand what the code does, and what you would like it does.
Your code
first checks
if the point is inthe minibuffer
.If so, then it tries to complete the minibuffer
- if (in minibuffer) cannot complete it, it calls dabbrev-expand
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 theend of some word
if so, it checks is yasnippet can expand.
- if yas cannot expand, it calls dabbrev-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))