通知を取り消さずにバッファを変更するにはどうすればよいですか?


11

Q:undo気づかずにバッファーにテキストを挿入/変更するにはどうすればよいですか?

これがユースケースです。すべてのファイルの先頭にコメントブロックがあり、ファイルに対する最新の変更のタイムスタンプを更新します。undoファシリティに気付かれずにそのタイムスタンプを変更できるようにしたいのですが。

undoここで短絡させたい理由は、LaTeXドキュメント(およびおそらく他のドキュメント)を編集/コンパイルするときに発生する次のエッジケースによるものです。

  1. ファイルに小さな変更を加えて、コンパイルされたドキュメントにどのように影響するかを確認します
  2. ファイルを保存します(タイムスタンプを更新します)。
  3. latexファイルで実行する
  4. 変更が悪いものであると判断する
  5. undo 変更

ステップ(5)(undo)の問題は、ステップ(1)で行われた変更を取り消すのではなく、ステップ(2)で更新されたタイムスタンプを取り消すことです。それは(私はできた私を気にしないだろうundo、それはまた、移動が多く、多くの行離れて実際の実質的な変更からほとんど常にファイルの先頭にすべての道のタイムスタンプを指していることを除いて、再び)。それは非常に耳障りで、私の集中力を完全に壊します。

私が訪問しているファイルに関して質問を投げかけていますが、それはより一般的にはバッファを変更することについてです。

それで、バッファへの特定の変更に気付かないようにするにはどうすればよいundoですか?


1
これは元に戻す質問とは関係ありませんが、「元に戻すことがポイントを移動する」問題に役立つ可能性があります。stackoverflow.com
nanny

2
この日付スタンプの変更が元に戻す履歴内の最新のアイテムに追加されているのが最善ではないでしょうか?その方法undoは両方を元に戻します。
Malabarba

私はあなたが本当にしたいと思いatomic-change-group

@john:それはどのように役立ちますか?グループへの2つの変更は、「小さな変更」(挿入など)と保存中に行われるタイムスタンプの更新という別々のコマンドによってトリガーされます。
Gilles「SO-悪をやめる」14

何らかの理由で、既存の回答でこれらの方法がどれも機能しなかったことに注意してください。ただし、この回答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-bind buffer-undo-listするだけであるletことがわかります。

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

これの主な制限は、バッファ内の文字数を変更しない変更(たとえば、「子猫」を「子犬」に変更するが、「猫」は変更しない)で機能するように見えることです。リストは間違ったポイントを参照しています。したがって、これは部分的なソリューションにすぎません


途中でアクティビティから抜け出した場合に備えて、それを巻き戻し保護で包むこともできます。私はあなたがすべてのものを追跡しやすくする関数でこれをすべてやっているとは思いませんでした
stsquad 2014

タイムスタンプ更新のソリューションを追加して、元に戻す履歴(および可能であればポイント履歴)を更新しないようにすることもできますか?
Kaushal Modi 14

@stsquad:良い考えです。後でそうしようとします。問題の関数とリストのヒントをありがとうございます。
ダン

@kaushalmodi:質問の明確化:実際のタイムスタンプ更新関数を見たいという意味ですか?
ダン

@Dan取り消しまたはポイント履歴を更新しないようにタイムスタンプ更新関数を変更する方法を知りたいです。
Kaushal Modi 14

3

取り消し操作は、取り消しリストのいくつかの要素を組み合わせますnil2つの変更グループ間の境界リストマークのエントリ。nilトップレベルループによって自動的に挿入されるリストの先頭にあるを削除することにより、タイムスタンプの更新を最後のバッファー変更とグループ化できます。これは、技術的には要求に一致しませんが、実際にはシナリオの問題を解決するはずです。

(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.