악 : 키 바인딩을 vim 방식으로 매핑 하시겠습니까?


13

나는 악 기능을 만들려고 노력하고 evil-jump-to-tag, C-]이맥스 바인딩처럼 행동 M-..

정상적인 동작은 태그 파일을 검색하기위한 괜찮지 만, 나는 그것이 점액의 위해도 작동하려면 slime-edit-definition, Elisps ' elisp-slime-nav-find-elisp-thing-at-point, Clojures cider-jump-to-var, 등 ...

이 주요 모드들과 그 이상은 키 바인딩에 대한 정의로의 점프와 동등한 것을 결합 시켰습니다 M-..

이블 모드에 대해 동일한 동작을 얻으려면 이러한 모든 모드에 대해 로컬로 키 바인딩을 바인딩해야합니까, 아니면이 키를 누를 때마다 해당 키에 대해 바인딩 된 기능을 사용하도록 키 바인딩을 가져 와서 이맥스에 알릴 수 있습니까? 이맥스 모드?


답변:


10

귀하의 답변 덕분에 지금 작동하고 있습니다.

(defun my-jump-to-tag ()
  (interactive)
  (evil-emacs-state)
  (call-interactively (key-binding (kbd "M-.")))
  (evil-change-to-previous-state (other-buffer))
  (evil-change-to-previous-state (current-buffer)))

(define-key evil-normal-state-map (kbd "C-]") 'my-jump-to-tag)

그러면 악한 상태가 "이맥스"로 설정되고 M-.에 바인딩 된 함수가 호출되고 다른 버퍼에서 이전 이맥스 상태로 다시 변경됩니다. 나는 그것을 elisp, slime and go로 시도했고 그것들 모두를 위해 노력하고 있습니다.


1
내가 사용하는 것은 간단합니다, 완전히 잘 작동하는 것 같다 : (define-key evil-normal-state-map (kbd "C-]") (kbd "\\ M-.")(여기서 "\"에 바인딩 evil-execute-in-emacs-state).
shosti

@ shosti : 예, 적어도 작동해야합니다. 나는 이것을 이렇게 시도했지만 두 번째 \와 M 사이의 공백을 포함하지 않았습니다.
martin

3

같은 것을 시도하십시오

(global-set-key "\C-]" "\M-.")

또는 evil이 키 바인드를 이미 사용중인 경우 다음과 같은 작업이 필요할 수 있습니다.

(define-key evil-mode-map "\C-]" "\M-.")

이것은 완전히의 동작을 재정의합니다 C-]당신이 호출 여부를 결정하는 기능을 가질 수 있기 때문에 타일러의 솔루션이 더 적합 @, 현재 주요 모드에 따라 악마의 동작을 유지하려는 경우, M-.또는 뭔가 esle을한다.

도움이 되나요?


2

evil의 키맵을 이해하지 못하지만 다음 함수는 M-.현재 바인딩 된 모든 것을 수행합니다 .

(defun my-tag-jump ()
    (interactive)
    (call-interactively (key-binding (kbd "M-."))))

이것을 적절한 evil키맵에 바인딩 하면 원하는 것을 할 수 있습니다. evil이를 수행 하는보다 구체적인 방법 이있을 수 있습니다 .

evil바인딩 C-]evil-motion-state-map따라서 다음을 시도 :

(eval-after-load "evil-maps"
    '(define-key evil-motion-state-map "\C-]" 'my-tag-jump))

악마 모드가에 바인딩 M-.되어 있기 때문에 이것이 어떻게 작동하는지 알 수 없습니다 evil-repeat-pop-next. 함수를 다음과 같이 변경하면 : (defun my-tag-jump () (interactive) (evil-emacs-state) (call-interactively (key-binding (kbd "M-.")))) (evil-normal- state))
martin

내가 말했듯이, 나는 사악한 키맵을 모른다. 아마도 더 나은 해결책은 evil-jump-to-tag정의 된 키 맵을 찾아서 내 기능에 리 바인드하는 것입니다.
Tyler

2

일반적으로 불가능합니다.

그 이유는 동일한 바인딩을 정의하는 여러 맵이있을 수 있으며 원하는 맵을 자동으로 파악할 수있는 방법이 없기 때문입니다. (이 예에서는 elisp-slime-nav-mode이러한 사소한 모드입니다). 따라서 실제로 신뢰할 수있는 유일한 방법은 원하는 정의를 정확하게 파악하는 것입니다.

말했듯이 ... 해킹 가능성이 있습니다 (항상 그런 것은 아닙니다 ...) 까다롭게 만드는 부분 중 하나는 다시 매핑하려는 바인딩이 잠재적으로 악의적 인 활성 키 맵에 의해 가려져 현재 바인딩을 얻는 것입니다 M-.쓸모가 없습니다.

