Zsh 中的 Readline 式括号突出显示

Zsh 中的 Readline 式括号突出显示

有时我在 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

相关内容