変更を比較するオプションを備えたキルバッファプロンプト


8

このsave-some-buffersコマンドは、変更された各ファイルを保存または無視するように求めます。また、変更されたファイルを、アクセスしているファイルと比較するオプションも提供します。

kill-bufferまたはから同じ動作が欲しいのkill-this-bufferですが。バッファが変更された場合、すでにyes / noプロンプトが表示されますが、差分を表示するオプションも必要です。

これを行うための組み込みの方法、または適切な拡張ポイントはありますか?それとも、自分のkill-bufferコマンドをバインドするだけですか?


調べてみてくださいdefadvice。これにより、組み込みを簡単に拡張できますkill-buffer
ナニー14年

ここで「前」のアドバイスを使用することは、私が実行できる独自のコマンドを作成することに相当します。私は自分のプロンプトを表示し、ユーザーが先に進んでバッファーを強制終了したい場合は、元のコマンドbuffer-modified-pを呼び出しkill-bufferて続行できると思います別のプロンプトなしで殺す。もっと良い方法があるかどうか疑問に思っていますが、これでうまくいくかもしれません。
glucas 2014年

ワオ。私はsave-some-buffersかなりの数年間使用しており、diff機能があることを知りませんでした...ありがとう!
mbork 2014年

@nanny私は結局このためのアドバイスを使用することになりました-以下の自分の答えを見てください。これまでのところ、問題なく動作しているようです。
グルカ2014

回答:


6

大きな問題はkill-buffer、この動作をそれ自体で実行するかどうかです。つまり、対話的に呼び出す場合だけでなく、既存のLispコードでそれを使用する場合でも、対話的に使用する場合にのみ実行するかです。

後者を想定します。その場合は、そのままにしkill-bufferて、必要なことを実行する独自のコマンドを定義し、通常はkill-bufferコマンドにバインドされているキーを再マップします。

(global-set-key [remap kill-buffer] 'my-kill-buffer)

my-kill-bufferコマンドについては、最初にバッファが変更されているかどうかを確認し、変更されている場合は起動ediffします。

変更されているかどうかを確認するには、を使用しますbuffer-modified-p

ediffあなたは、おそらくファイル(すなわち、保存されたように、バッファ)、および電流に対する差分を、修正バッファをつかむしたいと思います。それをするために少しいじる必要があるかもしれません-私はそれをする既存のediffコマンドを知りません。

しかし、おそらく本当に必要なのはのようなものだけですhighlight-changes-mode。Emacsのマニュアル、ノードを参照してくださいHighlight Interactively。つまり、highlight-changes-modeバッファが変更された場合に呼び出すだけで十分でしょう。


@Drewに感謝します。自分でkillコマンドを書きます。いくつかの便利なビット:diff-buffer-with-file差分を生成するために使用できます。またset-buffer-modified-p、ネイティブ実装から再度プロンプトが表示されることなく続行して強制終了する場合は、呼び出す必要があるようです。
グルカ2014年

5

他の回答とコメントに基づいて、変更されたバッファとアクセスしているファイルを比較するオプションを提供するカスタムのkillコマンドを次に示します。私はこれをマッピングしましC-x C-kたがkill-buffer、@ Drewの回答で提案されているように再マッピングすることもできます。

(defun my/kill-this-buffer ()
  (interactive)
  (catch 'quit
    (save-window-excursion
      (let (done)
        (when (and buffer-file-name (buffer-modified-p))
          (while (not done)
            (let ((response (read-char-choice
                             (format "Save file %s? (y, n, d, q) " (buffer-file-name))
                             '(?y ?n ?d ?q))))
              (setq done (cond
                          ((eq response ?q) (throw 'quit nil))
                          ((eq response ?y) (save-buffer) t)
                          ((eq response ?n) (set-buffer-modified-p nil) t)
                          ((eq response ?d) (diff-buffer-with-file) nil))))))
        (kill-buffer (current-buffer))))))

同じ基本的な実装を使用して、アドバイスすることもできますkill-buffer。このアプローチでkill-bufferは、たとえば、Ibufferからマークされたバッファーを削除するときに、呼び出された場所のどこにでも差分を表示するオプションが表示されます。

(defun my/kill-buffer (orig-func &optional buffer-or-name)
  (catch 'quit
    (save-window-excursion
      (with-current-buffer buffer-or-name
        (let (done (buf (current-buffer)))
          (when (and buffer-file-name (buffer-modified-p))
            (while (not done)
              (let ((response (read-char-choice
                               (format "Save file %s? (y, n, d, q) " (buffer-file-name buf))
                               '(?y ?n ?d ?q))))
                (setq done (cond
                            ((eq response ?q) (throw 'quit nil))
                            ((eq response ?y) (save-buffer) t)
                            ((eq response ?n) (set-buffer-modified-p nil) t)
                            ((eq response ?d) (diff-buffer-with-file) nil))))))
          (apply orig-func (list (current-buffer))))))))

(advice-add 'kill-buffer :around #'my/kill-buffer)

これを少し使用した今の1つの問題:read-charループでは、差分のスクロールやその他のアクションを実行できません。おそらく、map-y-or-npのアプローチを使用する必要があります。
グルカ2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.