Найкраща практика злого режиму? [зачинено]


104

Я використовую Vim як головний редактор протягом багатьох років і кілька разів пробував Emacs протягом цього часу. Тоді я виявив Зло і вирішив, що він досить добре відповідає моїй вимозі швидкого руху, щоб я нарешті міг перейти до Emacs.

Отже, всім користувачам Evil, як ви інтегруєте його у звичайні функції Emacs? Чи стикалися ви з будь-якими конфліктами між цим режимом та іншими? Який ваш гідний досвід / поради з цієї теми?

Відповіді:


71

Я використовував сильно налаштований vim, а тепер використовую ще більш спеціалізовані emacs. Я думаю, що ви знайдете кожен екземпляр введення файлів у моєму конфігураційному файлі https://github.com/mbriggs/.emacs.d-oldv2/blob/master/init/init-keymaps.el

Майте на увазі, я повторюю те, що справжні користувачі Emacs вважають єресь, тому YMMV, якщо ви хочете навчитися навчитися "справжнім" emacs (я насправді цього не роблю).

Одне, що я б рекомендував будь-якому колишньому вімер, це

;;; esc quits
(defun minibuffer-keyboard-quit ()
  "Abort recursive edit.
In Delete Selection mode, if the mark is active, just deactivate it;
then it takes a second \\[keyboard-quit] to abort the minibuffer."
  (interactive)
  (if (and delete-selection-mode transient-mark-mode mark-active)
      (setq deactivate-mark  t)
    (when (get-buffer "*Completions*") (delete-windows-on "*Completions*"))
    (abort-recursive-edit)))
