2011-12-15 11 views
5

Me gustaría saber la mejor manera de personalizar el auto-formateo/auto-sangría en vim para Common Lisp.La mejor manera de personalizar el auto-formateo/sangría automática en vim para Common Lisp

Auto-formateo (Yo suelo hacer esto escribiendo '==' en el modo de comando por línea) funciona muy bien para el lenguaje base lisp en vim (por ejemplo, defmacro, defun, lambda, if, con-output-to -string), pero cada vez que se definen construcciones de lenguaje nuevo (por ejemplo, usando macros), encuentro que el formato para el nuevo constructo a menudo no es lo que me gustaría que fuera.

Por ejemplo, aquí es como vim formatos 'cuando (constructo Lisp estándar) y' ACuando (comúnmente usado versión anafórica 'cuando; no es parte de la norma Lisp)

(when 'this 
    (process 'this)) 

(awhen 'this 
     (process it)) 

me gustaría' ACuando a formato automático como 'cuando. ¿Alguna idea de cómo puedo hacer esto?

Editar: Gracias Gilligan y Tamas por la recomendación de Slimv. Como prueba, descargué MacVim (lo necesitaré trabajando con terminal vim, pero ese es un problema diferente) y delgado, conecté la descarga slimv en ~/.vim, lancé MacVim y cargué un archivo .lisp.

Luego inicié el servidor de lisp (hecho a través de una GUI con MacVim), que cargó mi ejecutable Lisp predeterminado y el archivo principal.

Y * dado que mi archivo principal ya está cargado con las extensiones de idioma que uso comúnmente (siendo uno de ellos), con el formato correcto al salir de la caja.

Me gusta mucho esta solución. En lugar de [1] tener que aprender a decir a vim que debe sangrar determinadas funciones de manera adecuada, y [2] escribir el código que hace esto explícitamente para cada extensión de idioma que defina, y [3] actualizar ese código cada vez que agregue un nuevo constructo de lenguaje. En cambio aprovecho slimv para hacer el formateo para mí. Y slimv puede 'aprender' nuevas extensiones de lenguaje, siempre que esas macros ya estén cargadas en el núcleo de lisp que usa la sesión del servidor. ¡Bastante resbaladizo!

He encontrado que esto funciona bien para una clase particular de extensiones de idioma. Usualmente se definen como una macro, usando la palabra clave de cuerpo &. Esto parece 'hacer lo correcto' la mayor parte del tiempo, pero hay macros que uso que todavía no se auto-formatean apropiadamente. Aunque diría que es más probable que esto sea un problema con la forma en que se escribe la macro (extensión de lenguaje no estándar) que con cualquier otra cosa.

Por lo tanto, esta solución funciona bien para mí en la mayoría de los casos, y no tuve que codificar (y mantener) nada. ¡Buena cosa!

+1

Me alegra que te guste slimv.Si encuentra algún problema de sangrado, infórmelo a mí (soy el autor de slimv, puede encontrar mi dirección de correo electrónico en la documentación). –

+0

La respuesta Slimv no es tan útil para las personas que buscan una mejor sangría de los formularios estándar en un dialecto Lisp que no es Common Lisp. – Kaz

Respuesta

5

esto podría no ser una respuesta directa a su pregunta, pero puedo sugerir que instale el plugin slimv: http://www.vim.org/scripts/script.php?script_id=2531

Es un gran plugin que integra la funcionalidad BABA en vim y además de muchas otras cosas que también viene con una indentación mejorada para clisp & clojure. Sin embargo, no sangrará de la manera que desee.

+1

Slimv también sangrará correctamente si está conectado al servidor swank y awhen está definido en el REPL actual. La sangría se basa en la información de tiempo de ejecución tomada del servidor swank, al igual que en Emacs con Slime. –

+0

Ah, aún mejor - Para resumir, @claytonstanely: debe instalar slimv :) – gilligan

1

Si su tipo de archivo es 'lisp', entonces creo que necesita agregar reglas de sangrado para su caso especial en el archivo 'lisp.vim' en el directorio '/ vim7x/indent'. Puede encontrar un poco más de información en ayuda en :h indent-expr y :h indentexpr.

Alguien puede decirte mejor, pero creo que el archivo de sangría lisp.vim por defecto básicamente no hace nada porque la función incorporada lispindent() se usa para obtener valores de sangría. Deseará:

(1) establecer la función utilizada para obtener valores de sangría (es decir, indentexpr) para una función en su propio archivo sangría/lisp.vim, por ejemplo, GetLispIndent().
(2) en su función GetLispIndent(), usará lispindent() para obtener valores de sangría para todas las líneas excepto su caso especial. Vea los archivos de sangrado de otros idiomas y lea los documentos para tener una idea de cómo funciona Indentexpr, por ejemplo, java.vim.

+0

El archivo 'lisp.vim' en el directorio' indent' contiene casi nada. Esto se debe a que la sangría de Lisp se realiza mediante un "modo de ceceo" especial, que se remonta a una característica de Vi clásica. – Kaz

1

Para aquellos que están buscando este tema y no quieren ejecutar Slimv, porque no están trabajando con Common Lisp u otras razones, esta es la primicia.

La sangría de Lisp de Vim no es similar a la de otros idiomas; tiene un "modo Lisp" especial. Este modo se activa de forma

:set lisp 

que se realiza de forma automática para .lisp archivos. El modo Lisp no es una invención de Vim; Las implementaciones clásicas de Vi tienen un modo Lisp activado con :set lisp. (No está descrito por POSIX, lamentablemente).

El modo Lisp de Vim tiene un mecanismo simple por el cual las formas son operadores especiales que requieren una indentación de dos espacios: a saber, un parámetro llamado lispwords que contiene una lista de identificadores separados por comas.

Puede probarse a sí mismo que esta es la lista de identificadores que se utiliza, incluso cuando está editando un archivo Common Lisp .list con resaltado de sintaxis y todo. Simplemente haga :set listwords[TAB] y edite la lista para eliminar algo de ella, como defun. Luego intente reinventar un defun: ahora verá la sangría de estilo de función en lugar del estilo de operador.

El soporte de resaltado de sintaxis para Common Lisp está separado del parámetro lispwords del modo Lisp; tiene su propia lista de identificadores. Por ejemplo, en Vim 7.3 si escribe esto:

(symbol-macrolet ((foo bar)) 
       you get indented out to here!) 

Esto es a pesar del hecho de que symbol-macrolet es reconocido y de color. ¿Por qué? Es porque symbol-macrolet no aparece en la lista bastante escasa lispwords, mientras que sí aparece en el archivo de definición de resaltado de sintaxis lisp.vim.

El resultado es que puede juntar algunas secuencias de comandos que escanea su directorio de archivos .lisp para macros y genera un comando set lispwords=... que se coloca en un directorio .vimrc.

O si está trabajando en un dialecto de Lisp personalizado, puede simplemente hacer que su archivo de resaltado de sintaxis Vim personalice lispwords cuando se carga.

Aquí hay un descuido: la opción lispwords no tiene valor local; no puede usar setlocal lispwords ... para darle un valor específico de memoria intermedia. En otras palabras, parece que (al menos en el Vim 7.3 que estoy usando en Ubuntu) no puede tener dos o más búferes abiertos con diferentes dialectos de Lisp con identificadores diferentes para la sangría. El contenido predeterminado de lispwords contiene una combinación de Lisp y Símbolos de esquema para intentar ser una especie de solución de "talla única".