Eliminar automáticamente el par de cierre sin causar pares desequilibrados


8

Estoy escribiendo una función VIML que, en el modo de inserción, permite una <BS>a través de la parte inicial de un par ( [, {, etc.) para eliminar la parte de cierre del par si es el siguiente carácter después del cursor (como auto-pares y vim-autoclose ). Esta función será diferente porque la parte de cierre del par no se eliminará si hay pares desequilibrados.

Ejemplos:

El formato es <initial> => <result-after-backspace>donde mi cursor está delante de |.

((|)    =>   (|)

((|))   =>   (|)

(|)     =>   |

(defn   =>   (defn
  (|)          |)

¿Cómo puedo determinar si los pares están desequilibrados o no antes de continuar y eliminar el par de cierre?

He probado ambos pares automáticos y vim-autoclose . Con ambos complementos, la parte de cierre del par siempre se elimina.


¿Podría aclarar su prefacio? ¿Desea evitar todos los complementos, o solo los similares a los dos que menciona? Si es lo último, ¿qué pasa con esos dos que no te gustan?
Tom

No quiero usar ningún complemento para esto. He actualizado el prefacio.

1
He votado para cerrar esta pregunta. Creo que el tema básico como tal está bien, pero sus restricciones lo convierten en una pregunta de "por favor escriba un código para mí por favor kthxbye" en este momento. No creo que queramos permitir este tipo de preguntas aquí ...
Martin Tournoij

1
@Carpetsmoker Más allá de la redacción de esta pregunta hay un problema que aún no se ha resuelto en ningún complemento que haya visto. Me parece claro que una vez que esta pregunta se responda con éxito, cada complemento de tipo de cierre automático o par automático podrá beneficiarse de su solución. ¿Cómo sugeriría que cambie la redacción para que sea aceptable?

2
@merb, el complemento de crédito hace exactamente lo que quieres. Si desea esa funcionalidad sin usar realmente el complemento, le sugiero que examine la fuente en github. Creo que sería más instructivo que intentar reproducir una versión aquí. github.com/kovisoft/paredit
Quincy Bowers

Respuestas:


1

Si entiendo su pregunta correctamente, la clave es determinar si el carácter en el cursor es un delimitador coincidente.

Considere los comandos de modo normal v%"zyy v%%"zy.

  • Si el cursor está en un delimitador coincidente, entonces el primer comando extraerá una cadena de longitud de al menos 2 (el delimitador, su par y cualquier texto en el medio) @z. El segundo tirará de una cadena de longitud exactamente 1, nuevamente, el delimitador en sí mismo @z.
  • Si el cursor está en un delimitador sin igual, entonces el primer comando extraerá una cadena de longitud 1, el delimitador en sí mismo @z. Abortar.
  • Si el cursor no está en un delimitador y hay un delimitador en la línea, entonces el segundo comando tirará una cadena de longitud mayor que 1 en @z. Abortar.
  • Si el cursor no está en un delimitador y no hay otro delimitador en la línea, entonces el primer comando arrastrará una cadena de longitud exactamente 1, el carácter en sí mismo @z. Abortar.

Por lo tanto, tenemos el siguiente resultado:

El cursor está en un delimitador coincidente si y solo si el comando de modo normal v%"zytira una cadena de longitud de al menos 2 @zy el comando de modo normal v%%"zytira una cadena de longitud exactamente de 1 a @z.

Sugerencias para VimL: :norm ...y strlen(@z)ayudará aquí.


¿Responde esto a tu pregunta o me falta algo?
wchargin

Determinar si el carácter del cursor coincide o no no es exactamente la clave. La clave es determinar si una forma determinada está equilibrada o no. Si el formulario está equilibrado y nos encontramos en esta posición: (|)presionar <BS>debería eliminar ambos. Sin embargo, si el formulario de nivel superior no está equilibrado, así: (defn (|)presionar <BS>solo debería eliminar lo que normalmente se eliminaría, en este caso dejándonos con (defn |).

1

Ok, terminé revisando paredit.vim y sacando algunas funciones para crear esto: vim-pear . Inserta y elimina delimitadores en pares mientras mantiene un estado equilibrado.


Genial :-) ¿Cómo lo uso? ¿Puedo instalarlo y se habilitará por defecto? ¿También es posible habilitar / deshabilitar esto solo para tipos de archivo específicos?
Martin Tournoij

Habilitado para todo por defecto. Envía un PR si quieres algo así. Puedo hacerlo yo mismo en algún momento.

El enlace está (actualmente) roto.
Rico el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.