comparison lisp/files.el @ 5245:0d71bcf96ffd

Add ` diff-buffer-with-file'. 2010-08-18 Mike Sperber <mike@xemacs.org> * files.el (diff-files-for-recover): Abstract this out out `recover-file'. (diff-buffer-with-file): Add from (GPLv2) FSF Emacs. (recover-file): Use `diff-files-for-recover'.
author Mike Sperber <sperber@deinprogramm.de>
date Wed, 18 Aug 2010 17:44:24 +0200
parents cdca98f2d36f
children d4fae3ebf26a
comparison
equal deleted inserted replaced
5244:04811a268716 5245:0d71bcf96ffd
3057 ;; 3057 ;;
3058 ;; If a hook returned t, file is already "written". 3058 ;; If a hook returned t, file is already "written".
3059 (if (not done) 3059 (if (not done)
3060 (basic-save-buffer-1)) 3060 (basic-save-buffer-1))
3061 'continue-save-buffer)) 3061 'continue-save-buffer))
3062
3063 (defun diff-buffer-with-file (&optional buffer)
3064 "View the differences between BUFFER and its associated file.
3065 This requires the external program `diff' to be in your `exec-path'."
3066 (interactive "bBuffer: ")
3067 (with-current-buffer (get-buffer (or buffer (current-buffer)))
3068 (if (and buffer-file-name
3069 (file-exists-p buffer-file-name))
3070 (let ((tempfile (make-temp-file "buffer-content-")))
3071 (unwind-protect
3072 (save-restriction
3073 (widen)
3074 (write-region (point-min) (point-max) tempfile nil 'nomessage)
3075 (diff-files-for-recover "File"
3076 buffer-file-name tempfile buffer-file-name tempfile
3077 buffer-file-coding-system)
3078 (sit-for 0))
3079 (when (file-exists-p tempfile)
3080 (delete-file tempfile))))
3081 (message "Buffer %s has no associated file on disc" (buffer-name))
3082 ;; Display that message for 1 second so that user can read it
3083 ;; in the minibuffer.
3084 (sit-for 1)))
3085 ;; return always nil, so that save-buffers-kill-emacs will not move
3086 ;; over to the next unsaved buffer when calling `d'.
3087 nil)
3088
3089 (defun diff-files-for-recover (purpose file-1 file-2
3090 failed-file-1 failed-file-2
3091 coding-system)
3092 "Diff two files for recovering or comparing against the last saved version.
3093 PURPOSE is an informational string used for naming the resulting buffer.
3094 FILE-1 and FILE-2 are the two files to compare.
3095 FAILED-FILE-1 and FAILED-FILE-2 are the names of files for which we should
3096 generate directory listings on failure.
3097 CODING-SYSTEM is the coding system of the resulting buffer."
3098 (with-output-to-temp-buffer (concat "*" purpose " Diff*")
3099 (buffer-disable-undo standard-output)
3100 (let ((coding-system-for-read coding-system))
3101 (condition-case ferr
3102 (progn
3103 (apply #'call-process
3104 recover-file-diff-program
3105 nil standard-output nil
3106 (append
3107 recover-file-diff-arguments
3108 (list file-1 file-2)))
3109 (if (fboundp 'diff-mode)
3110 (save-excursion
3111 (set-buffer standard-output)
3112 (declare-fboundp (diff-mode)))))
3113 (io-error
3114 (save-excursion
3115 (let ((switches
3116 (declare-boundp
3117 dired-listing-switches)))
3118 (if (file-symlink-p failed-file-2)
3119 (setq switches (concat switches "L")))
3120 (set-buffer standard-output)
3121 ;; XEmacs had the following line, not in FSF.
3122 (setq default-directory (file-name-directory failed-file-2))
3123 ;; Use insert-directory-safely,
3124 ;; not insert-directory, because
3125 ;; these files might not exist.
3126 ;; In particular, FAILED-FILE-2 might not
3127 ;; exist if the auto-save file
3128 ;; was for a buffer that didn't
3129 ;; visit a file, such as
3130 ;; "*mail*". The code in v20.x
3131 ;; called `ls' directly, so we
3132 ;; need to emulate what `ls' did
3133 ;; in that case.
3134 (insert-directory-safely failed-file-1 switches)
3135 (insert-directory-safely failed-file-2 switches))
3136 (terpri)
3137 (princ "Error during diff: ")
3138 (display-error ferr standard-output)))))))
3062 3139
3063 (defcustom save-some-buffers-query-display-buffer t 3140 (defcustom save-some-buffers-query-display-buffer t
3064 "*Non-nil makes `\\[save-some-buffers]' switch to the buffer offered for saving." 3141 "*Non-nil makes `\\[save-some-buffers]' switch to the buffer offered for saving."
3065 :type 'boolean 3142 :type 'boolean
3066 :group 'editing-basics) 3143 :group 'editing-basics)
3687 (insert-file-contents file) 3764 (insert-file-contents file)
3688 (let ((coding-system-for-write 3765 (let ((coding-system-for-write
3689 'escape-quoted)) 3766 'escape-quoted))
3690 (write-region (point-min) (point-max) 3767 (write-region (point-min) (point-max)
3691 temp nil 'silent))) 3768 temp nil 'silent)))
3692 (with-output-to-temp-buffer "*Autosave Diff*" 3769 (diff-files-for-recover "Autosave" temp file-name file file-name 'escape-quoted))
3693 (buffer-disable-undo standard-output)
3694 (let ((coding-system-for-read
3695 'escape-quoted))
3696 (condition-case ferr
3697 (apply #'call-process
3698 recover-file-diff-program
3699 nil standard-output nil
3700 (append
3701 recover-file-diff-arguments
3702 (list temp file-name)))
3703 (io-error
3704 (save-excursion
3705 (let ((switches
3706 (declare-boundp
3707 dired-listing-switches)))
3708 (if (file-symlink-p file)
3709 (setq switches (concat switches "L")))
3710 (set-buffer standard-output)
3711 ;; XEmacs had the following line, not in FSF.
3712 (setq default-directory (file-name-directory file))
3713 ;; Use insert-directory-safely,
3714 ;; not insert-directory, because
3715 ;; these files might not exist.
3716 ;; In particular, FILE might not
3717 ;; exist if the auto-save file
3718 ;; was for a buffer that didn't
3719 ;; visit a file, such as
3720 ;; "*mail*". The code in v20.x
3721 ;; called `ls' directly, so we
3722 ;; need to emulate what `ls' did
3723 ;; in that case.
3724 (insert-directory-safely file switches)
3725 (insert-directory-safely file-name switches))
3726 (terpri)
3727 (princ "Error during diff: ")
3728 (display-error ferr
3729 standard-output)))))))
3730 (ignore-errors (kill-buffer buffer)) 3770 (ignore-errors (kill-buffer buffer))
3731 (ignore-file-errors 3771 (ignore-file-errors
3732 (delete-file temp))))))))))))))) 3772 (delete-file temp)))))))))))))))
3733 3773
3734 (defun recover-session () 3774 (defun recover-session ()