알림을 취소하지 않고 버퍼를 수정하는 방법은 무엇입니까?


11

Q : 알리지 않고 버퍼에 텍스트를 어떻게 삽입 / 수정 undo합니까?

사용 사례는 다음과 같습니다. 모든 파일의 시작 부분에 주석 블록이 있는데, 그중에서도 가장 최근의 파일 변경에 대한 타임 스탬프가 업데이트됩니다. 타임 스탬프를 수정하지 않고 해당 타임 스탬프를 수정할 수 있기를 원합니다 undo.

내가 undo여기서 단락하려는 이유 는 LaTeX 문서를 편집 / 컴파일 할 때 발생하는 다음과 같은 에지 케이스 때문일 수 있습니다.

  1. 파일을 약간 변경하여 컴파일 된 문서에 어떤 영향을 미치는지 확인하십시오.
  2. 파일 저장 (타임 스탬프 업데이트)
  3. latex파일에서 실행
  4. 변화가 나쁜 것이라고 결정
  5. undo 변화들

단계 (5) ( undo) 에서의 문제점은 단계 ( 1)에서 이루어진 변경을 취소하지 않고 단계 (2)에서 타임 스탬프 업데이트를 취소한다는 점이다. 그것은 undo파일의 상단에있는 타임 스탬프로 포인트를 이동시키는 것을 제외하고는 나를 귀찮게하지 않을 것입니다. 그것은 매우 찌그러지고 나의 집중력을 완전히 파괴합니다.

내가 방문하는 파일과 관련하여 질문을 던지고 있지만 더 일반적으로 버퍼 수정에 관한 것입니다.

그래서 : 어떻게 방지 할 수 있습니다 undo버퍼에 특정 수정을 몰래에서?


1
이것은 실행 취소 질문과 관련이 없지만 "실행 취소 지점 이동"문제를 해결하는 데 도움이 될 수 있습니다. stackoverflow.com/a/20510025/1279369
nanny

2
이 날짜 스탬프 변경 사항이 실행 취소 기록에서 가장 최근 항목에 추가 된 것이 가장 좋지 않습니까? 그렇게 undo하면 둘 다 취소 할 수 있습니다.
Malabarba

나는 당신이 정말로 원하는 것이라고 생각합니다 atomic-change-group.

@ john : 어떻게 도움이 될까요? 그룹에 대한 두 가지 변경 사항은 "작은 변경"(예 : 삽입)과 저장 중에 완료된 타임 스탬프 업데이트와 같은 별도의 명령에 의해 트리거됩니다.
Gilles 'SO- 악의를 멈춰라'

어떤 이유로 든 기존 답변에서 이러한 방법 중 어느 것도 나를 위해 효과가 없었지만 이 답변 with-undo-collapse은 매우 유용한 매크로를 정의 합니다. emacs.stackexchange.com/a/7560/2418
ideasman42

답변:


6

@stsquad의 대답이 올바른 길로 안내했습니다. 기본적으로 단계는 다음과 같습니다.

  1. 저장 buffer-undo-list
  2. 비활성화 undo
  3. 당신의 일을
  4. 다시 활성화 undo하고 복원buffer-undo-list

다음은 그러한 기능의 스케치입니다.

(defun disable-undo-one-off ()
  (let ((undo buffer-undo-list))        ; save the undo list
    (buffer-disable-undo)               ; disable undo
    (do-some-stuff)                     ; do your thing
    (buffer-enable-undo)                ; re-enable undo
    (setq buffer-undo-list undo)))      ; restore the undo list

편집 : 실제로, 더 간단한 해결책은 여전히 ​​단순히 let바인딩하는 buffer-undo-list것이므로 let원래 목록이 복원 될 때 get 본문에있는 목록의 변경 사항이 혼란스럽게 됩니다.

(defun disable-undo-one-off ()
  (let (buffer-undo-list)
    (do-some-stuff)))

이것에 대한 주요 제한 사항은 버퍼에있는 문자 수를 변경하지 않는 수정 (예 : "고양이"를 "강아지"로 변경하지만 "고양이"로 변경하지 않음)에 대해 작동하는 것 같습니다. 그렇지 않으면 나머지 실행 취소 목록은 이제 잘못된 점을 참조하고 있습니다. 따라서 이것은 부분적인 해결책 일뿐 입니다.


당신은 당신이 일의 중간에 활동에서 벗어날 경우 unwind 보호에서 그것을 감싸고 싶을 수도 있습니다. 나는 당신이 물건을 쉽게 추적 할 수있는 기능 으로이 모든 것을하고 있다는 것을 몰랐습니다.
stsquad

또한 타임 스탬프 업데이트를 위해 솔루션에 추가하여 실행 취소 기록 (및 가능한 경우 포인트 기록)을 업데이트하지 않습니까?
Kaushal Modi

@stsquad : 좋은 생각입니다. 나중에하려고합니다. 해당 기능 및 목록에 대한 팁을 주셔서 다시 한 번 감사드립니다.
Dan

@ kaushalmodi : 명확한 질문 : 실제 타임 스탬프 업데이트 기능을보고 싶다는 의미입니까?
Dan

@Dan 실행 취소 또는 포인트 이력을 업데이트하지 않도록 타임 스탬프 업데이트 기능을 수정하는 방법을 알고 싶습니다.
Kaushal Modi

3

실행 취소 작업은 실행 취소 목록의 여러 요소를 결합 합니다 . nil목록 의 항목은 두 변경 그룹 사이의 경계를 나타냅니다. 을 제거함으로써 nil자동으로 최상위의 loop¹에 의해 삽입 된 목록의 시작, 그룹화 기술적 시나리오에서 문제를 해결해야 실질적으로 귀하의 요청과 일치하지 않지만 마지막 버퍼 변화와 타임 스탬프 업데이트를 할 수 있습니다.

(defun time-stamp-group-undo ()
  (if (eq nil (car buffer-undo-list))
      (setq buffer-undo-list (cdr buffer-undo-list)))
  (time-stamp))

(경고 : 테스트되지 않았으므로 실행 취소 목록에 더 많은 마사지가 필요할 수 있습니다.)

타임 스탬프 업데이트에 대한 위치 항목 (정수)을 수정하여 실행 취소 목록을 다른 방식으로 재생할 수도 있습니다 .

¹ 은 그룹 삽입과 비슷한 방식으로 제거합니다. self-insert-command


2

제안한 문제는 실행 취소 트리가 현재 위치에서 원하는 위치로 갈 수있는 델타 목록이라는 것입니다. 버퍼에서 실행 취소 추적을 비활성화하는 것이 완벽하게 가능하지만 변경 사항을 적극적으로 기록하지 않는 효과가 무엇인지 확실하지 않습니다. 현재 증가하는 로그 또는 새로 고침 페이지에 대한 정보를 취소하는 것이 의미가 없으므로 특정 버퍼에서 실행 취소를 켜거나 끄는 토글이 있습니다. 그러나 전환시 변경 사항을 해결합니다.

(defun my-toggle-buffer-undo ()
  "Toggle undo tracking in current buffer."
  (interactive)
  (with-current-buffer (current-buffer)
    (if (eq buffer-undo-list t)
        (setq buffer-undo-list nil)
      (buffer-disable-undo (current-buffer)))))

(define-key my-toggle-map "u" 'my-toggle-buffer-undo)

buffer-disable-undo는 실제로 buffer-undo-listnil로 설정 합니다. 아마도 버퍼 실행 취소 목록 의 상태를 저장하면 나중에 복원 할 수 있습니까?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.