Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

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.

share|improve this answer
    
thanks for your awesome answer - this is exactly what i was looking for. now i can check $BUFFER on keystroke and decide which helpfile to show in my second terminal. yeah! :) –  nifr Jun 8 '13 at 2:25
1  
@nifr: You're welcome... btw. it's zsh that's awesome ;) –  mpy Jun 8 '13 at 9:53

For Bash you can create following test.sh script:

#!/usr/bin/env bash

ARRAY=('1' '2' '3' '4' '5' '6' '7' '8' '9' '0' '-' '=' 'BACKSPACE' ''
'q' 'w' 'e' 'r' 't' 'y' 'u' 'i' 'o' 'p' '[' ']' 'NEWLINE' '' 
'a' 's' 'd' 'f' 'g' 'h' 'j' 'k' 'l' ';' "'" '' '' '' 'z' 'x' 'c' 
'v' 'b' 'n' 'm' '0' ',' '.' '/' '' '' 'SPACE')

while read row 
do
    if [[ "$row" == *press* ]]
    then
        index=$((${row/key press   /}-10))
        if [[ "${ARRAY[$index]}" == 'NEWLINE' ]] 
        then
                printf "\n"
        elif [[ "${ARRAY[$index]}" == 'BACKSPACE' ]] 
        then
            echo  -ne "\b \b"
        elif [[ "${ARRAY[$index]}" == 'SPACE' ]] 
        then
            printf " "
        else
            printf "%s" "${ARRAY[$index]}"
        fi
    fi
done

It's a simple script that is receiveing some of keyboard codes and print them in the screen. Now pass keyboard codes to it:

$ stdbuf -o0 xinput test 'AT Translated Set 2 keyboard' | bash test.sh

Now if you type in another terminal, it should receive key values. I don't know if there is any clever way to map key codes to their ASCII values so I'm just doing a simple mapping. You can improve this code to react to other keys as well. Note however that script will receive all keyboard input, not only passed to one given terminal.

As for task itself (checking for the current command being typed) you can use compgen -c to generate list of possible completions based on passed argument:

 $ compgen -c 'ls' | head -1
 ls
 $ compgen -c 'lsp' | head -1
 lspci
share|improve this answer
    
thanks for your detailed answer :) sadly i wasnt able to verify it is working as there seems to be no stdbuf in cygwin ( which i'm forced to use at work currently ). Definitely going to try it out this weekend. –  nifr Jun 8 '13 at 2:22
    
@nifr: did you try it out? can you post whether it worked? –  iconoclast Jan 6 at 2:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.