Estou usando o vim para editar documentos de látex. Muitas vezes, vou querer mudar o nome de uma variável para outra coisa. No entanto, é um pouco chato ter que percorrer correspondências irrelevantes quando procuro o nome da variável. Eu gostaria de pesquisar apenas em "zonas matemáticas", conforme definido no arquivo de sintaxe tex. Existe uma maneira fácil de limitar uma pesquisa a uma região de sintaxe específica?
10
synIDattr()
para obter grupos de sintaxe para o caractere sob o cursor. Você pode escrever uma função que realiza a pesquisa (ou faznormal n
) e depois usasynIDattr()
para decidir se deve permanecer nesse local ou continuar a pesquisa adiante.Respostas:
Aqui está uma função que você pode tentar. Eu só testei um pouco, mas parece funcionar bem.
A função chama a função de pesquisa do Vim em um loop até encontrar uma correspondência 'comum' que também é uma correspondência 'qualificada' para um item de sintaxe específico ou até chegar ao final do buffer.
São necessários dois argumentos. O primeiro é o padrão de pesquisa e é passado inalterado para a
search()
função do Vim . Veja:help search()
como essa função funciona. O segundo argumento é o nome do item de sintaxe no qual você deseja filtrar essas correspondências. Isso também pode ser um padrão e é comparado como uma expressão regular que não diferencia maiúsculas de minúsculas.Para encontrar o padrão 'alfa' nas zonas matemáticas, você pode fazer
O
.
no final é o átomo padrão para qualquer caractere único, veja:help /.
. Isso ocorre porque há muitos itens de sintaxe zona matemática chamadatexMathZoneA
,texMathZoneB
etc.A
search()
função move o cursor para a próxima correspondência 'comum'. Em seguida, nossa função obtém todos os IDs de item de sintaxe para essa nova posição do cursorsynstack()
. Dando um loop neles, ele recupera o nome de cada item e o testa contra osyntaxitem
argumento. Veja:help synstack()
e:help synIDattr()
. Se houver uma correspondência 'qualificada', ele retornará o número da linha. Se atingir o final do buffer sem encontrar nenhuma correspondência 'qualificada', ele retornará0
. O objetivo da função é levar o cursor para a próxima correspondência 'qualificada', para que você possa fazer alguma operação lá, mas é útil retornar "número da linha ou 0" para indicar se é significativo chamar a função novamente, por exemplo, se você quiser chamar a função repetidamente de outra função ou macro.Eu escolhi usar o
W
sinalizador parasearch()
isso porque ele evita 'envolver' o final do buffer. Caso contrário, a função poderá ficar paralisada, pois continua encontrando as mesmas correspondências "comuns", mas nenhuma correspondência "qualificada".fonte
Caso suas "zonas matemáticas" sejam qualificadas por algum padrão sintático, por exemplo, a string "math", você pode pelo menos usar sequências de padrões para encontrar uma linha com o padrão correspondente, como em:
(Nota: os dois padrões podem estar em linhas diferentes!)
Isso pode não restringir suas correspondências às zonas - para isso você precisa identificar o final da zona -, mas exibirá apenas essas correspondências após um padrão inicial / math /. Você pode repetir a pesquisa para a próxima ocorrência usando o histórico do modo ex (
:
up-arrow
enter
).Nota: ISTR que nas versões anteriores do vim / vi eu também era capaz de usar esse método diretamente como um comando de pesquisa (em oposição a um comando ex-mode)
/math//your pattern/
com a vantagem de menos digitação e uso dos comandosn
eN
, mas não posso confirmar isso para a minha versão atual do vim.fonte
Se você estiver procurando pela string
foo
dentro$...$
ou$$...$$
, isso deve funcionar:Isso ancora a correspondência em um
$
caractere, mas seleciona apenas a sequênciafoo
.Não é realmente uma solução fácil, mas é possível usar um
:global
+:substitute
para encontrar "zonas matemáticas" e pesquisar dentro delas:Fingindo que
:substitute
é um comando de pesquisa, você pode ir para a próxima ocorrência comn
e sair comq
. Se você confirmar uma substituição por engano, não deverá haver nenhum problema.Você terá que definir a lista dentro de
%(
...)
com os nomes dos ambientes matemáticos que você usa (a lista completa é um pouco pesada:)align|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat
. Observe que estou usando um\v
padrão muito mágico ( ) aqui.Explicação:
:global
executar um comando Ex (:s
) em cada linha onde os jogos padrão (:help :global
)/\v
iniciar um padrão muito mágico (:h /
,:h pattern
,:h magic
)\\begin\{
corresponder a um literal\begin{
%(align|alignat|displaymath)
jogo qualquer uma destas palavras (:h /\%(
,:h /bar
)\}/
corresponder a um literal}
e acabar com o padrão.+1,/\\end/-1
um intervalo que consiste na próxima linha (contando desde a encontrada por:global
) até a linha anterior à encontrada pelo padrão de pesquisa/\\end
. Dentro desse intervalo,s/foo/&/gc
pesquise e substitua todas as ocorrências do literalfoo
por si mesmo, após confirmação (:h :substitute
)fonte
\mathit
nomes de variáveis, é muito mais fácil encontrá-los.Se você estiver procurando a string 'manhã' dentro do arquivo
/morning
, em seguida, entere pressione npara mover direção para frentefonte
I would like to search only in "math zones"
seu método procura o arquivo inteiro e não delimita uma zona de pesquisa.Não há opção a não ser escrever uma função dedicada para isso. Eu escrevi uma função que pesquisa a string que você deseja e só para se:
Você acabou de chamá-lo com a string que deseja pesquisar.
Pretendo escrever uma função semelhante para o GrammerousCheck que só para com erros gramaticais fora da matemática.
fonte