Underscore is not a word character
An underscore _ is a word character in Vim. This means that word motions like w skip over underlines in a sequence of letters as if it was a letter itself. In contrast, in Evil the underscore is often a non-word character like operators, e.g. +.
The reason is that Evil uses Emacs’ definition of a word and this definition does often not include the underscore. In Emacs word characters are determined by the syntax-class of the buffer. The syntax-class usually depends on the major-mode of this buffer. This has the advantage that the definition of a “word” may be adapted to the particular type of document being edited. Evil uses Emacs’ definition and does not simply use Vim’s definition in order to be consistent with other Emacs functions. For example, word characters are exactly those characters that are matched by the regular expression character class [:word:].
If you would be satisfied by having the * and # searches use symbols instead of words, this can be achieved by setting the evil-symbol-word-search variable to t.
If you want the underscore to be recognised as word character for other motions, you can modify its entry in the syntax-table:
(modify-syntax-entry ?_ "w")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.:
(add-hook 'c-mode-common-hook
(lambda () (modify-syntax-entry ?_ "w")))This gives the underscore the word syntax-class in all C-like buffers.
Similarly to Emacs’ definition of a word, the definition of a “symbol” is also dependent on the syntax-class of the buffer, which often includes the underscore. The default text objects keymap associates kbd:😮 with the symbol object, making kbd::cio a good alternative to Vim’s kbd::ciw, for example. The following will swap between the word and symbol objects in the keymap:
(define-key evil-outer-text-objects-map "w" 'evil-a-symbol)
(define-key evil-inner-text-objects-map "w" 'evil-inner-symbol)
(define-key evil-outer-text-objects-map "o" 'evil-a-word)
(define-key evil-inner-text-objects-map "o" 'evil-inner-word)This will not change the motion keys, however. One way to make word motions operate as symbol motions is to alias the evil-word `thing' [1] to the evil-symbol thing:
(defalias 'forward-evil-word 'forward-evil-symbol)(1) Many of Evil’s text objects and motions are defined in terms of the `thingatpt' library, which in this case are defined entirely in terms of
forward-THINGfunctions. Thus aliasing one to another should make all motions and text objects implemented in terms of that `thing' behave the same. ↩︎