comparison lisp/ediff.el @ 26263:4f315ca65976

*** empty log message ***
author Michael Kifer <kifer@cs.stonybrook.edu>
date Mon, 01 Nov 1999 07:16:15 +0000
parents 5c9c0bd0a408
children 3ec5a485d0ab
comparison
equal deleted inserted replaced
26262:c416a18b0a5d 26263:4f315ca65976
1 ;;; ediff.el --- a comprehensive visual interface to diff & patch 1 ;;; ediff.el --- a comprehensive visual interface to diff & patch
2 2
3 ;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 3 ;; Copyright (C) 1994 -- 1999 Free Software Foundation, Inc.
4 4
5 ;; Author: Michael Kifer <kifer@cs.sunysb.edu> 5 ;; Author: Michael Kifer <kifer@cs.sunysb.edu>
6 ;; Created: February 2, 1994 6 ;; Created: February 2, 1994
7 ;; Keywords: comparing, merging, patching, version control. 7 ;; Keywords: comparing, merging, patching, version control.
8 8
9 (defconst ediff-version "2.70.2" "The current version of Ediff") 9 (defconst ediff-version "2.74" "The current version of Ediff")
10 (defconst ediff-date "May 21, 1998" "Date of last update") 10 (defconst ediff-date "October 31, 1999" "Date of last update")
11 11
12 12
13 ;; This file is part of GNU Emacs. 13 ;; This file is part of GNU Emacs.
14 14
15 ;; GNU Emacs is free software; you can redistribute it and/or modify 15 ;; GNU Emacs is free software; you can redistribute it and/or modify
40 ;; separate frames), and the differences are highlighted as you step 40 ;; separate frames), and the differences are highlighted as you step
41 ;; through them. You can also copy difference regions from one buffer to 41 ;; through them. You can also copy difference regions from one buffer to
42 ;; another (and recover old differences if you change your mind). 42 ;; another (and recover old differences if you change your mind).
43 43
44 ;; Ediff also supports merging operations on files and buffers, including 44 ;; Ediff also supports merging operations on files and buffers, including
45 ;; merging using ancestor versions. Both comparison and merging operations can 45 ;; merging using ancestor versions. Both comparison and merging operations can
46 ;; be performed on directories, i.e., by pairwise comparison of files in those 46 ;; be performed on directories, i.e., by pairwise comparison of files in those
47 ;; directories. 47 ;; directories.
48 48
49 ;; In addition, Ediff can apply a patch to a file and then let you step 49 ;; In addition, Ediff can apply a patch to a file and then let you step
50 ;; though both files, the patched and the original one, simultaneously, 50 ;; though both files, the patched and the original one, simultaneously,
54 ;; effect, apply patches selectively (i.e., you can copy a difference 54 ;; effect, apply patches selectively (i.e., you can copy a difference
55 ;; region from file_orig to file, thereby undoing any particular patch that 55 ;; region from file_orig to file, thereby undoing any particular patch that
56 ;; you don't like). 56 ;; you don't like).
57 57
58 ;; Ediff is aware of version control, which lets the user compare 58 ;; Ediff is aware of version control, which lets the user compare
59 ;; files with their older versions. Ediff can also work with remote and 59 ;; files with their older versions. Ediff can also work with remote and
60 ;; compressed files. Details are given below. 60 ;; compressed files. Details are given below.
61 61
62 ;; Finally, Ediff supports directory-level comparison, merging and patching. 62 ;; Finally, Ediff supports directory-level comparison, merging and patching.
63 ;; See the on-line manual for details. 63 ;; See the on-line manual for details.
64 64
65 ;; This package builds upon the ideas borrowed from emerge.el and several 65 ;; This package builds upon the ideas borrowed from emerge.el and several
66 ;; Ediff's functions are adaptations from emerge.el. Much of the functionality 66 ;; Ediff's functions are adaptations from emerge.el. Much of the functionality
67 ;; Ediff provides is also influenced by emerge.el. 67 ;; Ediff provides is also influenced by emerge.el.
68 68
69 ;; The present version of Ediff supersedes Emerge. It provides a superior user 69 ;; The present version of Ediff supersedes Emerge. It provides a superior user
70 ;; interface and has numerous major features not found in Emerge. In 70 ;; interface and has numerous major features not found in Emerge. In
71 ;; particular, it can do patching, and 2-way and 3-way file comparison, 71 ;; particular, it can do patching, and 2-way and 3-way file comparison,
72 ;; merging, and directory operations. 72 ;; merging, and directory operations.
73 73
74 74
75 75
76 ;;; Bugs: 76 ;;; Bugs:
77 77
78 ;; 1. The undo command doesn't restore deleted regions well. That is, if 78 ;; 1. The undo command doesn't restore deleted regions well. That is, if
79 ;; you delete all characters in a difference region and then invoke 79 ;; you delete all characters in a difference region and then invoke
80 ;; `undo', the reinstated text will most likely be inserted outside of 80 ;; `undo', the reinstated text will most likely be inserted outside of
81 ;; what Ediff thinks is the current difference region. (This problem 81 ;; what Ediff thinks is the current difference region. (This problem
82 ;; doesn't seem to exist with XEmacs.) 82 ;; doesn't seem to exist with XEmacs.)
83 ;; 83 ;;
84 ;; If at any point you feel that difference regions are no longer correct, 84 ;; If at any point you feel that difference regions are no longer correct,
85 ;; you can hit '!' to recompute the differences. 85 ;; you can hit '!' to recompute the differences.
86 86
87 ;; 2. On a monochrome display, the repertoire of faces with which to 87 ;; 2. On a monochrome display, the repertoire of faces with which to
88 ;; highlight fine differences is limited. By default, Ediff is using 88 ;; highlight fine differences is limited. By default, Ediff is using
89 ;; underlining. However, if the region is already underlined by some other 89 ;; underlining. However, if the region is already underlined by some other
90 ;; overlays, there is no simple way to temporarily remove that residual 90 ;; overlays, there is no simple way to temporarily remove that residual
91 ;; underlining. This problem occurs when a buffer is highlighted with 91 ;; underlining. This problem occurs when a buffer is highlighted with
92 ;; hilit19.el or font-lock.el packages. If this residual highlighting gets 92 ;; hilit19.el or font-lock.el packages. If this residual highlighting gets
93 ;; in the way, you can do the following. Both font-lock.el and hilit19.el 93 ;; in the way, you can do the following. Both font-lock.el and hilit19.el
94 ;; provide commands for unhighlighting buffers. You can either place these 94 ;; provide commands for unhighlighting buffers. You can either place these
95 ;; commands in `ediff-prepare-buffer-hook' (which will unhighlight every 95 ;; commands in `ediff-prepare-buffer-hook' (which will unhighlight every
96 ;; buffer used by Ediff) or you can execute them interactively, at any time 96 ;; buffer used by Ediff) or you can execute them interactively, at any time
97 ;; and on any buffer. 97 ;; and on any buffer.
98 98
99 99
100 ;;; Acknowledgements: 100 ;;; Acknowledgements:
101 101
102 ;; Ediff was inspired by Dale R. Worley's <drw@math.mit.edu> emerge.el. 102 ;; Ediff was inspired by Dale R. Worley's <drw@math.mit.edu> emerge.el.
103 ;; Ediff would not have been possible without the help and encouragement of 103 ;; Ediff would not have been possible without the help and encouragement of
104 ;; its many users. See Ediff on-line Info for the full list of those who 104 ;; its many users. See Ediff on-line Info for the full list of those who
105 ;; helped. Improved defaults in Ediff file-name reading commands. 105 ;; helped. Improved defaults in Ediff file-name reading commands.
106 106
107 ;;; Code: 107 ;;; Code:
108 108
109 (provide 'ediff) 109 (provide 'ediff)
110 110
267 ;; Visit FILE and arrange its buffer to Ediff's liking. 267 ;; Visit FILE and arrange its buffer to Ediff's liking.
268 ;; FILE is actually a variable symbol that must contain a true file name. 268 ;; FILE is actually a variable symbol that must contain a true file name.
269 ;; BUFFER-NAME is a variable symbol, which will get the buffer object into 269 ;; BUFFER-NAME is a variable symbol, which will get the buffer object into
270 ;; which FILE is read. 270 ;; which FILE is read.
271 ;; LAST-DIR is the directory variable symbol where FILE's 271 ;; LAST-DIR is the directory variable symbol where FILE's
272 ;; directory name should be returned. HOOKS-VAR is a variable symbol that will 272 ;; directory name should be returned. HOOKS-VAR is a variable symbol that will
273 ;; be assigned the hook to be executed after `ediff-startup' is finished. 273 ;; be assigned the hook to be executed after `ediff-startup' is finished.
274 ;; `ediff-find-file' arranges that the temp files it might create will be 274 ;; `ediff-find-file' arranges that the temp files it might create will be
275 ;; deleted. 275 ;; deleted.
276 (defun ediff-find-file (file-var buffer-name &optional last-dir hooks-var) 276 (defun ediff-find-file (file-var buffer-name &optional last-dir hooks-var)
277 (let* ((file (symbol-value file-var)) 277 (let* ((file (symbol-value file-var))
457 457
458 458
459 ;;;###autoload 459 ;;;###autoload
460 (defun ediff-directories (dir1 dir2 regexp) 460 (defun ediff-directories (dir1 dir2 regexp)
461 "Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have 461 "Run Ediff on a pair of directories, DIR1 and DIR2, comparing files that have
462 the same name in both. The third argument, REGEXP, is a regular expression that 462 the same name in both. The third argument, REGEXP, is a regular expression
463 can be used to filter out certain file names." 463 that can be used to filter out certain file names."
464 (interactive 464 (interactive
465 (let ((dir-A (ediff-get-default-directory-name)) 465 (let ((dir-A (ediff-get-default-directory-name))
466 f) 466 f)
467 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) 467 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil))
468 (ediff-read-file-name "Directory B to compare:" 468 (ediff-read-file-name "Directory B to compare:"
483 483
484 ;;;###autoload 484 ;;;###autoload
485 (defun ediff-directory-revisions (dir1 regexp) 485 (defun ediff-directory-revisions (dir1 regexp)
486 "Run Ediff on a directory, DIR1, comparing its files with their revisions. 486 "Run Ediff on a directory, DIR1, comparing its files with their revisions.
487 The second argument, REGEXP, is a regular expression that filters the file 487 The second argument, REGEXP, is a regular expression that filters the file
488 names. Only the files that are under revision control are taken into account." 488 names. Only the files that are under revision control are taken into account."
489 (interactive 489 (interactive
490 (let ((dir-A (ediff-get-default-directory-name))) 490 (let ((dir-A (ediff-get-default-directory-name)))
491 (list (ediff-read-file-name 491 (list (ediff-read-file-name
492 "Directory to compare with revision:" dir-A nil) 492 "Directory to compare with revision:" dir-A nil)
493 (read-string "Filter through regular expression: " 493 (read-string "Filter through regular expression: "
502 502
503 503
504 ;;;###autoload 504 ;;;###autoload
505 (defun ediff-directories3 (dir1 dir2 dir3 regexp) 505 (defun ediff-directories3 (dir1 dir2 dir3 regexp)
506 "Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that 506 "Run Ediff on three directories, DIR1, DIR2, and DIR3, comparing files that
507 have the same name in all three. The last argument, REGEXP, is a regular 507 have the same name in all three. The last argument, REGEXP, is a regular
508 expression that can be used to filter out certain file names." 508 expression that can be used to filter out certain file names."
509 (interactive 509 (interactive
510 (let ((dir-A (ediff-get-default-directory-name)) 510 (let ((dir-A (ediff-get-default-directory-name))
511 f) 511 f)
512 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) 512 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil))
529 529
530 ;;;###autoload 530 ;;;###autoload
531 (defalias 'edirs3 'ediff-directories3) 531 (defalias 'edirs3 'ediff-directories3)
532 532
533 ;;;###autoload 533 ;;;###autoload
534 (defun ediff-merge-directories (dir1 dir2 regexp) 534 (defun ediff-merge-directories (dir1 dir2 regexp &optional merge-autostore-dir)
535 "Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have 535 "Run Ediff on a pair of directories, DIR1 and DIR2, merging files that have
536 the same name in both. The third argument, REGEXP, is a regular expression that 536 the same name in both. The third argument, REGEXP, is a regular expression
537 can be used to filter out certain file names." 537 that can be used to filter out certain file names."
538 (interactive 538 (interactive
539 (let ((dir-A (ediff-get-default-directory-name)) 539 (let ((dir-A (ediff-get-default-directory-name))
540 f) 540 f)
541 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) 541 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil))
542 (ediff-read-file-name "Directory B to merge:" 542 (ediff-read-file-name "Directory B to merge:"
547 (read-string "Filter through regular expression: " 547 (read-string "Filter through regular expression: "
548 nil 'ediff-filtering-regexp-history) 548 nil 'ediff-filtering-regexp-history)
549 ))) 549 )))
550 (ediff-directories-internal 550 (ediff-directories-internal
551 dir1 dir2 nil regexp 'ediff-merge-files 'ediff-merge-directories 551 dir1 dir2 nil regexp 'ediff-merge-files 'ediff-merge-directories
552 nil merge-autostore-dir
552 )) 553 ))
553 554
554 ;;;###autoload 555 ;;;###autoload
555 (defalias 'edirs-merge 'ediff-merge-directories) 556 (defalias 'edirs-merge 'ediff-merge-directories)
556 557
557 ;;;###autoload 558 ;;;###autoload
558 (defun ediff-merge-directories-with-ancestor (dir1 dir2 ancestor-dir regexp) 559 (defun ediff-merge-directories-with-ancestor (dir1 dir2 ancestor-dir regexp
560 &optional
561 merge-autostore-dir)
559 "Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors. 562 "Merge files in directories DIR1 and DIR2 using files in ANCESTOR-DIR as ancestors.
560 Ediff merges files that have identical names in DIR1, DIR2. If a pair of files 563 Ediff merges files that have identical names in DIR1, DIR2. If a pair of files
561 in DIR1 and DIR2 doesn't have an ancestor in ANCESTOR-DIR, Ediff will merge 564 in DIR1 and DIR2 doesn't have an ancestor in ANCESTOR-DIR, Ediff will merge
562 without ancestor. The fourth argument, REGEXP, is a regular expression that 565 without ancestor. The fourth argument, REGEXP, is a regular expression that
563 can be used to filter out certain file names." 566 can be used to filter out certain file names."
564 (interactive 567 (interactive
565 (let ((dir-A (ediff-get-default-directory-name)) 568 (let ((dir-A (ediff-get-default-directory-name))
566 f) 569 f)
567 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) 570 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil))
579 nil 'ediff-filtering-regexp-history) 582 nil 'ediff-filtering-regexp-history)
580 ))) 583 )))
581 (ediff-directories-internal 584 (ediff-directories-internal
582 dir1 dir2 ancestor-dir regexp 585 dir1 dir2 ancestor-dir regexp
583 'ediff-merge-files-with-ancestor 'ediff-merge-directories-with-ancestor 586 'ediff-merge-files-with-ancestor 'ediff-merge-directories-with-ancestor
587 nil merge-autostore-dir
584 )) 588 ))
585 589
586 ;;;###autoload 590 ;;;###autoload
587 (defun ediff-merge-directory-revisions (dir1 regexp) 591 (defun ediff-merge-directory-revisions (dir1 regexp
592 &optional merge-autostore-dir)
588 "Run Ediff on a directory, DIR1, merging its files with their revisions. 593 "Run Ediff on a directory, DIR1, merging its files with their revisions.
589 The second argument, REGEXP, is a regular expression that filters the file 594 The second argument, REGEXP, is a regular expression that filters the file
590 names. Only the files that are under revision control are taken into account." 595 names. Only the files that are under revision control are taken into account."
591 (interactive 596 (interactive
592 (let ((dir-A (ediff-get-default-directory-name))) 597 (let ((dir-A (ediff-get-default-directory-name)))
593 (list (ediff-read-file-name 598 (list (ediff-read-file-name
594 "Directory to merge with revisions:" dir-A nil) 599 "Directory to merge with revisions:" dir-A nil)
595 (read-string "Filter through regular expression: " 600 (read-string "Filter through regular expression: "
596 nil 'ediff-filtering-regexp-history) 601 nil 'ediff-filtering-regexp-history)
597 ))) 602 )))
598 (ediff-directory-revisions-internal 603 (ediff-directory-revisions-internal
599 dir1 regexp 'ediff-merge-revisions 'ediff-merge-directory-revisions 604 dir1 regexp 'ediff-merge-revisions 'ediff-merge-directory-revisions
605 nil merge-autostore-dir
600 )) 606 ))
601 607
602 ;;;###autoload 608 ;;;###autoload
603 (defalias 'edir-merge-revisions 'ediff-merge-directory-revisions) 609 (defalias 'edir-merge-revisions 'ediff-merge-directory-revisions)
604 610
605 ;;;###autoload 611 ;;;###autoload
606 (defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp) 612 (defun ediff-merge-directory-revisions-with-ancestor (dir1 regexp
613 &optional
614 merge-autostore-dir)
607 "Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors. 615 "Run Ediff on a directory, DIR1, merging its files with their revisions and ancestors.
608 The second argument, REGEXP, is a regular expression that filters the file 616 The second argument, REGEXP, is a regular expression that filters the file
609 names. Only the files that are under revision control are taken into account." 617 names. Only the files that are under revision control are taken into account."
610 (interactive 618 (interactive
611 (let ((dir-A (ediff-get-default-directory-name))) 619 (let ((dir-A (ediff-get-default-directory-name)))
612 (list (ediff-read-file-name 620 (list (ediff-read-file-name
613 "Directory to merge with revisions and ancestors:" dir-A nil) 621 "Directory to merge with revisions and ancestors:" dir-A nil)
614 (read-string "Filter through regular expression: " 622 (read-string "Filter through regular expression: "
615 nil 'ediff-filtering-regexp-history) 623 nil 'ediff-filtering-regexp-history)
616 ))) 624 )))
617 (ediff-directory-revisions-internal 625 (ediff-directory-revisions-internal
618 dir1 regexp 'ediff-merge-revisions-with-ancestor 626 dir1 regexp 'ediff-merge-revisions-with-ancestor
619 'ediff-merge-directory-revisions-with-ancestor 627 'ediff-merge-directory-revisions-with-ancestor
628 nil merge-autostore-dir
620 )) 629 ))
621 630
622 ;;;###autoload 631 ;;;###autoload
623 (defalias 632 (defalias
624 'edir-merge-revisions-with-ancestor 633 'edir-merge-revisions-with-ancestor
630 ;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors) 639 ;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors)
631 ;; on a pair of directories (three directories, in case of ancestor). 640 ;; on a pair of directories (three directories, in case of ancestor).
632 ;; The third argument, REGEXP, is a regular expression that can be used to 641 ;; The third argument, REGEXP, is a regular expression that can be used to
633 ;; filter out certain file names. 642 ;; filter out certain file names.
634 ;; JOBNAME is the symbol indicating the meta-job to be performed. 643 ;; JOBNAME is the symbol indicating the meta-job to be performed.
635 ;; MERGE-DIR is the directory in which to store merged files. 644 ;; MERGE-AUTOSTORE-DIR is the directory in which to store merged files.
636 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname 645 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname
637 &optional startup-hooks) 646 &optional startup-hooks
647 merge-autostore-dir)
638 ;; ediff-read-file-name is set to attach a previously entered file name if 648 ;; ediff-read-file-name is set to attach a previously entered file name if
639 ;; the currently entered file is a directory. This code takes care of that. 649 ;; the currently entered file is a directory. This code takes care of that.
640 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)) 650 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))
641 dir2 (if (file-directory-p dir2) dir2 (file-name-directory dir2))) 651 dir2 (if (file-directory-p dir2) dir2 (file-name-directory dir2)))
642 652
643 (if (stringp dir3) 653 (if (stringp dir3)
644 (setq dir3 (if (file-directory-p dir3) dir3 (file-name-directory dir3)))) 654 (setq dir3 (if (file-directory-p dir3) dir3 (file-name-directory dir3))))
650 (error "Directories A and C are the same: %s" dir1)) 660 (error "Directories A and C are the same: %s" dir1))
651 ((and (eq jobname 'ediff-directories3) 661 ((and (eq jobname 'ediff-directories3)
652 (string= dir2 dir3)) 662 (string= dir2 dir3))
653 (error "Directories B and C are the same: %s" dir1))) 663 (error "Directories B and C are the same: %s" dir1)))
654 664
665 (if merge-autostore-dir
666 (or (stringp merge-autostore-dir)
667 (error "%s: Directory for storing merged files must be a string"
668 jobname)))
655 (let (diffs ; var where ediff-intersect-directories returns the diff list 669 (let (diffs ; var where ediff-intersect-directories returns the diff list
656 merge-autostore-dir
657 file-list meta-buf) 670 file-list meta-buf)
658 (if (and ediff-autostore-merges (ediff-merge-metajob jobname)) 671 (if (and ediff-autostore-merges
672 (ediff-merge-metajob jobname)
673 (not merge-autostore-dir))
659 (setq merge-autostore-dir 674 (setq merge-autostore-dir
660 (ediff-read-file-name "Directory to save merged files:" 675 (read-file-name "Save merged files in directory: "
661 (if ediff-use-last-dir 676 (if ediff-use-last-dir
662 ediff-last-merge-autostore-dir 677 ediff-last-merge-autostore-dir
663 (ediff-strip-last-dir dir1)) 678 (ediff-strip-last-dir dir1))
664 nil))) 679 nil
680 'must-match)))
665 ;; verify we are not merging into an orig directory 681 ;; verify we are not merging into an orig directory
666 (if (stringp merge-autostore-dir) 682 (if merge-autostore-dir
667 (cond ((and (stringp dir1) (string= merge-autostore-dir dir1)) 683 (cond ((and (stringp dir1) (string= merge-autostore-dir dir1))
668 (or (y-or-n-p "Merge directory same as directory A, sure? ") 684 (or (y-or-n-p
685 "Directory for saving merged files = Directory A. Sure? ")
669 (error "Directory merge aborted"))) 686 (error "Directory merge aborted")))
670 ((and (stringp dir2) (string= merge-autostore-dir dir2)) 687 ((and (stringp dir2) (string= merge-autostore-dir dir2))
671 (or (y-or-n-p "Merge directory same as directory B, sure? ") 688 (or (y-or-n-p
689 "Directory for saving merged files = Directory B. Sure? ")
672 (error "Directory merge aborted"))) 690 (error "Directory merge aborted")))
673 ((and (stringp dir3) (string= merge-autostore-dir dir3)) 691 ((and (stringp dir3) (string= merge-autostore-dir dir3))
674 (or (y-or-n-p 692 (or (y-or-n-p
675 "Merge directory same as ancestor directory, sure? ") 693 "Directory for saving merged files = Ancestor Directory. Sure? ")
676 (error "Directory merge aborted"))))) 694 (error "Directory merge aborted")))))
677 695
678 (setq file-list (ediff-intersect-directories 696 (setq file-list (ediff-intersect-directories
679 jobname 'diffs 697 jobname 'diffs
680 regexp dir1 dir2 dir3 merge-autostore-dir)) 698 regexp dir1 dir2 dir3 merge-autostore-dir))
695 jobname 713 jobname
696 startup-hooks)) 714 startup-hooks))
697 (ediff-show-meta-buffer meta-buf) 715 (ediff-show-meta-buffer meta-buf)
698 )) 716 ))
699 717
718 ;; MERGE-AUTOSTORE-DIR can be given to tell ediff where to store the merged
719 ;; files
700 (defun ediff-directory-revisions-internal (dir1 regexp action jobname 720 (defun ediff-directory-revisions-internal (dir1 regexp action jobname
701 &optional startup-hooks) 721 &optional startup-hooks
722 merge-autostore-dir)
702 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))) 723 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)))
703 724
704 (let (file-list meta-buf merge-autostore-dir) 725 (if merge-autostore-dir
705 (if (and ediff-autostore-merges (ediff-merge-metajob jobname)) 726 (or (stringp merge-autostore-dir)
727 (error "%S: Directory for storing merged files must be a string"
728 jobname)))
729 (let (file-list meta-buf)
730 (if (and ediff-autostore-merges
731 (ediff-merge-metajob jobname)
732 (not merge-autostore-dir))
706 (setq merge-autostore-dir 733 (setq merge-autostore-dir
707 (ediff-read-file-name "Directory to save merged files:" 734 (read-file-name "Save merged files in directory: "
708 (if ediff-use-last-dir 735 (if ediff-use-last-dir
709 ediff-last-merge-autostore-dir 736 ediff-last-merge-autostore-dir
710 (ediff-strip-last-dir dir1)) 737 (ediff-strip-last-dir dir1))
711 nil))) 738 nil
739 'must-match)))
712 ;; verify merge-autostore-dir != dir1 740 ;; verify merge-autostore-dir != dir1
713 (if (and (stringp merge-autostore-dir) 741 (if (and merge-autostore-dir
714 (stringp dir1) 742 (stringp dir1)
715 (string= merge-autostore-dir dir1)) 743 (string= merge-autostore-dir dir1))
716 (or (y-or-n-p 744 (or (y-or-n-p
717 "Directory for saving merges is the same as directory A. Sure? ") 745 "Directory for saving merged file = directory A. Sure? ")
718 (error "Merge of directory revisions aborted"))) 746 (error "Merge of directory revisions aborted")))
719 747
720 (setq file-list 748 (setq file-list
721 (ediff-get-directory-files-under-revision 749 (ediff-get-directory-files-under-revision
722 jobname regexp dir1 merge-autostore-dir)) 750 jobname regexp dir1 merge-autostore-dir))
795 ;;;###autoload 823 ;;;###autoload
796 (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) 824 (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks)
797 "Run Ediff on a pair of regions in two different buffers. 825 "Run Ediff on a pair of regions in two different buffers.
798 Regions \(i.e., point and mark\) are assumed to be set in advance. 826 Regions \(i.e., point and mark\) are assumed to be set in advance.
799 This function is effective only for relatively small regions, up to 200 827 This function is effective only for relatively small regions, up to 200
800 lines. For large regions, use `ediff-regions-linewise'." 828 lines. For large regions, use `ediff-regions-linewise'."
801 (interactive 829 (interactive
802 (let (bf) 830 (let (bf)
803 (list (setq bf (read-buffer "Region's A buffer: " 831 (list (setq bf (read-buffer "Region's A buffer: "
804 (ediff-other-buffer "") t)) 832 (ediff-other-buffer "") t))
805 (read-buffer "Region's B buffer: " 833 (read-buffer "Region's B buffer: "
833 (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) 861 (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks)
834 "Run Ediff on a pair of regions in two different buffers. 862 "Run Ediff on a pair of regions in two different buffers.
835 Regions \(i.e., point and mark\) are assumed to be set in advance. 863 Regions \(i.e., point and mark\) are assumed to be set in advance.
836 Each region is enlarged to contain full lines. 864 Each region is enlarged to contain full lines.
837 This function is effective for large regions, over 100-200 865 This function is effective for large regions, over 100-200
838 lines. For small regions, use `ediff-regions-wordwise'." 866 lines. For small regions, use `ediff-regions-wordwise'."
839 (interactive 867 (interactive
840 (let (bf) 868 (let (bf)
841 (list (setq bf (read-buffer "Region A's buffer: " 869 (list (setq bf (read-buffer "Region A's buffer: "
842 (ediff-other-buffer "") t)) 870 (ediff-other-buffer "") t))
843 (read-buffer "Region B's buffer: " 871 (read-buffer "Region B's buffer: "
1169 (if (stringp file) 1197 (if (stringp file)
1170 (file-name-nondirectory file) "current buffer"))) 1198 (file-name-nondirectory file) "current buffer")))
1171 ancestor-rev 1199 ancestor-rev
1172 (read-string 1200 (read-string
1173 (format 1201 (format
1174 "Ancestor version (default: %s): " 1202 "Ancestor version (default: %s's base revision): "
1175 (if (stringp file) 1203 (if (stringp file)
1176 (file-name-nondirectory file) "current buffer")))) 1204 (file-name-nondirectory file) "current buffer"))))
1177 (ediff-load-version-control) 1205 (ediff-load-version-control)
1178 (funcall 1206 (funcall
1179 (intern (format "ediff-%S-merge-internal" ediff-version-control-package)) 1207 (intern (format "ediff-%S-merge-internal" ediff-version-control-package))
1180 rev1 rev2 ancestor-rev startup-hooks merge-buffer-file))) 1208 rev1 rev2 ancestor-rev startup-hooks merge-buffer-file)))
1181 1209
1182 ;;;###autoload 1210 ;;;###autoload
1183 (defun run-ediff-from-cvs-buffer (pos) 1211 (defun run-ediff-from-cvs-buffer (pos)
1184 "Run Ediff-merge on appropriate revisions of the selected file. 1212 "Run Ediff-merge on appropriate revisions of the selected file.
1185 First run after `M-x cvs-update'. Then place the cursor on a line describing a 1213 First run after `M-x cvs-update'. Then place the cursor on a line describing a
1186 file and then run `run-ediff-from-cvs-buffer'." 1214 file and then run `run-ediff-from-cvs-buffer'."
1187 (interactive "d") 1215 (interactive "d")
1188 (ediff-load-version-control) 1216 (ediff-load-version-control)
1189 (let ((tin (tin-locate cvs-cookie-handle pos))) 1217 (let ((tin (tin-locate cvs-cookie-handle pos)))
1190 (if tin 1218 (if tin
1193 1221
1194 1222
1195 ;;; Apply patch 1223 ;;; Apply patch
1196 1224
1197 ;;;###autoload 1225 ;;;###autoload
1198 (defun ediff-patch-file () 1226 (defun ediff-patch-file (&optional arg patch-buf)
1199 "Run Ediff by patching SOURCE-FILENAME." 1227 "Run Ediff by patching SOURCE-FILENAME.
1200 ;; This now returns the control buffer 1228 If optional PATCH-BUF is given, use the patch in that buffer
1201 (interactive) 1229 and don't ask the user.
1202 (let (source-dir source-file patch-buf) 1230 If prefix argument, then: if even argument, assume that the patch is in a
1231 buffer. If odd -- assume it is in a file."
1232 (interactive "P")
1233 (let (source-dir source-file)
1203 (require 'ediff-ptch) 1234 (require 'ediff-ptch)
1204 (setq patch-buf (ediff-get-patch-buffer)) 1235 (setq patch-buf
1236 (ediff-get-patch-buffer
1237 (if arg (prefix-numeric-value arg)) patch-buf))
1205 (setq source-dir (cond (ediff-use-last-dir ediff-last-dir-patch) 1238 (setq source-dir (cond (ediff-use-last-dir ediff-last-dir-patch)
1206 ((and (not ediff-patch-default-directory) 1239 ((and (not ediff-patch-default-directory)
1207 (buffer-file-name patch-buf)) 1240 (buffer-file-name patch-buf))
1208 (file-name-directory 1241 (file-name-directory
1209 (expand-file-name 1242 (expand-file-name
1210 (buffer-file-name patch-buf)))) 1243 (buffer-file-name patch-buf))))
1211 (t default-directory))) 1244 (t default-directory)))
1212 (setq source-file 1245 (setq source-file
1213 ;; the default is the directory, not the visited file name 1246 ;; the default is the directory, not the visited file name
1214 (ediff-read-file-name 1247 (read-file-name
1215 "Which file to patch? " source-dir (ediff-get-default-file-name))) 1248 "File to patch (directory, if multifile patch): "
1249 source-dir (ediff-get-default-file-name)))
1216 (ediff-dispatch-file-patching-job patch-buf source-file))) 1250 (ediff-dispatch-file-patching-job patch-buf source-file)))
1217 1251
1218 ;;;###autoload 1252 ;;;###autoload
1219 (defun ediff-patch-buffer () 1253 (defun ediff-patch-buffer (&optional arg patch-buf)
1220 "Run Ediff by patching BUFFER-NAME." 1254 "Run Ediff by patching BUFFER-NAME."
1221 (interactive) 1255 (interactive "P")
1222 (let (patch-buf) 1256 (require 'ediff-ptch)
1223 (require 'ediff-ptch) 1257 (setq patch-buf
1224 (setq patch-buf (ediff-get-patch-buffer)) 1258 (ediff-get-patch-buffer
1225 (ediff-patch-buffer-internal 1259 (if arg (prefix-numeric-value arg)) patch-buf))
1226 patch-buf 1260 (ediff-patch-buffer-internal
1227 (read-buffer "Which buffer to patch? " 1261 patch-buf
1228 (cond ((eq patch-buf (current-buffer)) 1262 (read-buffer
1229 (ediff-other-buffer (current-buffer))) 1263 "Which buffer to patch? "
1230 (t (current-buffer))) 1264 (ediff-prompt-for-patch-buffer))))
1231 'must-match))))
1232 1265
1266
1233 ;;;###autoload 1267 ;;;###autoload
1234 (defalias 'epatch 'ediff-patch-file) 1268 (defalias 'epatch 'ediff-patch-file)
1235 ;;;###autoload 1269 ;;;###autoload
1236 (defalias 'epatch-buffer 'ediff-patch-buffer) 1270 (defalias 'epatch-buffer 'ediff-patch-buffer)
1237 1271
1242 1276
1243 ;;;###autoload 1277 ;;;###autoload
1244 (defun ediff-revision (&optional file startup-hooks) 1278 (defun ediff-revision (&optional file startup-hooks)
1245 "Run Ediff by comparing versions of a file. 1279 "Run Ediff by comparing versions of a file.
1246 The file is an optional FILE argument or the file visited by the current 1280 The file is an optional FILE argument or the file visited by the current
1247 buffer. Use `vc.el' or `rcs.el' depending on `ediff-version-control-package'." 1281 buffer. Use `vc.el' or `rcs.el' depending on `ediff-version-control-package'."
1248 ;; if buffer is non-nil, use that buffer instead of the current buffer 1282 ;; if buffer is non-nil, use that buffer instead of the current buffer
1249 (interactive "P") 1283 (interactive "P")
1250 (if (stringp file) (find-file file)) 1284 (if (stringp file) (find-file file))
1251 (let (rev1 rev2) 1285 (let (rev1 rev2)
1252 (setq rev1 1286 (setq rev1
1278 (if (locate-library (symbol-name ediff-version-control-package)) 1312 (if (locate-library (symbol-name ediff-version-control-package))
1279 (progn 1313 (progn
1280 (message "") ; kill the message from `locate-library' 1314 (message "") ; kill the message from `locate-library'
1281 (require ediff-version-control-package)) 1315 (require ediff-version-control-package))
1282 (or silent 1316 (or silent
1283 (error "Version control package %S.el not found. Use vc.el instead" 1317 (error "Version control package %S.el not found. Use vc.el instead"
1284 ediff-version-control-package))))) 1318 ediff-version-control-package)))))
1285 1319
1286 1320
1287 ;;;###autoload 1321 ;;;###autoload
1288 (defun ediff-version () 1322 (defun ediff-version ()
1328 ;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body)) 1362 ;;; eval: (put 'ediff-with-current-buffer 'edebug-form-spec '(form body))
1329 ;;; End: 1363 ;;; End:
1330 1364
1331 (require 'ediff-util) 1365 (require 'ediff-util)
1332 1366
1367 (run-hooks 'ediff-load-hook)
1368
1333 ;;; ediff.el ends here 1369 ;;; ediff.el ends here