커서 키가 흥미롭습니다.

커서 키가 흥미롭습니다.

Ubuntu 및 Arch에서는 zsh 쉘을 기본 쉘로 사용합니다.

내 다음 줄을 사용하여 zsh 셸에서 기록을 자동 완성하는 바로 가기(위쪽 화살표)를 구성했습니다 .zshrc.

bindkey "^[[A" history-beginning-search-backward

그러나 Ubuntu에서.zshrc 부팅 및/또는 다시 시작하면 바로 가기가 작동하지 않습니다(무엇을 입력하기 시작하더라도 마지막 명령만 얻음). 반면 Arch에서는 잘 작동합니다(마지막 명령만 얻음) what) I type)으로 시작합니다.

이 문제를 해결하는 방법을 아는 사람이 있나요?

답변1

대부분의 xterm과 유사한 터미널에서는 Up(대부분의 탐색 키와 마찬가지로) 터미널이 입력했는지 여부에 따라 보내기 ␛[A또는 를 보냅니다.␛OA키보드 전송모드인지 아닌지. 그리고 terminfo smkx항목은 rmkx터미널을 이 모드로 전환하거나 종료하는 데 사용될 수 있습니다.

kcuu1(키 커서 위로 1) terminfo 항목은 다음과 같은 경우 전송된 Up시퀀스를 설명합니다.키보드 전송모드, 즉 ␛OA.

데비안과 그 파생물에는 /etc/zsh/zshrc다음을 수행하는 파일이 있습니다:

function zle-line-init () {
   emulate -L zsh
   printf > /dev/tty '%s' ${terminfo[smkx]}
}

이렇게 하면 zle이 활성화될 때 터미널이 이 모드로 전환됩니다. 즉, 이제 terminfo 데이터베이스를 사용하여 키 입력으로 전송되는 문자 순서를 이해할 수 있습니다.

이 문서도$key연관 배열 정의위젯에 매핑하는 데 도움이 되는 terminfo 항목을 기반으로 합니다. 따라서 이러한 시스템에서는 다음을 수행할 수 있습니다.

(($+key[Up])) && bindkey $key[Up] history-beginning-search-backward

터미널이 있는 시스템에서 실행 중인 작업의 경우키보드 전송패턴과 해시가 거의 또는 전혀 없는 패턴의 경우 $key다음과 같이 할 수 있습니다.

bindkey $terminfo[kcuu1] history-beginning-search-backward
bindkey ${terminfo[kcuu1]/O/[} history-beginning-search-backward

또한보십시오:

답변2

커서 키가 흥미롭습니다.

편집 키만큼 흥미롭지는 않지만진짜기쁨.

당신은두 세트키보드의 커서 키,커서 키보드그리고 그것에 관한 것계산기 키보드.

대부분의 터미널 에뮬레이터는 각 키 세트를 개별적으로 사용할 수 있는 DEC VT 모델을 채택하려고 시도합니다(때로는 매우 열악함).신청방법그리고일반 모드개인 모드 설정 DECCKM(커서 키보드 모드) 및 DECNKM(숫자 키보드 모드)을 각각 사용하십시오. 응용 프로그램 모드의 개념은 본질적으로 관련 키보드의 키가 추가 응용 프로그램 기능 키가 된다는 것입니다.

⇐ 커서 키보드입니다.
  • 일반 모드에서 화살표 키는 수정자가 적용되지 않는 한 ECMA-48 CUB, CUF및 제어 시퀀스를 보냅니다 CUU. 이 경우에는 제어 시퀀스를 보냅니다.CUD⎇ AltDECFNK
  • 애플리케이션 모드에서 화살표 키는 SS3단일 Shift 3 시퀀스를 보냅니다.
⇐ 계산기 키보드입니다.
  • 일반 모드에서 화살표 키는 수정자가 적용되지 않는 한(제어 시퀀스를 보내는 경우 ) 또는 숫자 잠금 및 Shift 조합으로 인해 숫자가 전송되지 않는 한 ECMA-48 CUB, CUF및 제어 시퀀스를 CUU보냅니다 .CUD⎇ AltDECFNK
  • 응용 프로그램 모드에서 화살표 키는 다음을 보냅니다.다른 세트 SS3단일 교대 3 시퀀스(숫자 잠금 및 교대 조합으로 인해 숫자가 전송되지 않는 한).

[ AZLE에게 위젯에 바인딩하도록 지시하는 시퀀스는 제어 시퀀스의 ECMA-48 7비트 별칭, CSI ACUP("커서 위로") 제어 시퀀스입니다. 이 제어 시퀀스는 키보드가 일반 모드에 있고 수정자가 비활성화된 경우 ⎇ AltDEC VT 및 해당 에뮬레이터 터미널 에뮬레이터에 의해서만 생성됩니다 . 연결된 키보드가 애플리케이션 모드에 있을 때 전송된 시프트 시퀀스와 일치하지 않습니다.

terminfo 데이터베이스는 터미널 I/O에 이 모델을 사용하지 않기 때문에 상황을 더욱 혼란스럽게 만들고 추가적인 재미를 제공합니다. 대신 자체적으로 사용합니다.다른"로컬" 및 "원격" 키 개념을 구현한 모델로, 이는 실제로 DEC VT 애플리케이션/일반 모드 전환과 관련이 없으며 궁극적으로 전환하는 로컬/원격 전환 메커니즘을 갖습니다.둘 다키보드는 응용 프로그램/일반 모드 간에 분리될 수 없습니다.

terminfo는 DEC VT를 에뮬레이션하지 않는 터미널이나 터미널 에뮬레이터를 사용하는 경우를 대비해 ZLE를 구성하는 특정 터미널 유형에 직접 연결하지 않는 방법입니다. Z 셸은 데이터베이스 레코드에서 필요한 기능 항목에 액세스하는 방법을 제공합니다. 따라서 terminfo에서 위쪽/아래쪽/왼쪽/오른쪽 커서 키가 생성할 것으로 예상하는 제어 시퀀스를 읽을 수 있으며 bindkey해당 제어 시퀀스를 위젯에 매핑하는 적절한 명령을 실행할 수 있습니다.

문제는 terminfo가 작업에 충분하지 않다는 것입니다. 녹음하는 방법은 한 가지뿐입니다하나각 키에 대한 제어 순서를 확인할 수 있으며 보시다시피 키는적어도누른 모드와 수정자에 따라 세 가지 다른 시퀀스가 ​​나타납니다. (DEC VT 모델에서 수정자는 전송된 제어 시퀀스에 큰 영향을 미칠 수 있습니다.) 따라서 터미널을 terminfo가 예상하는 것을 생성하는 모드로 전환해야 합니다.

그러나 상황은 더욱 악화됩니다. 정보라는 용어가 일관성이 없습니다. 단일 제어 시퀀스는 때로 terminfo 레코드와 같은 DEC VT 애플리케이션 모드 시퀀스입니다.터미널 putty유형, 때로는 terminfo 레코드와 같은 DEC VT 일반 모드 시퀀스터미널 rxvt유형, 그러나 DECFNK순서대로는 아닙니다. 따라서 특정 터미널이나 터미널 에뮬레이터를 사용하여 애플리케이션 모드로 전환해야 하는지 일반 모드로 전환해야 하는지 알 수 있는 방법이 없습니다. 한 사람에게는 옳은 것이 다른 사람에게는 그르다.

따라서 또 다른 접근 방식은 terminfo를 무시하고 자신이이미bindkey그리고 원래 명령을 사용하면 터미널이 항상 DEC VT처럼 보일 것이라고 가정하는 것이 좋습니다 . 터미널이 애플리케이션 모드인지 일반 모드인지 확인하려면 다음 중 두 가지만 필요하며 전송되는 제어 시퀀스가 ​​일치합니다.

바인딩 키 "^[OA" 기록이 뒤로 검색되기 시작합니다.

그러나 이는 CUP제어 시퀀스에 추가 매개변수를 추가하는 누른 수정자 키에 대처하지 못하므로 ZLE가 찾고 있는 모든 것이 매개변수가 없는 일반 문자열일 때 ZLE에서 사용하는 단순 문자열 일치가 실패하게 됩니다 CUP. 가능한 모든 수정자 조합에 의해 생성된 가능한 모든 제어 시퀀스에 대해 bindkey추가 명령을 수동으로 실행 해야 합니다.CUP

시퀀스 1 8 |
-ri를 읽을 때
하다
    바인딩 키 "^[[1;${i}A"" 기록이 뒤로 검색되기 시작합니다.
완벽한

ZLE는 혼자가 아닙니다. 다른 terminfo 기반 프로그램(예: fish쉘)에도 동일한 문제가 발생합니다. ( fish쉘 사람들은 또한 한 터미널 에뮬레이터에 대한 올바른 응용 프로그램/일반 모드 선택이 다른 터미널 에뮬레이터에 잘못될 수 있다는 것을 발견했습니다.) 이것을 다시 빌드하십시오(비교libtermkey이러한 프로그램이 입력을 위한 실제 ECMA-48 제어 시퀀스 파서를 갖게 된 것은 오래전 일입니다. 하지만 아직까지 이 문제를 해결한 사람은 아무도 없습니다.

추가 읽기

관련 정보