Richiesta di kill-buffer con opzione per diff le modifiche


8

Il save-some-bufferscomando richiede di salvare o ignorare ogni file modificato e fornisce anche un'opzione per diff il file modificato rispetto al file che sta visitando.

Vorrei lo stesso comportamento da kill-buffero kill-this-buffer. Se il buffer viene modificato, esiste già un prompt sì / no, ma mi piacerebbe anche l'opzione di vedere le differenze.

Esiste un modo integrato per farlo o un punto di estensione appropriato? O dovrei semplicemente associare il mio comando kill-buffer?


Potresti voler esaminare defadvice. Ciò ti consentirà di estendere facilmente il built-in kill-buffer.
tata

Usare i consigli "prima" qui sembra paragonabile a scrivere il mio comando, cosa che potrei fare: presenterei il mio prompt, e se l'utente vuole andare avanti e uccidere il buffer immagino di poter impostare buffer-modified-pe chiamare l'originale kill-bufferper continuare uccidere senza un altro prompt. Mi chiedo se c'è un modo migliore, ma potrei provarlo.
Glucas,

Wow. Sto usando save-some-buffersda alcuni anni e non ho mai saputo che ha una difffunzione ... Grazie!
mbork,

@nanny Alla fine ho usato i consigli per questo - vedi la mia risposta di seguito. Finora sembra funzionare bene, grazie.
Glucas,

Risposte:


6

La grande domanda è se si desidera questo comportamento per kill-buffersé, il che significa non solo quando lo si chiama in modo interattivo, ma per ogni suo utilizzo nel codice Lisp esistente o se lo si desidera solo per un uso interattivo.

Presumo quest'ultimo. In tal caso, lascia kill-bufferperdere, definisci il tuo comando che fa quello che vuoi e rimappa le chiavi che sono normalmente associate kill-bufferal tuo comando:

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

Per il tuo my-kill-buffercomando, controlla dall'inizio se il buffer è stato modificato e, in tal caso, avvialo ediffper esso.

Per verificare se è stato modificato, utilizzare buffer-modified-p.

A ediffte presumibilmente vorresti afferrare il file (cioè il buffer come salvato) e diffonderlo rispetto al buffer modificato corrente. Potrebbe essere necessario giocherellare un po 'per farlo - non so di un ediffcomando esistente che lo fa.

Ma forse tutto ciò di cui hai veramente bisogno è qualcosa del genere highlight-changes-mode. Vedere il manuale di Emacs, nodo Highlight Interactively. In altre parole, forse tutto ciò che serve è invocare highlight-changes-modese il buffer è stato modificato.


Grazie @Drew, scriverò il mio comando kill. Un paio di bit utili: posso usare diff-buffer-with-fileper produrre i diff. Sembra anche che debba chiamare set-buffer-modified-pse voglio procedere e uccidere senza essere richiesto nuovamente dall'implementazione nativa.
Glucas,

5

Sulla base delle altre risposte e commenti, ecco un comando kill personalizzato che fornisce l'opzione per diff un buffer modificato con il file che sta visitando. Ho mappato questo C-x C-kma potrei anche rimappare kill-buffercome suggerito nella risposta di @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))))))

Utilizzando la stessa implementazione di base, potresti anche consigliare kill-buffer. Con questo approccio hai la possibilità di vedere le differenze ovunque kill-buffervenga chiamato, ad esempio quando uccidi i buffer contrassegnati da 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)

Un problema ora che l'ho usato un po ': il ciclo read-char non consente di scorrere le differenze o eseguire altre azioni. Probabilmente ho bisogno di usare l'approccio adottato da map-y-or-np.
glucas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.