2010-12-30 12 views
6

Ich bin auf der Suche nach einer yasnippet Vorlage, die mir erlauben würde, einen Lizenz-Header zu einem Skript-Puffer in Emacs hinzuzufügen. Kinda wie this, aber ein bisschen verbessert:box-style Kommentare mit yasnippet

  1. Der Header pro-Benutzerdaten umfassen muss, wie das Datum Name und E-Mail des Urhebers, die mit embedded elisp expansion von yasnippet erhalten werden kann.
  2. Der Header muss mit einer Syntax kommentiert werden, die vom Programmiermodus abhängt, in dem sich die Datei gerade befindet. Es gibt bereits a gist of a snippet that does all that. Grundsätzlich wird am Ende des Snippets (comment-region (point-min) (point)) eingebettet.
  3. Jetzt, Ich möchte den Kommentar-Stil in eine Box ändern. Sehen Sie sich die emacs-Dokumentation für die Variable comment-style an, oder, wenn Sie sehen möchten, wie ein Boxstil-Kommentar aussieht, rufen Sie einfach M-x comment-box für eine aktive Region auf: Er ruft comment-region mit den richtigen Optionen auf.

Ein erster Ansatz, das zu tun ist, um die Art zu installieren, indem das Ende des vorherigen Schnipsel Modifizieren:

