Skip to content

Instantly share code, notes, and snippets.

@joelanders
Created November 5, 2013 01:21
Show Gist options
  • Save joelanders/7312307 to your computer and use it in GitHub Desktop.
Save joelanders/7312307 to your computer and use it in GitHub Desktop.
zsh/zle selecta binding
# What it does: you type a command (like vim), then you hit a key
# (like ctrl-t), then you make a selection, and the command runs
# with your selection as an argument.
# The advantage is that you don't have to make a function for each
# command that you want to use with selecta.
# vs() { vim $(...) }
# es() { emacs-client $(...) }
# First attempt, not ideal because it leaves your history looking like
# vim $(find . -not -path './.git*' | selecta)
# instead of having the command that was actually executed.
bindkey -s '^t' " \$(find . -not -path './.git*' | selecta)\n"
# Second attempt, history looks like it should.
# $BUFFER is the command you're editing.
# zle -N registers a function as a zle widget.
# don't try to bind it to ^s, which is intercepted by the terminal...
function find-selecta {
BUFFER+=" $(find . -not -path './.git*' | selecta)"
zle accept-line
}
zle -N find-selecta
bindkey '^t' find-selecta
@sgeb
Copy link

sgeb commented Apr 11, 2014

Here's an improved version:

# insert a file or directory at current cursor position in the buffer
function _selecta-arg-find {
    trap '' INT
    zle -U "$(find . 2>/dev/null | egrep -v '^.$|/.svn|/.git' | selecta)"
    zle redisplay
    trap - INT
}
zle -N _selecta-arg-find
bindkey '^t' _selecta-arg-find

The trap statements are needed so that <Ctrl-C> exits selecta without losing the current zle buffer. The default SIGINT trap would abort the whole command and return to a blank prompt.

zle -U {string} pushes string onto the zle input stack. It's as if the user entered it on the keyboard. This allows the widget to add a selecta result in mid-line, which wouldn't work with BUFFER+={string}.

The command zle redisplay re-displays the whole buffer and is necessary because selecta erases parts of it.

Note that there is no zle accept-line, meaning you can use it multiple times on the same buffer. Great for example when editing/copying/moving/deleting multiple files at once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment