#+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

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