2012-02-04 2 views
2

isearch-mode (이후 대화 형 검색 및 바꾸기 도구 일종의, 나는 좋은 출발점이 될 것 같아서) 이후에 그것을 흉내 내 마이너 모드를 정의하려고합니다. 내 명령 (글로벌 키 바인딩에서 테스트) 잘 작동하지만 일부 키 (즉, TAB 및 RET) 로컬로 (마이너 모드 맵에서 바인딩) 심각한 문제가 있습니다. 나는 이런 식으로 뭔가를하고 있어요 :Emacs 부 모드에서 TAB 및 RET을 리바 인하는 방법은 무엇입니까?

(defvar my-mode-map 
    (let ((map (make-sparse-keymap))) 
    (define-key map "\s" 'my-command) 
    (define-key map "\t" 'another-one) 
    (define-key map "\r" 'yet-another) 
    map)) 

(. 물론, 내가 사소한 모드 -지도 - alist에 내 키 맵을 넣어했다)

을 공간 바인딩 명령은 잘 작동하는 동안, TAB을 그리고 RET 어떻게 든하지 않습니다. "\ t"에서 "[f11]"과 같이 변경하면 정상적으로 작동합니다. 나는 "벡터 표기법"([? \ t])을 사용하여 동일한 결과를 보았습니다. (C-h C-v-ing 이후에는 키맵이 놀랍지 않았습니다.) 무슨 일이 일어날까요?

편집 : 문제를 명확히하기 위해 나는 그것을 격리하려고 시도했으며 다음 코드를 생각해 냈습니다. Tab 키가 느낌표를 삽입하는 인위적인, 오히려 최소한의 부 모드 tabbang을 가지고 있다고 가정하십시오. 나는이 일을 해요 :

(defvar tabbang-mode) 
(add-to-list 'minor-mode-alist '(tabbang-mode tabbang-mode) t) 

(defvar tabbang-mode-map 
    (let ((map (make-sparse-keymap))) 
    (define-key map [?\t] 'tabbang-insert-bang) 
    (define-key map [?\C-\t] 'tabbang-insert-bang) 
    (define-key map [f11] 'tabbang-insert-bang) 
    (define-key map [?\r] 'tabbang-done) 
    (define-key map [t] 'tabbang-other-char) 
    map)) 
(add-to-list 'minor-mode-map-alist `(tabbang-mode . ,tabbang-mode-map) t) 

(defun tabbang-insert-bang() 
    (interactive) 
    (insert "!")) 

(defun tabbang-mode() 
    (interactive) 
    (setq tabbang-mode " tabbang")) 

(defun tabbang-other-char() 
    (interactive) 
    (tabbang-done) 
    (setq unread-command-events 
    (append (listify-key-sequence (this-command-keys)) 
     unread-command-events))) 

(defun tabbang-done() 
    (interactive) 
    (setq tabbang-mode nil)) 

나의 tabbang-mode, "기타"키가 제대로 모드를 종료하고 자신을 삽입, F11 쾅 (올바른), 탭 (올바른) 모드를 종료하지 않고 삽입을 삽입에있는 동안 아무것도 (틀린), C-TAB는 "정의되지 않은 키"오류 (틀린 틀림)를 내고, RET은 모드를 빠져 나옵니다 (올바른), 줄 바꿈 (틀린)을 삽입합니다. 그리고 나는 "신선한"이맥스 (사이트 파일과 내 .emacs를로드하지 않고)를 시도했기 때문에 다른 코드가 개입하지 않아야했다. (어쨌든 TAB 등을 캡쳐하는 야닛을 두려워했다.) 무슨 일이 벌어지고 있는가?

답변

5

"\ t"및 "\ r"대신 (kbd "<tab>")(kbd "<return>")으로 변경할 수 있습니다. 네, 완벽하게 다음 작품은 나를 위해 당신의 편집에 대응


:

... 
(defvar tabbang-mode-map 
    (let ((map (make-sparse-keymap))) 
    (define-key map (kbd "<tab>") 'tabbang-insert-bang) 
    (define-key map (kbd "<C-tab>") 'tabbang-insert-bang) 
    (define-key map (kbd "<f11>") 'tabbang-insert-bang) 
    (define-key map (kbd "<return>") 'tabbang-done) 
    (define-key map (kbd "t") 'tabbang-other-char) 
    map)) 
(add-to-list 'minor-mode-map-alist `(tabbang-mode . ,tabbang-mode-map) t) 
... 
+0

올바르지 않습니다. 나는 당신이'(kbd ")'과'(kbd")'을 의미한다고 생각합니다. – tripleee

+0

. 그것과는 별도로 - 나는 C-TAB을 묶고 싶지 않다. 나는 TAB을 원한다. (그리고 나는 C-TAB에 문제가있다. 잠시 후에 나는 그것을 반영하기 위해 질문을 편집 할 것이다.) – mbork

+0

와우들. 그래, 나는 실수로'C'를 추가했다. 결정된. – Inaimathi

0

"탭"(즉, 당신이 "\t"로 얻을이) 유효한에 해당하지 않는 문자열 키 이름. 탭의 경우 "\C-i", 개행의 경우 "\C-j"과 같은 것이 필요합니다.

+0

잘 모르겠습니다. '[? \ t]'로 시도한 결과 두 구문 모두 키맵에서'(9. my-command)'와 같은 결과를 얻었으므로이 부분을 올바르게 수행했다고 가정합니다. 어쨌든,''\ C-i "'를 사용하면 어쨌든 키맵에서 같은 항목을 얻을 수 있습니다 (작동하지 않습니다). – mbork

3

문제는 다음과 같습니다. 일부 키는 function-key-map을 통해 번역됩니다.이 키는 그렇지 않은 경우 키가 언 바운드 될 때만 번역을 수행합니다. 예 : [Tab]에 대한 바인딩이 없으면 Tab 키를 누를 때 GUI에서 생성 된 [tab] 이벤트가 [? \ t]로 변환됩니다. [return]도 [? \ r]에 매핑됩니다. 이제 문제는 catchall [t] 바인딩은 모든 키 시퀀스에 바인딩이 있음을 의미하므로 [tab]은 더 이상 [? \ t]에 다시 매핑되지 않습니다. isearch는 isearch-other-meta-char에서하는 것과 같은 문제를 겪고 있습니다.

이 문제에 대한 올바른 접근 방식은 [t] 바인딩을 피하고 대신 다른 방식으로 "다른 키의 종료 모드"를 구현하는 것입니다. 요즘의 내 규칙은 다음과 같습니다. 읽지 않은 명령 이벤트로 되돌아가는 경우, 아마 잘못했을 수도 있습니다. "). 이를 수행하는 한 가지 방법은 'this-command'가 자신의 것인지 아닌지 또는 (this-command-keys-vector)가 키맵에 묶여 있는지 여부를 검사하는 pre-command-hook을 사용하는 것입니다.Emacs-24에서는 다음과 같은 코드를 사용합니다.

(defun set-temporary-overlay-map (map &optional keep-pred) 
    (let* ((clearfunsym (make-symbol "clear-temporary-overlay-map")) 
     (overlaysym (make-symbol "t")) 
     (alist (list (cons overlaysym map))) 
     (clearfun 
      `(lambda() 
      (unless ,(cond ((null keep-pred) nil) 
          ((eq t keep-pred) 
          `(eq this-command 
            (lookup-key ',map 
               (this-command-keys-vector)))) 
          (t `(funcall ',keep-pred))) 
       (remove-hook 'pre-command-hook ',clearfunsym) 
       (setq emulation-mode-map-alists 
        (delq ',alist emulation-mode-map-alists)))))) 
    (set overlaysym overlaysym) 
    (fset clearfunsym clearfun) 
    (add-hook 'pre-command-hook clearfunsym) 
    (push alist emulation-mode-map-alists))) 
+0

왜 overlaysym을 overlaysym으로 설정합니까? – nymo

+0

임시 맵이 활성화되도록 심볼의 값을 설정해야한다는 것을 알았습니다. – nymo

관련 문제