Настройка псевдонимов для шаблона расширения истории

Настройка псевдонимов для шаблона расширения истории

аналогично существующему $_, который, как я узнал, обозначает !-1:$, я хотел бы создать псевдонимы для $__, $___и так далее, которые ссылаются на 2-ю или 3-ю -последнюю команду. Я пробовал добавлять

alias "$__"='!-2:$'

в моем .zshrc.local. Если возможно, я хотел бы написать zsh-функцию, которая возвращает 1-й аргумент n-й последней команды на основе количества подчеркиваний.

arch linux kernel 5.1.4-arch
zsh 5.7.1 (x86_64-pc-linux-gnu)

решение1

Эта функция уже существует

Вам не нужно ничего сложного, чтобы получить доступ к последнему слову предыдущих команд. Просто нажмите ESC-.(ie Alt+ .) или ESC-_(ie Alt+ _). Это вызовет команду редактораinsert-last-word, который вставляет последнее слово из предыдущей командной строки. Нажмите клавишу еще раз, чтобы получить последнее слово из командной строки перед этим, и так далее. Если вы нажмете ESC-.один раз слишком много, используйте C-_(отменить), чтобы вернуться к слову, которое у вас было только что.

По умолчанию эта команда не привязана к клавише в режиме vi, но вы можете привязать ее с помощью bindkey.

Вы можете передать числовой аргумент, чтобы получить другое слово: положительный, чтобы начать справа (1 — последнее слово), ноль или отрицательный, чтобы начать слева (0 — первое слово, которое обычно является именем команды, 1 — слово после него, которое является первым аргументом и т. д.). Например, ESC . ESC - ESC 1 ESC .вставляет первый аргумент предпоследней команды.

Возможны многочисленные вариации этой команды путем определения собственного виджета вокруг zle insert-last-word. Zsh поставляется сcopy-earlier-wordиsmart-insert-last-wordкоторые вы можете использовать как есть или в качестве примеров кода.

Если вы действительно хотите $__расширить до последнего слова предпоследней команды, я дам несколько решений ниже, но сначала мне нужно объяснить, что происходит.

Почему ваша попытка не сработала

Во-первых, вы не определяете то, что, как вы думаете, вы определяете. alias "$__"=…определяет псевдоним, имя которого является текущим значением переменной __на момент выполнения определения псевдонима. Это, вероятно, пусто, поэтому вы выполняете, alias ='!-2:$'который ищет команду, вызванную '!-2:$'на пути поиска (=расширениечасть расширения имени файла). Чтобы определить псевдоним с именем $__, необходимо передать $__команду alias, например, с помощью alias '$__'=…или alias \$__=….

Во-вторых, псевдоним раскрывается только в командной позиции, т.е. как первое слово команды (после любых начальных назначений переменных и перенаправлений). Для того, чтобы этот псевдоним был полезен, он должен бытьглобальный псевдоним:alias -g '$__'=…

В-третьих, этот псевдоним не принесет никакой пользы, поскольку расширение псевдонима происходит после расширения истории.

darkstar
darkstar% alias -g '$__'='!-2:$'
darkstar% echo $__
!-2:$

$_не «стоит за» !-1:$. $_и !-1:$являются двумя способами доступа к одной и той же информации в общих случаях. Вы можете сказать, что $_«является псевдонимом» !-1:$, или наоборот, что !-1:$«является псевдонимом» $_, но это использование «псевдонима» в его общеанглийском смысле, а не в техническом смысле псевдонимов оболочки, и это неточно, потому что эти два не всегда имеют одинаковое значение. !-1:$являетсяистория расширение( !) конструкция, которая расширяется доПоследнее слово( :$) принадлежащийпредыдущая командная строка( -1). $_этоparameter expansionиспользуя параметр_который оболочка устанавливает в последний аргумент предыдущей команды. Это имеет значение, если вы запускаете командные строки, которые не являются одной простой командой, например:

darkstar% for x in 1 2 3; do echo $x; done
1
2
3
darkstar% echo $_ is not !-1:$
echo $_ is not done
3 is not done
darkstar% echo $_ and !-1:$ are different; echo $_ and !-1:$ are different
echo $_ and done are different; echo $_ and done are different
done and done are different
different and done are different

Определение $__по команде

Вы можете определитьфункция ловушкиназываетсяTRAPDEBUGкоторый запускается перед выполнением каждой команды. Запомните текущее значение $_(обратите внимание, что вам нужно сделать это в первую очередь, потому что первая команда внутри ловушки перезапишет _), затем «сдвиньте» переменные с несколькими подчеркиваниями.

darkstar% TRAPDEBUG () { _0=$_; ___=$__; __=$_1; _1=$_0; }
darkstar% echo one        
one
darkstar% echo two        
two
darkstar% echo three      
three
darkstar% echo $_,$__,$___
three,two,one

$_1не всегда будет таким же, как $_, поскольку отладочная ловушка не срабатывает в тех же самых обстоятельствах, которые вызывают _ее установку, но она довольно близка.

Определение $__в командной строке

Вы можете зарегистрироватьфункция крючкадля запуска до или после ввода командной строки. В этом случае либоprecmdилиpreexec. Они запускаются до и после выполнения команды соответственно.

preexec_set_underscore_variables () {
  ___=$__
  __=$_1
  _1=$historywords[1]
}
preexec_functions+=(preexec_set_underscore_variables)

я используюhistorywordsчтобы получить последнее слово из командной строки. Я сохраняю его в , _1потому что _уже занято. И функция «сдвигает» переменные истории последнего слова на единицу.

darkstar% echo one
one
darkstar% echo two
two
darkstar% echo three
three
darkstar% echo $_ $__ $___
three two one

Связанный контент