Zsh에서 강조 표시되는 Readline 스타일 브래킷

Zsh에서 강조 표시되는 Readline 스타일 브래킷

때로는 Zsh로 긴 명령을 작성하거나 R이나 Perl과 같은 다른 언어의 코드가 포함된 긴 문자열 리터럴로 끝나는 Zsh 명령을 작성하지만 괄호, 대괄호 또는 중괄호를 잊어버립니다. blink-matching-paren닫는 괄호를 입력하면 Readline 변수는 해당하는 여는 괄호를 잠시 깜박입니다. Zsh와 비슷한 것을 어떻게 얻을 수 있나요? show-paren-mode텍스트 커서가 위에 있을 때마다 해당 일치하는 괄호를 강조 표시하는 Emacs와 동등한 기능이 더 좋습니다 .

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

관련 정보