As a lot of people, I have removed _ from iskeyword, so it considers it kind of like whitespace. This is really useful for changing part of an identifier in languages like Python and Rust with normal commands like w, e and b. However, it also breaks * and #. Does (Neo)Vim have an option / plugin to force these to use Words instead? :)

  • "As a lot of people" [citation needed]
    – romainl
    Dec 12, 2022 at 6:20

2 Answers 2


* is roughly equivalent to searching for the string:

'\<' . escape(expand('<cword>'), '/.*~[^$\') . '\>'

(the escape is slightly different for #). So, one option is to create a custom mapping which uses WORDs instead of words (<c-r><c-a> means cWORD).

nnoremap <silent> * /<c-r>=escape('<c-r><c-a>', '/.*~[^$\')<cr>/<cr>
nnoremap <silent> # ?<c-r>=escape('<c-r><c-a>', '/?.*~[^$\')<cr>?<cr>

On the other hand, this is not necessarily useful, for example,

else if (tag_cmd) ...

pressing * on tag_cmd will search for literal (tag_cmd). Also, in vim, # always skips the current word unlike this implementation.

Another idea is to temporarily remove _ from iskeyword:

nnoremap * <cmd>se isk-=_<cr>*<cmd>se isk+=_<cr>
nnoremap # <cmd>se isk-=_<cr>#<cmd>se isk+=_<cr>

Since * is implemented using / and ? as described above, n and N will continue to work.


Partial solution - since 0.8.0, neovim supports * and # on visual selections, so you can select it manually, or make a shortcut

Source https://youtu.be/TX_uOJiIjcM

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.