Linux – How to execute a function in bash or zsh on every letter being typed into prompt

bashcommand linelinuxtmuxzsh

I know about preexec() hooks for zsh and the way this can be achieved in bash. ( link )

But can i get the current input while still typing?

The idea behind this question is the following:

in order to allow quicker learning of commands,arguments and shortcuts i want to search the command being typed in a "database" providing "help / good-to-know / shortcut" hints and show these in another session with screen/tmux while typing in the other.

Is it possible to check for the current command being typed? If it does not work on every keystroke a timer loop might work aswell.

Best Answer

I can only answer for zsh, where this can be done, yes.

First, there are already some widgets for incremental completion. The first one is apparently that by Y. Fujii. Although its site is in Japanese, you can easily figure out without speaking that language, how it works and how to use it. Auto-fu is an extension of the original script.

So far the references. In zsh the zsh line editor (zle) is in charge of the interactive use of the command line. Apart from a lot of other variables provided to widgets (see man zshzle), these are of interest to you as you want to capture the current command line:

$BUFFER: The entire contents of the edit buffer.

$LBUFFER: The part of the buffer that lies to the left of the cursor position.

$RBUFFER: The part of the buffer that lies to the right of the cursor position.

These variables are writable, what will alter the current command line!

To capture each keystroke, you can modify the widget self-insert which is executed (by default) for every keystroke except LF or CR. Here is an example, which does nothing very useful, but appends for every keystroke a dot to $RBUFFER -- just to illustrate how this works:

function self-insert() {
  RBUFFER+="."
  # execute some other command, but ensure they don't produce any output.
  zle .self-insert
  }
zle -N self-insert

.self-insert is the built-in widget, so we don't run into an infinity loop.

So, you either can start from scratch or start from Fujii's script and modify it. One benefit of the latter is, that it also does some handling of deleting keystrokes which I neglected here.

Related Question