Как указать аргументы команды для bind -x на основе истории?

Псевдонимы раскрываются, только если команда появляется непосредственно в коде, без какого-либо расширения. Запись таких вещей, как \ a , $ V , $ (echo a) и т. Д., Подавляет поиск псевдонимов.

Кроме того, bash (в отличие от других оболочек)в любом случае не раскрывает псевдонимы в сценариях по умолчанию, поэтому a на самом деле не запускает псевдоним в bash.

Используйте функцию вместо псевдонима. Вам нужно будет использовать исходное имя для определения функции.

V=a
a () { echo test; }
"$V"     # prints test

(Есть и другие способы сделать что-то вроде того, что вы хотите, используя eval , но не используйте eval , если вы точно не знаете, что делаете. Цитируйте правильно с eval сложно.)

3
21.02.2017, 01:26
2 ответа

В функции, привязанной к ключу, вы можете получить доступ и изменить текущее содержимое командной строки через переменные READLINE_LINE и READLINE_POINT. Proof-of-concept (непроверенный код):

synopsis () (
  set -f
  IFS=$'\t\n\r ;&|'
  words=($READLINE_LINE)
  while [[ "${words[1]}" == @([<>]*|[A-Za-z0-9_]##=) ]]; do
    shift words
  done
  command=${words[1]}
  "$command" --help
)
bind -x '"\C-h": synopsis'

Метод, который вы пробовали с расширением истории, не может работать. Расширение истории происходит при выполнении командной строки. При вызове привязки история не расширяется.

Но ваша основная проблема в том, что ваш shell недостаточно крут. Эта возможность уже существует в zsh, она называется run-help.

bash$ echo 'autoload run-help' >~/.zshrc
bash$ zsh
darkstar% ls -FAlt+h
1
27.01.2020, 21:25

Одна из возможностей - использовать bind без -x, вставив synopsis в начало строки:

bind "'\C-h": "\C-asynopsis \C-j"

Это было бы нормально с одним аргументом. Более сложной версией будет:

bind '"\C-h": "\C-e !#:0\e^\e\C-] \C-usynopsis\C-j"'

Разбиваем на части:

'\C-e '    end-of-line
' !#:0'    insert space and 1st argument of current line
'\e^'      history-expand-line
'\e\C-] '  character-search-backward (to last space)
'\C-u'     unix-line-discard (delete to beginning of line)
'synopsis' insert 'synopsis' in front of the first argument
'\C-j'     accept-line

Это обрабатывает строку с несколькими аргументами, выполняя synopsis только с первым аргументом. (Я бы также использовал "\C-xh" или "\eh" вместо "\C-h", которые уже могут быть стиранием/задним пробелом/"backward-delete-char")

.
1
27.01.2020, 21:25

Теги

Похожие вопросы