아직로드되지 않은 키맵에 키를 바인딩하는 방법은 무엇입니까?


9

내가 사용 use-package및 설치 패키지를 관리하기 위해 bind-key내가 좋아하는 사용자 정의 키에 할당 행동을.

나는 (예를 들어, 기본 이맥스 키 바인딩의 대부분을 무시 C-n된다 M-k, C-p된다 M-i),하지만 난 내 키 바인딩 방식을 재정의 다른 모드로 OK입니다. 그러나 때로는 키 바인딩을 유지하고 싶습니다. M-k기본 Gnus 또는 Helm보다 다른 것을 원합니다 .

그러나 키맵이 존재하지 않으면 키맵에 바인딩을 추가 할 수 없기 때문에 Emacs 시작시 서로 충돌합니다 use-package. 예를 들어 (void-variable helm-map)Helm 및 Gnus가 아직 완전히로드되지 않았으므로 다음 명령에서 오류 (예 :)가 발생합니다.

(bind-key "M-Y" 'helm-end-of-buffer helm-map)
(bind-key "M-k" 'helm-next-line helm-find-files-map)
(bind-key "M-s" 'other-window gnus-summary-mode-map)

use-package한 파일에서 모든 파일을 호출 bind-key하고 다른 파일에서 사용자 정의 키 바인딩을 수행합니다. use-package사용자 지정 키 바인딩 체계를 독립 실행 형 패키지로 게시하고 싶기 때문에 바인딩을 호출 에 넣고 싶지 않습니다 . 내 계획을 설치하는 사람이 Helm 및 Gnus 로컬 키 바인딩도 무시하도록하려면 어떻게해야합니까?

bind-key패키지를 최근에로드하고 모든 키 설정이 하나의 파일 안에있는 경우에도 모든 키가 설정 되도록를 사용하여 모드 로컬 키 바인딩을 관리하는 방법은 무엇입니까?

답변:


20

with-eval-after-load특정 모듈이로드 될 때까지 (키맵을 정의 할 때까지) 키 바인딩을 연기하는 데 사용할 수 있습니다 .

(with-eval-after-load "helm"
  (bind-key "M-Y" #'helm-end-of-buffer helm-map))

C-h v helm-map키맵이 정의 된 모듈을 찾아서 첫 번째 행의 문자열에 넣을 내용을 찾는 데 사용하십시오 .


with-eval-after-loadEmacs 24.4에서 소개되었습니다. 이전 Emacs 버전이있는 경우 eval-after-load대신 사용 하고 bind-key통화 앞에 작은 따옴표를 넣어야합니다 .

(eval-after-load "helm"
  '(bind-key "M-Y" #'helm-end-of-buffer helm-map))

여러 넣고 싶은 경우 bind-key에,이 양식에 전화를 with-eval-after-load당신과 함께 단지 그들에게 차례에 1 점을 추가하는 듯하지만, eval-after-load당신이 그들 모두를 포장해야합니다 progn:

(eval-after-load "helm"
  '(progn
     (bind-key "M-Y" #'helm-end-of-buffer helm-map)
     (bind-key "M-k" #'helm-next-line helm-find-files-map)))

9

해결책

주어진 패키지가로드 된 후 물건을 실행하려면 한 후 그 둘 필요가 :config에서 use-package.

다음은 질문에 스 니펫을 사용하는 예입니다.

스 니펫 # 1

(use-package helm
  :config
  (progn
    (bind-key "M-Y" #'helm-end-of-buffer helm-map)
    (bind-key "M-k" #'helm-next-line helm-find-files-map)))

(use-package gnus
  :config
  (bind-key "M-s" #'other-window gnus-summary-mode-map))

설명

emacs의 다른 위치 init.el또는로드 / 필요한 중첩 파일에 아래 2 개의 스 니펫을 두는 것이 좋습니다.

스 니펫 # 2

(use-package gnus)

스 니펫 # 3

(use-package gnus
  :config
  (bind-key "M-s" #'other-window gnus-summary-mode-map))

그 이유는 위의 두 코드 중 어떤 것이 먼저 실행되는지는 중요하지 않기 때문입니다.

아래는 Snippet # 3이 확장 한 이유입니다.

M-x pp-macroexpand-last-sexp포인트 (커서)가 해당 스 니펫의 마지막 닫는 괄호 뒤에있을 때 수행하여 아래를 얻습니다 .

스 니펫 # 4

(if (not (require 'gnus nil t))
    (ignore (message (format "Could not load %s" 'gnus)))
  (condition-case-unless-debug err
      (bind-key "M-s" #'other-window gnus-summary-mode-map)
    (error
     (ignore
      (display-warning 'use-package
                       (format "%s %s: %s" "gnus" ":config"
                               (error-message-string err))
                       :error))))
  t)

위의 스 니펫은 기본적으로

  • gnus먼저 필요한 다음 bind-key양식이 실행됩니다.
  • 이 없으면 gnus* 메시지 * 버퍼에 해당 패키지를로드 할 수 없다는 메시지가 표시됩니다.
  • 실행에 문제가 있으면 오류가 발생합니다. (bind-key "M-s" #'other-window gnus-summary-mode-map)

또한 위의 Snippet # 2에gnus 이미 필요하고 Snippet # 3에 의해 다시 필요한 require경우 이미로드 된 패키지를 다시로드하지 않기 때문에 중요 하지 않습니다.


참고

github 의 use-package기본 사항 에서

:config패키지가로드 된 후 코드를 실행하는 데 사용할 수 있습니다. 로드가 느리게 수행되는 경우 (아래 자동로드에 대한 자세한 내용 참조)이 실행은 자동로드가 수행 될 때까지 지연됩니다.

스 니펫 # 5

(use-package foo
  :init
  (setq foo-variable t)
  :config
  (foo-mode 1))

위에서 패키지가로드 되기 전에:init 섹션 ( (setq foo-variable t))을 실행합니다 . 그러나 섹션 에서 로드 된 후에 실행 됩니다. foo(foo-mode 1):config foo


3

다른 답변과는 반대로 항상 후크를 사용했습니다.

(defun my-company-maps()
  (define-key company-active-map "\C-x\M-h" 'company-show-doc-buffer)
  (define-key company-active-map "\C-n" 'company-select-next)
  (define-key company-active-map "\C-p" 'company-select-previous)
  (define-key company-active-map "\C-h" 'delete-backward-char))

(add-hook 'company-mode-hook 'my-company-maps)

나도, 이것이 바람직한 방법이라고 생각했다.
의미있는 사용자 이름

2

바인드 키를 이미 사용하고 있으므로 다음과 같은 문서를 참조하십시오 bind-key.el.

키 바인딩이 동일한 키를 바인드 할 수있는 모든 부 모드를 무시하려면`bind-key * '형식을 사용하십시오.

(bind-key* "<C-return>" 'other-window)

키맵 내에서 키를 바인드 해제하려면 (예를 들어, 선호하는 주요 모드가 어디서나 대체하지 않으려는 바인딩을 변경하지 못하게하려면) unbind-key를 사용하십시오.

(unbind-key "C-c x" some-other-mode-map)

파일 정의 some-other-mode-map가 아직로드 되지 않았기 때문에 키맵이 현재 정의되지 않은 경우 마지막 양식이 분류됩니다 . 따라서 이것을 use-packagefor some-other-mode(패키지 정의 some-other-mode-map)에 넣거나 다음을 사용할 수 있습니다 with-eval-after-load.

(with-eval-after-load 'some-other-mode
  (unbind-key "C-c x" some-other-mode-map))

다른 대안은 주요 모드로 재정의해서는 안되는 모든 바인딩을 포함하는 자체 마이너 모드를 정의하는 것입니다.

(defvar my-very-own-keymap (make-keymap) "my very own keymap.")

(define-key my-very-own-keymap (kbd "M-i") 'my-foo)

(define-minor-mode my-very-own-keys-minor-mode
  "Minor mode with my very own keybindings."
  t " my-own-keys" my-very-own-keymap)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.