(let ((comment-style 'box)) 
      (comment-region (point-min) (point))) 

Leider wird die Vertiefung geschraubt, und meine Box nicht rechteckig ist,. Wenn ich von Schnipsel starten:

Copyright (c) ${1:`(nth 5 (decode-time))`} 
All rights reserved. 

Redistribution and use in source and binary forms, with or 
without modification, are permitted` 
     (let ((comment-style 'box)) 
      (comment-region (point-min) (point)))` 

Die Erweiterung dieses Snippet "bricht das Feld" (Ich bin das Debuggen dieses Schnipsel mit ocaml Kommentar Syntax, nicht, dass es sollte egal):

(**************************************************************) 
(* Copyright (c) 2010         *) 
(* All rights reserved.          *) 
(*               *) 
(* Redistribution and use in source and binary forms, with or *) 
(* without modification, are permitted  *) 
(**************************************************************) 
  • Zuerst dachte ich, die zweite Zeile wurde auf der Grundlage der Größe der vor der Expansion eingebetteten Code eingerückt, aber in diesem Fall sollte es die endgültige *) dieser Zeile 25 Felder zu früh kommen, nicht 4.
  • Wenn es eingerückt basierend auf nein Text am Einbettungspunkt vorhanden ist, sollte das endgültige *) auch 4 Plätze ankommen spät, nicht zu bald.
  • Schließlich verstehe ich nicht, was los ist mit der letzten Zeile, in der keine eingebettete Code-Erweiterung ist: Normalerweise habe ich kein Problem, eine quadratische Kommentarfeld aus einem Absatz mit einer kurzen letzten Zeile (entweder mit comment-box oder der elisp Funktion in dem ersten Kommentar-Block dieser Frage.

ich habe versucht, der Kommentar nach Schnipsel Expansion passieren zu machen, jede Nebenwirkung zu vermeiden, indem sie yas/after-exit-snippet-hook hinzufügen, ersetzen die letzte Funktion des obigen Schnipsel mit:

(add-hook 'yas/after-exit-snippet-hook 
     (let ((comment-style 'box)) 
      (comment-region (point-min) (point))) nil t) 

Aber das hat nicht geholfen. Selbst wenn es so wäre, würde es mich mit einem Expansionshaken verlassen, der die Snippets notieren würde, die ich in diesem Puffer verwenden möchte, etwas, das ich sicher nicht will.

sollte ich noch hinzufügen, dass ich durch das Hinzufügen

# expand-env: ((yas/indent-line 'fixed)) 

am Anfang meiner Schnipsel yas/indent-line-fixed zu setzen versucht, aber das hat nichts ändern. Irgendwelche Ideen, wie man eine rechteckige Box erhält?


Edit: Wir haben a very nice answer, along with a proposed fix, (! Dicken Lob & Dank, Seiji), aber eine Frage bleibt, wie es auf den Fall anzupassen, wo man möchte ein Feld wieder zu verwenden, sagen, wie die Wiederverwendung von $1 in :

Copyright (c) ${1:`(nth 5 (decode-time))`} 
All rights reserved. 

Redistribution and use in $1, in source and binary forms 
`(let ((comment-style 'box)) 
     (comment-region (point-min) (point-at-eol 0)))` 

In diesem Fall kann die Template-Engine kopiert der (variable-length) Wert $1 für das Feld erhalten, nämlich 2011, bis zur letzten Zeile, bei Vorlage Expansion (nach Einkerbung), was eine Kommentarzeile 2 Chara cters zu breit. Es wird schwer vorherzusagen, wenn man die Vorlage schreibt, dass man Zeichen an dieser Zeile entfernen sollte. Vielleicht Feldwiederverwendung und richtigen Einzug sind zu viel, um gleichzeitig zu fragen. Sieht jemand einen Weg, dies zu tun?

Antwort

5

Durch das Ändern Ihres Snippets wird die letzte Zeile repariert.

Copyright (c) ${1:`(nth 5 (decode-time))`} 
All rights reserved. 

Redistribution and use in source and binary forms, with or 
without modification, are permitted 
`(let ((comment-style 'box))(comment-region (point-min) (point-at-eol 0)))` 

Beachten Sie, dass es zwischen der Lizenz („... sind zulässig“) und Embedded-Emacs Code lispeln ein Zeilenumbruch ist.

Wie für die zweite Zeile, werde ich zuerst erklären, warum dies auftritt und dann eine (hässliche) Lösung anbieten. Wenn Ihr Snippet in eine Datei eingefügt wird, werden eingebettete Lispeblöcke nacheinander vom Anfang des Puffers bis zum Ende ausgewertet. Dies bedeutet, dass (nth 5 (decode-time)) durch 2011 ersetzt wurde, wenn der nächste Block, (comment-region ...), ausgewertet wird.

Als Ergebnis sieht comment-region die zweite Zeile als

Copyright (c) ${1:2011} 

So legt comment-region genug weißen Räume diese Zeichenfolge. Dann transformiert die Vorlagen-Engine ${1:2011} in 2011, und diese Umwandlung verkürzt die Zeichenfolge um 5 Zeichen. Dies erklärt das vorzeitige Auftreten von *) um 5 Zeichen in der zweiten Zeile.

Eine Möglichkeit, diese Situation zu beheben, ist Putting 5 White Spaces zurück nach comment-region ausgewertet --- Etwas entlang der Linie:

Copyright (c) ${1:`(nth 5 (decode-time))`} @ 
All rights reserved. 

Redistribution and use in source and binary forms, with or 
without modification, are permitted. 
`(let ((comment-style 'box))(comment-region (point-min) (point-at-eol 0)))`` 
(replace-string "@" "  " nil (point-min) (point))`$0 
+0

Danke für die "Point-at-Eol" Vorschlag, es vollständig behoben das Problem der letzte Linie. ** Tolle ** Erklärung, danke. Ihr Fix funktioniert, aber es ist schmerzhaft, auf viele Felder in einer Zeile zu verallgemeinern (wo Sie den Textbaustein für jede Vorlage manuell zählen müssen) und unmöglich auf eine * Wiederverwendung * des Feldes $ 1 an anderer Stelle in der Vorlage zu erweitern (wo Sie würden) müssen ** so viele Leerzeichen entfernen wie die Auswertung der erzeugten eingebetteten Lispes **. Ich warte eine Weile, und wenn niemand eine Lösung dafür findet, werde ich Ihre Antwort "akzeptieren". – huitseeker

+1

Ich stimme zu, dass meine Lösung für die zweite Zeile suboptimal ist. Es wäre toll, wenn 'yas/after-exit-snipeet-hook' an dem Text arbeitet, den wir sehen. Es scheint jedoch, dass der Hook auf dem zugrunde liegenden Text (z.B. $ {1: ...} ') funktioniert. Übrigens, wenn Sie den Hook in '# expand-env' setzen, wirkt sich der Hook nur auf den Snippet und nicht auf andere Snippets aus --- indem Sie' # expand-env: ((yas/after-exit-snippet-hook (Liste (lassen ((Kommentar-Stil 'Box)) (Kommentar-Bereich (Punkt-min) (Punkt-Max) nil))))) ' –

1

Diese von Nutzen für Sie sein könnten:

# -*- mode: snippet -*- 
# name: param 
# key: param 
# -- 
m.parameter :${1:arg},${1:$(make-string (- 14 (string-width text)) ?\ 
         )}:${2:type}$> 

Es verwendet eine Spiegelung mit einer Funktion zum Erstellen der Positionierung Leerzeichen. Also, für Sie, so etwas wie dies bedeuten könnte:

(* Copyright (c) ${1:2011}${1:$(make-string (- 72 (string-width text)) ?\)} *) 
(* ${2}${2:$(make-string (- 72 (string-width text)))}*) 

Eine weitere Option könnte sein, yas/after-exit-snippet-hook zu verwenden, aber das scheint veraltet zu sein.(oh, und ich wollte den Text selbst filtern, die Kommentar-Region, die Sie bereits versucht haben, ist klüger. Versuchen Sie Einrückung-Region?)

+0

Dies ist schlau, aber leider, wie in [Seiji's Antwort] (http erklärt : //stackoverflow.com/questions/4563788/box-style-comments-with-yasnippet/4583535#4583535), ersetzt die Template-Engine die Felder * nach * der Ausführung von Blöcken, was bedeutet, dass das Leerzeichen von '(make-string ...) 'ist zweimal 5 Zeichen kurz (für' $ {1:} $ {1:} '). (Danke für den Haken Vorschlag, aber ich erwähnte bereits meine erfolglosen Versuche in der ursprünglichen Frage) – huitseeker