7 |
;; Keywords: comparing, merging, patching, tools, unix |
;; Keywords: comparing, merging, patching, tools, unix |
8 |
|
|
9 |
(defconst ediff-version "2.78" "The current version of Ediff") |
(defconst ediff-version "2.78" "The current version of Ediff") |
10 |
(defconst ediff-date "January 25, 2003" "Date of last update") |
(defconst ediff-date "January 25, 2003" "Date of last update") |
11 |
|
|
12 |
|
|
13 |
;; This file is part of GNU Emacs. |
;; This file is part of GNU Emacs. |
200 |
dir-B f) |
dir-B f) |
201 |
(list (setq f (ediff-read-file-name |
(list (setq f (ediff-read-file-name |
202 |
"File A to compare" |
"File A to compare" |
203 |
dir-A |
dir-A |
204 |
(ediff-get-default-file-name) |
(ediff-get-default-file-name) |
205 |
'no-dirs)) |
'no-dirs)) |
206 |
(ediff-read-file-name "File B to compare" |
(ediff-read-file-name "File B to compare" |
207 |
(setq dir-B |
(setq dir-B |
208 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
209 |
ediff-last-dir-B |
ediff-last-dir-B |
210 |
(file-name-directory f))) |
(file-name-directory f))) |
211 |
(progn |
(progn |
212 |
(setq file-name-history |
(setq file-name-history |
217 |
file-name-history)) |
file-name-history)) |
218 |
(ediff-get-default-file-name f 1))) |
(ediff-get-default-file-name f 1))) |
219 |
))) |
))) |
220 |
(ediff-files-internal file-A |
(ediff-files-internal file-A |
221 |
(if (file-directory-p file-B) |
(if (file-directory-p file-B) |
222 |
(expand-file-name |
(expand-file-name |
223 |
(file-name-nondirectory file-A) file-B) |
(file-name-nondirectory file-A) file-B) |
225 |
nil ; file-C |
nil ; file-C |
226 |
startup-hooks |
startup-hooks |
227 |
'ediff-files)) |
'ediff-files)) |
228 |
|
|
229 |
;;;###autoload |
;;;###autoload |
230 |
(defun ediff-files3 (file-A file-B file-C &optional startup-hooks) |
(defun ediff-files3 (file-A file-B file-C &optional startup-hooks) |
231 |
"Run Ediff on three files, FILE-A, FILE-B, and FILE-C." |
"Run Ediff on three files, FILE-A, FILE-B, and FILE-C." |
239 |
dir-A |
dir-A |
240 |
(ediff-get-default-file-name) |
(ediff-get-default-file-name) |
241 |
'no-dirs)) |
'no-dirs)) |
242 |
(setq ff (ediff-read-file-name "File B to compare" |
(setq ff (ediff-read-file-name "File B to compare" |
243 |
(setq dir-B |
(setq dir-B |
244 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
245 |
ediff-last-dir-B |
ediff-last-dir-B |
253 |
dir-B)) |
dir-B)) |
254 |
file-name-history)) |
file-name-history)) |
255 |
(ediff-get-default-file-name f 1)))) |
(ediff-get-default-file-name f 1)))) |
256 |
(ediff-read-file-name "File C to compare" |
(ediff-read-file-name "File C to compare" |
257 |
(setq dir-C (if ediff-use-last-dir |
(setq dir-C (if ediff-use-last-dir |
258 |
ediff-last-dir-C |
ediff-last-dir-C |
259 |
(file-name-directory ff))) |
(file-name-directory ff))) |
266 |
file-name-history)) |
file-name-history)) |
267 |
(ediff-get-default-file-name ff 2))) |
(ediff-get-default-file-name ff 2))) |
268 |
))) |
))) |
269 |
(ediff-files-internal file-A |
(ediff-files-internal file-A |
270 |
(if (file-directory-p file-B) |
(if (file-directory-p file-B) |
271 |
(expand-file-name |
(expand-file-name |
272 |
(file-name-nondirectory file-A) file-B) |
(file-name-nondirectory file-A) file-B) |
282 |
(defalias 'ediff3 'ediff-files3) |
(defalias 'ediff3 'ediff-files3) |
283 |
|
|
284 |
|
|
285 |
;; Visit FILE and arrange its buffer to Ediff's liking. |
;; Visit FILE and arrange its buffer to Ediff's liking. |
286 |
;; FILE is actually a variable symbol that must contain a true file name. |
;; FILE is actually a variable symbol that must contain a true file name. |
287 |
;; BUFFER-NAME is a variable symbol, which will get the buffer object into |
;; BUFFER-NAME is a variable symbol, which will get the buffer object into |
288 |
;; which FILE is read. |
;; which FILE is read. |
299 |
(error "File `%s' does not exist or is not readable" file)) |
(error "File `%s' does not exist or is not readable" file)) |
300 |
((file-directory-p file) |
((file-directory-p file) |
301 |
(error "File `%s' is a directory" file))) |
(error "File `%s' is a directory" file))) |
302 |
|
|
303 |
;; some of the commands, below, require full file name |
;; some of the commands, below, require full file name |
304 |
(setq file (expand-file-name file)) |
(setq file (expand-file-name file)) |
305 |
|
|
306 |
;; Record the directory of the file |
;; Record the directory of the file |
307 |
(if last-dir |
(if last-dir |
308 |
(set last-dir (expand-file-name (file-name-directory file)))) |
(set last-dir (expand-file-name (file-name-directory file)))) |
309 |
|
|
310 |
;; Setup the buffer |
;; Setup the buffer |
311 |
(set buffer-name (find-file-noselect file)) |
(set buffer-name (find-file-noselect file)) |
312 |
|
|
313 |
(ediff-with-current-buffer (symbol-value buffer-name) |
(ediff-with-current-buffer (symbol-value buffer-name) |
314 |
(widen) ; Make sure the entire file is seen |
(widen) ; Make sure the entire file is seen |
315 |
(cond (file-magic ; file has a handler, such as jka-compr-handler or |
(cond (file-magic ; file has a handler, such as jka-compr-handler or |
362 |
startup-hooks |
startup-hooks |
363 |
(list (cons 'ediff-job-name job-name)) |
(list (cons 'ediff-job-name job-name)) |
364 |
merge-buffer-file))) |
merge-buffer-file))) |
365 |
|
|
366 |
|
|
367 |
;;;###autoload |
;;;###autoload |
368 |
(defalias 'ediff 'ediff-files) |
(defalias 'ediff 'ediff-files) |
387 |
;;;###autoload |
;;;###autoload |
388 |
(defun ediff-buffers (buffer-A buffer-B &optional startup-hooks job-name) |
(defun ediff-buffers (buffer-A buffer-B &optional startup-hooks job-name) |
389 |
"Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B." |
"Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B." |
390 |
(interactive |
(interactive |
391 |
(let (bf) |
(let (bf) |
392 |
(list (setq bf (read-buffer "Buffer A to compare: " |
(list (setq bf (read-buffer "Buffer A to compare: " |
393 |
(ediff-other-buffer "") t)) |
(ediff-other-buffer "") t)) |
404 |
;;;###autoload |
;;;###autoload |
405 |
(defalias 'ebuffers 'ediff-buffers) |
(defalias 'ebuffers 'ediff-buffers) |
406 |
|
|
407 |
|
|
408 |
;;;###autoload |
;;;###autoload |
409 |
(defun ediff-buffers3 (buffer-A buffer-B buffer-C |
(defun ediff-buffers3 (buffer-A buffer-B buffer-C |
410 |
&optional startup-hooks job-name) |
&optional startup-hooks job-name) |
411 |
"Run Ediff on three buffers, BUFFER-A, BUFFER-B, and BUFFER-C." |
"Run Ediff on three buffers, BUFFER-A, BUFFER-B, and BUFFER-C." |
412 |
(interactive |
(interactive |
413 |
(let (bf bff) |
(let (bf bff) |
414 |
(list (setq bf (read-buffer "Buffer A to compare: " |
(list (setq bf (read-buffer "Buffer A to compare: " |
415 |
(ediff-other-buffer "") t)) |
(ediff-other-buffer "") t)) |
433 |
|
|
434 |
;;;###autoload |
;;;###autoload |
435 |
(defalias 'ebuffers3 'ediff-buffers3) |
(defalias 'ebuffers3 'ediff-buffers3) |
|
|
|
436 |
|
|
437 |
|
|
438 |
|
|
439 |
;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer |
;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer |
440 |
(defun ediff-buffers-internal (buf-A buf-B buf-C startup-hooks job-name |
(defun ediff-buffers-internal (buf-A buf-B buf-C startup-hooks job-name |
441 |
&optional merge-buffer-file) |
&optional merge-buffer-file) |
459 |
(setq buf-B-file-name (file-name-nondirectory buf-B-file-name))) |
(setq buf-B-file-name (file-name-nondirectory buf-B-file-name))) |
460 |
(if (stringp buf-C-file-name) |
(if (stringp buf-C-file-name) |
461 |
(setq buf-C-file-name (file-name-nondirectory buf-C-file-name))) |
(setq buf-C-file-name (file-name-nondirectory buf-C-file-name))) |
462 |
|
|
463 |
(setq file-A (ediff-make-temp-file buf-A buf-A-file-name) |
(setq file-A (ediff-make-temp-file buf-A buf-A-file-name) |
464 |
file-B (ediff-make-temp-file buf-B buf-B-file-name)) |
file-B (ediff-make-temp-file buf-B buf-B-file-name)) |
465 |
(if buf-C-is-alive |
(if buf-C-is-alive |
466 |
(setq file-C (ediff-make-temp-file buf-C buf-C-file-name))) |
(setq file-C (ediff-make-temp-file buf-C buf-C-file-name))) |
467 |
|
|
468 |
(ediff-setup (get-buffer buf-A) file-A |
(ediff-setup (get-buffer buf-A) file-A |
469 |
(get-buffer buf-B) file-B |
(get-buffer buf-B) file-B |
470 |
(if buf-C-is-alive (get-buffer buf-C)) |
(if buf-C-is-alive (get-buffer buf-C)) |
503 |
(let ((dir-A (ediff-get-default-directory-name)) |
(let ((dir-A (ediff-get-default-directory-name)) |
504 |
f) |
f) |
505 |
(list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) |
(list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) |
506 |
(ediff-read-file-name "Directory B to compare:" |
(ediff-read-file-name "Directory B to compare:" |
507 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
508 |
ediff-last-dir-B |
ediff-last-dir-B |
509 |
(ediff-strip-last-dir f)) |
(ediff-strip-last-dir f)) |
510 |
nil) |
nil) |
511 |
(read-string "Filter through regular expression: " |
(read-string "Filter through regular expression: " |
549 |
(let ((dir-A (ediff-get-default-directory-name)) |
(let ((dir-A (ediff-get-default-directory-name)) |
550 |
f) |
f) |
551 |
(list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) |
(list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) |
552 |
(setq f (ediff-read-file-name "Directory B to compare:" |
(setq f (ediff-read-file-name "Directory B to compare:" |
553 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
554 |
ediff-last-dir-B |
ediff-last-dir-B |
555 |
(ediff-strip-last-dir f)) |
(ediff-strip-last-dir f)) |
556 |
nil)) |
nil)) |
557 |
(ediff-read-file-name "Directory C to compare:" |
(ediff-read-file-name "Directory C to compare:" |
558 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
559 |
ediff-last-dir-C |
ediff-last-dir-C |
560 |
(ediff-strip-last-dir f)) |
(ediff-strip-last-dir f)) |
561 |
nil) |
nil) |
562 |
(read-string "Filter through regular expression: " |
(read-string "Filter through regular expression: " |
578 |
(let ((dir-A (ediff-get-default-directory-name)) |
(let ((dir-A (ediff-get-default-directory-name)) |
579 |
f) |
f) |
580 |
(list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) |
(list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) |
581 |
(ediff-read-file-name "Directory B to merge:" |
(ediff-read-file-name "Directory B to merge:" |
582 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
583 |
ediff-last-dir-B |
ediff-last-dir-B |
584 |
(ediff-strip-last-dir f)) |
(ediff-strip-last-dir f)) |
585 |
nil) |
nil) |
586 |
(read-string "Filter through regular expression: " |
(read-string "Filter through regular expression: " |
607 |
(let ((dir-A (ediff-get-default-directory-name)) |
(let ((dir-A (ediff-get-default-directory-name)) |
608 |
f) |
f) |
609 |
(list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) |
(list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) |
610 |
(setq f (ediff-read-file-name "Directory B to merge:" |
(setq f (ediff-read-file-name "Directory B to merge:" |
611 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
612 |
ediff-last-dir-B |
ediff-last-dir-B |
613 |
(ediff-strip-last-dir f)) |
(ediff-strip-last-dir f)) |
614 |
nil)) |
nil)) |
615 |
(ediff-read-file-name "Ancestor directory:" |
(ediff-read-file-name "Ancestor directory:" |
616 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
617 |
ediff-last-dir-C |
ediff-last-dir-C |
618 |
(ediff-strip-last-dir f)) |
(ediff-strip-last-dir f)) |
619 |
nil) |
nil) |
620 |
(read-string "Filter through regular expression: " |
(read-string "Filter through regular expression: " |
670 |
;;;###autoload |
;;;###autoload |
671 |
(defalias |
(defalias |
672 |
'edir-merge-revisions-with-ancestor |
'edir-merge-revisions-with-ancestor |
673 |
'ediff-merge-directory-revisions-with-ancestor) |
'ediff-merge-directory-revisions-with-ancestor) |
674 |
|
|
675 |
;;;###autoload |
;;;###autoload |
676 |
(defalias 'edirs-merge-with-ancestor 'ediff-merge-directories-with-ancestor) |
(defalias 'edirs-merge-with-ancestor 'ediff-merge-directories-with-ancestor) |
681 |
;; only file names that match the regexp are considered. |
;; only file names that match the regexp are considered. |
682 |
;; JOBNAME is the symbol indicating the meta-job to be performed. |
;; JOBNAME is the symbol indicating the meta-job to be performed. |
683 |
;; MERGE-AUTOSTORE-DIR is the directory in which to store merged files. |
;; MERGE-AUTOSTORE-DIR is the directory in which to store merged files. |
684 |
(defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname |
(defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname |
685 |
&optional startup-hooks |
&optional startup-hooks |
686 |
merge-autostore-dir) |
merge-autostore-dir) |
687 |
;; ediff-read-file-name is set to attach a previously entered file name if |
;; ediff-read-file-name is set to attach a previously entered file name if |
705 |
(or (stringp merge-autostore-dir) |
(or (stringp merge-autostore-dir) |
706 |
(error "%s: Directory for storing merged files must be a string" |
(error "%s: Directory for storing merged files must be a string" |
707 |
jobname))) |
jobname))) |
708 |
(let (;; dir-diff-struct is of the form (common-list diff-list) |
(let (;; dir-diff-struct is of the form (common-list diff-list) |
709 |
;; It is a structure where ediff-intersect-directories returns |
;; It is a structure where ediff-intersect-directories returns |
710 |
;; commonalities and differences among directories |
;; commonalities and differences among directories |
711 |
dir-diff-struct |
dir-diff-struct |
713 |
(if (and ediff-autostore-merges |
(if (and ediff-autostore-merges |
714 |
(ediff-merge-metajob jobname) |
(ediff-merge-metajob jobname) |
715 |
(not merge-autostore-dir)) |
(not merge-autostore-dir)) |
716 |
(setq merge-autostore-dir |
(setq merge-autostore-dir |
717 |
(read-file-name "Save merged files in directory: " |
(read-file-name "Save merged files in directory: " |
718 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
719 |
ediff-last-merge-autostore-dir |
ediff-last-merge-autostore-dir |
734 |
(or (y-or-n-p |
(or (y-or-n-p |
735 |
"Directory for saving merged files = Ancestor Directory. Sure? ") |
"Directory for saving merged files = Ancestor Directory. Sure? ") |
736 |
(error "Directory merge aborted"))))) |
(error "Directory merge aborted"))))) |
737 |
|
|
738 |
(setq dir-diff-struct (ediff-intersect-directories |
(setq dir-diff-struct (ediff-intersect-directories |
739 |
jobname |
jobname |
740 |
regexp dir1 dir2 dir3 merge-autostore-dir)) |
regexp dir1 dir2 dir3 merge-autostore-dir)) |
741 |
(setq startup-hooks |
(setq startup-hooks |
744 |
(cons `(lambda () |
(cons `(lambda () |
745 |
;; tell what to do if the user clicks on a session record |
;; tell what to do if the user clicks on a session record |
746 |
(setq ediff-session-action-function (quote ,action)) |
(setq ediff-session-action-function (quote ,action)) |
747 |
;; set ediff-dir-difference-list |
;; set ediff-dir-difference-list |
748 |
(setq ediff-dir-difference-list |
(setq ediff-dir-difference-list |
749 |
(cdr (quote ,dir-diff-struct)))) |
(cdr (quote ,dir-diff-struct)))) |
750 |
startup-hooks)) |
startup-hooks)) |
751 |
(setq meta-buf (ediff-prepare-meta-buffer |
(setq meta-buf (ediff-prepare-meta-buffer |
752 |
'ediff-filegroup-action |
'ediff-filegroup-action |
753 |
(car dir-diff-struct) |
(car dir-diff-struct) |
754 |
"*Ediff Session Group Panel" |
"*Ediff Session Group Panel" |
760 |
|
|
761 |
;; MERGE-AUTOSTORE-DIR can be given to tell ediff where to store the merged |
;; MERGE-AUTOSTORE-DIR can be given to tell ediff where to store the merged |
762 |
;; files |
;; files |
763 |
(defun ediff-directory-revisions-internal (dir1 regexp action jobname |
(defun ediff-directory-revisions-internal (dir1 regexp action jobname |
764 |
&optional startup-hooks |
&optional startup-hooks |
765 |
merge-autostore-dir) |
merge-autostore-dir) |
766 |
(setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))) |
(setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))) |
770 |
(error "%S: Directory for storing merged files must be a string" |
(error "%S: Directory for storing merged files must be a string" |
771 |
jobname))) |
jobname))) |
772 |
(let (file-list meta-buf) |
(let (file-list meta-buf) |
773 |
(if (and ediff-autostore-merges |
(if (and ediff-autostore-merges |
774 |
(ediff-merge-metajob jobname) |
(ediff-merge-metajob jobname) |
775 |
(not merge-autostore-dir)) |
(not merge-autostore-dir)) |
776 |
(setq merge-autostore-dir |
(setq merge-autostore-dir |
777 |
(read-file-name "Save merged files in directory: " |
(read-file-name "Save merged files in directory: " |
778 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
779 |
ediff-last-merge-autostore-dir |
ediff-last-merge-autostore-dir |
787 |
(or (y-or-n-p |
(or (y-or-n-p |
788 |
"Directory for saving merged file = directory A. Sure? ") |
"Directory for saving merged file = directory A. Sure? ") |
789 |
(error "Merge of directory revisions aborted"))) |
(error "Merge of directory revisions aborted"))) |
790 |
|
|
791 |
(setq file-list |
(setq file-list |
792 |
(ediff-get-directory-files-under-revision |
(ediff-get-directory-files-under-revision |
793 |
jobname regexp dir1 merge-autostore-dir)) |
jobname regexp dir1 merge-autostore-dir)) |
798 |
;; tell what to do if the user clicks on a session record |
;; tell what to do if the user clicks on a session record |
799 |
(setq ediff-session-action-function (quote ,action))) |
(setq ediff-session-action-function (quote ,action))) |
800 |
startup-hooks)) |
startup-hooks)) |
801 |
(setq meta-buf (ediff-prepare-meta-buffer |
(setq meta-buf (ediff-prepare-meta-buffer |
802 |
'ediff-filegroup-action |
'ediff-filegroup-action |
803 |
file-list |
file-list |
804 |
"*Ediff Session Group Panel" |
"*Ediff Session Group Panel" |
821 |
(interactive "P") |
(interactive "P") |
822 |
(ediff-windows dumb-mode wind-A wind-B |
(ediff-windows dumb-mode wind-A wind-B |
823 |
startup-hooks 'ediff-windows-wordwise 'word-mode)) |
startup-hooks 'ediff-windows-wordwise 'word-mode)) |
824 |
|
|
825 |
;;;###autoload |
;;;###autoload |
826 |
(defun ediff-windows-linewise (dumb-mode &optional wind-A wind-B startup-hooks) |
(defun ediff-windows-linewise (dumb-mode &optional wind-A wind-B startup-hooks) |
827 |
"Compare WIND-A and WIND-B, which are selected by clicking, linewise. |
"Compare WIND-A and WIND-B, which are selected by clicking, linewise. |
832 |
(interactive "P") |
(interactive "P") |
833 |
(ediff-windows dumb-mode wind-A wind-B |
(ediff-windows dumb-mode wind-A wind-B |
834 |
startup-hooks 'ediff-windows-linewise nil)) |
startup-hooks 'ediff-windows-linewise nil)) |
835 |
|
|
836 |
;; Compare WIND-A and WIND-B, which are selected by clicking. |
;; Compare WIND-A and WIND-B, which are selected by clicking. |
837 |
;; With prefix argument, DUMB-MODE, or on a non-windowing display, |
;; With prefix argument, DUMB-MODE, or on a non-windowing display, |
838 |
;; works as follows: |
;; works as follows: |
844 |
wind-B (ediff-get-next-window wind-B wind-A)) |
wind-B (ediff-get-next-window wind-B wind-A)) |
845 |
(setq wind-A (ediff-get-window-by-clicking wind-A nil 1) |
(setq wind-A (ediff-get-window-by-clicking wind-A nil 1) |
846 |
wind-B (ediff-get-window-by-clicking wind-B wind-A 2))) |
wind-B (ediff-get-window-by-clicking wind-B wind-A 2))) |
847 |
|
|
848 |
(let ((buffer-A (window-buffer wind-A)) |
(let ((buffer-A (window-buffer wind-A)) |
849 |
(buffer-B (window-buffer wind-B)) |
(buffer-B (window-buffer wind-B)) |
850 |
beg-A end-A beg-B end-B) |
beg-A end-A beg-B end-B) |
851 |
|
|
852 |
(save-excursion |
(save-excursion |
853 |
(save-window-excursion |
(save-window-excursion |
854 |
(sit-for 0) ; sync before using window-start/end -- a precaution |
(sit-for 0) ; sync before using window-start/end -- a precaution |
867 |
(ediff-regions-internal |
(ediff-regions-internal |
868 |
buffer-A beg-A end-A buffer-B beg-B end-B |
buffer-A beg-A end-A buffer-B beg-B end-B |
869 |
startup-hooks job-name word-mode nil))) |
startup-hooks job-name word-mode nil))) |
870 |
|
|
871 |
|
|
872 |
;;;###autoload |
;;;###autoload |
873 |
(defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) |
(defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) |
878 |
region. |
region. |
879 |
This function is effective only for relatively small regions, up to 200 |
This function is effective only for relatively small regions, up to 200 |
880 |
lines. For large regions, use `ediff-regions-linewise'." |
lines. For large regions, use `ediff-regions-linewise'." |
881 |
(interactive |
(interactive |
882 |
(let (bf) |
(let (bf) |
883 |
(list (setq bf (read-buffer "Region's A buffer: " |
(list (setq bf (read-buffer "Region's A buffer: " |
884 |
(ediff-other-buffer "") t)) |
(ediff-other-buffer "") t)) |
893 |
(error "Buffer %S doesn't exist" buffer-A)) |
(error "Buffer %S doesn't exist" buffer-A)) |
894 |
(if (not (ediff-buffer-live-p buffer-B)) |
(if (not (ediff-buffer-live-p buffer-B)) |
895 |
(error "Buffer %S doesn't exist" buffer-B)) |
(error "Buffer %S doesn't exist" buffer-B)) |
896 |
|
|
897 |
|
|
898 |
(let ((buffer-A |
(let ((buffer-A |
899 |
(ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-")) |
(ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-")) |
900 |
(buffer-B |
(buffer-B |
907 |
(set-buffer buffer-B) |
(set-buffer buffer-B) |
908 |
(setq reg-B-beg (region-beginning) |
(setq reg-B-beg (region-beginning) |
909 |
reg-B-end (region-end))) |
reg-B-end (region-end))) |
910 |
|
|
911 |
(ediff-regions-internal |
(ediff-regions-internal |
912 |
(get-buffer buffer-A) reg-A-beg reg-A-end |
(get-buffer buffer-A) reg-A-beg reg-A-end |
913 |
(get-buffer buffer-B) reg-B-beg reg-B-end |
(get-buffer buffer-B) reg-B-beg reg-B-end |
914 |
startup-hooks 'ediff-regions-wordwise 'word-mode nil))) |
startup-hooks 'ediff-regions-wordwise 'word-mode nil))) |
915 |
|
|
916 |
;;;###autoload |
;;;###autoload |
917 |
(defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) |
(defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) |
918 |
"Run Ediff on a pair of regions in specified buffers. |
"Run Ediff on a pair of regions in specified buffers. |
923 |
Each region is enlarged to contain full lines. |
Each region is enlarged to contain full lines. |
924 |
This function is effective for large regions, over 100-200 |
This function is effective for large regions, over 100-200 |
925 |
lines. For small regions, use `ediff-regions-wordwise'." |
lines. For small regions, use `ediff-regions-wordwise'." |
926 |
(interactive |
(interactive |
927 |
(let (bf) |
(let (bf) |
928 |
(list (setq bf (read-buffer "Region A's buffer: " |
(list (setq bf (read-buffer "Region A's buffer: " |
929 |
(ediff-other-buffer "") t)) |
(ediff-other-buffer "") t)) |
938 |
(error "Buffer %S doesn't exist" buffer-A)) |
(error "Buffer %S doesn't exist" buffer-A)) |
939 |
(if (not (ediff-buffer-live-p buffer-B)) |
(if (not (ediff-buffer-live-p buffer-B)) |
940 |
(error "Buffer %S doesn't exist" buffer-B)) |
(error "Buffer %S doesn't exist" buffer-B)) |
941 |
|
|
942 |
(let ((buffer-A |
(let ((buffer-A |
943 |
(ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-")) |
(ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-")) |
944 |
(buffer-B |
(buffer-B |
949 |
(setq reg-A-beg (region-beginning) |
(setq reg-A-beg (region-beginning) |
950 |
reg-A-end (region-end)) |
reg-A-end (region-end)) |
951 |
;; enlarge the region to hold full lines |
;; enlarge the region to hold full lines |
952 |
(goto-char reg-A-beg) |
(goto-char reg-A-beg) |
953 |
(beginning-of-line) |
(beginning-of-line) |
954 |
(setq reg-A-beg (point)) |
(setq reg-A-beg (point)) |
955 |
(goto-char reg-A-end) |
(goto-char reg-A-end) |
956 |
(end-of-line) |
(end-of-line) |
957 |
(or (eobp) (forward-char)) ; include the newline char |
(or (eobp) (forward-char)) ; include the newline char |
958 |
(setq reg-A-end (point)) |
(setq reg-A-end (point)) |
959 |
|
|
960 |
(set-buffer buffer-B) |
(set-buffer buffer-B) |
961 |
(setq reg-B-beg (region-beginning) |
(setq reg-B-beg (region-beginning) |
962 |
reg-B-end (region-end)) |
reg-B-end (region-end)) |
963 |
;; enlarge the region to hold full lines |
;; enlarge the region to hold full lines |
964 |
(goto-char reg-B-beg) |
(goto-char reg-B-beg) |
965 |
(beginning-of-line) |
(beginning-of-line) |
966 |
(setq reg-B-beg (point)) |
(setq reg-B-beg (point)) |
967 |
(goto-char reg-B-end) |
(goto-char reg-B-end) |
968 |
(end-of-line) |
(end-of-line) |
969 |
(or (eobp) (forward-char)) ; include the newline char |
(or (eobp) (forward-char)) ; include the newline char |
970 |
(setq reg-B-end (point)) |
(setq reg-B-end (point)) |
971 |
) ; save excursion |
) ; save excursion |
972 |
|
|
973 |
(ediff-regions-internal |
(ediff-regions-internal |
974 |
(get-buffer buffer-A) reg-A-beg reg-A-end |
(get-buffer buffer-A) reg-A-beg reg-A-end |
975 |
(get-buffer buffer-B) reg-B-beg reg-B-end |
(get-buffer buffer-B) reg-B-beg reg-B-end |
976 |
startup-hooks 'ediff-regions-linewise nil nil))) ; no word mode |
startup-hooks 'ediff-regions-linewise nil nil))) ; no word mode |
977 |
|
|
978 |
;; compare region beg-A to end-A of buffer-A |
;; compare region beg-A to end-A of buffer-A |
979 |
;; to regions beg-B -- end-B in buffer-B. |
;; to regions beg-B -- end-B in buffer-B. |
980 |
(defun ediff-regions-internal (buffer-A beg-A end-A buffer-B beg-B end-B |
(defun ediff-regions-internal (buffer-A beg-A end-A buffer-B beg-B end-B |
981 |
startup-hooks job-name word-mode |
startup-hooks job-name word-mode |
982 |
setup-parameters) |
setup-parameters) |
983 |
(let ((tmp-buffer (get-buffer-create ediff-tmp-buffer)) |
(let ((tmp-buffer (get-buffer-create ediff-tmp-buffer)) |
984 |
overl-A overl-B |
overl-A overl-B |
985 |
file-A file-B) |
file-A file-B) |
986 |
|
|
987 |
;; in case beg/end-A/B aren't markers--make them into markers |
;; in case beg/end-A/B aren't markers--make them into markers |
988 |
(ediff-with-current-buffer buffer-A |
(ediff-with-current-buffer buffer-A |
989 |
(setq beg-A (move-marker (make-marker) beg-A) |
(setq beg-A (move-marker (make-marker) beg-A) |
991 |
(ediff-with-current-buffer buffer-B |
(ediff-with-current-buffer buffer-B |
992 |
(setq beg-B (move-marker (make-marker) beg-B) |
(setq beg-B (move-marker (make-marker) beg-B) |
993 |
end-B (move-marker (make-marker) end-B))) |
end-B (move-marker (make-marker) end-B))) |
994 |
|
|
995 |
;; make file-A |
;; make file-A |
996 |
(if word-mode |
(if word-mode |
997 |
(ediff-wordify beg-A end-A buffer-A tmp-buffer) |
(ediff-wordify beg-A end-A buffer-A tmp-buffer) |
998 |
(ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer)) |
(ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer)) |
999 |
(setq file-A (ediff-make-temp-file tmp-buffer "regA")) |
(setq file-A (ediff-make-temp-file tmp-buffer "regA")) |
1000 |
|
|
1001 |
;; make file-B |
;; make file-B |
1002 |
(if word-mode |
(if word-mode |
1003 |
(ediff-wordify beg-B end-B buffer-B tmp-buffer) |
(ediff-wordify beg-B end-B buffer-B tmp-buffer) |
1004 |
(ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer)) |
(ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer)) |
1005 |
(setq file-B (ediff-make-temp-file tmp-buffer "regB")) |
(setq file-B (ediff-make-temp-file tmp-buffer "regB")) |
1006 |
|
|
1007 |
(setq overl-A (ediff-make-bullet-proof-overlay beg-A end-A buffer-A)) |
(setq overl-A (ediff-make-bullet-proof-overlay beg-A end-A buffer-A)) |
1008 |
(setq overl-B (ediff-make-bullet-proof-overlay beg-B end-B buffer-B)) |
(setq overl-B (ediff-make-bullet-proof-overlay beg-B end-B buffer-B)) |
1009 |
(ediff-setup buffer-A file-A |
(ediff-setup buffer-A file-A |
1019 |
(cons 'ediff-job-name job-name)) |
(cons 'ediff-job-name job-name)) |
1020 |
setup-parameters)) |
setup-parameters)) |
1021 |
)) |
)) |
1022 |
|
|
1023 |
|
|
1024 |
;;; Merge files and buffers |
;;; Merge files and buffers |
1025 |
|
|
1026 |
;;;###autoload |
;;;###autoload |
1027 |
(defalias 'ediff-merge 'ediff-merge-files) |
(defalias 'ediff-merge 'ediff-merge-files) |
1028 |
|
|
1029 |
(defsubst ediff-merge-on-startup () |
(defsubst ediff-merge-on-startup () |
1030 |
(ediff-do-merge 0) |
(ediff-do-merge 0) |
1031 |
(ediff-with-current-buffer ediff-buffer-C |
(ediff-with-current-buffer ediff-buffer-C |
1034 |
;;;###autoload |
;;;###autoload |
1035 |
(defun ediff-merge-files (file-A file-B |
(defun ediff-merge-files (file-A file-B |
1036 |
;; MERGE-BUFFER-FILE is the file to be |
;; MERGE-BUFFER-FILE is the file to be |
1037 |
;; associated with the merge buffer |
;; associated with the merge buffer |
1038 |
&optional startup-hooks merge-buffer-file) |
&optional startup-hooks merge-buffer-file) |
1039 |
"Merge two files without ancestor." |
"Merge two files without ancestor." |
1040 |
(interactive |
(interactive |
1047 |
dir-A |
dir-A |
1048 |
(ediff-get-default-file-name) |
(ediff-get-default-file-name) |
1049 |
'no-dirs)) |
'no-dirs)) |
1050 |
(ediff-read-file-name "File B to merge" |
(ediff-read-file-name "File B to merge" |
1051 |
(setq dir-B |
(setq dir-B |
1052 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
1053 |
ediff-last-dir-B |
ediff-last-dir-B |
1054 |
(file-name-directory f))) |
(file-name-directory f))) |
1055 |
(progn |
(progn |
1056 |
(setq file-name-history |
(setq file-name-history |
1062 |
(ediff-get-default-file-name f 1))) |
(ediff-get-default-file-name f 1))) |
1063 |
))) |
))) |
1064 |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
1065 |
(ediff-files-internal file-A |
(ediff-files-internal file-A |
1066 |
(if (file-directory-p file-B) |
(if (file-directory-p file-B) |
1067 |
(expand-file-name |
(expand-file-name |
1068 |
(file-name-nondirectory file-A) file-B) |
(file-name-nondirectory file-A) file-B) |
1071 |
startup-hooks |
startup-hooks |
1072 |
'ediff-merge-files |
'ediff-merge-files |
1073 |
merge-buffer-file)) |
merge-buffer-file)) |
1074 |
|
|
1075 |
;;;###autoload |
;;;###autoload |
1076 |
(defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor |
(defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor |
1077 |
&optional |
&optional |
1091 |
dir-A |
dir-A |
1092 |
(ediff-get-default-file-name) |
(ediff-get-default-file-name) |
1093 |
'no-dirs)) |
'no-dirs)) |
1094 |
(setq ff (ediff-read-file-name "File B to merge" |
(setq ff (ediff-read-file-name "File B to merge" |
1095 |
(setq dir-B |
(setq dir-B |
1096 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
1097 |
ediff-last-dir-B |
ediff-last-dir-B |
1098 |
(file-name-directory f))) |
(file-name-directory f))) |
1099 |
(progn |
(progn |
1100 |
(setq file-name-history |
(setq file-name-history |
1105 |
dir-B)) |
dir-B)) |
1106 |
file-name-history)) |
file-name-history)) |
1107 |
(ediff-get-default-file-name f 1)))) |
(ediff-get-default-file-name f 1)))) |
1108 |
(ediff-read-file-name "Ancestor file" |
(ediff-read-file-name "Ancestor file" |
1109 |
(setq dir-ancestor |
(setq dir-ancestor |
1110 |
(if ediff-use-last-dir |
(if ediff-use-last-dir |
1111 |
ediff-last-dir-ancestor |
ediff-last-dir-ancestor |
1120 |
(ediff-get-default-file-name ff 2))) |
(ediff-get-default-file-name ff 2))) |
1121 |
))) |
))) |
1122 |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
1123 |
(ediff-files-internal file-A |
(ediff-files-internal file-A |
1124 |
(if (file-directory-p file-B) |
(if (file-directory-p file-B) |
1125 |
(expand-file-name |
(expand-file-name |
1126 |
(file-name-nondirectory file-A) file-B) |
(file-name-nondirectory file-A) file-B) |
1129 |
startup-hooks |
startup-hooks |
1130 |
'ediff-merge-files-with-ancestor |
'ediff-merge-files-with-ancestor |
1131 |
merge-buffer-file)) |
merge-buffer-file)) |
1132 |
|
|
1133 |
;;;###autoload |
;;;###autoload |
1134 |
(defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor) |
(defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor) |
1135 |
|
|
1136 |
;;;###autoload |
;;;###autoload |
1137 |
(defun ediff-merge-buffers (buffer-A buffer-B |
(defun ediff-merge-buffers (buffer-A buffer-B |
1138 |
&optional |
&optional |
1140 |
;; associated with the merge buffer |
;; associated with the merge buffer |
1141 |
startup-hooks job-name merge-buffer-file) |
startup-hooks job-name merge-buffer-file) |
1142 |
"Merge buffers without ancestor." |
"Merge buffers without ancestor." |
1143 |
(interactive |
(interactive |
1144 |
(let (bf) |
(let (bf) |
1145 |
(list (setq bf (read-buffer "Buffer A to merge: " |
(list (setq bf (read-buffer "Buffer A to merge: " |
1146 |
(ediff-other-buffer "") t)) |
(ediff-other-buffer "") t)) |
1151 |
(save-window-excursion (other-window 1)) |
(save-window-excursion (other-window 1)) |
1152 |
(ediff-other-buffer bf)) |
(ediff-other-buffer bf)) |
1153 |
t)))) |
t)))) |
1154 |
|
|
1155 |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
1156 |
(or job-name (setq job-name 'ediff-merge-buffers)) |
(or job-name (setq job-name 'ediff-merge-buffers)) |
1157 |
(ediff-buffers-internal |
(ediff-buffers-internal |
1158 |
buffer-A buffer-B nil startup-hooks job-name merge-buffer-file)) |
buffer-A buffer-B nil startup-hooks job-name merge-buffer-file)) |
1159 |
|
|
1160 |
;;;###autoload |
;;;###autoload |
1161 |
(defun ediff-merge-buffers-with-ancestor (buffer-A buffer-B buffer-ancestor |
(defun ediff-merge-buffers-with-ancestor (buffer-A buffer-B buffer-ancestor |
1162 |
&optional |
&optional |
1167 |
;; with the merge buffer |
;; with the merge buffer |
1168 |
merge-buffer-file) |
merge-buffer-file) |
1169 |
"Merge buffers with ancestor." |
"Merge buffers with ancestor." |
1170 |
(interactive |
(interactive |
1171 |
(let (bf bff) |
(let (bf bff) |
1172 |
(list (setq bf (read-buffer "Buffer A to merge: " |
(list (setq bf (read-buffer "Buffer A to merge: " |
1173 |
(ediff-other-buffer "") t)) |
(ediff-other-buffer "") t)) |
1186 |
(ediff-other-buffer (list bf bff))) |
(ediff-other-buffer (list bf bff))) |
1187 |
t) |
t) |
1188 |
))) |
))) |
1189 |
|
|
1190 |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
(setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) |
1191 |
(or job-name (setq job-name 'ediff-merge-buffers-with-ancestor)) |
(or job-name (setq job-name 'ediff-merge-buffers-with-ancestor)) |
1192 |
(ediff-buffers-internal |
(ediff-buffers-internal |
1193 |
buffer-A buffer-B buffer-ancestor startup-hooks job-name merge-buffer-file)) |
buffer-A buffer-B buffer-ancestor startup-hooks job-name merge-buffer-file)) |
1194 |
|
|
1195 |
|
|
1196 |
;;;###autoload |
;;;###autoload |
1197 |
(defun ediff-merge-revisions (&optional file startup-hooks merge-buffer-file) |
(defun ediff-merge-revisions (&optional file startup-hooks merge-buffer-file) |
1219 |
(funcall |
(funcall |
1220 |
(intern (format "ediff-%S-merge-internal" ediff-version-control-package)) |
(intern (format "ediff-%S-merge-internal" ediff-version-control-package)) |
1221 |
rev1 rev2 nil startup-hooks merge-buffer-file))) |
rev1 rev2 nil startup-hooks merge-buffer-file))) |
1222 |
|
|
1223 |
|
|
1224 |
;;;###autoload |
;;;###autoload |
1225 |
(defun ediff-merge-revisions-with-ancestor (&optional |
(defun ediff-merge-revisions-with-ancestor (&optional |
1269 |
(if tin |
(if tin |
1270 |
(cvs-run-ediff-on-file-descriptor tin) |
(cvs-run-ediff-on-file-descriptor tin) |
1271 |
(error "There is no file to merge")))) |
(error "There is no file to merge")))) |
1272 |
|
|
1273 |
|
|
1274 |
;;; Apply patch |
;;; Apply patch |
1275 |
|
|
1276 |
;;;###autoload |
;;;###autoload |
1294 |
(buffer-file-name patch-buf)))) |
(buffer-file-name patch-buf)))) |
1295 |
(t default-directory))) |
(t default-directory))) |
1296 |
(setq source-file |
(setq source-file |
1297 |
(read-file-name |
(read-file-name |
1298 |
"File to patch (directory, if multifile patch): " |
"File to patch (directory, if multifile patch): " |
1299 |
;; use an explicit initial file |
;; use an explicit initial file |
1300 |
source-dir nil nil (ediff-get-default-file-name))) |
source-dir nil nil (ediff-get-default-file-name))) |
1317 |
(read-buffer |
(read-buffer |
1318 |
"Which buffer to patch? " |
"Which buffer to patch? " |
1319 |
(current-buffer)))) |
(current-buffer)))) |
1320 |
|
|
1321 |
|
|
1322 |
;;;###autoload |
;;;###autoload |
1323 |
(defalias 'epatch 'ediff-patch-file) |
(defalias 'epatch 'ediff-patch-file) |
1327 |
|
|
1328 |
|
|
1329 |
|
|
1330 |
;;; Versions Control functions |
;;; Versions Control functions |
1331 |
|
|
1332 |
;;;###autoload |
;;;###autoload |
1333 |
(defun ediff-revision (&optional file startup-hooks) |
(defun ediff-revision (&optional file startup-hooks) |
1334 |
"Run Ediff by comparing versions of a file. |
"Run Ediff by comparing versions of a file. |
1344 |
ediff-last-dir-A |
ediff-last-dir-A |
1345 |
default-directory) |
default-directory) |
1346 |
(ediff-get-default-file-name) |
(ediff-get-default-file-name) |
1347 |
'no-dirs))) |
'no-dirs))) |
1348 |
(find-file file) |
(find-file file) |
1349 |
(if (and (buffer-modified-p) |
(if (and (buffer-modified-p) |
1350 |
(y-or-n-p (message "Buffer %s is modified. Save buffer? " |
(y-or-n-p (message "Buffer %s is modified. Save buffer? " |
1356 |
(format "Revision 1 to compare (default: %s's latest revision): " |
(format "Revision 1 to compare (default: %s's latest revision): " |
1357 |
(file-name-nondirectory file))) |
(file-name-nondirectory file))) |
1358 |
rev2 |
rev2 |
1359 |
(read-string |
(read-string |
1360 |
(format "Revision 2 to compare (default: %s's current state): " |
(format "Revision 2 to compare (default: %s's current state): " |
1361 |
(file-name-nondirectory file)))) |
(file-name-nondirectory file)))) |
1362 |
(ediff-load-version-control) |
(ediff-load-version-control) |
1368 |
|
|
1369 |
;;;###autoload |
;;;###autoload |
1370 |
(defalias 'erevision 'ediff-revision) |
(defalias 'erevision 'ediff-revision) |
1371 |
|
|
1372 |
|
|
1373 |
;; Test if version control package is loaded and load if not |
;; Test if version control package is loaded and load if not |
1374 |
;; Is SILENT is non-nil, don't report error if package is not found. |
;; Is SILENT is non-nil, don't report error if package is not found. |
1375 |
(defun ediff-load-version-control (&optional silent) |
(defun ediff-load-version-control (&optional silent) |
1420 |
(progn |
(progn |
1421 |
(select-window ctl-window) |
(select-window ctl-window) |
1422 |
(set-window-buffer ctl-window ctl-buf))))))) |
(set-window-buffer ctl-window ctl-buf))))))) |
1423 |
|
|
1424 |
|
|
1425 |
|
|
1426 |
|
|