Як виконати функцію в bash або zsh на кожній букві, що вводиться в підказку?


3

Я знаю про гачки preexec () для zsh і про те, як цього можна досягти в bash. ( посилання )

Але чи можу я отримати поточний вклад під час введення тексту?

Ідея цього питання полягає в наступному:

для того, щоб дозволити швидше вивчити команди, аргументи та ярлики, я хочу шукати команду, що вводиться у "базі даних", що дає "підказки" допомога / добре знати / ярлик "і показувати їх на іншому сеансі за допомогою екрана / tmux під час набору тексту в іншому.

Чи можна перевірити чи вводиться поточна команда? Якщо це не працює на кожному натисканні клавіші, цикл таймера може також працювати.

Відповіді:


4

Я можу відповісти лише за те zsh, де це можна зробити, так.

По-перше, вже є деякі віджети для поступового завершення . Перший, мабуть, Ю. Фуджі. Хоча його сайт на японській мові, ви можете легко зрозуміти, не розмовляючи цією мовою, як вона працює та як нею користуватися. Авто-фу - це розширення оригінального сценарію.

Поки посилання. У zshв редакторі ЗШ лінії ( zle) відповідають за інтерактивне використання командного рядка. Окрім безлічі інших змінних, що надаються віджетам (див. man zshzle), Вони цікавлять вас, оскільки ви бажаєте захопити поточний командний рядок :

$ BUFFER : весь вміст буфера редагування.

$ LBUFFER : частина буфера, що знаходиться зліва від позиції курсору.

$ RBUFFER : Частина буфера, що знаходиться праворуч від позиції курсору.

Ці змінні можна записати, що змінить поточний командний рядок!

Щоб зафіксувати кожен набір клавіш, ви можете змінити віджет, self-insertякий виконується (за замовчуванням) для кожного натискання клавіші, крім LFабо CR. Ось приклад, який не робить нічого дуже корисного, але додає до кожного натискання клавіші крапку $RBUFFER- лише щоб проілюструвати, як це працює:

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 є вбудованим віджетом, тому ми не стикаємося з циклом нескінченності.

Отже, ви можете або починати з нуля, або починати з сценарію Fujii і змінювати його. Однією з переваг останнього є те, що він також виконує певні операції зі видаленням натискань клавіш, якими я тут нехтував.


дякую за вашу приголомшливу відповідь - саме це я шукав. тепер я можу перевірити $ BUFFER на натисканні клавіші та вирішити, який файл довідки показати у моєму другому терміналі. так! :)
Nicolai Fröhlich

1
@nifr: Ласкаво просимо ... btw. це ЗШ , що є дивним;)
МРУ

2

Для Bash ви можете створити такий test.shсценарій:

#!/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

Це простий скрипт, який отримує деякі коди клавіатури і друкує їх на екрані. Тепер передайте йому коди клавіатури:

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

Тепер, якщо ви вводите інший термінал, він повинен отримувати ключові значення. Я не знаю, чи є якийсь розумний спосіб зіставити ключові коди до їх значень ASCII, тому я просто роблю просте відображення. Ви можете покращити цей код, щоб реагувати і на інші клавіші. Однак зауважте, що сценарій отримуватиме всі введення з клавіатури, не передані лише одному заданому терміналу.

Що стосується самої задачі (перевірка поточної команди, яка вводиться), ви можете використовувати compgen -cдля створення списку можливих завершень на основі переданого аргументу:

 $ compgen -c 'ls' | head -1
 ls
 $ compgen -c 'lsp' | head -1
 lspci

дякую за детальну відповідь :), на жаль, я не зміг переконатися, що він працює, оскільки здається, що в cygwin немає stdbuf (який я зараз змушений використовувати на роботі). Однозначно збираюся спробувати це у вихідні.
Nicolai Fröhlich

@nifr: ти спробував це? чи можете ви розмістити, чи працювало це?
іконоборство
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.