P: Jak wstawić / zmodyfikować tekst w buforze bez undo
zauważenia?
Oto przypadek użycia. Na początku każdego pliku mam blok komentarza, który między innymi aktualizuje znacznik czasu ostatniej zmiany pliku. Chciałbym móc modyfikować ten znacznik czasu bez undo
zauważania go przez urządzenia.
Powodem, dla którego chcę undo
tutaj zewrzeć , jest następujący przypadek krawędzi, który pojawia się podczas edytowania / kompilowania dokumentów LaTeX (i prawdopodobnie innych, ale to ten, który najbardziej mnie doprowadza do szału):
- Wprowadź niewielką zmianę w pliku, aby zobaczyć, jak wpłynie on na skompilowany dokument
- Zapisz plik (który aktualizuje znacznik czasu)
- Uruchom
latex
na pliku - Zdecyduj, że zmiana jest zła
undo
zmiany
Problem w kroku (5) ( undo
) polega na tym, że nie powoduje to cofnięcia zmiany dokonanej w kroku (1), a raczej cofnięcie aktualizacji znacznika czasu w kroku (2). To by mi nie przeszkadzało (mógłbym jeszcze undo
raz), z wyjątkiem tego, że przesuwa się on aż do znacznika czasu na górze pliku, który prawie zawsze jest o wiele, wiele linii od faktycznej zmiany merytorycznej. To bardzo denerwujące i całkowicie zaburza moją koncentrację.
Zadaję pytanie dotyczące pliku, który odwiedzam, ale ogólnie chodzi o modyfikację buforów.
Więc: jak mogę zapobiec undo
zauważeniu określonej modyfikacji bufora?
undo
cofnęłoby się jedno i drugie.atomic-change-group
.with-undo-collapse
makro, które było bardzo przydatne: emacs.stackexchange.com/a/7560/2418Odpowiedzi:
Odpowiedź @ stsquad doprowadziła mnie na właściwą ścieżkę. Zasadniczo kroki są następujące:
buffer-undo-list
undo
undo
i przywróćbuffer-undo-list
Oto szkic takiej funkcji:
Edycja: w rzeczywistości okazuje się, że prostszym rozwiązaniem jest po prostu
let
-bindowaniebuffer-undo-list
, aby zmiany na liście w treścilet
zostały zablokowane po przywróceniu oryginalnej listy:Głównym ograniczeniem jest to, że wydaje się, że działa w przypadku modyfikacji, które nie zmieniają liczby znaków w buforze (np. Zmieniają „kocięta” na „szczenięta”, ale nie „koty”), ponieważ w przeciwnym razie reszta cofania lista odnosi się teraz do niewłaściwych punktów. Dlatego jest to tylko częściowe rozwiązanie .
źródło
Operacja cofania łączy kilka elementów z listy cofania .
nil
Wpis znaków lista granica między dwiema grupami zmiana. Usuwającnil
początek listy, która jest automatycznie wstawiana przez pętlę najwyższego poziomu¹, możesz zgrupować aktualizację znacznika czasu z ostatnią zmianą bufora, która technicznie nie odpowiada twojemu żądaniu, ale praktycznie powinna rozwiązać problem w twoim scenariuszu.(Ostrzeżenie: nieprzetestowane, lista cofnięć może wymagać więcej masowania.)
Możesz także grać z listą cofnięć w inny sposób, modyfikując wpis pozycji (liczbę całkowitą) dla aktualizacji sygnatury czasowej.
¹ robi podobne usuwanie do wstawiania grup.
self-insert-command
źródło
Problem z tym, co sugerujesz, polega na tym, że cofnięcie drzewa jest listą delt, które można dostać z miejsca, w którym się znajdujesz, do miejsca, w którym chcesz się znaleźć. Chociaż można całkowicie wyłączyć śledzenie cofania w buforze, nie jestem pewien, jaki byłby efekt nieaktywnego rejestrowania zmian. Obecnie mam przełącznik, aby włączyć / wyłączyć cofanie w określonym buforze, ponieważ nie ma sensu, aby cofać informacje w rosnącym dzienniku lub odświeżającej stronie. Jednak niweluje zmiany przy przełączaniu:
bufor-wyłącz-cofnij tak naprawdę ustawia bufor-cofnij listę na zero . Może jeśli zapisałeś stan przełączania buforów na liście , możesz go później przywrócić?
źródło