(define-key evil-normal-state-map [escape] 'keyboard-quit)
(define-key evil-visual-state-map [escape] 'keyboard-quit)
(define-key minibuffer-local-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-ns-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-completion-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-must-match-map [escape] 'minibuffer-keyboard-quit)
(define-key minibuffer-local-isearch-map [escape] 'minibuffer-keyboard-quit)

так що esc насправді закриває майже все (наприклад, очікування підказки у minibuffer)


7
Визначення minibuffer- key
Адам Белл

1
@Adam вибачте з цього приводу>.> У мене встановлено багато речей, іноді я використовую функцію, яку, на мою думку, вбудовано, але насправді приходить десь з іншого
Метт Бріггс,

3
Я вважаю, що це не працює для мене. Я використовую останній Emacs 24.4, хтось відчуває те саме?
Дзунг Нгуен

1
Посилання розірвано. Я вважаю, що це нове: github.com/mbriggs/.emacs.d/blob/master/config/keybinds.el
Шон Шкіра

1
@SeanLeather Оновлена ​​відповідь на робоче посилання.
Крістофер Дно

34

Оскільки хтось, хто прийшов від emacs, спробував vim і зрозумів, що можна отримати багато речей, я багато експериментував, коли вперше почав використовувати зло. Хоча наступне є суперечливим, я хотів зберегти ключі emacs, які більш універсально використовуються в терміналах, firefox, какао тощо ..., але не хотів втрачати можливості редагування vim. Я вирішив відновити наступні ключі у своїх .emacs:

(define-key evil-normal-state-map "\C-e" 'evil-end-of-line)
(define-key evil-insert-state-map "\C-e" 'end-of-line)
(define-key evil-visual-state-map "\C-e" 'evil-end-of-line)
(define-key evil-motion-state-map "\C-e" 'evil-end-of-line)
(define-key evil-normal-state-map "\C-f" 'evil-forward-char)
(define-key evil-insert-state-map "\C-f" 'evil-forward-char)
(define-key evil-insert-state-map "\C-f" 'evil-forward-char)
(define-key evil-normal-state-map "\C-b" 'evil-backward-char)
(define-key evil-insert-state-map "\C-b" 'evil-backward-char)
(define-key evil-visual-state-map "\C-b" 'evil-backward-char)
(define-key evil-normal-state-map "\C-d" 'evil-delete-char)
(define-key evil-insert-state-map "\C-d" 'evil-delete-char)
(define-key evil-visual-state-map "\C-d" 'evil-delete-char)
(define-key evil-normal-state-map "\C-n" 'evil-next-line)
(define-key evil-insert-state-map "\C-n" 'evil-next-line)
(define-key evil-visual-state-map "\C-n" 'evil-next-line)
(define-key evil-normal-state-map "\C-p" 'evil-previous-line)
(define-key evil-insert-state-map "\C-p" 'evil-previous-line)
(define-key evil-visual-state-map "\C-p" 'evil-previous-line)
(define-key evil-normal-state-map "\C-w" 'evil-delete)
(define-key evil-insert-state-map "\C-w" 'evil-delete)
(define-key evil-visual-state-map "\C-w" 'evil-delete)
(define-key evil-normal-state-map "\C-y" 'yank)
(define-key evil-insert-state-map "\C-y" 'yank)
(define-key evil-visual-state-map "\C-y" 'yank)
(define-key evil-normal-state-map "\C-k" 'kill-line)
(define-key evil-insert-state-map "\C-k" 'kill-line)
(define-key evil-visual-state-map "\C-k" 'kill-line)
(define-key evil-normal-state-map "Q" 'call-last-kbd-macro)
(define-key evil-visual-state-map "Q" 'call-last-kbd-macro)
(define-key evil-normal-state-map (kbd "TAB") 'evil-undefine)

(defun evil-undefine ()
 (interactive)
 (let (evil-mode-map-alist)
   (call-interactively (key-binding (this-command-keys)))))

На жаль, ці операції перетинаються з операцією vim "переміщення на один екран вгору або вниз". Однак мені стало зручніше використовувати таке:

(define-key evil-normal-state-map (kbd "DEL") (lambda ()
                    (interactive)
                    (previous-line 10)
                    (evil-scroll-line-up 10)
                    ))

(define-key evil-normal-state-map (kbd "=") (lambda ()
                      (interactive)
                      (next-line 10)
                      (evil-scroll-line-down 10)
                      ))

Крім того, якщо ви переходите з vim і хочете швидкий шлях від вставки до звичайного режиму, використовуючи "jk" (або будь-яку іншу двотактну комбінацію), найкращий спосіб - скопіювати текст з http://www.emacswiki.org/ emacs / скачати / key-chord.el та вставити його у ~ / .emacs.d / key-chord.el. Потім додайте до своїх .emacs:

;load a file named key-chord.el from some directory in the load-path (e.g. "~/.emacs.d")
(require 'key-chord)
(key-chord-mode 1)
(key-chord-define-global "jk" 'evil-normal-state)

Крім того, якщо ви приїжджаєте з vim і вважаєте, що копіювання в буфер обміну в emacs не є корисним, ви, мабуть, праві. Однак ви можете скористатися наступним корисним після запуску sudo apt-get install xsel:

(defun copy-to-clipboard ()
  (interactive)
  (if (display-graphic-p)
      (progn
        (message "Yanked region to x-clipboard!")
        (call-interactively 'clipboard-kill-ring-save)
        )
    (if (region-active-p)
        (progn
          (shell-command-on-region (region-beginning) (region-end) "xsel -i -b")
          (message "Yanked region to clipboard!")
          (deactivate-mark))
      (message "No region active; can't yank to clipboard!")))
  )

(evil-define-command paste-from-clipboard()
  (if (display-graphic-p)
      (progn
        (clipboard-yank)
        (message "graphics active")
        )
    (insert (shell-command-to-string "xsel -o -b"))
    )
  )

(global-set-key [f8] 'copy-to-clipboard)
(global-set-key [f9] 'paste-from-clipboard)

Очевидно, вам доведеться вирішити для себе, чи вартує будь-яка з цих суперечливих змін, але, можливо, ці основні зміни вас надихнуть.

Для деяких інших дійсно цікавих реалізацій функцій, таких як видалення та вставка, видалення без копіювання до буфера обміну, ефективний рух 4x / 16x, використання відліків для специфікації реєстру пасти, налаштування вкладки, які фактично працюють для c / c ++ та багато іншого, ви можете перевірити викладіть повний .emacs, init.el, my-keymaps.el і my -fun.el версони на моєму git за адресою https://github.com/Russell91/emacs


2
все це чудово, я додав у wikemacs: wikemacs.org/index.php/Evil#Configuration
Ehvince

Я розумію вашу волю до повторного використання ваших звичок від emacs. Для роботи в Firefox я настійно рекомендую спробувати Vimperator addon, який приносить багато функцій vim, подібних до вашого перегляду. Однак він використовує команди руху vim за замовчуванням (як це стосується lessкоманд та інших).
Ян Вльчинський

Так само, як і вам, мені не подобається прив'язка зла в режимі вставки-стану, тому я просто перев’язую "i" у мапі нормальної держави на "злий-emacs-стан.
користувач49117

Замість того, щоб замінити клавіатуру evil, я видаляю її, тому вона повертається до налаштувань клавіатури звичайних emacs, наприклад(dolist (m (list evil-normal-state-map evil-motion-state-map evil-insert-state-map)) (define-key m "\C-e" 'nil))
Bach Lien

30

Я також був користувачем Viper / Vimpulse з величезною кількістю конфігурації. Тоді я знайшов Evil-mode.

Який ваш гідний досвід / поради з цієї теми?

Це вся моя конфігурація злого режиму, і вона чудово працює для мене:

(require 'evil)
(evil-mode 1)

;; Remap org-mode meta keys for convenience
(mapcar (lambda (state)
    (evil-declare-key state org-mode-map
      (kbd "M-l") 'org-metaright
      (kbd "M-h") 'org-metaleft
      (kbd "M-k") 'org-metaup
      (kbd "M-j") 'org-metadown
      (kbd "M-L") 'org-shiftmetaright
      (kbd "M-H") 'org-shiftmetaleft
      (kbd "M-K") 'org-shiftmetaup
      (kbd "M-J") 'org-shiftmetadown))
  '(normal insert))

Чи стикалися ви з будь-якими конфліктами між цим режимом та іншими?

Ні, на відміну від Viper / Vimpulse, який спричиняв проблеми в декількох режимах.


Я отримую цю помилку: progn: Значення символу як змінної - недійсне: стан Де визначено стан?
justingordon

Можна спробуватиevil-emacs-state
Кенні Мейєр

2
Чи можете ви уточнити, де ви це поклали?
justingordon

1
Це фантастично, я шукав саме це. Оновлення неохайно!
jplindstrom

1
Подивіться на цей github.com/edwtjo/evil-org-mode
avendael

17

Я почав використовувати Evil місяць тому; перед цим я намагався використовувати viper / vimpulse без особливого успіху. Якщо чесно, vimpulse - це дуже приємно, але використовувати його в різних режимах було дещо клопітно (наприклад, режим компіляції, коли vimpulse завжди божевільний) залишаючи emacs в якомусь режимі між vi-emacs-то.

Коли я перейшов на Зло, я нарешті почав досліджувати повну силу Emacs, і повірте, я не пошкодував. Зло прекрасно працює у всіх режимах, які я використовував (в основному редагування, компіляція, подряпини та графіки) і навіть читання інформації / людини / довідки працює без проблем.

Крім того, я виявив лише перемикання буфера непарним, як я це робив: замість цього: b <0-9>: b-TAB-then-complete-name або: bn. Зауважте, однак, що розробники Evil намагаються (в деяких випадках) знижувати функціонал, що повторюється, натомість:! (для виконання команди оболонки), ви повинні використовувати рідний M- !.

Якщо у вас з’являється заклик додати / переосмислити деякі власні колишні команди, просто відкрийте зла-maps.el і відредагуйте його (спробуйте це in vim!).

Зло ще молодий, але перспективний проект, і я чекаю дня, коли замінить гадюку в офіційній дистрибуції Emacs.


4
Чи повинно це означати, що додавати / перевизначати команди у vim неможливо?
Джон Тайрі

1
Команди, визначені користувачем @JohnTyree, потрібно починати з великої літери у Vim, тоді як усі вбудовані команди починаються з малої літери.
Остін Тейлор

10

Мені подобається зберігати буфер, коли я виходжу з insert-mode: (відредаговано: не просити зберегти, коли для цього буфера немає асоційованого файлу, як, наприклад, у подряпині чи магнітному буфері)

(defun my-save ()
  (if (buffer-file-name)
    (evil-save))
)

   (add-hook 'evil-insert-state-exit-hook 'my-save)

Для отримання додаткових можливостей див. http://wikemacs.org/index.php/Evil

Коментарі вітаємо покращення!


Дякую. До речі, ваше посилання розірвано.
Амос

Спасибі теж. Вікімейки повернуться. Сайт знаходиться в обслуговуванні, сподіваємось, знову не надто довго.
Переконати

9
  1. Я використовую злого вождя і використовую ", xm" для заміни "Mx", тому я рідко натискаю клавішу Alt. Є також general.el, який підтримує кілька ключів лідера.

  2. зло-сірник , натисніть "%" для переходу між парою тегів.

  3. злий-ботанік-коментатор , натисніть "9, ci", щоб коментувати / коментувати 9 рядків

  4. уникати використання ключа ESC, ви можете натиснути "kj" замість цього.

  5. Майте віру у вільне програмне забезпечення! Нічого неможливого зі Злом, яке поєднує силу Віма та Емака. Наприклад, багато людей припускають, що злісні зв'язки клавіш конфліктують з існуючими плагінами Emacs без важкого повторного прив'язки. Це насправді неправильно


0

Поступаючи з боку emacs, я дуже віддаю перевагу M-. має бути визначеним, але функція, яка працює на, M-.відрізняється в різних режимах. Я міг би перекрити його звичайним чином, (define-key evil-normal-state-map (kbd "M-.") 'foo)коли fooперевіряє поточний основний режим і виконує відповідну функцію, але це звучить так, як це вимагає багато жорсткого кодування. Більш загальне рішення таке:

(defun evil-emacs-key-binding (key)
  (evil-execute-in-emacs-state)
  (key-binding key))

(defmacro evil-revert-key-binding (state-map key)
  `(define-key ,state-map ,key (lambda ()
                                 (interactive)
                                 (call-interactively
                                  (evil-emacs-key-binding ,key)))))

(eval-after-load "evil-autoloads"
  '(add-hook 'evil-after-load-hook
        (lambda ()
          (evil-revert-key-binding evil-normal-state-map (kbd "M-."))
          ;; and so on
        )))

Крім цього, мені подобаються плагіни зловмисного оточення (хоча я відчуваю, що смарт-одяг є більш повним рішенням) і злісний лідер .

Я використовував клавіш-акорд, щоб зіставити jk на ESC, як я навчився робити у vim, але він наполягав на тому, щоб kj ставився до jk як до jk, тому замість цього я використовую наступне:

(defun evil-escape-if-next-char (trigger)
  "Watches the next letter. If `trigger', then switch to normal mode,
otherwise keep the previously inserted key and forward unpressed
key to `unread-command-events'."
  (self-insert-command 1)
  (let ((next-key (read-event)))
    (if (eq trigger next-key)
        (progn
          (delete-char -1)
          (evil-normal-state))
      (setq unread-command-events (cons next-key unread-command-events)))))

(defun evil-escape-if-next-char-is-k (arg)
  (interactive "p")
  (if (= arg 1)
      (evil-escape-if-next-char ?k)
    (self-insert-command arg)))

(eval-after-load "evil-autoloads"
  '(add-hook 'evil-after-load-hook
             (lambda ()
               ;; … other stuff …
               (define-key evil-insert-state-map (kbd "j") 'evil-escape-if-next-char-is-k))))

я використовую (setq evil-move-cursor-back nil) що не дуже vimmy (хоча ви, мабуть, ви можете змусити ваш vimrc зробити це також), я просто ніколи не звик до переміщення курсору назад після виходу з вставки.

Практична порада: використовуйте evil-local-mode-hookдля таких речей, як ледачий завантаження злого-об'ємного режиму, це не допоможе поставити його в звичайний спосіб evil-mode-hook. Отже, якщо ви встановлюєте злі та злісні об'ємні програми при встановленні пакунків, ви можете розпочати це, коли будете M-x evil-modeробити

(eval-after-load "evil-surround-autoloads"
  '(add-hook 'evil-local-mode-hook #'evil-surround-mode))

(Звичайно, якщо ви завжди працюєте в злому режимі і завжди встановлено зло, немає необхідності в цьому автозавантаженні, але я вважаю за краще мати. встановлені пакети elpa.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.