font-lock – Fontifica una región de un búfer con otro modo mayor

Pregunta:

Tengo un búfer que muestra la documentación de los módulos de Ansible. Este búfer tiene su propio modo principal que proporciona todo el material estándar. En particular, le asigna fuentes al búfer para resaltar el marcado en línea, las opciones, las secciones, etc. En general, es bastante similar a Mx man .

En la parte inferior de la documentación suele haber algunos ejemplos de código en YAML. También me gustaría fontificar estos. Podría agregar mis propias palabras clave de bloqueo de fuente para YAML, por supuesto, pero prefiero reutilizar la fuente del modo YAML.

¿Cómo puedo hacer eso? Específicamente, ¿cómo puedo usar un modo principal diferente para fontificar una región particular de un búfer?

Tenga en cuenta que el modo YAML no necesita estar activo en esta región. El búfer completo es solo un búfer de visualización pasivo y no está diseñado para ser editado. Realmente solo necesito la fontificación producida como si el modo YAML estuviera activo en esa región.

Supongo que podría copiar la región del búfer en un búfer temporal, habilitar el modo YAML, escribir el búfer y copiar todas las propiedades del texto. Funcionaría eso? Si es así, ¿cómo copio las propiedades del texto y cuáles son las propiedades relevantes para copiar? ¿O hay un mejor enfoque?

Respuesta:

Recientemente me encontré con un problema similar, básicamente quería escribir fragmentos de código en la documentación que obtuve en otra fuente. Seguí el enfoque mencionado hacia el final de su respuesta y funcionó bien para mí. La función que terminé con algo como lo siguiente

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

Como @Malabarba señaló en los comentarios, el enfoque simple anterior no funciona si el búfer de destino usa el modo de bloqueo de fuente. Sin embargo, podemos engañar a font-lock-mode para que crea que la cadena ya está bloqueada con la fuente configurando la propiedad de texto font-lock-face en la face (obtenemos la propiedad de la face establecida, cuando usamos la función anterior) y configurando el texto -propiedad fontified en t . La siguiente función toma una cadena devuelta por la función anterior y realiza el procesamiento requerido para que la cadena se inserte fontificada (esto se toma de la función org-mode's org-src-font-lock-fontify-block

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

Ahora puedes usarlo de la siguiente manera

(insert (my-fontify-using-faces (my-fontify-yaml "application: test\nversion: 1")))

Leave a Comment

Your email address will not be published.

Scroll to Top

istanbul avukat

-

web tasarım