Временный текст в расположении окна без текста для его настройки или наложения?

9

Вопрос: как временно отобразить текст в окне в тех местах экрана, где нет текста для его наложения / наложения?

Я знаком с основной идеей текстовых свойств и наложений (см. Также эту ветку ), несколько раз использовал их, но ни в коем случае не разбираюсь в них. Мое ограниченное понимание состоит в том, что должен быть текст, чтобы настроить или наложить его, но мне интересно, как использовать разделы окна, в которых нет текста.

Вот скриншот для примера:

введите описание изображения здесь

Как можно поместить текст (временно) в одно из красных полей на скриншоте, то есть в пустое пространство справа от текста или ниже последней строки в буфере?

Дэн
источник
Короче говоря, вы можете использовать свойство display для отображения текста, которого там нет. Кто-нибудь может дать полный ответ, прежде чем я вернусь домой.
Малабарба
Режим компании завершает наложение на текст либо при наличии достаточного количества точек после или перед с помощью свойства display, либо он использует свойство after-string для отображения чего-либо ниже конца буфера. Я менее уверен в том, чтобы отображать что-то сбоку, но это возможно при правильной ширине и положении наложения.
Васамаса
Разве вы не можете просто insertотправить текст в буфер и настроить его ?
Рекадо

Ответы:

6

Я подобрал рабочий пример функции, которая берет строку и временно отображает ее с таймаутом после текста буфера:

(defun my-momentarily-display-after-buffer-end (string &optional timeout)
  (let ((ov (make-overlay (point-max) (point-max))))
    (overlay-put ov 'after-string
                 (concat (propertize " " 'display
                                     '(space :align-to (+ left-fringe 10)))
                         (propertize string 'display
                                     '(raise -1))
                         "\n\n"))
    (sit-for (or timeout 5))
    (delete-overlay ov)))

Следующее заклинание приведет к вашему примеру с красной рамкой:

(my-momentarily-display-after-buffer-end "Nothing to see here...")

Причина, по которой это работает, заключается в том, что наложения используют маркеры в качестве позиций для отображения между ними. Использование крайней позиции в качестве начала и конца наложения позволяет отображать текст после него с помощью after-stringсвойства. Так как оверлеи могут содержать персонализированный текст, я настроил его так, чтобы он отображался с отступом и с пробелами вокруг него.

Другой пример может использовать ту же идею для отображения текста после конца строки:

(defun my-momentarily-display-after-line-end (string &optional timeout)
  (let ((ov (make-overlay (line-end-position) (line-end-position))))
    (overlay-put
     ov 'after-string
     (concat (propertize " " 'display
                         `(space :align-to (- right-fringe
                                              ,(1+ (length string)))))
             string))
    (sit-for (or timeout 5))
    (delete-overlay ov)))

Следующий вызов приведет к вашему примеру с красной рамкой справа:

(my-momentarily-display-after-line-end "annotation")

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

wasamasa
источник
2

Вы можете временно отображать текст в буфере с помощью функции momentary-string-display. Требуется сообщение для отображения и позиция в буфере.

Эта:

(momentary-string-display "hello there" 200)

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

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

(let ((ov (make-overlay 1 1)))
  (overlay-put ov 'before-string "this text is not part of the buffer"))

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

По-видимому, невозможно разместить оверлей в любой позиции в буфере, которая больше point-max/ buffer-size, т.е. вы, вероятно, не сможете разместить текст в какой-то конкретной позиции ниже текста в буфере, если не будете обходить это ограничение. Конечно, вы можете поместить текст сразу после буфера текста со after-stringсвойством на оверлей, прикрепленный к point-maxпозиции.

rekado
источник