有时我在 Zsh 中编写一个长命令,或者更确切地说,一个以包含 R 或 Perl 等其他语言代码的长字符串文字结尾的 Zsh 命令,但我忘记了括号、方括号或大括号。blink-matching-paren
当您键入右括号时,Readline 变量会短暂闪烁相应的左括号。我怎样才能为 Zsh 获得类似的东西?更好的是 Emacs 的 等价物show-paren-mode
,只要文本光标位于括号上,它就会突出显示相应的匹配括号。
brackets
来自的荧光笔是zsh-syntax-highlighting
这个方向的东西,但它在引用的结构中不起作用,而这正是我真正需要它的地方(尽管令人困惑的是,如果括号是反斜杠转义的,它仍然会突出显示括号)。
答案1
我认为没有zsh
等效的内置机制,但您应该能够使用自定义小部件来完成此操作,例如:
zmodload zsh/zselect
showmatch() {
emulate -L zsh
set -o rematchpcre
local -A pair=(
']' '['
')' '('
'}' '{'
)
local MBEGIN
zle .self-insert
if [[ $LBUFFER =~ "(\\$pair[$KEYS](?:[^$KEYS$pair[$KEYS]]++|(?1))*\\$KEYS)\$" ]]; then
local oldCURSOR=$CURSOR
CURSOR=$MBEGIN-1
zle -R
zselect -t 50 -r 0 < /dev/tty
CURSOR=$oldCURSOR
fi
}
zle -N showmatch
bindkey ']' showmatch
bindkey ')' showmatch
bindkey '}' showmatch
if
您还可以通过将/ 的内部替换fi
为以下内容来暂时突出显示匹配括号之间的区域:
local oldCURSOR=$CURSOR
region_highlight+=("$((MBEGIN-1)) $CURSOR bg=yellow,fg=black,bold")
CURSOR=$MBEGIN-1
zle -R
zselect -t 50 -r 0 < /dev/tty
CURSOR=$oldCURSOR
region_highlight[-1]=()
(此处以黄底黑字突出显示)。
您还可以将其show-paren-mode
与当光标击中一端时类似的匹配括号的突出显示相结合,如下所示:
zmodload zsh/zselect
SHOWMATCH_GR=fg=black,bg=yellow,bold
showmatch() {
emulate -L zsh
set -o rematchpcre
local -A pair=(
']' '['
')' '('
'}' '{'
)
local MBEGIN
zle .self-insert
if [[ $LBUFFER =~ "(\\$pair[$KEYS](?:[^$KEYS$pair[$KEYS]]++|(?1))*\\$KEYS)\$" ]]; then
local oldCURSOR=$CURSOR
local -a old_region_highlight=($region_highlight)
region_highlight+=("$((MBEGIN-1)) $CURSOR $SHOWMATCH_GR")
CURSOR=$MBEGIN-1
zle -R
zselect -t 50 -r 0 < /dev/tty
CURSOR=$oldCURSOR
region_highlight=($old_region_highlight)
fi
}
zle -N showmatch
bindkey ']' showmatch
bindkey ')' showmatch
bindkey '}' showmatch
zle-line-pre-redraw() {
emulate -L zsh
set -o rematchpcre
region_highlight=(${region_highlight:#* $SHOWMATCH_GR})
local a=$BUFFER[CURSOR+1] b c MBEGIN o=0
local -A pair=(
']' '['
')' '('
'}' '{'
)
[[ -n "$RBUFFER" ]] &&
case $a in
([[\({])
b=${(k)pair[(re)$a]}
[[ $RBUFFER =~ "^(\\$a(?:[^$b$a]++|(?1))*\\$b)" ]] && o=$CURSOR;;
([]\)}])
b=$pair[$a]
[[ $LBUFFER$a =~ "(\\$b(?:[^$a$b]++|(?1))*\\$a)\$" ]];;
(*) return;;
esac &&
region_highlight+=("$((o+MBEGIN-1)) $((o+MEND)) $SHOWMATCH_GR")
}
zle -N zle-line-pre-redraw