Alle ausstehenden Klammern schließen

14

Beim Schreiben von Lisp-Codes stecke ich manchmal tief in einem verschachtelten Ausdruck und möchte nur die fehlenden schließenden Klammern einfügen. Im Moment füge ich sie nur ein, bis ich ein nicht übereinstimmendes Paren erhalte, aber es ist nicht sehr effizient.
Gibt es einen Befehl zum Einfügen aller fehlenden Klammern?

Zu Ihrer Information, ich verwende Smartparens, um automatisch passende Parens einzufügen. Trotzdem muss ich das manchmal einfach tun.

Rlazo
quelle
2
FWIW, Franz Lisp (vor CL) hatte ein Feature, in dem ein ]Super-Right-Paren fungierte und alle offenen Parens schloss, wie Sie es wünschen.
Drew
2
Ich habe in der Vergangenheit die gleiche Methode angewendet. Seitdem benutze ich paredit , wodurch das Problem vor dem Start gestoppt wird. Die einzige Einschränkung ist, dass das Einfügen von Code nicht die gleiche Ausgleichsbehandlung erhält.
Elarson

Antworten:

6

Hier ist eine Funktion, die alle nicht geschlossenen Klammern und anderen übereinstimmenden Paare schließt. Es basiert auf Emacs 'Sexp-Analyse. Es unterstützt nur einzelne Zeichen matched pairs, so etwas wie {-mit geschlossen wird }, nicht -}. Für Lisp spielt das keine Rolle.

(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))))
Gilles 'SO - hör auf böse zu sein'
quelle
IIUC, Dies erfordert, dass sich der Punkt nicht in einer passenden Klammer befindet. Ich hatte den Eindruck, dass der OQ von einigen innerhalb eines Lisp-Ausdrucks aus arbeiten musste, wobei fertige Klammern nicht übereinstimmen, andere jedoch nicht.
Malabarba
@Malabarba Hiermit werden alle zuvor geöffneten Klammern geschlossen, unabhängig davon, ob sie nach Punkt bereits übereinstimmende schließende Klammern hatten oder nicht. So verstehe ich die Frage, aber es ist zugegebenermaßen in diesem Punkt nicht klar. Wo würden nach Ihrer Interpretation die abschließenden Begrenzer eingefügt? ZB mit ([-!-foo], fügst du ])an Punkt ein, oder )nach foo]?
Gilles 'SO- hör auf böse zu sein'
wenn Sie von meinem Verständnis haben ([-!-foo], würde ich einfügen )nach foo]. Aber ich könnte mich natürlich irren. Vielleicht kann @rlazo näher darauf eingehen.
Malabarba
Für meinen Anwendungsfall ist @Gilles richtig. Es ist mir egal, ob die Begrenzer nach dem Punkt geschlossen sind. Ich möchte alles vor dem Punkt schließen.
Rlazo
3

Ich habe herausgefunden, dass, wenn Sie Schleim installiert haben, es einen Befehl gibt, der aufgerufen wird slime-close-all-parens-in-sexp

Rlazo
quelle
Hmm ... also scheint dies auf der aktuellen Zeile zu schließen. Es wäre schön, wenn es einen Ansatz gäbe, der "den aktuellen Block" schloss. Dies könnte erreicht werden, indem man zum Ende der Datei geht und dann den Sexp rückwärts bewegt, bis etwas nicht mehr gefunden wird.
Att Righ
1

Ein sehr primitiver (und mit ziemlicher Sicherheit falscher) Weg, dies zu tun, wäre

(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 ")")))

Unter anderem wird davon ausgegangen, dass folgende Klammern eingefügt werden müssen:

  • schließende
  • am aktuellen Standort benötigt

Ich denke, es könnte gerade genug sein, um für Ihren speziellen Anwendungsfall nützlich zu sein

Sigma
quelle
Dies bleibt in einer Endlosschleife stecken, wenn Sie zu viele schließende Klammern haben.
Emil Vikström
@ EmilVikström yep, das ist in der Tat nicht kompatibel mit meiner ersten angegebenen Einschränkung :)
Sigma