Texto temporário no local da janela sem texto para propertizar / sobrepor?

9

P: como mostro temporariamente o texto em uma janela nos locais da tela sem texto para propertizar / sobrepor?

Estou familiarizado com a idéia básica por trás das propriedades e sobreposições de texto (veja também este tópico ), usei-as algumas vezes, mas não sou de forma alguma especialista nelas. Meu entendimento limitado é que precisa haver texto para propertizar ou sobrepor, mas estou pensando em como usar seções de uma janela que não contêm texto.

Aqui está uma captura de tela para um exemplo:

insira a descrição da imagem aqui

Como colocar texto (temporariamente) em uma das caixas vermelhas da captura de tela, ou seja, o espaço em branco à direita do texto ou abaixo da última linha do buffer?

Dan
fonte
Em resumo, você pode usar a propriedade display para exibir o texto que não está lá. Alguém pode dar uma resposta completa antes de eu chegar em casa.
Malabarba 3/11
O modo empresa realiza a colocação de uma sobreposição no texto, se houver um ponto posterior ou anterior suficiente com a propriedade display, como alternativa, ele usa a propriedade after-string para exibir algo abaixo do final do buffer. Tenho menos certeza de exibir algo ao lado, mas parece possível com a largura e a posição corretas da sobreposição.
wasamasa
Você não pode apenas insertenviar texto para o buffer e propertizá-lo?
rekado

Respostas:

6

Eu criei um exemplo de trabalho de uma função que pega uma string e a exibe temporariamente com um tempo limite após o texto do buffer:

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

O encantamento a seguir resultará no seu exemplo inferior da caixa vermelha:

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

A razão pela qual isso funciona é porque as sobreposições usam marcadores como posições a serem exibidas entre elas. O uso da posição mais externa como início e fim da sobreposição permite exibir o texto após ele usando a after-stringpropriedade Como as sobreposições podem conter texto protegido, eu o configurei para aparecer recuado e com espaço em branco ao redor.

O outro exemplo pode usar a mesma idéia para exibir texto após o final da linha:

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

A chamada a seguir resultará no exemplo da caixa vermelha do lado direito:

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

Você pode ficar muito mais louco e adicionar rostos para distinguir essas sobreposições do texto do buffer, exibi-las por mais tempo, ajustar sua posição, detectar quando não há espaço vazio e usar sobreposições normais de texto apropriado, etc. o código-fonte do modo empresa, porque é muito legível e demonstra um uso mais elaborado (e principalmente livre de erros) de sobreposições para criar um menu pop-up flexível com os recursos sugeridos.

wasamasa
fonte
2

Você pode exibir temporariamente texto em um buffer com a função momentary-string-display. É preciso uma mensagem para exibir e uma posição no buffer.

Este:

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

colocará a string "olá lá" na posição 200 no buffer. Ele moverá todos os outros textos neste momento para o lado para abrir espaço para o "hello world", mas tudo será restaurado para onde estava quando você pressionou qualquer tecla.

Você não precisa de texto no buffer para criar sobreposições, embora isso seja um requisito para propriedades de texto. Aqui está uma sobreposição com largura zero que resulta em texto adicional a ser exibido:

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

Observe que essa sobreposição afastará o texto do buffer; não cobrirá o texto na posição especificada.

Parece não ser possível colocar uma sobreposição em qualquer posição do buffer que seja maior que point-max/ buffer-size, ou seja, você provavelmente não poderá colocar texto em uma posição específica abaixo do texto do buffer, a menos que você se intrometa nessa restrição. Obviamente, é possível colocar o texto logo após o texto do buffer com a after-stringpropriedade em uma sobreposição fixada na point-maxposição.

rekado
fonte