2010-10-08 12 views
9

Me gustaría escribir una función en vimscript que encuentre el último paréntesis abierto o paréntesis en una línea. Esto no es necesariamente un problema fácil, ya que tiene que ser capaz de manejar todo lo siguiente:Vimscript: find last parenthese or bracket

function(abc 
function(abc, [def 
function(abc, [def], "string(" 
function(abc, [def], "string(", ghi(

Como se puede ver, entre paréntesis anidados, diferentes símbolos, y la cadena de tokens todos necesitan ser manejados de forma inteligente. ¿Esto es posible? ¿Hay herramientas con expresiones regulares de vimscript para realizar búsquedas basadas en el contexto que conozcan la diferencia entre paréntesis no cerrados y paréntesis en cadenas?

Dado que puede sintaxis resaltar corchetes desequilibrados, debería ser posible encontrar el último paréntesis/corchete no cerrado en una línea. ¿Cómo puede hacerse esto?

+1

La mitad de un par de paréntesis se llama paréntesis. –

+0

Si la intención es ayudar con el resaltado, anote la pregunta y la respuesta aquí: http://superuser.com/questions/545278/how-to-have-vim-show-unclosed-parenthesis. El complemento 'vim-matchopen' resalta el último paréntesis, corchete y corchete relativo al cursor (ya sea cerrado o no cerrado). –

Respuesta

4

Así que, básicamente, tiene que encontrar el último parenthese que no está en el comentario ni en la cadena.

No estoy seguro de lo que esta sintaxis es así que puse esas líneas en una memoria intermedia e hice

:set ft=javascript 

para obtener cadenas destacando

function(abc 
function(abc, [def 
function(abc, [def], "string(" 
function(abc, [def], "string(", ghi(

Ahora ponga su cursor al paréntesis que abre tercera línea y emita el siguiente comando:

:echo synIDattr(synID(line('.'), col('.'), 0), 'name') =~? '\(Comment\|String\)' 

Te hará eco de '1' y significa que c Haracter bajo el cursor está en comentario o en una cadena.

Si coloca el cursor en el último col de la última línea y hace el mismo comando, obtendrá '0'.

Ahora puede iterar hacia atrás sobre paréntesis y probarlos contra 'comentario' y 'cadena' y obtener el último paréntesis abierto.

Puede consultar this archive of "LISP: Balance unmatched parentheses in Vim" para ver cómo cerrar los paréntesis no coincidentes usando vimscript.

+0

Gracias!Todavía es un poco más complejo que eso (considere una línea que termine en "función (abc, def(), ghi", el último parentesco no es el último parenthese sin parentesco), pero synIDattr es exactamente lo que necesitaba para poder hacer el resto del trabajo. – So8res

1

No tengo ninguna respuesta directa para usted, pero es posible que desee comprobar el código en el complemento matchparen.vim, que es un complemento estándar incluido en las instalaciones de Vim (en el directorio del complemento). Ese complemento es el que se usa para resaltar parens pareados, si tiene habilitada esa función. El código es más general de lo que necesita, ya que coincide con otras líneas, pero es posible que pueda trabajar con él y probar si encuentra una coincidencia en la misma línea, o al menos obtener algunas ideas de su código.

4

Uso [( y ]):

[(   go to [count] previous unmatched '('. 
])   go to [count] next unmatched ')'. 

Para llaves: [{ y [}.

+1

Interesante. ¿Cómo se implementa esto? ¿Hay algún equivalente para encontrar corchetes sin igual? ¿Hay alguna manera fácil de usar esto en una función vimscript sin mover el cursor? – So8res

+3

Busque 'searchpair()' en la ayuda/documentación. – Jeet