P: Como insiro / modifico o texto em um buffer sem undo
perceber?
Aqui está o caso de uso. Eu tenho um bloco de comentários no início de cada arquivo que, entre outras coisas, atualiza um carimbo de data / hora para a alteração mais recente em um arquivo. Eu gostaria de poder modificar esse carimbo de data / hora sem que as undo
instalações percebam.
A razão pela qual eu quero undo
entrar em curto-circuito aqui é devido ao seguinte caso extremo, que surge ao editar / compilar documentos LaTeX (e provavelmente outros, mas esse é o que mais me deixa louco):
- Faça uma pequena alteração no arquivo para ver como ele afetará o documento compilado
- Salve o arquivo (que atualiza o registro de data e hora)
- Executar
latex
no arquivo - Decida que a mudança é ruim
undo
as mudanças
O problema na etapa (5) ( undo
) é que ela não desfaz a alteração feita na etapa (1), mas desfaz a atualização do registro de data e hora na etapa (2). Isso não me incomodaria (eu poderia apenas undo
novamente), exceto que também move o ponto até o carimbo de data / hora na parte superior do arquivo, que quase sempre está a muitas, muitas linhas da mudança substantiva real. É muito chocante e quebra completamente minha concentração.
Estou apresentando a pergunta em relação a um arquivo que estou visitando, mas geralmente trata-se de modificar buffers.
Então: como impedir que eu undo
observe uma modificação específica em um buffer?
undo
, desfaria os dois.atomic-change-group
.with-undo-collapse
macro que foi muito útil: emacs.stackexchange.com/a/7560/2418Respostas:
A resposta de @ stsquad me colocou no caminho certo. Basicamente, as etapas são:
buffer-undo-list
undo
undo
e restaure obuffer-undo-list
Então, aqui está um esboço dessa função:
Edit: na verdade, verifica-se que uma solução mais simples ainda é simplesmente
let
-bind,buffer-undo-list
para que as alterações na lista no corpo do clobber sejam bloqueadaslet
quando a lista original for restaurada:A principal limitação disso é que parece funcionar para modificações que não alteram o número de caracteres no buffer (por exemplo, alterando "gatinhos" para "filhotes", mas não "gatos"), porque, caso contrário, o restante A lista agora se refere aos pontos errados. Portanto, essa é apenas uma solução parcial .
fonte
Uma operação de desfazer combina vários elementos da lista de desfazer . Uma
nil
entrada na lista marca o limite entre dois grupos de alterações. Ao remover onil
início da lista que é automaticamente inserido pelo loop de nível superior¹, você pode agrupar a atualização do carimbo de data / hora com a última alteração no buffer, que tecnicamente não corresponde à sua solicitação, mas praticamente deve resolver o problema no seu cenário.(Aviso: não testado, a lista de desfazer pode exigir mais massagens.)
Você também pode jogar com a lista de desfazer de uma maneira diferente, modificando a entrada da posição (um número inteiro) para a atualização do carimbo de data / hora.
¹ faz uma remoção semelhante para agrupar inserções.
self-insert-command
fonte
O problema com o que você sugere é que a árvore de desfazer é uma lista de deltas para ir de onde você está e para onde você quer estar. Embora seja perfeitamente possível desativar o rastreamento de desfazer em um buffer, não tenho certeza de qual seria o efeito de não registrar ativamente as alterações. Atualmente, tenho uma alternância para ativar / desativar desfazer em um buffer específico, pois não faz sentido desfazer informações em um log crescente ou em uma página de atualização. No entanto, ele corrige as alterações ao alternar:
buffer-disable-undo, na verdade, apenas define buffer-undo-list para zero . Talvez se você salvou o estado de buffer-undo-list na alternância, poderia restaurá-lo depois?
fonte