Mensaje de Kill-buffer con la opción de diferenciar los cambios

8

El save-some-bufferscomando solicita guardar o ignorar cada archivo modificado, y también proporciona una opción para diferenciar el archivo modificado con el archivo que está visitando.

Me gustaría el mismo comportamiento de kill-buffero kill-this-buffer. Si se modifica el búfer, ya hay un sí / no, pero también me gustaría la opción de ver los diferenciales.

¿Hay una forma integrada de hacer esto, o un punto de extensión apropiado? ¿O debería vincular mi propio comando kill-buffer?

glucas
fuente
Es posible que desee investigar defadvice. Esto le permitirá ampliar fácilmente el incorporado kill-buffer.
niñera
Usar el consejo 'antes' aquí parece comparable a escribir mi propio comando, lo que podría hacer: presentaría mi propio aviso, y si el usuario quiere seguir adelante y matar el búfer, supongo que puedo configurar buffer-modified-py llamar al original kill-bufferpara continuar matando sin otro aviso. Me pregunto si hay una mejor manera, pero podría intentarlo.
glucas
Guau. Lo he estado usando save-some-buffersdurante varios años y nunca supe que tiene una difffunción ... ¡Gracias!
mbork
@nanny Terminé usando consejos para esto después de todo, mira mi propia respuesta a continuación. Hasta ahora parece funcionar bien, gracias.
glucas

Respuestas:

6

La gran pregunta es si desea este comportamiento para kill-buffersí mismo, lo que significa no solo cuando lo llama de forma interactiva sino para cada uso del mismo en el código Lisp existente, o si lo desea solo para uso interactivo.

Asumiré lo último. En ese caso, déjelo kill-buffersolo, defina su propio comando que haga lo que desee y vuelva a asignar las teclas que normalmente están vinculadas kill-buffera su comando:

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

Para su my-kill-buffercomando, simplemente verifique desde el principio si el búfer ha sido modificado, y si es así, inicie ediffpara ello.

Para verificar si se ha modificado, use buffer-modified-p.

Para ediffque presumiblemente que desee tomar el archivo (es decir, el búfer como salvado) y comparación contra la corriente, tampón modificado. Es posible que necesite tocar un poco para hacer eso, no sé de un ediffcomando existente que lo haga.

Pero tal vez todo lo que realmente necesitas es algo así highlight-changes-mode. Vea el manual de Emacs, nodo Highlight Interactively. En otras palabras, quizás todo lo que necesita es invocar highlight-changes-modesi el búfer ha sido modificado.

Dibujó
fuente
Gracias @Drew, escribiré mi propio comando kill. Un par de bits útiles: puedo usar diff-buffer-with-filepara producir los diffs. También parece que necesito llamar set-buffer-modified-psi quiero continuar y matar sin que se lo solicite nuevamente desde la implementación nativa.
glucas
5

En base a las otras respuestas y comentarios, aquí hay un comando de matar personalizado que brinda la opción de diferenciar un búfer modificado con el archivo que está visitando. He mapeado esto, C-x C-kpero también podría reasignar kill-buffercomo se sugiere en la respuesta de @ 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))))))

Usando la misma implementación básica, también podría aconsejar kill-buffer. Con este enfoque, tiene la opción de ver las diferencias en cualquier lugar que kill-bufferse llame, por ejemplo, al eliminar los búferes marcados de 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)
glucas
fuente
Un problema ahora que lo he usado un poco: el bucle read-char no permite desplazar los diffs ni realizar otras acciones. Probablemente necesito usar el enfoque adoptado por map-y-or-np.
glucas