Emacs에서 전체적으로 키 바인딩 무시


100

전역 적으로 재정의하고 해당 키에 대한 다른 모든 바인딩보다 우선하는 키 바인딩을 어떻게 설정할 수 있습니까? 모든 주 / 부 모드 맵을 재정의하고 내 바인딩이 항상 적용되는지 확인하고 싶습니다.

물론 이것은 작동하지 않습니다.

(global-set-key "\C-i" 'some-function)

그것은 작동 text-mode하지만 내가 사용할 때 lisp-mode, C-i반동 lisp-indent-line입니다.

이 바인딩을 통해 lisp-mode다른 모든 모드에서 개별적으로 재정의 할 수 있지만 더 쉬운 방법이 있어야합니다. 새 파일 형식에 대한 새 모드를 설치할 때마다 돌아가서 모든 키 바인딩이 새 모드로 재정의되지 않는지 확인해야합니다.

저는 이미 다른 편집자들로부터 배웠고 뿌리 내린 바인딩을 에뮬레이트하고 싶기 때문에 이것을하고 싶습니다.

답변:


149

모든 "재정의"키 바인딩에 대해 부 모드를 사용합니다.

(defvar my-keys-minor-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map (kbd "C-i") 'some-function)
    map)
  "my-keys-minor-mode keymap.")

(define-minor-mode my-keys-minor-mode
  "A minor mode so that my key settings override annoying major modes."
  :init-value t
  :lighter " my-keys")

(my-keys-minor-mode 1)

다른 사람이 키보드를 운전하거나 기본 키 바인딩이 수행하는 작업을 확인해야하는 경우 한 번에 모든 수정 사항을 해제 할 수 있다는 추가 이점이 있습니다 (부 모드를 비활성화하기 만하면됩니다).

미니 버퍼에서이 기능을 꺼야 할 수도 있습니다.

(defun my-minibuffer-setup-hook ()
  (my-keys-minor-mode 0))

(add-hook 'minibuffer-setup-hook 'my-minibuffer-setup-hook)

1
이것은 좋은 생각 인 것 같습니다. 마이너 모드가 다른 마이너 모드와 싸우지 않도록 할 수있는 방법이 있습니까?
Brian Carper

3
귀하의 부 모드가 minor-mode-map-alist 목록에서 첫 번째인지 확인하십시오.
Trey Jackson

2
트레이 말이 맞아. 일반적으로 이것을 .emacs의 끝에 두는 것으로 충분합니다. 또한 재정의 할 대부분의 바인딩은 주 모드가 설정하는 바인딩입니다. 일반적으로 부 모드는 방해가되지 않습니다.
scottfrazer

이 접근 방식을 따랐지만 Ci에 바인딩하는 모든 것이 TAB 키에도 바인딩된다는 것을 깨달았습니다. 어떤 제안?
Steve

3
Brian Carper : 이후에로드되는 마이너 모드를 처리하기위한 개선 사항은 다음과 같습니다. stackoverflow.com/questions/683425/…
phils

30

scottfrazer의 답변에 추가로 다음을 작성하여 이후에로드 된 라이브러리가 자체의 새 키맵을 가져 오더라도 키 바인딩이 우선 순위를 유지하도록 다음을 작성했습니다.

키맵은 컴파일 시간에 생성 될 수 있기 때문에 load이를 수행하는 가장 좋은 장소 인 것 같습니다.

(add-hook 'after-load-functions 'my-keys-have-priority)

