Fontify область буфера с другим основным режимом

12

У меня есть буфер, который показывает документацию для модулей Ansible. Этот буфер имеет свой собственный основной режим, который обеспечивает все стандартные вещи. Примечательно, что он обозначает буфер для выделения встроенной разметки, параметров, разделов и т. Д. В целом, он очень похож на M-x man.

В нижней части документации обычно есть несколько примеров кода на YAML. Я хотел бы также прояснить это. Конечно, я мог бы добавить свои собственные ключевые слова блокировки шрифта для YAML, но я бы предпочел повторно использовать фонификацию режима YAML.

Как я могу это сделать? В частности, как я могу использовать другой основной режим для обозначения определенной области буфера?

Обратите внимание, что режим YAML не обязательно должен быть активным в этом регионе. Весь буфер является только пассивным буфером отображения и не предназначен для редактирования. Мне действительно нужно только оформление, как будто режим YAML был активен в этом регионе.

Я предполагаю, что могу скопировать область буфера во временный буфер, включить режим YAML, сообщить о буфере и скопировать все свойства текста. Будет ли это работать? Если да, то как мне скопировать свойства текста и какие соответствующие свойства нужно скопировать? Или есть лучший подход?

lunaryorn
источник
Как реализована неамлская фонтификация? Применяете ли вы свойства текста вручную или используете режим font-lock-mode?
Малабарба
Ссылки в этом посте суммируют, по крайней мере, значительную часть доступных вариантов: wisdomandwonder.com/link/8610/…
grettke

Ответы:

10

Недавно я столкнулся с подобной проблемой, я в основном хотел описать фрагменты кода в документации, которую я получил из другого источника. Я придерживался подхода, упомянутого ближе к концу вашего ответа, и он работал хорошо для меня. Функция, которую я закончил с чем-то вроде следующего

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

Как отметил @Malabarba в комментариях, простой подход выше не работает, если целевой буфер использует режим font-lock-mode. Однако мы можем обмануть font-lock-mode, заставив поверить, что строка уже заблокирована шрифтом, установив для свойства text font-lock-faceзначение face(мы получим faceнабор свойств, когда будем использовать вышеописанную функцию) и установив text-property fontifiedдля t. Следующая функция принимает строку , возвращенную функцией выше и делает необходимой обработку таким образом , что строка вставляется fontified (это берется из орга-режим в 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))

Теперь вы можете использовать его следующим образом

(insert (my-fontify-using-faces (my-fontify-yaml "application: test\nversion: 1")))
Икбал Ансари
источник
Это то же решение, которое я нашел sx.el, но важно отметить, что оно будет работать, только если целевой буфер не использует режим font-lock-mode.
Малабарба
Правильно! Я только что понял, что это работает для меня, потому что я использовал в буфере, где не использовалась font-lock (буфер справки)
Iqbal Ansari
@Malabarba нашел способ заставить эту работу работать с буферами назначения с включенным режимом font-lock
Iqbal Ansari
Большое спасибо, работает отлично !
lunaryorn
О, классно! Рад, что смог помочь :)
Икбал Ансари
3

Здесь может помочь библиотека Narrow Indirect ( narrow-indirect) - взгляните на заголовок комментария. Это зависит от:

  1. сужение, ограничивающее редактирование частью буфера, и
  2. косвенные буферы, которые копируют буфер в другой, для которого вы можете изменить основной режим.

Обратите внимание, что сужение по умолчанию отключено, поскольку оно считается недружественным для начинающих (по умолчанию используется привязка C-x n n). Вы можете включить его, поместив в файл инициализации следующее:

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

Вы также можете посмотреть на мою ручной работы myfn-narrow-indirectв моей конф .

freakhill
источник
Влияет ли сужение на фактическую блокировку шрифта, т. Е. Держать его вне внешней области сужения? Блокировка шрифтов действительно никогда не снимает ограничения буфера?
lunaryorn
И вообще, вики-пакет не вариант.
lunaryorn
Кроме того, вам не нужно удалять disabledсвойство из команды, чтобы вызвать его из Emacs Lisp. Это влияет только на интерактивное использование.
lunaryorn
0

Я хотел бы предложить посмотреть на org-src-font-lock-fontify-block, который предоставляет эту функциональность для исходных блоков режима org. Кажется, просто скопировать соответствующие части в другой буфер, включить там основной режим, а затем скопировать отформатированный текст обратно. Hackish, но, похоже, работает.

Йоаким Хорсман
источник
2
Этот ответ больше похож на комментарий, поскольку он предлагает предполагаемое направление для решения проблемы, но не полный ответ. Пожалуйста, подумайте о том, чтобы поменять его на комментарий.
Дан