Nota: O post Como mover o ponto para o final de outro buffer, usando `with-current-buffer` e` goto-char`? presumivelmente, faz a mesma pergunta que esta, mas as respostas dadas a ela não se aplicam prontamente ao meu caso aqui. Por exemplo, essas respostas envolvem a inserção de texto no outro buffer, etc. A pergunta que estou fazendo aqui é consideravelmente mais simples, e espero que a resposta seja igualmente simples.
Suponha que
- o quadro do Emacs é dividido em duas janelas, onde uma das janelas contém um buffer chamado
*whatever*
e a outra contém o*scratch*
buffer padrão ; - o
*whatever*
buffer contém várias linhas de texto; - o cursor no
*whatever*
buffer está no início desse buffer (ou seja, no seu(point-min)
); - o
*scratch*
buffer é o atual;
Se agora eu avaliar qualquer um dos seguintes no *scratch*
buffer, a posição do cursor no *whatever*
buffer permanecerá inalterada:
(with-current-buffer "*whatever*"
(goto-char (point-max)))
(with-current-buffer "*whatever*"
(end-of-buffer))
(save-excursion
(set-buffer "*whatever*")
(goto-char (point-max)))
(save-excursion
(set-buffer "*whatever*")
(end-of-buffer))
Eu acho que, o que (goto-char (point-max))
quer que (end-of-buffer)
faça ou a *whatever*
posição do cursor seja descartado posteriormente.
Como devo modificar qualquer um dos trechos acima para que o cursor
*whatever*
do buffer seja posicionado (persistentemente!) No final desse buffer.O que eu deveria ter feito para responder a essa pergunta usando os documentos do Emacs? Eu tentei tudo o que conseguia pensar.
Depois de ler a resposta esclarecedora de Jules Tamagnan, percebi que precisava explicitar mais uma estipulação:
Estou procurando uma solução que funcione independentemente do buffer em questão ser visível em uma janela ou não.
Afinal, se eu visualizar o buffer B em uma janela W , mover o cursor para um local específico L , exibir outro buffer C na mesma janela W e finalmente apontar W de volta para o buffer B , espero ver o cursor em o mesmo local L onde eu o deixei. IOW, deve haver uma maneira de um buffer lembrar onde está o seu ponto, independentemente de estar associado a uma janela ou não.
E o caso em que o buffer de destino está atualmente visível em duas ou mais janelas ( W1 , W2 , W3 , ...)? Existem muitas possibilidades razoáveis para este caso. A solução proposta pode, por exemplo, alterar a posição do cursor
- na janela ativa mais recente entre W1 , W2 , W3 , ...;
- em todas as janelas W1 , W2 , W3 , ...; ou
- etc etc.
(Não tenho uma opinião forte sobre esse caso de canto, pois espero que seja extremamente raro na prática.)
Respostas:
Essa foi uma pergunta bem legal, eu aprendi muita coisa que não sabia ao tentar descobrir isso. O que eu aprendi foi que cada janela tem seu próprio valor
point
. Isso é importante porque significa que o ponto não está associado ao buffer, mas à janela real. Como vimos, isso faz uma grande diferença.O que precisamos fazer então é definir o valor do ponto na janela, a função para isso é
set-window-point
(eu encontrei isso no google, acho que se não souber por onde começar a procurar na compilação no emacs-docs procurando no google pode lançar alguma luz). Precisamos então dizerset-window-point
qual janela selecionar. Para fazer isso eu useiget-buffer-window
(mais uma vez eu usei o google para encontrar isso).Este código só funcionará se o buffer estiver aberto em uma janela. É possível criar outra versão onde você abre o buffer em uma janela, define o ponto e volta à configuração original da janela. O código abaixo é muito mais simples.
Espero que isso ajude, se você tiver outras perguntas ou se não funcionar exatamente como deseja, deixe-me saber.
fonte
( A resposta de Jules Tamagnan identifica o problema, eu o expandirei.)
Suas soluções com
save-excursion
ou desave-excursion
fato funcionam! Você pode vê-lo verificando o valor(point)
desse buffer posteriormente, por exemplo,sempre retorna 42 (desde que seja uma posição válida no buffer. Isso é mencionado ainda como uma pegadinha na documentação de
save-excursion
: restaura apenas a posição no buffer original, não a posição em qualquer outro buffer.Se você achar que a posição do buffer não é a que você definiu, é porque outra coisa está mudando, e essa coisa provavelmente é uma janela (ou um gancho em algum lugar, mas a maioria dos ganchos não tem nada a ver com isso - ainda assim, poderia ser um gancho de saída do processo, por exemplo). Na documentação sobre o ponto , há uma observação:
Se o buffer for mostrado em uma janela, o ponto do buffer será atualizado para o ponto da janela toda vez que o ponto for alterado ou a janela for exibida novamente. Como conseqüência, definir o ponto basicamente dura apenas enquanto o código Lisp durar: assim que o loop de comando de nível superior assume o controle, a janela é exibida novamente (mesmo que não seja visível, tanto quanto eu saiba) e o a posição do buffer é substituída. Com efeito, a posição escolhida pelo usuário supera a posição escolhida pelo programa.
Se você também deseja atualizar o ponto de qualquer janela que exibe o buffer, pode chamar
get-buffer-window-list
para enumerar as janelas:Mas considere que, se o usuário estava visitando o buffer, talvez não gostasse de mudar o ponto debaixo do nariz.
Até onde eu sei, o Emacs não rastreia quando as janelas foram selecionadas (isso é "ativo" na terminologia do Emacs), você só pode saber se elas estão atualmente selecionadas. Se você começar a se preocupar com as janelas selecionadas, lembre-se de que cada quadro tem uma janela selecionada, e o Emacs nem sempre sabe quando os quadros são selecionados (
(selected-frame)
não corresponde completamente à experiência do usuário final, especialmente com quadros dentro de emuladores de terminal, pois o Emacs não tem como para saber quando o usuário tem a janela do emulador de terminal ativa).fonte