(defun my-keys-have-priority (_file)
  "Try to ensure that my keybindings retain priority over other minor modes.

Called via the `after-load-functions' special hook."
  (unless (eq (caar minor-mode-map-alist) 'my-keys-minor-mode)
    (let ((mykeys (assq 'my-keys-minor-mode minor-mode-map-alist)))
      (assq-delete-all 'my-keys-minor-mode minor-mode-map-alist)
      (add-to-list 'minor-mode-map-alist mykeys))))

스크립트를 붙여 넣었지만 아무런 영향을주지 않았습니다. (
alper

@alper 실제로 사용중인 코드와 문제를 재현하기위한 특정 예제 / 레시피를 포함하여 모든 관련 세부 정보가 포함 된 질문을 게시하는 것이 좋습니다.
phils dec

21

use-package, eval을 설치 하면 완료됩니다.

(require 'bind-key)
(bind-key* "C-i" 'some-function)

5
use-package는 bind-key에 종속되지만 사용 사례에는 bind-key 만 설치하면 충분합니다.
xuchunyang

2
이 ( 'bind-key'패키지)가 가장 편리한 솔루션 인 것 같습니다. 공유해 주셔서 감사합니다.
올리길로

일치하는 항목을 찾을 수 없습니다. use-package .Install package: use-package [No Match]
alper

14

"emacs undefine org mode keybindings"를 검색하는 동안이 질문을 발견했습니다. 기존 Cc Cb 동작의 바인딩을 해제하여 내 글로벌 맵이 조직 버퍼에서 작동하도록 버퍼를 묻히고 싶었 기 때문입니다.

이것은 저에게 가장 간단한 해결책이되었습니다.

(add-hook 'org-mode-hook
      (lambda ()
        (local-unset-key (kbd "C-c C-b"))))

1
이것은 모드에 따라 다르며 단일 사용 사례에서 작동하더라도 더 큰 그림을 다루지 않습니다.
RichieHH

12

scottfrazer의 대답이 정확히 당신이 요청한 것이지만, 나는 후손에 대해 또 다른 해결책을 언급 할 것입니다.

에서 매뉴얼 이맥스 :

"Lisp 프로그램에서 Cc 문자를 키로 정의하지 마십시오. Cc와 문자 (대문자 또는 소문자)로 구성된 시퀀스는 사용자 용으로 예약되어 있으므로 사용자를 위해 예약 된 유일한 시퀀스이므로 차단하지 마십시오."

개인 전역 바인딩을 Cc와 문자에 바인딩하면 "안전해야"합니다. 그러나 이것은 단지 관례 일 뿐이며 모든 모드는 여전히 바인딩을 재정의 할 수 있습니다.


3
모든 모드의 조직 모드가이 규칙을 위반할 것이라고는 예상하지 못했습니다. 'Cc Ch'는 Cc a, b, c 및 l이 각각 org-agenda, org-iswitchb, org-capture 및 org-store-link에 바인딩되어 있음을 알려줍니다.
Nate Parsons

7
Afaik, 바인딩은 조직 모드에서 사용하기 위해 제안하는 첫 번째 단계이지만 사용자가 직접 정의해야하며 (즉, 기본적으로 수행되지 않음) 그렇게하는 동안 다른 것을 선택할 수 있습니다. (또한, 이러한 바인딩 글로벌 있어야되기 때문에 조직의 주요 모드에 바인딩이 아니다)
Nikana Reklawyks

3

"특정 모드 맵에 대해 명시 적으로 재정의하지 않는 한 항상 맵에서 키 바인드를 사용"하고 scottfrazier의 접근 방식을 사용한다고 가정 하고 싶다면 다음을 수행하십시오.

(defun locally-override (key cmd)
  (unless (local-variable-p 'my-keys-minor-mode-map)
    (set (make-variable-buffer-local 'my-keys-minor-mode-map)
         (make-sparse-keymap))
    (set-keymap-parent my-keys-minor-mode-map 
                       (default-value 'my-keys-minor-mode-map)))
  (define-key my-keys-minor-mode-map key cmd))

그래서

(locally-override "\C-i" nil)

현재 버퍼의 부 모드에서만 "\ Ci"바인딩을 제거해야합니다. 경고 : 이것은 완전히 테스트되지 않았지만 올바른 접근 방식으로 보입니다. my-keys-minor-mode-map의 전역 값을 처리하는 것이 아니라 부모를 설정하는 요점은 이후 전역 값에 대한 변경 사항이 자동으로 로컬 값에 반영된다는 것입니다.


2

나는 당신이 할 수 있다고 생각하지 않습니다. 이는 함수에서 지역 변수 선언으로 숨길 수없는 전역 변수를 정의하고 싶다고 말하는 것과 거의 동일합니다. 범위는 그렇게 작동하지 않습니다.

그러나 모드 목록을 살펴보고 모든 항목에 다시 할당하는 elisp 함수를 작성하는 방법이있을 수 있습니다.


이 범위 지정 개념은 기술적으로 정확하지만 overriding-local-map다른 모든 맵을 재정의하도록 특별히 설계되었습니다. 그러나 그것을 사용하는 것은 위험합니다.
event_jr 2014

2

이 작업을 직접 수행하고 싶지 않다면 주변을 확인하고 다른 사람이 이미 수행했는지 확인해야합니다.

윈도우와 같은 키 바인딩을 제공하는 Emacs 용 패키지가 있습니다. Google을 통해 찾을 수 있어야합니다.


4
당신이 생각하고있는 패키지는 아마도 cua-mode.
Drew

1
네, 패키지입니다.
JesperE 2013-08-25
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.