#+title:    :editor evil
#+subtitle: The text editor Emacs was missing
#+created:  April 08, 2020
#+since:    2.0.0

* Description :unfold:
This holy module brings the Vim editing model to Emacs.

** Maintainers
- [[doom-user:][@hlissner]]

[[doom-contrib-maintainer:][Become a maintainer?]]

** Module flags
- +everywhere ::
  Enable evilified keybinds everywhere possible. Uses the [[https://github.com/emacs-evil/evil-collection][evil-collection]] plugin
  as a foundation.

** Packages
- [[doom-package:evil]]
- [[doom-package:evil-args]]
- [[doom-package:evil-collection]] if [[doom-module:+everywhere]]
- [[doom-package:evil-easymotion]]
- [[doom-package:evil-embrace]]
- [[doom-package:evil-escape]]
- [[doom-package:evil-exchange]]
- [[doom-package:evil-indent-plus]]
- [[doom-package:evil-lion]]
- [[doom-package:evil-nerd-commentary]]
- [[doom-package:evil-numbers]]
- [[doom-package:evil-quick-diff]]
- [[doom-package:evil-snipe]]
- [[doom-package:evil-surround]]
- [[doom-package:evil-textobj-anyblock]]
- [[doom-package:evil-vimish-fold]]
- [[doom-package:evil-visualstar]]
- [[doom-package:exato]]

** Hacks
- The o/O keys will respect and continue commented lines (can be disabled by
  setting ~+evil-want-o/O-to-continue-comments~ to ~nil~).
- In visual mode, [[kbd:][*]] and [[kbd:][#]] will search for the current selection instead of the
  word-at-point.
- The ~:g[lobal]~ ex command has been modified to highlight matches.
- More of vim's filename modifiers are supported in ex commands (like ~:p~,
  ~:p:h~ or ~:t~) than vanilla evil-mode offers.
- A custom filename modifier is available in Doom: ~:P~, which expands to the
  project root (throws an error if not in a project).

** TODO Changelog
# This section will be machine generated. Don't edit it by hand.
/This module does not have a changelog yet./

* Installation
[[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]]

/This module has no external requirements./

* TODO Usage
#+begin_quote
 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]]
#+end_quote

** Ported vim plugins
The following vim plugins have been ported to evil:

| Vim Plugin            | Emacs Plugin                   | Keybind(s)                     |
|-----------------------+--------------------------------+--------------------------------|
| vim-commentary        | evil-nerd-commenter            | omap [[kbd:][gc]]                        |
| vim-easymotion        | evil-easymotion                | omap [[kbd:][gs]]                        |
| vim-lion              | evil-lion                      | omap [[kbd:][gl]] / [[kbd:][gL]]                   |
| vim-seek or vim-sneak | evil-snipe                     | mmap [[kbd:][s]] / [[kbd:][S]], omap [[kbd:][z]] / [[kbd:][Z]] & [[kbd:][x]] / [[kbd:][X]] |
| vim-surround          | evil-embrace and evil-surround | vmap [[kbd:][S]], omap [[kbd:][ys]]                |
| vim-unimpaired        | (provided by Doom)             | [[https://github.com/hlissner/doom-emacs/blob/develop/modules/editor/evil/config.el#L413-L460][see the list]]                   |

This module has also ported vim-unimpaired keybinds to Emacs.

In other modules:
- The [[doom-module::ui neotree]] & [[doom-module::ui treemacs]] modules provide a =NERDTree= equivalent.
- The [[doom-module::editor multiple-cursors]] module contains functionality equal to the
  following vim plugins:
  - [[doom-package:evil-multiedit]] => [[github:hlissner/vim-multiedit][vim-multiedit]]
  - [[doom-package:evil-mc]] => [[https://github.com/terryma/vim-multiple-cursors][vim-multiple-cursors]]

** Custom Text Objects
This module provides a couple extra text objects, along with the built-in ones.
For posterity, here are the built-in ones:

- [[kbd:][w W]] words
- [[kbd:][s]] sentences
- [[kbd:][p]] paragraphs
- [[kbd:][b]] parenthesized blocks
- [[kbd:][b ( ) { } [ ] < >]] braces, parentheses and brackets
- [[kbd:][' " `]] quotes
- [[kbd:][t]] tags
- [[kbd:][o]] symbols

And these are text objects added by this module:
- [[kbd:][a]] C-style function arguments (provided by ~evil-args~)
- [[kbd:][B]] any block delimited by braces, parentheses or brackets (provided by
  ~evil-textobj-anyblock~)
- [[kbd:][c]] Comments
- [[kbd:][f]] For functions (but relies on the major mode to have sane definitions for
  ~beginning-of-defun-function~ and ~end-of-defun-function~)
- [[kbd:][g]] The entire buffer
- [[kbd:][i j k]] by indentation ([[kbd:][k]] includes one line above; [[kbd:][j]] includes one line above and
  below) (provided by ~evil-indent-plus~)
- [[kbd:][q]] For quotes (any kind)
- [[kbd:][u]] For URLs
- [[kbd:][x]] XML attributes (provided by ~exato~)

** Custom Ex Commands
| Ex Command            | Description                                                                          |
|-----------------------+--------------------------------------------------------------------------------------|
| ~:@~                  | Apply macro on selected lines                                                        |
| ~:al[ign][!] REGEXP~  | Align text to the first match of REGEXP. If BANG, align all matches on each line     |
| ~:cp[!] NEWPATH~      | Copy the current file to NEWPATH                                                     |
| ~:dash QUERY~         | Look up QUERY (or the symbol at point) in dash docsets                               |
| ~:dehtml [INPUT]~     | HTML decode selected text / inserts result if INPUT is given                         |
| ~:enhtml [INPUT]~     | HTML encode selected text / inserts result if INPUT is given                         |
| ~:iedit REGEXP~       | Invoke iedit on all matches for REGEXP                                               |
| ~:k[ill]all[!]~       | Kill all buffers (if BANG, affect buffer across workspaces)                          |
| ~:k[ill]b~            | Kill all buried buffers                                                              |
| ~:k[ill]m[!] REGEXP~  | Kill buffers whose name matches REGEXP (if BANG, affect buffers across workspaces)   |
| ~:k[ill]o~            | Kill all other buffers besides the selected one                                      |
| ~:k[ill]~             | Kill the current buffer                                                              |
| ~:lo[okup] QUERY~     | Look up QUERY on an online search engine                                             |
| ~:mc REGEXP~          | Invoke multiple cursors on all matches for REGEXP                                    |
| ~:mv[!] NEWPATH~      | Move the current file to NEWPATH                                                     |
| ~:na[rrow]~           | Narrow the buffer to the selection                                                   |
| ~:pad~                | Open a scratch pad for running code quickly                                          |
| ~:ral[ign][!] REGEXP~ | Right-Align text that matches REGEXP. If BANG, align all matches on each line        |
| ~:repl~               | Open a REPL and/or copy the current selection to it                                  |
| ~:retab~              | Convert indentation to the default within the selection                              |
| ~:rev[erse]~          | Reverse the selected lines                                                           |
| ~:rm[!] [PATH]~       | Delete the current buffer's file and buffer                                          |
| ~:tcd[!]~             | Send =cd X= to tmux. X = the project root if BANG, X = ~default-directory~ otherwise |

* TODO Configuration
#+begin_quote
 🔨 This module has no configuration documentation yet. [[doom-contrib-module:][Write some?]]
#+end_quote

* Troubleshooting
[[doom-report:][Report an issue?]]

** Can't access the universal argument key ([[kbd:][C-u]])
For maximum Vim emulation, this module commandeers the C-u key for scrolling (as
it does in Vim). The same goes for [[kbd:][C-u]] in insert mode (which deletes to BOL). In
both cases the universal argument has been moved to [[kbd:][<leader> u]].

To undo this, use:
#+begin_src emacs-lisp
;; add to $DOOMDIR/config.el
(setq! evil-want-C-u-scroll nil
       evil-want-C-u-delete nil)
#+end_src

** The [[kbd:][s]]/[[kbd:][S]] keys behave differently from Vim
Doom replaces the [[kbd:][s]] and [[kbd:][S]] keys with the [[doom-package:evil-snipe]] package (a port of
vim-seek/vim-sneak for 2-character versions of f/F/t/T).

To disable evil-snipe on s/S, you can either:
1. Disable ~evil-snipe-mode~ by adding ~(remove-hook 'doom-first-input-hook
   #'evil-snipe-mode)~ to =$DOOMDIR/config.el=,
2. Or disable [[doom-package:evil-snipe]] completely with ~(package! evil-snipe :disable t)~
   added to =$DOOMDIR/packages.el=, but this will also disable incremental
   highlighting for the f/F/t/T motions keys.
3. Or use [[kbd:][cl]] and [[kbd:][cc]], respectively; they do the same thing.

** The [[kbd:][Y]] key behaves differently from Vim (should yank the whole line)
Doom changes the behavior of the [[kbd:][Y]] key in normal mode to yank-to-EOL (equivalent
to [[kbd:][y$]]). This was to make it consistent with the [[kbd:][C]] and [[kbd:][D]] capital operators, and
because it was redundant with [[kbd:][yy]], which is easier to type than [[kbd:][y$]].

If you prefer the old behavior, it can be reversed with:
#+begin_src emacs-lisp
;; add to $DOOMDIR/config.el
(setq! evil-want-Y-yank-to-eol nil)
#+end_src

* Frequently asked questions
[[doom-suggest-faq:][Ask a question?]]

** How do I remove evil?
:PROPERTIES:
:ID:       f3925da6-5f0b-4d11-aa08-7bb58bea1982
:END:
1. [[id:01cffea4-3329-45e2-a892-95a384ab2338][Disable this module]].
2. Run ~$ doom sync~ to clean up lingering dependencies and regenerate your
   autoloads files.
3. [OPTIONAL] Change ~doom-leader-alt-key~ and ~doom-localleader-alt-key~. These
   are bound to [[kbd:][C-c]] and [[kbd:][C-c l]] by default.

#+begin_quote
 🚧 Ignore ~doom-leader-key~ and ~doom-localleader-key~, they don't apply to
    non-evil sessions.
#+end_quote

Evil-specific configuration and keybindings (defined with ~map!~) will be
ignored without [[doom-module::editor evil]] present (and omitted when byte-compiling).

** Include underscores in evil word motions?
A more in-depth answer and explanation for this can be found [[https://evil.readthedocs.io/en/latest/faq.html#underscore-is-not-a-word-character][in Evil's
documentation]].

TL;DR If you want the underscore to be recognized as word character, you can
modify its entry in the syntax-table:
#+begin_src emacs-lisp
(modify-syntax-entry ?_ "w")
#+end_src

This gives the underscore the word syntax-class. You can use a mode-hook to
modify the syntax-table in all buffers of some mode, e.g.
#+begin_src emacs-lisp
;; For python
(add-hook! 'python-mode-hook (modify-syntax-entry ?_ "w"))
;; For ruby
(add-hook! 'ruby-mode-hook (modify-syntax-entry ?_ "w"))
;; For Javascript
(add-hook! 'js2-mode-hook (modify-syntax-entry ?_ "w"))
#+end_src

** How do I disable synchronization between the kill ring and system clipboard?

In vim, operations that put or delete text (kill and yank in Emacs terminology)
act on the unnamed register by default. The unnamed register unrelated the
system clipboard. Evil uses the kill ring instead of the unnamed register. As
the kill ring is synchronized with the system clipboard by default, operations
like [[kbd:][dd]] or [[kbd:][cw]] place the killed text in the system clipboard, surprisingly so for
users who are used to the vim behavior.

The synchronization between the system clipboard and kill ring can be disabled,
making these operations behave closer to their vim counterparts:
#+begin_src emacs-lisp
(setq select-enable-clipboard nil)
#+end_src

Like in vim, the clipboard can still be accessed by using the [[kbd:][+]] register, e.g.
[[kbd:]["+dd]] or [[kbd:]["+cw]].

* TODO Appendix
#+begin_quote
 🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]]
#+end_quote
