Search code examples
bashshellzshbash-completionzsh-completion

Tab-triggered snippets in shell


Is there a way to use tab key in bash or zsh to trigger a snippet, like e.g. Sublime Text does it?

For example, if I have configured that x should be expanded to ~/projects/one/two/x/, so:

$ cd x[TAB]

would turn into

$ cd ~/projects/one/two/x/

Solution

  • That's quite easy in zsh, actually.

    First, you need a shell function that does whatever you want if the conditions are met (here, if the zle special variable $LBUFFER — that is, what's at the left of the current position in the zle buffer — is x) and fallbacks to the regular completion otherwise:

    expandSnippetOrComplete() {
        [[ $LBUFFER = x ]] && LBUFFER=~/projects/one/two/x/ || zle expand-or-complete
    }
    

    Second, you have to make this shell function a zle widget, that is, a function that can be called within zle instead of from the command line.

    zle -N expandSnippetOrComplete
    

    Third, you have to bind this widget to the tab key:

    bindkey "^i" expandSnippetOrComplete
    

    That's it!

    Now, you might want to do that if the last word before the current position in the zle buffer is x, be it at the beginning or not. If so, then this should do the trick:

    local ALBUFFER
    ALBUFFER=($=LBUFFER) # split $LBUFFER on $IFS, put the resulting in $ALBUFFER
    [[ $ALBUFFER[-1] = x ]] && LBUFFER[-1]=~/projects/one/two/x/ || zle expand-or-complete