Following along some nice tutorials on the subject, let’s try building up a nice scenario with VI. After a week or so, I’m quite digging my fusion of Emacs and Vi. What’s left?
- Integration with my mode line
- Go crazy with simpler keys under the Leader project
- Program my new keyboard to jump to particular states based on
particular keys... especially =C-z
and\
(which is hard to get to with my new keyboard.io)
(use-package evil
:ensure t
:config
(evil-mode 1)
;; Let's not bother with Evil in *every* mode...
(dolist (mode '(ag-mode
flycheck-error-list-mode
git-rebase-mode))
(add-to-list 'evil-emacs-state-modes mode))
;; Start in insert mode for small buffers
(dolist (mode '(text-mode))
(add-to-list 'evil-insert-state-modes mode))
(evil-add-hjkl-bindings eww-mode-map 'emacs
(kbd "/") 'evil-search-forward
(kbd "n") 'evil-search-next
(kbd "N") 'evil-search-previous)
:bind (:map evil-normal-state-map
;; Don't need 'q' to start recording a macro...
;; I'm more familiar with Emacs' way of doing things.
("q" . nil)
;; Why is 'f' line-bound?
;; Wanna rebind f to avy?
("f" . iy-go-to-char)
("F" . iy-go-to-char-backward)
;; How about avy to 't'?
("t" . avy-goto-char-timer)
("T" . avy-goto-word-timer)
;; Shame that meta keys don't work, so let's
;; use the 'z' prefix:
("z." . find-tag)
("z," . ha/xref-pop-marker-stack))
;; While I'm still getting used to Evil, I'll eschew certain
;; advanced features, and fall-back on my Emacs. Setting to `nil'
;; falls back to Emacs defaults.
:bind (:map evil-insert-state-map
("C-a" . nil)
("C-e" . nil)
("C-d" . nil)
("C-k" . nil)
("C-t" . nil)
("M-." . nil)
("M-," . nil)))
The evil-goggles mode, while slightly slowing down editing, gives some visual hints when making changes. This will be useful while I’m learning these new bindings.
(use-package evil-goggles
:ensure t
:config
(evil-goggles-mode))
The evil-surround project looks pretty useful with little extra learning overhead.
(use-package evil-surround
:ensure t
:config
(global-evil-surround-mode))
Essentially, enter a command, like c
, and then hit s
to deal with
what is surrounding the current text. Note: You don’t need to be on
the surrounders, just in, as the first key after the s
is the
surround character.
t
- Deals with HTML and XML tags (use
>
if you want just the angle brackets) f
- Surrounds the function
#
- Deals with Ruby-variable string substitution, i.e. #{…}
Obviously, see the last section on ‘the web site’ for details.
Not sure of the exact benefit that evil-leader confers, but I think I can see where I would put all customization over here.
(defun ha/evil-insert-single ()
"Inserts a single character, and then returns to previous Evil state."
(interactive)
(insert (read-char)))
(use-package evil-leader
:ensure t
:config
(evil-leader/set-leader "<SPC>")
(global-evil-leader-mode)
(evil-leader/set-key
"j" 'avy-goto-char-timer
"o" 'ace-window
"b" 'ido-switch-buffer
"n" 'org-next-visible-heading
"p" 'org-previous-visible-heading
"^" 'outline-up-heading
"." 'xref-find-definitions
"," 'xref-pop-marker-stack
"<SPC>" 'ha/evil-insert-single))
evil-execute-in-emacs-state
executes the next command in Emacs state without staying in there.
Make sure that we can simply require
this library.
(provide 'init-evil)