Fontifier une région d'un tampon avec un autre mode majeur

12

J'ai un tampon qui montre la documentation des modules Ansible. Ce tampon a son propre mode majeur qui fournit tous les trucs standard. Notamment, il caractérise le tampon pour mettre en évidence le balisage en ligne, les options, les sections, etc. Dans l'ensemble, il est assez similaire à M-x man.

Au bas de la documentation, il y a généralement quelques exemples de code dans YAML. Je voudrais également les classifier. Je pourrais ajouter mes propres mots clés de verrouillage de police pour YAML, bien sûr, mais je préférerais plutôt réutiliser la police de caractères du mode YAML.

Comment puis je faire ça? Plus précisément, comment puis-je utiliser un mode majeur différent pour faire une police dans une région particulière d'un tampon?

Notez que le mode YAML n'a pas besoin d'être actif dans cette région. L'ensemble du tampon n'est qu'un tampon d'affichage passif et n'est pas destiné à être modifié. Je n'ai vraiment besoin que de la police de caractères produite comme si le mode YAML était actif dans cette région.

Je suppose que je pourrais copier la région du tampon dans un tampon temporaire, activer le mode YAML, faire le tampon et recopier toutes les propriétés du texte. Cela fonctionnerait-il? Si oui, comment copier les propriétés du texte et quelles sont les propriétés pertinentes à copier? Ou existe-t-il une meilleure approche?

lunaryorn
la source
Comment la fontification non-yaml est-elle implémentée? Appliquez-vous les propriétés de texte manuellement ou utilisez-vous le mode de verrouillage de police?
Malabarba du
Les liens dans ce post résument au moins une bonne partie des options disponibles: wisdomandwonder.com/link/8610/…
grettke

Réponses:

10

J'ai récemment rencontré un problème similaire, je voulais essentiellement faire des extraits de code dans la documentation dont j'ai obtenu une autre source. J'ai suivi l'approche mentionnée vers la fin de votre réponse et cela a bien fonctionné pour moi. La fonction que je me suis retrouvé avec quelque chose comme ce qui suit

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

Comme @Malabarba l'a souligné dans les commentaires, l'approche simple ci-dessus ne fonctionne pas si le tampon de destination utilise le mode de verrouillage de police. Cependant, nous pouvons faire croire à font-lock-mode que la chaîne est déjà verrouillée par police en définissant la propriété text font-lock-facesur face, (nous obtenons le facejeu de propriétés lorsque nous utilisons la fonction ci-dessus) et en définissant text-property fontifiedsur t. La fonction suivante prend une chaîne renvoyée par la fonction ci-dessus et effectue le traitement requis pour que la chaîne soit insérée dans la police (cela provient de la org-src-font-lock-fontify-blockfonction de 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))

Vous pouvez maintenant l'utiliser comme suit

(insert (my-fontify-using-faces (my-fontify-yaml "application: test\nversion: 1")))
Iqbal Ansari
la source
C'est la même solution que j'ai trouvée sx.el, mais il est important de noter que cela ne fonctionnera que si le tampon de destination n'utilise pas le mode de verrouillage de police.
Malabarba
Droite! Je viens de réaliser que cela fonctionnait pour moi parce que j'utilisais dans un tampon où le verrouillage de police n'était pas utilisé (tampon d'aide)
Iqbal Ansari
@Malabarba a trouvé un moyen de faire fonctionner cela avec des tampons de destination avec le mode de verrouillage des polices activé
Iqbal Ansari
Merci beaucoup, fonctionne parfaitement !
lunaryorn
Oh sympa! Heureux d'avoir pu aider :)
Iqbal Ansari
3

La bibliothèque Narrow Indirect ( narrow-indirect) peut vous aider ici - jetez un œil au commentaire d'en-tête. Elle repose sur:

  1. rétrécissement, qui limite l'édition à une partie sur un tampon, et
  2. tampons indirects, qui copient un tampon dans un autre pour lequel vous pouvez changer le mode principal.

Notez que le rétrécissement est désactivé par défaut car il est considéré comme hostile aux débutants (la liaison par défaut est C-x n n). Vous pouvez l'activer en mettant ce qui suit dans votre fichier init:

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

Vous pouvez également regarder mon fait main myfn-narrow-indirectdans ma conf .

freakhill
la source
Le rétrécissement affecte-t-il réellement le verrouillage de la police, c'est-à-dire qu'il l'éloigne de l'extérieur de la région rétrécie? Le verrouillage des polices ne supprime-t-il jamais vraiment les restrictions de tampon?
lunaryorn
Et de toute façon, un package wiki n'est pas une option.
lunaryorn
De plus, vous n'avez pas besoin de supprimer la disabledpropriété d'une commande pour l'appeler depuis Emacs Lisp. Cela n'affecte que l'utilisation interactive.
lunaryorn
0

Je suggérerais de regarder org-src-font-lock-fontify-block qui fournit cette fonctionnalité pour les blocs sources en mode org. Il semble simplement copier les parties pertinentes dans un autre tampon, y activer le mode principal, puis recopier le texte fontifié. Hackish, mais cela semble fonctionner.

Joakim Hårsman
la source
2
Cette réponse ressemble plus à un commentaire dans la mesure où elle fournit une direction suggérée pour résoudre le problème, mais pas une réponse complète. Veuillez envisager de le changer en commentaire.
Dan