Zsh

如何在 zsh 中為歷史擴展設置別名?

  • September 3, 2018

我希望這個工作(它需要extendedglobhistsubstpattern):

alias ri='^(#b)E(?)^E${(l:2::0:)$((match[1]+1))}'

但它沒有:

$ alias sss='^(#b)E(?)^E${(l:2::0:)$((match[1]+1))}'                                               
$ echo /Users/evar/Downloads/Video/Teenage_Mutant_Ninja_Turtles_2003_S02E01_DVDRip_30NAMA.mkv
/Users/evar/Downloads/Video/Teenage_Mutant_Ninja_Turtles_2003_S02E01_DVDRip_30NAMA.mkv
$ sss                                                                                             
zsh: command not found: Pocket

我不介意使用函式而不是別名,但結果是一樣的。

我什至嘗試過export ss='^(#b)E(?)^E${(l:2::0:)$((match[1]+1))}'然後做$ss,但是失敗了zsh: command not found: ^(#b)E(?)^E${(l:2::0:)$((match[1]+1))}

使用eval '^(#b)E(?)^E${(l:2::0:)$((match[1]+1))}'也失敗了zsh: command not found: Pocket

更新:發現相關(可能重複)問題:

在 zsh 中替代 bash 的“歷史 -p”?

https://stackoverflow.com/questions/27494753/how-to-get-last-command-run-without-using

https://stackoverflow.com/questions/48696876/using-history-expansion-in-a-bash-alias-or-function

你不能,歷史擴展發生在別名或參數擴展之前。

我個人討厭歷史擴展,並且是我禁用的第一件事。

在這裡,我建議不要創建一個歷史擴展的別名,而是創建一個E<n>在游標左側增加一個數字的小元件:

increment-episode() {
 emulate -L zsh
 setopt extendedglob
 LBUFFER=${LBUFFER/(#b)(*E)(<->)/$match[1]${(l:${#match[2]}::0:)$((match[2]+1))}}
}

zle -N increment-episode

bindkey '\e+' increment-episode

然後,您只需按Up然後Alt+ +,您就會對每個階段發生的事情有一個視覺回饋,並且可以隨意撤消/重做/調整,而不是像 csh 歷史擴展那樣盲目工作(IMO 70 年代的一項功能)那時有感覺,但現在我們有更快、更有能力的終端和行編輯器了)。

但是如果你真的想盲目地用E遞增後的數字來評估歷史中上一個命令中的程式碼,你可以這樣做:

rerun-with-next-episode() {
 emulate -L zsh
 setopt extendedglob
 local new
 new=${${history:0:1}/(#b)E(<->)/E${(l:${#match[1]}::0:)$((match[1]+1))}}

 # display it
 print -ru2 -- $new

 # put it on the history
 print -rs -- $new

 # evaluate it
 eval -- $new
}

引用自:https://unix.stackexchange.com/questions/466540