Chiusura di tutte le parentesi in sospeso


14

Quando scrivo i codici lisp, a volte sono profondamente in un'espressione nidificata e tutto ciò che voglio è inserire tutta la parentesi di chiusura mancante. In questo momento li sto solo inserendo fino a quando non ottengo un paren corrispondente, ma non è molto efficiente.
Esiste un comando per inserire tutte le parentesi mancanti?

Cordiali saluti, sto usando smartparens per inserire automaticamente le parentesi corrispondenti. Tuttavia, a volte ho solo bisogno di farlo.


2
FWIW, Franz Lisp (prima di CL) aveva una funzione in cui un ]paren super-destra, chiudendo tutte le parentesi aperte, come da lei richiesto.
Disegnò il

2
Ho usato la stessa metodologia in passato. Da allora ho iniziato a utilizzare paredit , che interrompe il problema prima che inizi. L'unica avvertenza è che incollare nel codice non ottiene lo stesso trattamento di bilanciamento.
elarson,

Risposte:


6

Ecco una funzione che chiude tutte le parentesi non chiuse e le altre coppie abbinate. Si basa sull'analisi del sexp di Emacs. Supporta solo coppie abbinate a carattere singolo, quindi qualcosa di simile {-verrà chiuso con }, non -}. Per Lisp, non importa.

(defun close-all-parentheses ()
  (interactive "*")
  (let ((closing nil))
    (save-excursion
      (while (condition-case nil
         (progn
           (backward-up-list)
           (let ((syntax (syntax-after (point))))
             (case (car syntax)
               ((4) (setq closing (cons (cdr syntax) closing)))
               ((7 8) (setq closing (cons (char-after (point)) closing)))))
           t)
           ((scan-error) nil))))
    (apply #'insert (nreverse closing))))

IIUC, Ciò richiede che il punto non sia all'interno di alcun set di parentesi abbinate. Avevo l'impressione che OQ avesse bisogno di lavorare da alcuni all'interno di un'espressione lisp, in cui le parentesi fatte non corrispondevano ma altre no.
Malabarba,

@Malabarba Questo chiude tutte le parentesi aperte in precedenza, indipendentemente dal fatto che abbiano già avuto parentesi di chiusura corrispondenti dopo punto o no. Ecco come capisco la domanda, ma è vero che non è chiaro su questo punto. Secondo la tua interpretazione, dove verranno inseriti i delimitatori di chiusura? Ad es. Con ([-!-foo], si inserisce ])nel punto o )dopo foo]?
Gilles 'SO- smetti di essere malvagio'

dalla mia comprensione, se avete ([-!-foo], vorrei inserire )dopo foo]. Ma potrei sbagliarmi, ovviamente. Forse @rlazo può elaborare.
Malabarba,

per il mio caso d'uso, @Gilles ha ragione, non mi importa se i delimitatori sono chiusi dopo il punto, voglio chiudere tutto prima del punto.
rlazo,

3

Ho scoperto che se hai installato melma, c'è un comando per farlo, chiamato slime-close-all-parens-in-sexp


Hmm ... quindi questo sembra chiudersi sulla riga corrente. Potrebbe essere bello se ci fosse un approccio che chiudesse "il blocco attuale". Ciò potrebbe essere ottenuto andando alla fine del file e quindi spostando il sexp all'indietro fino a quando non viene trovato qualcosa di non chiuso.
Att Righ,

1

Un modo molto primitivo (e quasi certamente sbagliato) di farlo sarebbe

(defun buffer-needs-parens-fixing ()
  (save-excursion
    (condition-case nil
        (check-parens)
      (error (point)))))

(defun buffer-fix-parens ()
  (interactive)
  (while (buffer-needs-parens-fixing)
    (insert ")")))

Tra le altre limitazioni, si presuppone che tutte le parentesi che devono essere inserite siano:

  • quelli di chiusura
  • necessario nella posizione corrente

Immagino che potrebbe essere sufficiente per essere utile per il tuo caso d'uso specifico


Questo si blocca in un ciclo infinito se hai troppe parentesi di chiusura.
Emil Vikström,

@EmilVikström sì, non è compatibile con la mia prima limitazione dichiarata :)
Sigma
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.