Kill-buffer prompt avec option pour différencier les changements

8

La save-some-bufferscommande invite à enregistrer ou à ignorer chaque fichier modifié et fournit également une option pour différencier le fichier modifié du fichier qu'il visite.

Je voudrais le même comportement de kill-bufferou kill-this-buffer. Si le tampon est modifié, il y a déjà une invite oui / non, mais j'aimerais également avoir la possibilité de voir les différences.

Existe-t-il un moyen intégré de le faire ou un point d'extension approprié? Ou dois-je simplement lier ma propre commande kill-buffer?

glucas
la source
Vous voudrez peut-être examiner defadvice. Cela vous permettra d'étendre facilement la fonction intégrée kill-buffer.
nounou
Utiliser les conseils `` avant '' ici semble comparable à écrire ma propre commande, ce que je pourrais faire: je présenterais ma propre invite, et si l'utilisateur veut aller de l'avant et tuer le tampon, je suppose que je peux définir buffer-modified-pet appeler l'original kill-bufferpour continuer tuer sans autre invite. Je me demande s'il y a une meilleure façon, mais pourrait essayer.
glucas
Sensationnel. J'utilise save-some-buffersdepuis pas mal d'années et je ne savais pas qu'il avait une difffonctionnalité ... Merci!
mbork
@nanny, j'ai fini par utiliser des conseils pour cela - voir ma propre réponse ci-dessous. Jusqu'à présent, cela semble bien fonctionner, merci.
glucas

Réponses:

6

La grande question est de savoir si vous voulez ce comportement pour kill-bufferlui-même, ce qui signifie non seulement lorsque vous l'appelez de manière interactive, mais pour chaque utilisation dans le code Lisp existant, ou si vous le souhaitez uniquement pour une utilisation interactive.

Je suppose que ce dernier. Dans ce cas, laissez-le kill-buffertranquille, définissez votre propre commande qui fait ce que vous voulez et remappez les clés qui sont normalement liées kill-bufferà votre commande:

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

Pour votre my-kill-buffercommande, vérifiez simplement au départ si le tampon a été modifié, et si oui, lancez ediff-le.

Pour vérifier s'il a été modifié, utilisez buffer-modified-p.

Pour ediffvous, vous voudrez probablement saisir le fichier (c'est-à-dire le tampon tel qu'il est enregistré) et le comparer au tampon actuel modifié. Vous devrez peut-être jouer un peu pour faire cela - je ne connais pas de ediffcommande existante qui le fasse.

Mais peut-être que vous n'avez vraiment besoin que de quelque chose highlight-changes-mode. Voir le manuel Emacs, node Highlight Interactively. En d'autres termes, il vous suffit peut-être d'invoquer highlight-changes-modesi le tampon a été modifié.

A dessiné
la source
Merci @Drew, je vais écrire ma propre commande kill. Quelques bits utiles: je peux utiliser diff-buffer-with-filepour produire les diffs. Il semble également que je doive appeler set-buffer-modified-psi je veux continuer et tuer sans être à nouveau invité par l'implémentation native.
glucas
5

Sur la base des autres réponses et commentaires, voici une commande kill personnalisée qui offre la possibilité de différencier un tampon modifié avec le fichier qu'il visite. J'ai mappé cela à, C-x C-kmais je pourrais également remapper kill-buffercomme suggéré dans la réponse 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))))))

En utilisant la même implémentation de base, vous pouvez également conseiller kill-buffer. Avec cette approche, vous avez la possibilité de voir les différences n'importe où qui kill-bufferest appelé - par exemple, lors de la suppression des tampons marqués d'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
la source
Un problème maintenant que j'ai utilisé cela un peu: la boucle read-char ne permet pas de faire défiler les diffs ou d'effectuer d'autres actions. J'ai probablement besoin d'utiliser l'approche adoptée par map-y-or-np.
glucas