¿Texto temporal en la ubicación de la ventana sin texto para propiedad / superposición?

9

P: ¿cómo muestro temporalmente el texto en una ventana en ubicaciones de pantalla sin texto para propiedad / superposición?

Estoy familiarizado con la idea básica detrás de las propiedades y superposiciones de texto (vea también este hilo ), las he usado varias veces, pero de ninguna manera soy experto en ellas. Mi comprensión limitada es que debe haber texto para apropiarse o superponerse, pero me pregunto cómo usar secciones de una ventana que no tengan ningún texto.

Aquí hay una captura de pantalla para un ejemplo:

ingrese la descripción de la imagen aquí

¿Cómo se puede poner texto (temporalmente) en uno de los cuadros rojos en la captura de pantalla, es decir, el espacio en blanco a la derecha del texto, o debajo de la última línea en el búfer?

Dan
fuente
En resumen, puede usar la propiedad de visualización para mostrar texto que no está allí. Alguien puede dar una respuesta completa antes de que llegue a casa.
Malabarba
El modo empresa logra colocar una superposición en el texto si hay suficiente después o antes del punto con la propiedad de visualización, alternativamente, utiliza la propiedad de cadena posterior para mostrar algo debajo del final del búfer. Estoy menos seguro de mostrar algo a un lado, pero parece posible con el ancho y la posición correctos de la superposición.
wasamasa
¿No puedes simplemente insertenviar mensajes de texto al búfer y apropiarte de eso?
Rekado

Respuestas:

6

He preparado un ejemplo funcional de una función que toma una cadena y la muestra temporalmente con un tiempo de espera después del texto del búfer:

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

El siguiente encantamiento dará como resultado su ejemplo de cuadro rojo inferior:

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

La razón por la que esto funciona es porque las superposiciones usan marcadores como posiciones para mostrar entre ellas. El uso de la posición más externa como inicio y final de la superposición le permite mostrar texto después de él mediante la after-stringpropiedad. Dado que las superposiciones pueden contener texto propio, lo configuré para que aparezca sangrado y con espacios en blanco a su alrededor.

El otro ejemplo puede usar la misma idea para mostrar texto después del final de la línea:

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

La siguiente invocación resultará en su ejemplo de cuadro rojo del lado derecho:

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

Puede volverse mucho más loco y agregar caras para distinguir estas superposiciones del texto del búfer, mostrarlas durante más tiempo que un tiempo de espera, ajustar su posición, detectar cuándo no hay espacio vacío y usar superposiciones normales de texto propio, etc. Recomiendo mirar el código fuente del modo empresa porque es muy legible y demuestra un uso más elaborado (y en su mayoría libre de errores) de superposiciones para crear un menú emergente flexible con las características sugeridas.

wasamasa
fuente
2

Puede mostrar temporalmente el texto en un búfer con la función momentary-string-display. Se necesita un mensaje para mostrar y una posición en el búfer.

Esta:

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

colocará la cadena "hola allí" en la posición 200 en el búfer. En este punto, moverá el resto del texto a un lado para dejar espacio para "hola mundo", pero todo se restaurará a donde estaba cuando presionó cualquier tecla.

No necesita texto en el búfer para crear superposiciones, aunque eso es un requisito para las propiedades de texto. Aquí hay una superposición con ancho cero que da como resultado que se muestre texto adicional:

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

Tenga en cuenta que esta superposición alejará el texto del búfer; no cubrirá el texto en la posición dada.

Parece que no es posible colocar una superposición en ninguna posición en el búfer que sea mayor que point-max/ buffer-size, es decir, es probable que no pueda colocar texto en alguna posición específica debajo del texto del búfer a menos que modifique esta restricción. Por supuesto, puede colocar texto justo después del texto del búfer con la after-stringpropiedad en una superposición fijada en la point-maxposición.

rekado
fuente