2011-12-15 14 views
5

Vorrei conoscere il modo migliore per personalizzare la formattazione automatica/indentazione automatica in vim per Common Lisp.Il modo migliore per personalizzare la formattazione automatica/indentazione automatica in vim per Common Lisp

La formattazione automatica (di solito lo faccio digitando '==' in modalità comando per riga) funziona molto bene per il linguaggio di base lisp in vim (ad esempio defmacro, defun, lambda, if, with-output-to -stringa), ma ogni volta che vengono definiti nuovi costrutti di linguaggio (ad esempio, utilizzando macro), trovo che la formattazione per il nuovo costrutto spesso non è ciò che mi piacerebbe fosse.

Ad esempio, ecco come vim formati 'quando (lisp costrutto standard) e' AQuando (comunemente usato la versione anaforica di 'quando, non fa parte dello standard Lisp)

(when 'this 
    (process 'this)) 

(awhen 'this 
     (process it)) 

vorrei' AQuando a auto-formato come 'quando. Qualche idea su come posso farlo?

Modifica: Grazie Gilligan e Tamas per la raccomandazione Slimv. Come test, ho scaricato MacVim (avrò bisogno di questo con il terminale vim, ma questo è un problema diverso) e slimv, rsynched il download slimv in ~/.vim, lanciato MacVim e caricato un file .lisp.

Ho quindi avviato il server Lisp (eseguito tramite una GUI con MacVim), che ha caricato il file eseguibile e il file core Lisp predefinito.

E * poiché il mio file principale è già caricato con le estensioni del linguaggio che uso comunemente (anche se sono uno di loro), subito formattato correttamente appena estratto dalla confezione.

Mi piace molto questa soluzione. Invece di [1] devo imparare come dire a vim di indentare particolari funzioni in modo corretto, e [2] scrivere il codice che fa questo esplicitamente per ogni estensione di linguaggio che definisco e [3] aggiornando quel codice ogni volta che aggiungo un nuovo costruzione del linguaggio. Invece faccio leva su slimv per fare la formattazione per me. E slimv può "apprendere" nuove estensioni della lingua, purché tali macro siano già caricate nel core lisp utilizzato dalla sessione del server. Piuttosto lucido!

Ho trovato che questo funziona bene per una particolare classe di estensioni del linguaggio. Di solito quelli definiti come macro, usando la parola chiave body &. Questo sembra "fare la cosa giusta" il più delle volte, ma ci sono macro che uso che non vengono ancora correttamente formattate automaticamente. Anche se direi che questo è più probabile che sia un problema con il modo in cui la macro è scritta (estensione del linguaggio non standard) di qualsiasi altra cosa.

Quindi, questa soluzione funziona bene per me nella maggior parte dei casi, e non ho dovuto codificare (e mantenere) nulla. Grandi cose!

+1

Sono contento che ti piaccia slimv.Se trovi problemi di indentazione, segnalacelo (sono l'autore di slimv, puoi trovare il mio indirizzo email nella documentazione). –

+0

La risposta Slimv non è così utile per le persone che cercano un rientro migliore dei moduli standard in un dialetto Lisp che non sia Common Lisp. – Kaz

risposta

5

questo potrebbe non essere una risposta diretta alla tua domanda, ma vi consiglio vivamente di installare il plugin slimv: http://www.vim.org/scripts/script.php?script_id=2531

E 'un ottimo plugin che integra le funzionalità SLIME in vim e oltre a molte altre cose si tratta anche con una rientranza migliorata per clamore & clojure. Però non indenterà nel modo in cui vuoi.

+1

Slimv verrà indentato anche correttamente se connesso al server di swank e awhen è definito nel REPL corrente. Il rientro si basa sulle informazioni di runtime prese dal server di swank, proprio come in Emacs con Slime. –

+0

Ah, ancora meglio - Quindi per farla breve, @claytonstanely: dovresti installare slimv :) – gilligan

1

Se il tipo di file è 'lisp', penso che sia necessario aggiungere le regole di indentazione per il caso speciale nel file 'lisp.vim' nella directory '/ vim7x/indent'. Puoi trovare un po 'più di informazioni in aiuto allo :h indent-expr e allo :h indentexpr.

Qualcuno potrebbe essere in grado di dirti meglio, ma credo che il file di rientro di default lisp.vim non faccia nulla perché la funzione built-in lispindent() è usata per ottenere i valori di rientro. Si consiglia di:

(1) impostare la funzione utilizzata per ottenere i valori di rientro (ad esempio, indentexpr) su una funzione nel proprio file indent/lisp.vim, ad esempio GetLispIndent().
(2) nella funzione GetLispIndent() verrà utilizzato lispindent() per ottenere valori di rientro da restituire per tutte le righe tranne il caso speciale. Vedi i file indent di altre lingue e leggi i documenti per avere un'idea di come indentexpr funzioni, ad es. Java.vim.

+0

Il file 'lisp.vim' nella directory' indent' contiene quasi nulla. Questo perché l'indentazione di Lisp viene eseguita da una speciale "modalità lisp", che riconduce a una caratteristica del classico Vi. – Kaz

1

Per coloro che cercano questo argomento e non vogliono eseguire Slimv, perché non stanno lavorando con Common Lisp o altri motivi, ecco lo scoop.

Il rientro di Lisp di Vim non è così per altre lingue; ha una speciale "modalità Lisp". Questa modalità è attivata per

:set lisp 

che viene fatto automaticamente per .lisp file. La modalità Lisp non è un'invenzione di Vim; le classiche implementazioni Vi hanno una modalità Lisp attivata con :set lisp. (Non è descritto da POSIX, sfortunatamente).

La modalità Lisp di Vim ha un semplice meccanismo mediante il quale le forme sono operatori speciali che richiedono un'indentazione di due spazi: vale a dire un parametro chiamato lispwords che contiene un elenco di identificatori separati da virgole.

È possibile dimostrare a se stessi che questo è l'elenco identificativo utilizzato, anche quando si modifica un file Common Lisp .list con evidenziazione della sintassi e tutto. Basta fare :set listwords[TAB] e modificare l'elenco per rimuovere qualcosa da esso, ad esempio defun. Quindi prova a reindentare a defun: vedrai ora il rientro stile funzione invece dello stile operatore.

Il supporto per l'evidenziazione della sintassi per Common Lisp è separato dal parametro lispwords della modalità Lisp; ha una sua lista di identificatori. Per esempio, in Vim 7.3 se si accede a questo:

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

Questo è, nonostante il fatto che symbol-macrolet è riconosciuto e colorato. Perché? È perché symbol-macrolet non viene visualizzato nell'elenco piuttosto scarso lispwords, mentre appare nel file di definizione dell'evidenziazione della sintassi lisp.vim.

Il risultato è che si può COB insieme alcuni script che esegue la scansione del directory di .lisp file per le macro e genera un comando set lispwords=... che viene inserito in una directory .vimrc.

Oppure, se si sta lavorando su un dialetto Lisp personalizzato, è sufficiente impostare il file di evidenziazione della sintassi Vim per personalizzare lispwords durante il caricamento.

Ecco una svista: l'opzione lispwords non ha valore locale; non è possibile utilizzare setlocal lispwords ... per assegnargli un valore specifico per il buffer. In altre parole, sembra che (almeno nel Vim 7.3 che sto utilizzando in Ubuntu) non sia possibile aprire due o più buffer con dialetti diversi di Lisp con identificatori diversi per il rientro. Il contenuto predefinito di lispwords contiene un'infarinatura di Lisp e Simboli dello schema per cercare di essere una sorta di soluzione "taglia unica per tutti".

Problemi correlati