(defun lookup-no-evil (key)
  ;; excluding evil maps from the lookup. not sure if 
  ;; anything more than evail-normal-state-map is needed
  (let* ((evil-maps (list evil-normal-state-map))
         (bindings
          (remq nil
                (mapcar
                 (lambda (map)
                   (unless (memq map evil-maps)
                     (lookup-key map key)))
                 (current-active-maps)))))
    (when bindings
      ;; let's assume the first one is the right one. 
      ;; Given that minor modes are at the beginning 
      ;; (although this is *not* documented so should not 
      ;; be relied upon), it might be what we would have 
      ;;without evil-mode indeed
      (car bindings))))

(defmacro evil-remap (from to)
  ;; assuming that we want to put it in the normal-state map.
  ;; not sure about that
  `(define-key evil-normal-state-map ,to
       (lambda ()
         (interactive)
         (call-interactively (lookup-no-evil ,from)))))

(evil-remap (kbd "M-.") (kbd "C-]"))

나는 일반적으로 악을 전혀 사용하지 않으므로 조정이 필요할 수 있습니다 (내장 주석 참조)

또한 키 바인딩을 누를 때마다 동적으로 조회하는 대신 바인딩을 한 번 (예 : 모드 후크에서) 조회하는 것이 더 깔끔한 방법입니다. 그러나 어떤 사악한 후크를 사용 해야하는지 잘 모르겠으므로 연습으로 남겨 둡니다.)


2

@severin이 받아 들인 해결책은 거의 나를 위해 작동하지만 태그를 찾을 수 없으면 버퍼가 일반 모드로 돌아 가지 않습니다. 이 대안은 모든 경우에 저에게 효과적입니다.

(defun my-jump-to-tag ()
    (interactive)
    (evil-execute-in-emacs-state)
    (call-interactively (key-binding (kbd "M-."))))
(define-key evil-normal-state-map (kbd "C-]") 'my-jump-to-tag)

1

가장 깨끗한 방법은

(define-key evil-normal-state-map (kbd "M-.") 'xref-find-definitions)

(또한 관심있는 다른 모든 맵을 추가하십시오)

xref-find-definitionsM-.명령을 사용하여 볼 수 있듯이 emacs에 바인딩 된 함수 C-h k입니다.


1

일부 vim 스타일 키 바인딩 기능.

다음은 전역 맵과 다양한 악한 상태에서 vim 스타일 바인딩을 허용하도록 정의 된 기능과 임의의 키 맵 또는 임의의 바인딩 기능을 취하는 두 가지 일반적인 기능입니다. 이 기능들을 요지 에 넣었습니다 .

(defun kbd+ (keyrep &optional need-vector)
  (if (vectorp keyrep) keyrep (edmacro-parse-keys keyrep need-vector)))

(defun gmap (keyrep defstr)
  "Vim-style global keybinding. Uses the `global-set-key' binding function."
  (global-set-key (kbd+ keyrep) (edmacro-parse-keys defstr t)))

(defun fmap (keybind-fn keyrep defstr)
  "Vim-style keybinding using the key binding function KEYBIND-FN."
  (call keybind-fn (kbd+ keyrep) (edmacro-parse-keys defstr t)))

(defun xmap (keymap keyrep defstr)
  "Vim-style keybinding in KEYMAP. Uses the `define-key' binding function."
  (define-key keymap (kbd+ keyrep) (edmacro-parse-keys defstr t)))

(defun nmap (keyrep defstr) "Vim-style keybinding for `evil-normal-state.' Uses the `define-key' binding function."
      (xmap evil-normal-state-map keyrep defstr))
(defun imap (keyrep defstr) "Vim-style keybinding for `evil-insert-state'. Uses the `define-key' binding function."
      (xmap evil-insert-state-map keyrep defstr))
(defun vmap (keyrep defstr) "Vim-style keybinding for `evil-visual-state'. Uses the `define-key' binding function."
      (xmap evil-visual-state-map keyrep defstr))
(defun mmap (keyrep defstr) "Vim-style keybinding for `evil-motion-state'. Uses the `define-key' binding function."
      (xmap evil-motion-state-map keyrep defstr))

일반적으로 이러한 기능을 키보드-매크로 스타일 바인딩 (문제의 유스 케이스와 같은)에만 사용하고 emacs 스타일 키 바인딩을 다른 모든 것에 사용하는 것이 좋습니다.

노트

  • 패키지 의 bind-key매크로 use-package는 훌륭하고 다양한 키 바인딩 기능입니다.
  • 한 명령을 다른 명령으로 바꾸려면 Emacs의 리매핑 명령을 사용할 수 있습니다 .
  • 일반 키 바인딩에이 기능을 사용하는 경우 "noremap"버전이 없으므로 정의의 바인딩이 변경되면 사용자 정의 바인딩도 변경됩니다.

바인딩 C-]M-..

정상 상태에서, 당신이 바인딩 할 것이라는 점 참고 \M-.정상 상태 바인딩 이후, 바인딩 이맥스에 액세스 할 수 M-.'evil-repeat-pop-next. 따라서 정상 상태 바인딩은 다음과 같이 정의 할 수 있습니다.

(nmap "C-]" "\\ M-.")

또는 ( evil-jump-to-tag정상 상태의 키를 리 바인드 :

(nmap [remap evil-jump-to-tag] "\\ M-.")
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.