Initial Commit
[packages] / xemacs-packages / dired / dired-diff.el
1 ;; -*-Emacs-Lisp-*-
2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3 ;;
4 ;; File:           dired-diff.el
5 ;; RCS:
6 ;; Dired Version: 7.17
7 ;; Description:    Support for diff and related commands.
8 ;; Author:         Sandy Rutherford <sandy@ibm550.sissa.it>
9 ;; Created:        Fri Jun 24 08:50:20 1994 by sandy on ibm550
10 ;; 
11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12
13 ;;; This program is free software; you can redistribute it and/or modify
14 ;;; it under the terms of the GNU General Public License as published by
15 ;;; the Free Software Foundation; either version 1, or (at your option)
16 ;;; any later version.
17 ;;;
18 ;;; This program is distributed in the hope that it will be useful,
19 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ;;; GNU General Public License for more details.
22 ;;;
23 ;;; A copy of the GNU General Public License can be obtained from this
24 ;;; program's author (send electronic mail to sandy@ibm550.sissa.it) or
25 ;;; from the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
26 ;;; MA 02139, USA.
27
28 (provide 'dired-diff)
29 (require 'dired)
30 (require 'diff-mode)
31
32 (defvar emerge-last-dir-input)
33 (defvar emerge-last-dir-output)
34 (defvar emerge-last-dir-ancestor)
35 (defvar diff-switches)
36
37 (defun dired-diff-read-file-name (prompt)
38   ;; Read and return a file name for diff.
39   (let* ((mark-active t)
40          (default (and (mark)
41                        (save-excursion
42                          (goto-char (mark))
43                          (dired-get-filename nil t)))))
44     (read-file-name (format "%s %s with: %s"
45                             prompt (dired-get-filename 'no-dir)
46                             (if default
47                                 (concat "["
48                                         (dired-make-relative
49                                          default
50                                          (dired-current-directory) t)
51                                         "] ")
52                               ""))
53                     (default-directory) default t)))
54
55 (defun dired-diff-read-switches (switchprompt)
56   ;; Read and return a list of switches
57   (let* ((default (if (listp diff-switches)
58                       (mapconcat 'identity diff-switches " ")
59                     diff-switches))
60          (switches
61           (read-string (format switchprompt default) default)))
62     (let (result (start 0))
63       (while (string-match "\\(\\S-+\\)" switches start)
64         (setq result (cons (substring switches (match-beginning 1)
65                                       (match-end 1))
66                            result)
67               start (match-end 0)))
68       (nreverse result))))
69
70 ;;;###autoload
71 (defun dired-diff (file &optional switches)
72   "Compare file at point with file FILE using `diff'.
73 FILE defaults to the file at the mark.
74 The prompted-for file is the first file given to `diff'.
75 With a prefix allows the switches for the diff program to be edited."
76   (interactive
77    (list
78     (dired-diff-read-file-name "Diff") 
79     (and current-prefix-arg (dired-diff-read-switches "Options for diff: "))))
80   (if switches
81       (diff file (dired-get-filename) switches)
82     (diff file (dired-get-filename))))
83
84 ;;;###autoload
85 (defun dired-backup-diff (&optional switches)
86   "Diff this file with its backup file or vice versa.
87 Uses the latest backup, if there are several numerical backups.
88 If this file is a backup, diff it with its original.
89 The backup file is the first file given to `diff'."
90   (interactive (list (and current-prefix-arg
91                           (dired-diff-read-switches "Diff with switches: "))))
92   (if switches
93       (diff-backup (dired-get-filename) switches)
94     (diff-backup (dired-get-filename))))
95
96 ;;;###autoload
97 (defun dired-emerge (arg file out-file)
98   "Merge file at point with FILE using `emerge'.
99 FILE defaults to the file at the mark."
100   (interactive
101    (let ((file (dired-diff-read-file-name "Merge")))
102      (list
103       current-prefix-arg
104       file
105       (and current-prefix-arg (emerge-read-file-name
106                                "Output file"
107                                emerge-last-dir-output
108                                (dired-abbreviate-file-name file) file)))))
109   (emerge-files arg file (dired-get-filename) out-file))
110
111 ;;;###autoload
112 (defun dired-emerge-with-ancestor (arg file ancestor file-out)
113   "Merge file at point with FILE, using a common ANCESTOR file.
114 FILE defaults to the file at the mark."
115   (interactive
116    (let ((file (dired-diff-read-file-name "Merge")))
117      (list
118       current-prefix-arg
119       file
120       (emerge-read-file-name "Ancestor file" emerge-last-dir-ancestor nil file)
121       (and current-prefix-arg (emerge-read-file-name
122                                "Output file"
123                                emerge-last-dir-output
124                                (dired-abbreviate-file-name file) file)))))
125   (emerge-files-with-ancestor arg file (dired-get-filename)
126                               ancestor file-out))
127
128 ;;;###autoload
129 (defun dired-ediff (file)
130   "Ediff file at point with FILE.
131 FILE defaults to the file at the mark.
132 `ediff-directories' is used if both files are directories."
133   (interactive (list (dired-diff-read-file-name "Ediff")))
134   (let
135       ((file-at-mark-is-dir
136         (file-directory-p
137          (file-name-as-directory file)))
138        (file-at-point-is-dir
139         (file-directory-p
140          (file-name-as-directory (dired-get-filename)))))
141     (cond
142      ((and file-at-mark-is-dir file-at-point-is-dir)
143       (ediff-directories file (dired-get-filename) ""))
144      ((and (not file-at-mark-is-dir) (not file-at-point-is-dir))
145       (ediff-files file (dired-get-filename)))
146      (t
147       (apply
148        'warn
149        "Cannot compare file %s with directory %s"
150        (if file-at-mark-is-dir
151            (list (dired-get-filename) file)
152          (list file (dired-get-filename))))))))
153
154 ;;;###autoload
155 (defun dired-epatch (file)
156   "Patch file at point using `epatch'."
157   (interactive
158    (let ((file (dired-get-filename)))
159      (list
160       (and (or (memq 'patch dired-no-confirm)
161                (y-or-n-p (format "Patch %s? "
162                                 (file-name-nondirectory file))))
163            file))))
164   (if file
165       (ediff-patch-file file)
166     (message "No file patched.")))
167
168 ;;; Autoloads
169
170 ;;; Diff (diff)
171
172 (autoload 'diff "diff" "Diff two files." t)
173 (autoload 'diff-backup "diff"
174           "Diff this file with its backup or vice versa." t)
175
176 ;;; Emerge
177
178 (autoload 'emerge-files "emerge" "Merge two files." t)
179 (autoload 'emerge-files-with-ancestor "emerge"
180          "Merge two files having a common ancestor." t)
181 (autoload 'emerge-read-file-name "emerge")
182
183 ;; Ediff
184
185 (autoload 'ediff-files "ediff" "Ediff two files." t)
186 (autoload 'ediff-patch-file "ediff" "Patch a file." t)
187
188 ;;; end of dired-diff.el