Beschriften Sie einen Bereich eines Puffers mit einem anderen Hauptmodus

12

Ich habe einen Puffer, der Dokumentation für Ansible-Module zeigt. Dieser Puffer verfügt über einen eigenen Hauptmodus, der alle Standardfunktionen bereitstellt. Insbesondere wird der Puffer mit einer Schriftart versehen, um Inline-Markups, Optionen, Abschnitte usw. hervorzuheben. Insgesamt ist er ziemlich ähnlich M-x man.

Am Ende der Dokumentation befinden sich normalerweise einige Codebeispiele in YAML. Ich möchte diese auch fontifizieren. Ich könnte natürlich meine eigenen Schlüsselwörter für die Schriftsperre für YAML hinzufügen, aber ich würde es vorziehen, die Schriftart des YAML-Modus wiederzuverwenden.

Wie kann ich das machen? Wie kann ich einen anderen Hauptmodus verwenden, um einen bestimmten Bereich eines Puffers zu fontifizieren?

Beachten Sie, dass YAML - Modus muss nicht sein aktiv in dieser Region. Der gesamte Puffer ist nur ein passiver Anzeigepuffer und nicht zum Bearbeiten vorgesehen. Ich brauche wirklich nur die Schrift, die erzeugt wird, als ob der YAML-Modus in dieser Region aktiv wäre.

Ich nehme an, ich könnte den Bereich des Puffers in einen temporären Puffer kopieren, den YAML-Modus aktivieren, den Puffer fontifizieren und alle Texteigenschaften kopieren. Funktioniert das? Wenn ja, wie kopiere ich Texteigenschaften und welche relevanten Eigenschaften müssen kopiert werden? Oder gibt es einen besseren Ansatz?

Mondhorn
quelle
Wie wird die Nicht-Yaml-Fontifizierung implementiert? Wenden Sie Texteigenschaften manuell an oder verwenden Sie den Schriftsperrmodus?
Malabarba
Die Links in diesem Beitrag fassen mindestens einen guten Teil der verfügbaren
grettke

Antworten:

10

Ich bin vor kurzem auf ein ähnliches Problem gestoßen, ich wollte im Grunde Codeausschnitte in der Dokumentation, die ich aus einer anderen Quelle erhielt, fontifizieren. Ich bin dem Ansatz gefolgt, der gegen Ende Ihrer Antwort erwähnt wurde, und es hat für mich gut funktioniert. Die Funktion endete mit etwas wie der folgenden

(defun my-fontify-yaml (text)
  (with-temp-buffer
    (erase-buffer)
    (insert text)
    (delay-mode-hooks (yaml-mode))
    (font-lock-default-function 'yaml-mode)
    (font-lock-default-fontify-region (point-min)
                                      (point-max)
                                      nil)
    (buffer-string)))

Wie @Malabarba in Kommentaren hervorhob, funktioniert der oben beschriebene einfache Ansatz nicht, wenn der Zielpuffer den Schriftsperrmodus verwendet. Allerdings können wir font-Lock-Modus in dem Glauben verleiten , dass die Zeichenfolge bereits Schriftart , indem Sie die Texteigenschaft gesperrt sind font-lock-facezu dem face, (wir bekommen faceObjekt, wenn wir die Funktion oben verwenden) und Einstellung Text-Eigenschaft fontifiedauf t. Die folgende Funktion verwendet eine Zeichenfolge, die von der obigen Funktion zurückgegeben wird, und führt die erforderliche Verarbeitung durch, damit die Zeichenfolge in Schrift eingefügt wird (dies stammt aus der org-src-font-lock-fontify-blockFunktion von org-mode

(defun my-fontify-using-faces (text)
  (let ((pos 0))
    (while (setq next (next-single-property-change pos 'face text))
      (put-text-property pos next 'font-lock-face (get-text-property pos 'face text) text)
      (setq pos next))
    (add-text-properties 0  (length text) '(fontified t) text)
    text))

Jetzt können Sie es wie folgt verwenden

(insert (my-fontify-using-faces (my-fontify-yaml "application: test\nversion: 1")))
Iqbal Ansari
quelle
Dies ist die gleiche Lösung, für die ich gefunden habe sx.el, aber es ist wichtig zu beachten, dass sie nur funktioniert, wenn der Zielpuffer den Font-Lock-Modus nicht verwendet.
Malabarba
Richtig! Ich habe gerade festgestellt, dass dies bei mir funktioniert, weil ich in einem Puffer verwendet habe, in dem keine Schriftsperre verwendet wurde (Hilfepuffer)
Iqbal Ansari
@Malabarba hat eine Möglichkeit gefunden, diese Funktion mit Zielpuffern mit aktiviertem Schriftsperrmodus auszuführen
Iqbal Ansari
Vielen Dank, funktioniert einwandfrei !
Lunaryorn
Oh schön! Froh, dass ich helfen konnte :)
Iqbal Ansari
3

Library Narrow Indirect ( narrow-indirect) kann hier Abhilfe schaffen - siehe Kopfkommentar. Es beruht auf:

  1. Verengung, die die Bearbeitung auf einen Teil eines Puffers beschränkt, und
  2. indirekte Puffer, die einen Puffer in einen anderen kopieren, für den Sie den Hauptmodus ändern können.

Beachten Sie, dass die Verengung standardmäßig deaktiviert ist, da sie als anfängerunfreundlich eingestuft wird (die Standardbindung lautet C-x n n). Sie können es aktivieren, indem Sie Folgendes in Ihre Init-Datei einfügen:

(put 'narrow-to-region 'disabled nil)

Sie können sich auch meine Handarbeit myfn-narrow-indirectin meinem Conf ansehen .

verrückt
quelle
Beeinflusst die Verengung tatsächlich die Schriftsperre, dh halten Sie sie von außerhalb des verengten Bereichs fern? Entfernt die Schriftsperre wirklich niemals Puffereinschränkungen?
Lunaryorn
Ein Wiki-Paket ist sowieso keine Option.
Lunaryorn
Außerdem müssen Sie die disabledEigenschaft nicht aus einem Befehl entfernen , um sie in Emacs Lisp aufzurufen. Dies betrifft nur die interaktive Verwendung.
Lunaryorn
0

Ich würde vorschlagen, sich den org-src-font-lock-fontify-Block anzuschauen, der diese Funktionalität für org-mode-Quellblöcke bietet. Es scheint nur die relevanten Teile in einen anderen Puffer zu kopieren, den Hauptmodus dort zu aktivieren und dann den geschriebenen Text zurück zu kopieren. Hackish, aber es scheint zu funktionieren.

Joakim Hårsman
quelle
2
Diese Antwort sieht eher wie ein Kommentar aus, da sie eine vorgeschlagene Anleitung zur Lösung des Problems enthält, jedoch keine vollständige Antwort. Bitte überlegen Sie, es in einen Kommentar zu ändern.
Dan