Зло: прив'язка клавіш до карти vim?


13

Я намагаюся змусити функцію Зла evil-jump-to-tag, C-]вести себе як прив'язка Emacs M-..

Нормальна поведінка чудова для перегляду файлів тегів, але я хочу, щоб вона працювала також для Slime slime-edit-definition, Elisps ' elisp-slime-nav-find-elisp-thing-at-point, Clojures cider-jump-to-varтощо ...

Ці основні режими та багато іншого прив’язали деякий еквівалент переходу до визначення кнопок M-..

Щоб отримати таку саму поведінку в Evil-режимі, чи потрібно мені прив'язувати клавішну зв'язок локально для кожного з цих режимів, чи можливо взяти прив'язку клавіш і сказати Emacs, що кожного разу, коли цю клавішу натискати, використовувати функцію, пов'язану для цієї клавіші в режимі Emacs?


Пов'язані (більш прямий підхід, подібний до vim): emacs.stackexchange.com/q/12287/8283
idbrii

Відповіді:


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)

Це встановить злий стан на "Emacs", викличе функцію, пов'язану з M-., І повернеться до попереднього стану emacs в іншому буфері. Я спробував це з Elisp, слизом і іти, і це працює для всіх.


1
Те, що я використовую, простіше, і, здається, працює зовсім чудово: (define-key evil-normal-state-map (kbd "C-]") (kbd "\\ M-.")(де "\" прив’язане evil-execute-in-emacs-state).
шості

@shosti: Так, це має працювати принаймні так само. Я спробував це так, але не включав пробіл між другим \ та М.
март

3

Спробуйте щось на кшталт

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

або, якщо він evilвже використовує цю в'язку клавіш, вам може знадобитися щось подібне.

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

Це повністю скасує поведінку C-], якщо ви хочете утримати поведінку зла залежно від поточного мажоритарного режиму, рішення @ Тайлера є більш доречним, оскільки ви можете мати функцію, яка вирішує, чи потрібно дзвонити M-.чи робити щось вразливе.

Чи допомагає це?


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 () (інтерактивна) (evil-emacs-state) (call-interactively (key -inding (kbd "M-."))) (Evil-normal- держава))
мартін

Як я вже говорив, я не знаю злих клавішних файлів. Можливо, кращим рішенням є пошук ключової карти там, де evil-jump-to-tagвизначено, і відновлення її до моєї функції там.
Тайлер

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-definitionsце функція, прив'язана до M-.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))

Взагалі, краще використовувати ці функції лише для прив’язки клавіатури до макро-стилю (як-от у випадку використання запитання), а також для використання в інших стилях клавіатури.

примітки

  • bind-keyМакрос з use-packageпакета є відмінним і універсальним ключем функції зв'язування.
  • Якщо ви хочете замінити одну команду на іншу, ви можете використовувати команди перестановки Emacs .
  • Якщо ви використовуєте їх для звичайних прив'язок ключів, майте на увазі, що версій "noremap" немає, тож якщо прив'язки у вашому визначенні змінюються, так і ваші визначені користувачем прив'язки.

Прив’язування C-]до M-..

Зверніть увагу , що в нормальному стані, ви хочете прив'язати до \M-.доступу до Emacs зв'язування, так як нормальний стан прив'язок M-.до 'evil-repeat-pop-next. Отже, зв'язування нормального стану можна визначити за допомогою:

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

або (перезавантаження будь-якої evil-jump-to-tagклавіші у звичайному стані:

(nmap [remap evil-jump-to-tag] "\\ M-.")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.