질문

질문

내가 사용한 답변zsh는 Ctrl + 백스페이스, Ctrl + 삭제를 종료합니다.다음 키 바인딩을 구성합니다.

  • Ctrl+ Backspace: 현재 단어의 시작 부분까지 삭제,
  • Ctrl+ Delete: 현재 단어 끝까지 삭제,
  • Ctrl+ Shift+ Delete: 행 끝까지 삭제합니다.

이는 다음 명령을 사용하여 수행됩니다.

$ bindkey -M emacs '^[[3;5~' kill-word
$ bindkey -M emacs '^H' backward-kill-word 
$ bindkey -M emacs '^[[3;6~' kill-line  

키(예: 부품)를 인코딩하는 방법을 이해하기 위해 ^[[3;5~답변에 자세히 설명된 "트릭"을 사용했습니다." 시스템의 값을 보려면 Ctrl+ C Ctrl+를 입력하세요."Delete.

질문

Ctrl++를 명령 에 Shift바인딩 하고 싶습니다 (예: 커서와 줄 시작 사이의 모든 항목 삭제).Backspacebackward-kill-line

그러나 +++ 를 입력하면 프롬프트 Ctrl에만 표시됩니다. 즉, +와 동일한 키 조합이 표시됩니다.C CtrlShiftBackspace^HCtrlBackspace

답변1

Ctrl터미널은 + 와 동일한 이스케이프 시퀀스를 Shift보내 므로 zsh는 둘을 구별할 수 없습니다. 유일한 해결책은 다른 이스케이프 시퀀스를 보내도록 터미널을 구성하는 것입니다. 모든 터미널에서 이를 허용하는 것은 아닙니다.BackspaceCtrlBackspace

일부 터미널(예: xterm, rxvt, iTerm2 및 Emacs term)에서는 각 키와 코드에 대한 이스케이프 시퀀스를 수동으로 구성할 수 있습니다. 터미널 문서를 참조하세요.

예를 들어, xterm의 경우 다음 코드 조각을 .Xresources.load it 에 넣을 수 있습니다 xrdb -merge ~/.Xresources. 많은 환경에서는 로그인할 때 이를 로드합니다. 그렇지 않은 경우 X11 시작 파일에 이 명령을 추가하십시오.

XTerm.VT100.translations: #override \
    Ctrl Shift <Key>BackSpace: string("\033[27;6;8~") \n

그런 다음 이 이스케이프 시퀀스를 사용할 수 있습니다.

bindkey -M emacs '^[[27;6;8~' backward-kill-word 

터미널은 다음을 기반으로합니다.정맥 혈전색전증, Gnome-terminal, Guake 및 Terminator를 포함하여 운이 좋지 않습니다. 키 바인딩을 구성할 방법이 없습니다.특정 키에 대한 임시 지원을 기꺼이 추가할 수도 있습니다.하지만.

1 호환성을 위해 이 순서를 선택했습니다xterm modifyOtherKeys모드. 나는 일반적으로 를 활성화하는 것을 권장합니다. modifyOtherKeys이것은 대부분 이전 버전과의 호환성을 위한 것이지만 원하는 특정 키와 코드는 레벨 2에서만 활성화됩니다. 이는 처리하기 까다로운 문제입니다(예: Ctrl+문자는 해당 제어 문자를 보내지 않습니다).

답변2

X11 터미널 에뮬레이터의 경우 변경 방법을 제공하지 않고(절박한 경우) Ctrl+Shift+Backspace동일한 콘텐츠를 전송하면 더티 해킹으로 터미널 에뮬레이터와 X 서버 간의 통신을 가로챌 수 있으며, 예를 들어 다음을 대체합니다 . (키코드 22) 및 (키보드 96)을 Backspace누르면 X11 이벤트 메시지가 터미널 에뮬레이터로 전송됩니다 .BackspaceF12BackspaceShiftCtrl

그건 그렇고, zshUnix 도메인과 TCP 소켓 API가 내장되어 있기 때문에 비교적 쉽습니다. 다음 스크립트를 실행합니다.

that-script guake

그리고 당신의~/.zshrc

if [ -n "$WRAPPED_DISPLAY" ]; then
  export DISPLAY="$WRAPPED_DISPLAY"
  unset DISPLAY
fi

(해당 래퍼를 통과하는 해당 터미널 내에서 실행되는 다른 응용 프로그램을 방지하기 위해)

그리고 바인딩:

bindkey -M emacs '^[[24;6~' backward-kill-word

적어도 VTE를 누를 \e[24;6~때 전송되는 시퀀스 는 무엇입니까?Ctrl+Shift+F12xterm

#! /bin/zsh -

die() {
  (($# == 0)) || print -ru2 -- "$@"
  exit 1
}

case $DISPLAY in
  (:<->(.<->|))
    mode=unix;;
  ((localhost|127.0.0.1|"[::1]"):<->(.<->|))
    mode=tcp
    zmodload zsh/net/tcp || die;;
  (*)
    die "Unsupported display: $DISPLAY";;
esac

conn=${DISPLAY##*:}
port=${conn%%.*}
screennumber=${conn#$port}
(($# > 0)) || argv=(gnome-terminal --wait)

unset -v listen_fd
typeset -A clients

tcp_connect() ztcp -v localhost $((port + 6000))
unix_connect() zsocket /tmp/.X11-unix/X$port

zmodload zsh/net/socket || die
zmodload zsh/system || die
zmodload zsh/zselect || die

new_port=20
until
  new_socket_path=/tmp/.X11-unix/X$new_port
  zsocket -l $new_socket_path 2> /dev/null
do
  ((new_port++))
done
listen_fd=$REPLY

unset -v pid
trap '
  kill "$pid" 2> /dev/null
  wait "$pid"; ret=$?
  rm -f $new_socket_path
  exit "$ret"' EXIT INT TERM HUP
{
  coproc {
    export WRAPPED_DISPLAY=$DISPLAY DISPLAY=:$new_port$screennumber
    xauth list "$WRAPPED_DISPLAY" |
      awk '{$1 = "add " ENVIRON["DISPLAY"];print}' |
      xauth -q -
    "$@" <&3 3>&1 >&4 4>&- {listen_fd}<&-
  }
} 3<&0 4>&1
pid=$!
exec {child_monitor}<&p
coproc :

LC_ALL=C
set -o extendedglob

tear() {
  exec {1}>&- {2}>&-
  unset "clients[$1]"
}

typeset -A ready
while zselect -A ready -r $listen_fd $child_monitor ${(kv)clients}; do
  [[ $ready[$child_monitor] ]] && exit
  if [[ $ready[$listen_fd] ]]; then
    zsocket -a $listen_fd || die
    fd=$REPLY
    ${mode}_connect || die
    clients[$fd]=$REPLY
  fi
  for client server (${(kv)clients}) {
    for from fdin fdout (
      client $client $server
      server $server $client
    ) if [[ $ready[$fdin] ]]; then
        if sysread -s 65536 -i $fdin buf; then
          if [[ $from = server ]]; then
            if [[ $buf[1,2] = $'\x23\x83' ]]; then
              offsets=(9 17 73) # Generic XInputExtension Event 
            else
              offsets=(1 2 29)  # Normal Event
            fi
            if
              [[ $buf[offsets[1]] = ($'\x2'|$'\x3') ]] && # KeyPress or KeyRelease
                [[ $buf[offsets[2]] = $'\x16' ]] && # keycode 22, Backspace
                printf -v modifiers %d "'$buf[offsets[3]]" &&
                ((modifiers & 5 == 5)) # Shift+Ctrl
            then
              buf[offsets[2]]=$'\x60' # keycode 96, F12
            fi
          fi
          syswrite -o $fdout -- $buf || tear $client $server
        else
          tear $client $server
        fi
      fi
  }
done

여기서는 전체 X11 프로토콜 설명을 수행하지 않으며 주요 이벤트가 완전한 메시지로 표시된다고 가정합니다. 터미널이 X 서버와 통신 중일 때 이 키 조합을 누르면 놓칠 수 있습니다. 또한 모든 X11 트래픽은 zsh성능 지향 언어가 아닌 셸로 작성된 래퍼를 통과해야 하기 때문에 성능에 영향을 미칩니다 .

관련 정보