Ignorando diacríticos / acentos ao pesquisar

12

Existe uma maneira de instruir o Vim que eu quero ignorar sinais diacríticos / acentos ao pesquisar? Por exemplo, eu gostaria de poder procurar

kočička

inserindo

/kocicka

As opções ignorecasee smartcasesão muito úteis, mas parecem não ter nada a ver com sinais diacríticos / acentos.

s3rvac
fonte
3
Relacionado: :h [[=e :h patterns-composing.
Muru

Respostas:

16

Como o @muru mencionado no comentário , você pode usar uma classe de equivalência (descrita em :help /[[) que parece ser uma expressão de classe de caractere avaliada como um conjunto de caracteres semelhantes (ou seja, são os mesmos depois de remover qualquer acento / diacrítico).

Por exemplo, para procurar kočičkae kocickacom o mesmo padrão, você pode usar isto:

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

onde [[=c=]]é a classe de equivalência para o cpersonagem.


Para inserir automaticamente essa classe de caracteres sempre que você clicar em cuma pesquisa, use este mapeamento:

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

que pode ser dividido assim:

  • <expr> digite a avaliação de uma expressão
  • getcmdtype() =~ '[?/]' teste se você está escrevendo uma pesquisa para trás ou para frente
  • '[[=c=]]'retorne a classe de equivalência para o ccaractere se o teste anterior for bem-sucedido
  • 'c'retornar o ccaractere caso contrário

O mapeamento anterior tem 2 desvantagens:

  1. cobre apenas o cpersonagem
  2. pode dificultar a leitura do padrão

Pode ser melhorado remapeando <CR>assim:

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

Quando você pressiona <CR>após escrever um padrão para uma pesquisa, o mapeamento substitui automaticamente todos os caracteres alfabéticos pelo equivalente da classe de equivalência.


O mapeamento para <CR>é semelhante ao mapeamento anterior para c, exceto que ele não usa o argumento, <expr>mas o mapeamento do sistema <C-\>e.
<expr>permite inserir a avaliação de uma expressão, enquanto <C-\>epermite substituir toda a linha de comando pela avaliação de uma expressão.

user9433424
fonte
1
Além disso, se você quiser ir na direção inversa, por exemplo, /kočičkacorrespondências kocicka, poderá usar em '[[:lower:][:upper:]]'vez de '\a'. As alternativas '[:alpha:]'e '\I'não parecem funcionar com caracteres de vários bytes; no entanto, '[^[:punct:]]'parece funcionar (embora eu tenha menos certeza), e acho que você também criaria sua própria classe de equivalência (por exemplo '[А-яЁё]').
precisa saber é o seguinte
Eu gostaria que houvesse um cenário para isso. Enquanto o uso de [[= c =]] funciona, mas o tipo de erro significa que você precisa clicar sete vezes no backspace. Também a legibilidade sofre.
daliusd 7/02/19