Estoy usando vim para editar documentos de látex. A menudo, querré cambiar el nombre de una variable a otra cosa. Sin embargo, es un poco molesto tener que sortear coincidencias irrelevantes cuando busco el nombre de la variable. Me gustaría buscar solo en "zonas matemáticas" como se define en el archivo de sintaxis tex. ¿Hay alguna manera fácil de limitar una búsqueda a una región de sintaxis específica?
10
synIDattr()
para obtener grupos de sintaxis para el carácter debajo del cursor. Puede escribir una función que realice la búsqueda (o lo haganormal n
) y luego usesynIDattr()
para decidir si permanecer en esta ubicación o continuar la búsqueda hacia adelante.Respuestas:
Aquí hay una función que puedes probar. Solo lo probé un poco, pero parece funcionar bien.
La función llama a la función de búsqueda de Vim en un bucle hasta que encuentra una coincidencia 'ordinaria' que también es una coincidencia 'calificada' con un elemento de sintaxis particular, o hasta que llega al final del búfer.
Se necesitan dos argumentos. El primero es el patrón de búsqueda y se pasa sin cambios a la
search()
función de Vim . Vea:help search()
cómo funciona esa función. El segundo argumento es el nombre del elemento de sintaxis en el que desea filtrar estas coincidencias. Esto también puede ser un patrón y se compara como una expresión regular que no distingue entre mayúsculas y minúsculas.Para encontrar el patrón 'alfa' en zonas matemáticas puedes hacer
Al
.
final es el átomo de patrón para cualquier carácter individual, vea:help /.
. Esto es porque hay muchos elementos de sintaxis de zona matemática llamadostexMathZoneA
,texMathZoneB
etc.La
search()
función mueve el cursor a la siguiente coincidencia 'ordinaria'. Luego, nuestra función obtiene todas las ID de elementos de sintaxis para esa nueva posición del cursor consynstack()
. Al recorrerlos, recupera el nombre de cada elemento a su vez y lo prueba contra elsyntaxitem
argumento. Ver:help synstack()
y:help synIDattr()
. Si hay una coincidencia 'calificada', devuelve el número de línea. Si llega al final del búfer sin encontrar ninguna coincidencia 'calificada', regresa0
. El objetivo de la función es llevar el cursor a la siguiente coincidencia 'calificada' para que pueda realizar alguna operación allí, pero es útil devolver "número de línea o 0" para indicar si es significativo volver a llamar a la función, por instancia si desea llamar a la función repetidamente desde otra función o una macro.Elegí usar la
W
bandera para elsearch()
porque evita 'envolver' el final del búfer. De lo contrario, la función podría atascarse ya que sigue encontrando las mismas coincidencias "normales" pero no coincidencias "calificadas".fuente
En caso de que sus "zonas matemáticas" estén calificadas por algún patrón sintáctico, digamos, la cadena "matemáticas", entonces al menos podría usar secuencias de patrones para encontrar una línea con el patrón correspondiente, como en:
(Nota: ¡los dos patrones pueden estar en líneas diferentes!)
Es posible que esto no restrinja sus coincidencias a las zonas, para eso necesitaría identificar el final de la zona, pero solo mostrará esas coincidencias después de un patrón inicial / matemáticas /. Puede repetir la búsqueda de la próxima aparición utilizando el historial en modo ex (
:
up-arrow
enter
).Nota: ISTR que en versiones anteriores de vim / vi también pude usar ese método directamente como un comando de búsqueda (a diferencia de un comando ex-mode)
/math//your pattern/
con la ventaja de escribir y usar menos los comandosn
yN
, pero no puedo confirmar eso para mi versión vim actual.fuente
Si está buscando la cadena
foo
dentro de$...$
o$$...$$
, esto debería funcionar:Esto ancla la coincidencia a un
$
personaje pero solo selecciona la cadenafoo
.No es realmente una solución fácil, pero uno podría usar un
:global
+:substitute
para encontrar "zonas matemáticas" y buscar dentro de ellas:Fingiendo que
:substitute
es un comando de búsqueda, puede ir a la siguiente aparición conn
y salir conq
. Si confirma una sustitución por error, no debería haber ningún problema.Tendrás que configurar la lista dentro
%(
...)
con los nombres de los entornos matemáticos que utilizas (la lista completa es un poco pesada:)align|alignat|displaymath|eqnarray|equation|flalign|gather|math|multline|subequations|xalignat|xxalignat
. Tenga en cuenta que estoy usando un\v
patrón muy mágico ( ) aquí.Explicación:
:global
ejecutar un comando Ex (:s
) en cada línea, donde los partidos de patrones (:help :global
)/\v
comienzan un patrón muy mágica (:h /
,:h pattern
,:h magic
)\\begin\{
coincida con un literal\begin{
%(align|alignat|displaymath)
coincide con ninguna de estas palabras (:h /\%(
,:h /bar
)\}/
coincida con un literal}
y poner fin al patrón.+1,/\\end/-1
un rango que consiste en la siguiente línea (contando desde la encontrada por:global
) hasta la línea anterior a la encontrada por el patrón de búsqueda/\\end
. Dentro de ese rango,s/foo/&/gc
buscar y reemplazar cada aparición del literalfoo
consigo mismo, después de la confirmación (:h :substitute
)fuente
\mathit
alrededor de nombres de variables, encontrarlos es mucho más fácil.Si está buscando la cadena 'mañana' dentro del archivo
/morning
, enterpresione ny avance para avanzarfuente
I would like to search only in "math zones"
su método busca todo el archivo, no delimita una zona de investigación.No hay más opción que escribir una función dedicada para esto. Escribí una función que busca la cadena que desea y solo se detiene si:
Simplemente llámalo con la cadena que deseas buscar.
Tengo la intención de escribir una función similar para GrammerousCheck que solo se detiene en errores de gramática fuera de las matemáticas.
fuente