17

Is there a way to instruct Vim that I want to ignore diacritics/accents when searching? For example, I would like to be able to search for

kočička

by entering

/kocicka

The ignorecase and smartcase options are very useful, but they do not seem to have anything to do with diacritics/accents.

1
16

As @muru mentioned in the comment, you could use an equivalence class (described in :help /[[) which seems to be a character class expression evaluated as a set of similar characters (i.e. are the same once you remove any accent/diacritic).

For example, to look for kočička and kocicka with the same pattern, you could use this:

ko[[=c=]]i[[=c=]]ka

where [[=c=]] is the equivalence class for the c character.


To automatically insert this character class whenever you hit c while performing a search, you could use this mapping:

cnoremap <expr> c getcmdtype() =~ '[?/]' ? '[[=c=]]' : 'c'

which can be broken down like this:

  • <expr> type the evaluation of an expression
  • getcmdtype() =~ '[?/]' test whether you're writing a backward or forward search
  • '[[=c=]]' return the equivalence class for the c character if the previous test succeeded
  • 'c' return the c character otherwise

The previous mapping has 2 drawbacks:

  1. it only covers the c character
  2. it can make the pattern difficult to read

It could be improved by remapping <CR> like this:

cnoremap <CR> <C-\>e getcmdtype() =~ '[?/]' ? substitute(getcmdline(), '\a', '[[=\0=]]', 'g'): getcmdline()<CR><CR>

When you hit <CR> after writing a pattern for a search, the mapping will automatically replace all the alphabetic characters by their equivalence class counterpart.


The mapping for <CR> is similar to the previous mapping for c, except it doesn't use the argument <expr> but the system mapping <C-\>e.
<expr> allows you to insert the evaluation of an expression, while <C-\>e allows you to replace the whole command line with the evaluation of an expression.

2
  • 1
    Further, if you would like to go in the reverse direction, e.g., /kočička matches kocicka, then you can use '[[:lower:][:upper:]]' instead of '\a'. The alternatives '[:alpha:]' and '\I' don't seem to work with multi-byte characters; however, '[^[:punct:]]' seems to work (though I'm less sure), and I would guess building your own equivalence class (e.g., '[А-яЁё]') as well. – kevinlawler Jan 3 '18 at 21:04
  • 1
    I wish there was a setting for that. While using [[=c=]] works but mistype means you need to click backspace 7 times. As well readability suffers. – daliusd Feb 7 '19 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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