C- [를 어떻게 바인딩합니까?


10

C-[미국 영어 키보드의 이스케이프 키와 동일하므로 바인딩을 시도하면 M-동작 이 엉망이됩니다 .

이맥스는 아무 문제 이야기가없는 것으로 보인다 <escape>C-[GUI 프레임에서 분리합니다. 다음은 잘 작동하며 바인딩은 M-계속 작동합니다.

(global-set-key (kbd "<escape>") (lambda () (interactive) (message "<escape>")))

그러나 내가 묶으면

(global-set-key (kbd "C-[") (lambda () (interactive) (message "C-[")))

갑자기 이맥스가 미쳐 버리고 M-x휴식 처럼 묶어 버린다 . 또한, 누르면 C-[바운드 람다가 트리거되지 않습니다. 흥미롭게도 C-x @ c [(괄호를 열려면 수정 자 컨트롤을 적용하십시오) 여전히 말합니다 C-[ is undefined.

C-[이맥을 깨지 않고 무언가를 묶는 방법이 있습니까?

답변:


7

C-[에서와 마찬가지로 사용자 수준 맵에서 바인딩을 실제로 변경할 수는 없습니다 global-set-key. 그러나 해당 키맵에 도달하기 전에 키보드 이벤트로 변경할 수 있습니다. 예를 들어 말할 수 있습니다.

(define-key input-decode-map 
    (kbd "C-[") 
    [control-bracketleft])

그런 다음 [control-bracketleft]키맵에서 사용 하십시오. 아주 간단하지 않습니까?

감독의 컷

불행히도, 그렇게 간단하지는 않으며,이 솔루션에는 약간의 조정이 필요하며, 이는 매우 고통스러운 것으로 보입니다. 경고를 받았습니다. 그러나 사용자 수준 맵이 질문에 대답 할 수없는 이유를 먼저 살펴 보겠습니다. 다음에서는 더 정밀하게 "뭔가를 봐"라고 말할 때 emacs 26.1의 Emacs Lisp 매뉴얼을 참조합니다.

C-[매우 초기 단계에서 ASCII 제어 문자로 해석됩니다 ESC(21.7.1- 키보드 이벤트 참조 ). 이 코드는 더 긴 시퀀스의 접두사로 다른 모든 곳에 퍼져 있습니다. 그 이유는 다음과 같습니다. ESC실제로 메타 접두사 ( meta-prefix-char)이며 M-무언가 를 읽는 모든 바인딩 은로 시작하는 시퀀스로 변환됩니다 ESC. 따라서 세계지도를 변경하는 것만으로는 충분하지 않습니다. 먼저를 변경 meta-prefix-char한 다음 안전하게 매핑하기 전에 사용하는 모든지도에서 ESCmeta-prefix-char지도 로 다시 매핑 해야합니다 .M-C-[

그렇다면 물론 사용하십시오 input-decode-map. 우리가 사용하기를 원할지도 모르는 유사한지도가 몇 개 있지만 (섹션 21.8.3 및 22.14 참조)이지도를 고수합시다. 그리고 잘 ...이 작동합니다! 끝났습니까?

사실, 아닙니다. 이야기는 여기서 끝나지 않습니다. 이것은 윈도우 시스템을 사용하는 한 작동합니다. 불운으로 인해 리눅스 콘솔에서 비상 사태로 투옥되면 화살표 키 HomeM-바인딩은 모두 쓰레기입니다. 왜? 터미널이 ESC(입력 할 때하는) 말 을 할 때 C-[, 실제로 의미하고 ESC , 비 ASCII 문자를 전송하는 데 사용하는 것과 같은 종류의 시퀀스를 시작합니다.

재난을 관찰하면서, input-decode-map윈도우 시스템이 키보드를 제어하는 ​​경우에만 활성화되는 방식으로 위 수정 을 보호하는 것이 현명하다고 생각할 수 있습니다.

(let ((frame (framep (selected-frame))))
  (or (eq  t  frame)
      (eq 'pc frame)

      (define-key input-decode-map 
                  (kbd "C-[") 
                  [control-bracketleft])
     )))

그런 다음 터미널은 예전처럼 작동합니다.

이제 C-[터미널 을 다룰 수 있습니까? 사실, 우리는 리눅스 콘솔과 다른 터미널 에뮬레이터에서 할 수 있습니다. 그러나 새로운 등장 인물이 등장하기 때문에 이야기가 꽤 길어집니다. 이제는 더 이상 이맥스가 아닙니다. 이제 터미널이 중심 역할을합니다.

리눅스 콘솔이 말하는 것에 귀를 기울여 보자. C-v평범하게 들리려면 키 앞에 입력 하십시오. C-[이다 ESC; 그렇습니다 Esc. 위 화살표는 ESC [ A, 소리 M-a가납니다 ESC A. 흠 ... 이멕스의이 메타 키 할례는 그렇지 않나요? 어쨌든.

문자 이벤트 (그런데 어떤 구별되지 않습니다 사이에 경과 시간에 따라 몇 가지 트릭을 연주 할 준비가 우리가하지 않는 한 Esc에서 C-[우리는 선택의 여지가있어하지만 콘솔에게, 그것은) 것 우리가 실제로 의미하지를하는 일 ESC우리는 입력 할 때 C-[. 또한, C-[주식 터미널 코드의 유일한 문제는 아닙니다. 수정자는 대부분 전송 된 정보를 지 웁니다. 우리는 emacs를 커스터마이징하는 것과 같은 이유로 터미널을 커스터마이징해야합니다. 그렇게하면 훨씬 더 실용적입니다.

이 시점에서, 터미널 loadkeys(1)콘솔 의 설명서 페이지 , 리눅스 콘솔의 매뉴얼 페이지 , 커스텀 키 바인딩xterm(1) 섹션의 xterm , 다른 터미널의 경우 i-dont-know-know에 대해 자세히 살펴 봐야합니다 . 에서 , 당신은 사용자 지정 번역을 정의 할 수 있습니다 / 편집 현재 프로필 ... 설정키보드 . 다음은 이 후자의 대화 상자를 사용한 후 발췌 한 것입니다 .KDE konsole~/.local/share/konsole/Test.keytab

key [+Ctrl+AnyModifier : "\EO*["

당신은 터미널 전송 일단 ESC O 5 [위해 C-[(위의 구성 등)을, 당신은 이맥스로 돌아갈 수 있습니다. 물론 아직 끝나지 않았습니다.

주어진 터미널이 사용하는 방언을 emacs에 지시하기 위해을 조정할 수 있습니다 input-decode-map. 그렇습니다. 이것은이 이야기의 시작 부분에서 우리가 수정 한 바로 그 것이며 term/xterm.elxterm과 관련이있을 때 만지는 바로 그 것 입니다. 조정하기에 적합한 장소는 다음 tty-setup-hook과 같습니다 (섹션 40.1.3 참조).

(add-hook 'tty-setup-hook 
   (lambda ()
    (let ((term (getenv "TERM")))
      (cond 
        (;; xterm-function-map not in doc, but in term/xterm.el
         (boundp 'xterm-function-map) 
         (map-my-term-codes xterm-function-map))

        ((equal term "linux")
         (map-my-term-codes input-decode-map))
        )
      )))

이 후크는 터미널에있는 경우에만 실행됩니다. 따라서 창 시스템 초기화를위한 코드를 여기에 삽입 할 수 없습니다. 번역 기능 자체는 다음과 같습니다.

(defun map-my-term-codes (map)
      (define-key map (kbd "M-O 5 [") 
                      [control-bracketleft])
      )

그리고 당신은 약간의 휴식을 취할 수 있습니다 : 그것은 여행의 끝입니다. 물론 터미널에 신경 쓰지 않으면 고통스러운 부분을 모두 건너 뛸 수 있습니다. 그러나 당신은 그것이 또한 불완전하다는 것을 인정할 것입니다.

두 가지 최종 노트 :

  • ESC O 5 [코딩하기로 선택 했습니다 C-[. 이것은 단지 예일뿐입니다 . 좋은 선택 인 것처럼 보이지는 않습니다 . 5 의미 하는 부분 C-은 어떤 종류의 확립 된 협약을 따르는 것 같습니다

  • 리눅스 콘솔을 구성하면 나쁜 맛이 남습니다. 기존의 기존 심볼 을 사용하지 않고 바인딩을 수행하는 것이 불가능하고 필요한 것이 없습니다 . 대부분의 인터넷 예에서와 같이 F21- F246범위의 기호를 사용 하지만 만족스럽지 않습니다. 관련이없는 바인딩은 괜찮지 만 체계적인 스키마는 제공하지 않습니다.

편집하다

  • 나는 Esc다른 포스트 에서 ESC 접두사 키에 대한 바인딩을 제거하는 방법으로 자신의 성격을 가진 케이스로 이것을 완성했습니다 .
  • 여기에 공급할 구성 조각이 있습니다 loadkeys. 나는 이것을 /root/custom.kmap에 넣고 필요할 때로 드합니다 (드문 경우입니다). 내 실제 구성은 화살표와 수정 자의 다른 조합을 매핑하지만 다소 길고 기호와 시퀀스 선택에 의문의 여지가 있으며 키보드의 키 코드가 사용자의 키 코드와 일치하는지 확실하지 않습니다. 따라서 적절한 수준으로 유지합시다. 이것은 단지 예시 일뿐입니다.

    keymaps 0-127
    
    # http://tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html
    # web+man:keymaps
    # web+man:loadkeys
    
    # escape
    keycode  1  = F100
        alt keycode  1 = Escape # keep the Escape behavior somewhere          
    
    # keycode  26 = bracketleft
        control keycode 26 = F115 # Control_bracketleft does not exist          
    
    string F100     = "\033OO" # map this to [escape] in map-my-term-codes
    string F115     = "\033O5["
    

1
고마워, 좋은 답변입니다. 그러나 반드시 이와 같은 훌륭한 대답조차도 34 페이지의 첫 페이지에 부딪 힐 필요는 없습니다. 각 범프에는 커뮤니티에서 공유하는 작은 비용이 있습니다. 스팸 확인, 새로운 흥미로운 콘텐츠가 있는지 확인하는 등 약간의 개선 사항을 함께 그룹화 할 수 있습니까? 또는 당신이 가진 것을 고수하십시오. 경험에서 말하면, 완벽한 포스트와 같은 것은 없습니다.
Gilles 'SO- 악마 그만해'

@Gilles 알았습니다. 죄송합니다. 원하는대로 조정하는 데 문제가 있음을 알지 못했습니다.
Champignac

0

다음 솔루션은 약간 어색하지만 작동하는 것 같습니다.

다음을 ~/.xbindkeysrc포함하십시오 :

"xvkbd -xsendevent -text '\[Control_L]\[F13]'"
  m:0x14 + c:34

"xvkbd -xsendevent -text '\[Control_L]\[F14]'"
  m:0x14 + c:35

이제 xbindkeys변환됩니다 C-[C-<f13>C-]C-<f14>그들이 자유롭게 이맥스에 바인딩 할 수 있습니다. 예를 들어, abort-recursive-edit이외의 다른 것에 바인딩하고 싶을 것입니다 .C-]C-S-g

단점은 이제 C-[Emacs를 제외한 모든 응용 프로그램에서 깨졌으며 키 조합이 emacs로 전송되는지 테스트하는 논리를 추가하여 해결할 수 있습니다 ...


FWIW, 나는 특별한 것이 없다고 생각 C-]합니다.
Malabarba

그래, 나도 아니지만 C-]Xbindkeys를 시작한 후 바인딩이 작동 하지 않는 이상한 이유가 있기 때문에 나도 리바운드했다.
Kristóf Marussy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.