Для чего нужны оверлеи и чем они отличаются от свойств текста?

23

В руководстве говорится:

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

Исходя из его названия, он предполагает, что его можно использовать для создания «слоев» поверх существующего текста, но приведенное выше описание, кажется, указывает, что оно изменяет внешний вид текста, который очень похож на свойства текста.

Что такое конкретное использование оверлеев? Что они предлагают, чего нет в свойствах текста? Могут ли они использоваться для записи текста поверх текста в буфере, например, всплывающем окне, информационном окне и т. Д.?

Себастьян Ле Каллонек
источник
Прочитайте больше из этого руководства, а не только одно предложение. Это довольно четко объяснено, ИМО. В том числе отличия от свойств текста. Смотрите также (в том же руководстве) i text properties, конечно.
Дрю

Ответы:

10

Что такое оверлеи?

Прежде всего, это объекты elisp. Это будет актуально позже.

Как вы сказали сами, они представляют слои, которые наносятся поверх областей буфера. Эти слои имеют свойства текста, так же как и текст в буфере. Любое обычное свойство, которое имеет оверлей, применяется к тексту под ним. Однако есть некоторые свойства, которые являются специальными для наложений (они ничего не делают, если применяются к тексту).

Почему они полезны?

По двум причинам, на которые я намекал выше:

Они объекты

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

Этот ответ Стефана является хорошим примером наложений, используемых для отслеживания буферных областей. Вот короткий фрагмент этого.

(let ((ol (make-overlay beg end)))
  (overlay-put ol 'evaporate t)
  (overlay-put ol 'my--auto-align-regexp regexp)
  (push ol my--auto-align-overlays))

Он использует наложения для записи того, какие регионы должны быть выровнены, и какие регулярные выражения использовать для каждого из них. my--auto-align-overlaysявляется

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

Они немного мощнее

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

before-string
Значение этого свойства является строкой, добавляемой к отображению в начале наложения. Строка не появляется в буфере ни в каком смысле - только на экране.
line-prefix
Это свойство определяет спецификацию отображения, которая должна добавляться к каждой строке без продолжения во время отображения. Смотрите усечение.
wrap-prefix
Это свойство определяет спецификацию отображения, которая должна предшествовать каждой строке продолжения во время отображения. Смотрите усечение.

В частности, before-stringсвойство позволяет влиять на отображение буфера даже при наложении шириной 0. Что нельзя делать со свойством text. Все, что вы делаете со свойствами текста, должно либо проходить по существующему тексту (который может скрыть этот текст), либо проходить по новой строке текста, которую вы вставляете (которая изменяет реальное содержимое буфера).

Вот пример сниппета об этом. Оцените его во временном буфере.

(overlay-put (make-overlay (point) (point)) 'before-string "Hi there!")

Когда они плохие?

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

Malabarba
источник
12

Оверлеи и свойства текста имеют точно такие же возможности. Они добавляют поля изменений, кнопки, грани, значки полос, всплывающие подсказки, изображения, блики и т. Д. К определенной части текста. Однако существует огромная концептуальная разница:

Наложения являются независимыми , свойства текста - нет. Emacs имеет отдельный тип оверлея, но «тип свойства текста» отсутствует. Свойства текста по своей сути связаны со строкой, в которой они были установлены. С другой стороны, оверлеи прикрепляются к буферу.

Есть несколько практических последствий этого различия:

  • Вы можете установить свойства текста для строк, которые не являются частью какого-либо буфера, тогда как вам всегда нужен буфер для наложений.
  • Вы не можете хранить список текстовых свойств, которые вы добавили где-то, тогда как легко сохранить список наложений, добавленных в буфер, и, например, удалить все ваши наложения за один раз.
  • У вас может быть одно наложение, которое устанавливает несколько наложений на текст (например, лицо, всплывающую подсказку и значок края), так что вы можете использовать наложение для управления «группой» свойств как единым целым, в то время как нет такая вещь для свойств текста. Вы устанавливаете их индивидуально, и вы управляете ими индивидуально.

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

На практике вы бы использовали оверлеи, если материал, который вы хотите добавить к тексту, часто меняются, тогда как вы использовали бы свойства текста, если материал постоянный.

Например, Emacs использует свойства текста для создания кнопок и входных виджетов в M-x customizeбуфере. Эти виджеты создаются один раз и остаются там до тех пор, пока буфер активен, поэтому нет необходимости вносить оверлеи.

Тем не менее, Flycheck использует оверлеи для выделения ошибок в буфере, потому что часто нужно удалять и добавлять блики.

lunaryorn
источник