EmacsメインのEvil設定
Evil導入の目的
EmacsでLispを閲覧しているときにうっかりミスでソースを書き換えてしまって動かなくなったりするので、Vimで修正したりということがよくある。 新しいパッケージや設定を試したりするときにも同様なことが起きるので、そんなときにもVimの出番となる。
そこで、Emacsを使いながらVimの操作を覚えるためにEvil導入は良策だと考えるに至った。Evil導入を試すにあたり、数少ないTipsを調べてみた。
Evilバイブルである @taraoさん のTipsからは多くのことを教えられた。けれど私が作りたいのは、「EmacsをVimのごとく使う」という環境ではない。
徹底してEmacsのVim化を図ることにそれほど価値があるとは思えないからで、究極を追求するくらいならあっさりVimを使えば事足りるからである。 私の場合は、あくまでEmacsがメインであって「Vimのいいとこどりができたらいいな」ということである。
この点をしっかり自覚してからEvil導入を進めないと迷路から出られなくなると思う。
Evil設定
(leaf evil
:ensure t
:hook ((after-init-hook . evil-mode)
(find-file-hook . my:evil-insert-state))
:bind (("<zenkaku-hankaku>" . toggle-evil-mode)
(:evil-normal-state-map
("?" . chromium-vim-chert)
("C-e" . seq-end)
("SPC" . evil-insert-state)
("M-." . nil) ;; Use with other settings
("<hiragana-katakana>" . my:evil-normal-state)
([home] . open-dashboard)))
:init
;; options for Evil, must be written before (require 'evil)
(setq evil-insert-state-cursor '(bar . 4))
(setq evil-want-C-u-scroll t) ;; Enable scrolling with C-u
(setq evil-cross-lines t)
(setq evil-ex-search-vim-style-regexp nil)
(setq evil-search-module 'evil-search)
(setq evil-undo-system 'undo-fu)
:config
;; Use emacs key bindings in insert state
(setcdr evil-insert-state-map nil)
;; Go back to normal state with ESC
(define-key evil-insert-state-map [escape] 'my:evil-normal-state)
;; Hydra-select in visual-state region
(define-key evil-visual-state-map (kbd ".") 'hydra-selected/body)
;; Use muhenkan key as ESC
(define-key key-translation-map [muhenkan] 'evil-escape-or-quit)
(define-key evil-operator-state-map [muhenkan] 'evil-escape-or-quit)
;; Set the initial state for major mode
(evil-set-initial-state 'lisp-interaction-mode 'insert)
(evil-set-initial-state 'fundamental-mode 'insert)
(evil-set-initial-state 'easy-hugo-mode 'insert)
(add-to-list 'evil-emacs-state-modes 'neotree-mode)
(add-to-list 'evil-emacs-state-modes 'dired-mode)
(add-to-list 'evil-emacs-state-modes 'dashboard-mode)
(add-to-list 'evil-emacs-state-modes 'org-mode)
;; Customized functions
(defun evil-swap-key (map key1 key2)
"Swap KEY1 and KEY2 in MAP."
(let ((def1 (lookup-key map key1))
(def2 (lookup-key map key2)))
(define-key map key1 def2)
(define-key map key2 def1)))
(evil-swap-key evil-motion-state-map "j" "gj")
(evil-swap-key evil-motion-state-map "k" "gk")
(defun toggle-evil-mode ()
"Toggle on and off evil mode."
(interactive)
(if evil-mode (evil-mode 0)
(evil-mode 1)))
(defun my:evil-normal-state ()
"Turn off input-method then return to normal-state."
(interactive)
(if current-input-method (deactivate-input-method))
(evil-normal-state))
(defun evil-escape-or-quit (&optional prompt)
"If in evil state to ESC, else muhenkan key."
(interactive)
(cond
((or (evil-normal-state-p) (evil-insert-state-p) (evil-visual-state-p)
(evil-replace-state-p) (evil-visual-state-p)) [escape])
(t [muhenkan])))
(defun my:evil-insert-state ()
"New files are opened with insert-state."
(interactive)
(unless (file-exists-p buffer-file-name)
(evil-insert-state)))
(defvar my:auto-insert-state-buffers '("COMMIT_EDITMSG"))
(defun ad:switch-to-buffer (&rest _arg)
"Set buffer for automatic inser-state"
(when (member (buffer-name) my:auto-insert-state-buffers))
(evil-insert-state))
(advice-add 'switch-to-buffer :after #'ad:switch-to-buffer))
(leaf evil-plugins
:doc "Plugin for Evil modeline"
:el-get tarao/evil-plugins
:after evil
:require evil-mode-line)
- evil-local-mode を使って必要なメジャーモードだけEvil化する
- evil-mode をグローバル設定した上で、不要なEvil機能を除外する。
最初は、設定の簡単なevil-local-mode で試してみた。
ところが evil-modeline-color
が動作しなかったり、C-[
による [escape] 機能が動作しなかったりというバグがあって不満だったので 最終的に evil-mode
で設定を工夫することにした。