P: ¿Cómo inserto / modifico texto en un búfer sin undo
darme cuenta?
Aquí está el caso de uso. Tengo un bloque de comentarios al comienzo de cada archivo que, entre otras cosas, actualiza una marca de tiempo para el cambio más reciente en un archivo. Me gustaría poder modificar esa marca de tiempo sin que las undo
instalaciones lo noten.
La razón por la que quiero hacer un cortocircuito undo
aquí se debe al siguiente caso límite, que surge al editar / compilar documentos LaTeX (y probablemente otros, pero este es el que me vuelve loco con más frecuencia):
- Realice un pequeño cambio en el archivo para ver cómo afectará al documento compilado
- Guarde el archivo (que actualiza la marca de tiempo)
- Ejecutar
latex
en el archivo - Decide que el cambio es malo
undo
los cambios
El problema en el paso (5) ( undo
) es que no deshace el cambio realizado en el paso (1), sino que deshace la actualización de la marca de tiempo en el paso (2). Eso no me molestaría (podría undo
volver a hacerlo), excepto que también mueve el punto hasta la marca de tiempo en la parte superior del archivo, que casi siempre está a muchas, muchas líneas del cambio sustantivo real. Es muy discordante y rompe completamente mi concentración.
Estoy haciendo la pregunta con respecto a un archivo que estoy visitando, pero en general se trata de modificar buffers.
Entonces: ¿cómo puedo evitar undo
notar una modificación específica en un búfer?
undo
deshacería ambas.atomic-change-group
.with-undo-collapse
macro que fue muy útil: emacs.stackexchange.com/a/7560/2418Respuestas:
La respuesta de @ stsquad me llevó por el camino correcto. Básicamente, los pasos son:
buffer-undo-list
undo
undo
y restaurar elbuffer-undo-list
Así que aquí hay un boceto de dicha función:
Editar: en realidad, resulta que una solución más simple sigue siendo simplemente
let
vincularbuffer-undo-list
para que los cambios en la lista en el cuerpo dellet
clobbered cuando se restaure la lista original:La principal limitación con esto es que parece funcionar para modificaciones que no cambian el número de caracteres en el búfer (p. Ej., Cambiar "gatitos" a "cachorros", pero no "gatos"), porque de lo contrario el resto se deshace La lista ahora se refiere a los puntos equivocados. Por lo tanto, esta es solo una solución parcial .
fuente
Una operación de deshacer combina varios elementos de la lista de deshacer . Una
nil
entrada en la lista marca el límite entre dos grupos de cambio. Al eliminarnil
al principio de la lista que se inserta automáticamente por el bucle de nivel superior¹, puede agrupar la actualización de la marca de tiempo con el último cambio de búfer, que técnicamente no coincide con su solicitud, pero prácticamente debería resolver el problema en su escenario.(Advertencia: sin probar, la lista de deshacer puede requerir más masajes).
También puede jugar con la lista de deshacer de una manera diferente, modificando la entrada de posición (un entero) para la actualización de la marca de tiempo.
¹ realiza una eliminación similar a las inserciones de grupo.
self-insert-command
fuente
El problema con lo que sugiere es que el árbol de deshacer es una lista de deltas para llegar desde donde está hasta donde quiere estar. Si bien es perfectamente posible deshabilitar el seguimiento de deshacer en un búfer, no estoy seguro de cuál sería el efecto de no registrar activamente los cambios. Actualmente tengo un interruptor para activar / desactivar deshacer en un búfer en particular, ya que no tiene sentido tener información de deshacer en un registro creciente o una página de actualización. Sin embargo, rechaza los cambios en alternar:
buffer-disable-undo en realidad solo establece buffer-undo-list en nil . ¿Tal vez si guardaste el estado de buffer-undo-list en tu alternador podrías restaurarlo después?
fuente