comparison lisp/ediff.el @ 49588:37645a051842

Trailing whitespace deleted.
author Juanma Barranquero <lekktu@gmail.com>
date Tue, 04 Feb 2003 11:26:42 +0000
parents 0f80cb4f9d29
children 52709955c5a5 d7ddb3e565de
comparison
equal deleted inserted replaced
49587:e82b3fe06d4c 49588:37645a051842
5 ;; Author: Michael Kifer <kifer@cs.stonybrook.edu> 5 ;; Author: Michael Kifer <kifer@cs.stonybrook.edu>
6 ;; Created: February 2, 1994 6 ;; Created: February 2, 1994
7 ;; Keywords: comparing, merging, patching, tools, unix 7 ;; Keywords: comparing, merging, patching, tools, unix
8 8
9 (defconst ediff-version "2.78" "The current version of Ediff") 9 (defconst ediff-version "2.78" "The current version of Ediff")
10 (defconst ediff-date "January 25, 2003" "Date of last update") 10 (defconst ediff-date "January 25, 2003" "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
198 ediff-last-dir-A 198 ediff-last-dir-A
199 default-directory)) 199 default-directory))
200 dir-B f) 200 dir-B f)
201 (list (setq f (ediff-read-file-name 201 (list (setq f (ediff-read-file-name
202 "File A to compare" 202 "File A to compare"
203 dir-A 203 dir-A
204 (ediff-get-default-file-name) 204 (ediff-get-default-file-name)
205 'no-dirs)) 205 'no-dirs))
206 (ediff-read-file-name "File B to compare" 206 (ediff-read-file-name "File B to compare"
207 (setq dir-B 207 (setq dir-B
208 (if ediff-use-last-dir 208 (if ediff-use-last-dir
209 ediff-last-dir-B 209 ediff-last-dir-B
210 (file-name-directory f))) 210 (file-name-directory f)))
211 (progn 211 (progn
212 (setq file-name-history 212 (setq file-name-history
213 (cons (ediff-abbreviate-file-name 213 (cons (ediff-abbreviate-file-name
214 (expand-file-name 214 (expand-file-name
215 (file-name-nondirectory f) 215 (file-name-nondirectory f)
216 dir-B)) 216 dir-B))
217 file-name-history)) 217 file-name-history))
218 (ediff-get-default-file-name f 1))) 218 (ediff-get-default-file-name f 1)))
219 ))) 219 )))
220 (ediff-files-internal file-A 220 (ediff-files-internal file-A
221 (if (file-directory-p file-B) 221 (if (file-directory-p file-B)
222 (expand-file-name 222 (expand-file-name
223 (file-name-nondirectory file-A) file-B) 223 (file-name-nondirectory file-A) file-B)
224 file-B) 224 file-B)
225 nil ; file-C 225 nil ; file-C
226 startup-hooks 226 startup-hooks
227 'ediff-files)) 227 'ediff-files))
228 228
229 ;;;###autoload 229 ;;;###autoload
230 (defun ediff-files3 (file-A file-B file-C &optional startup-hooks) 230 (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." 231 "Run Ediff on three files, FILE-A, FILE-B, and FILE-C."
232 (interactive 232 (interactive
233 (let ((dir-A (if ediff-use-last-dir 233 (let ((dir-A (if ediff-use-last-dir
237 (list (setq f (ediff-read-file-name 237 (list (setq f (ediff-read-file-name
238 "File A to compare" 238 "File A to compare"
239 dir-A 239 dir-A
240 (ediff-get-default-file-name) 240 (ediff-get-default-file-name)
241 'no-dirs)) 241 'no-dirs))
242 (setq ff (ediff-read-file-name "File B to compare" 242 (setq ff (ediff-read-file-name "File B to compare"
243 (setq dir-B 243 (setq dir-B
244 (if ediff-use-last-dir 244 (if ediff-use-last-dir
245 ediff-last-dir-B 245 ediff-last-dir-B
246 (file-name-directory f))) 246 (file-name-directory f)))
247 (progn 247 (progn
251 (expand-file-name 251 (expand-file-name
252 (file-name-nondirectory f) 252 (file-name-nondirectory f)
253 dir-B)) 253 dir-B))
254 file-name-history)) 254 file-name-history))
255 (ediff-get-default-file-name f 1)))) 255 (ediff-get-default-file-name f 1))))
256 (ediff-read-file-name "File C to compare" 256 (ediff-read-file-name "File C to compare"
257 (setq dir-C (if ediff-use-last-dir 257 (setq dir-C (if ediff-use-last-dir
258 ediff-last-dir-C 258 ediff-last-dir-C
259 (file-name-directory ff))) 259 (file-name-directory ff)))
260 (progn 260 (progn
261 (setq file-name-history 261 (setq file-name-history
264 (file-name-nondirectory ff) 264 (file-name-nondirectory ff)
265 dir-C)) 265 dir-C))
266 file-name-history)) 266 file-name-history))
267 (ediff-get-default-file-name ff 2))) 267 (ediff-get-default-file-name ff 2)))
268 ))) 268 )))
269 (ediff-files-internal file-A 269 (ediff-files-internal file-A
270 (if (file-directory-p file-B) 270 (if (file-directory-p file-B)
271 (expand-file-name 271 (expand-file-name
272 (file-name-nondirectory file-A) file-B) 272 (file-name-nondirectory file-A) file-B)
273 file-B) 273 file-B)
274 (if (file-directory-p file-C) 274 (if (file-directory-p file-C)
280 280
281 ;;;###autoload 281 ;;;###autoload
282 (defalias 'ediff3 'ediff-files3) 282 (defalias 'ediff3 'ediff-files3)
283 283
284 284
285 ;; Visit FILE and arrange its buffer to Ediff's liking. 285 ;; Visit FILE and arrange its buffer to Ediff's liking.
286 ;; FILE is actually a variable symbol that must contain a true file name. 286 ;; 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 287 ;; BUFFER-NAME is a variable symbol, which will get the buffer object into
288 ;; which FILE is read. 288 ;; which FILE is read.
289 ;; LAST-DIR is the directory variable symbol where FILE's 289 ;; LAST-DIR is the directory variable symbol where FILE's
290 ;; directory name should be returned. HOOKS-VAR is a variable symbol that will 290 ;; directory name should be returned. HOOKS-VAR is a variable symbol that will
297 (temp-file-name-prefix (file-name-nondirectory file))) 297 (temp-file-name-prefix (file-name-nondirectory file)))
298 (cond ((not (file-readable-p file)) 298 (cond ((not (file-readable-p file))
299 (error "File `%s' does not exist or is not readable" file)) 299 (error "File `%s' does not exist or is not readable" file))
300 ((file-directory-p file) 300 ((file-directory-p file)
301 (error "File `%s' is a directory" file))) 301 (error "File `%s' is a directory" file)))
302 302
303 ;; some of the commands, below, require full file name 303 ;; some of the commands, below, require full file name
304 (setq file (expand-file-name file)) 304 (setq file (expand-file-name file))
305 305
306 ;; Record the directory of the file 306 ;; Record the directory of the file
307 (if last-dir 307 (if last-dir
308 (set last-dir (expand-file-name (file-name-directory file)))) 308 (set last-dir (expand-file-name (file-name-directory file))))
309 309
310 ;; Setup the buffer 310 ;; Setup the buffer
311 (set buffer-name (find-file-noselect file)) 311 (set buffer-name (find-file-noselect file))
312 312
313 (ediff-with-current-buffer (symbol-value buffer-name) 313 (ediff-with-current-buffer (symbol-value buffer-name)
314 (widen) ; Make sure the entire file is seen 314 (widen) ; Make sure the entire file is seen
315 (cond (file-magic ; file has a handler, such as jka-compr-handler or 315 (cond (file-magic ; file has a handler, such as jka-compr-handler or
316 ;;; ange-ftp-hook-function--arrange for temp file 316 ;;; ange-ftp-hook-function--arrange for temp file
317 (ediff-verify-file-buffer 'magic) 317 (ediff-verify-file-buffer 'magic)
360 buf-B file-B 360 buf-B file-B
361 buf-C file-C 361 buf-C file-C
362 startup-hooks 362 startup-hooks
363 (list (cons 'ediff-job-name job-name)) 363 (list (cons 'ediff-job-name job-name))
364 merge-buffer-file))) 364 merge-buffer-file)))
365 365
366 366
367 ;;;###autoload 367 ;;;###autoload
368 (defalias 'ediff 'ediff-files) 368 (defalias 'ediff 'ediff-files)
369 369
370 ;;;###autoload 370 ;;;###autoload
385 (ediff-files bak ori))) 385 (ediff-files bak ori)))
386 386
387 ;;;###autoload 387 ;;;###autoload
388 (defun ediff-buffers (buffer-A buffer-B &optional startup-hooks job-name) 388 (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." 389 "Run Ediff on a pair of buffers, BUFFER-A and BUFFER-B."
390 (interactive 390 (interactive
391 (let (bf) 391 (let (bf)
392 (list (setq bf (read-buffer "Buffer A to compare: " 392 (list (setq bf (read-buffer "Buffer A to compare: "
393 (ediff-other-buffer "") t)) 393 (ediff-other-buffer "") t))
394 (read-buffer "Buffer B to compare: " 394 (read-buffer "Buffer B to compare: "
395 (progn 395 (progn
402 (ediff-buffers-internal buffer-A buffer-B nil startup-hooks job-name)) 402 (ediff-buffers-internal buffer-A buffer-B nil startup-hooks job-name))
403 403
404 ;;;###autoload 404 ;;;###autoload
405 (defalias 'ebuffers 'ediff-buffers) 405 (defalias 'ebuffers 'ediff-buffers)
406 406
407 407
408 ;;;###autoload 408 ;;;###autoload
409 (defun ediff-buffers3 (buffer-A buffer-B buffer-C 409 (defun ediff-buffers3 (buffer-A buffer-B buffer-C
410 &optional startup-hooks job-name) 410 &optional startup-hooks job-name)
411 "Run Ediff on three buffers, BUFFER-A, BUFFER-B, and BUFFER-C." 411 "Run Ediff on three buffers, BUFFER-A, BUFFER-B, and BUFFER-C."
412 (interactive 412 (interactive
413 (let (bf bff) 413 (let (bf bff)
414 (list (setq bf (read-buffer "Buffer A to compare: " 414 (list (setq bf (read-buffer "Buffer A to compare: "
415 (ediff-other-buffer "") t)) 415 (ediff-other-buffer "") t))
416 (setq bff (read-buffer "Buffer B to compare: " 416 (setq bff (read-buffer "Buffer B to compare: "
417 (progn 417 (progn
431 (or job-name (setq job-name 'ediff-buffers3)) 431 (or job-name (setq job-name 'ediff-buffers3))
432 (ediff-buffers-internal buffer-A buffer-B buffer-C startup-hooks job-name)) 432 (ediff-buffers-internal buffer-A buffer-B buffer-C startup-hooks job-name))
433 433
434 ;;;###autoload 434 ;;;###autoload
435 (defalias 'ebuffers3 'ediff-buffers3) 435 (defalias 'ebuffers3 'ediff-buffers3)
436 436
437 437
438 438
439 ;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer 439 ;; 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 440 (defun ediff-buffers-internal (buf-A buf-B buf-C startup-hooks job-name
441 &optional merge-buffer-file) 441 &optional merge-buffer-file)
442 (let* ((buf-A-file-name (buffer-file-name (get-buffer buf-A))) 442 (let* ((buf-A-file-name (buffer-file-name (get-buffer buf-A)))
443 (buf-B-file-name (buffer-file-name (get-buffer buf-B))) 443 (buf-B-file-name (buffer-file-name (get-buffer buf-B)))
457 (setq buf-A-file-name (file-name-nondirectory buf-A-file-name))) 457 (setq buf-A-file-name (file-name-nondirectory buf-A-file-name)))
458 (if (stringp buf-B-file-name) 458 (if (stringp buf-B-file-name)
459 (setq buf-B-file-name (file-name-nondirectory buf-B-file-name))) 459 (setq buf-B-file-name (file-name-nondirectory buf-B-file-name)))
460 (if (stringp buf-C-file-name) 460 (if (stringp buf-C-file-name)
461 (setq buf-C-file-name (file-name-nondirectory buf-C-file-name))) 461 (setq buf-C-file-name (file-name-nondirectory buf-C-file-name)))
462 462
463 (setq file-A (ediff-make-temp-file buf-A buf-A-file-name) 463 (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)) 464 file-B (ediff-make-temp-file buf-B buf-B-file-name))
465 (if buf-C-is-alive 465 (if buf-C-is-alive
466 (setq file-C (ediff-make-temp-file buf-C buf-C-file-name))) 466 (setq file-C (ediff-make-temp-file buf-C buf-C-file-name)))
467 467
468 (ediff-setup (get-buffer buf-A) file-A 468 (ediff-setup (get-buffer buf-A) file-A
469 (get-buffer buf-B) file-B 469 (get-buffer buf-B) file-B
470 (if buf-C-is-alive (get-buffer buf-C)) 470 (if buf-C-is-alive (get-buffer buf-C))
471 file-C 471 file-C
472 (cons `(lambda () 472 (cons `(lambda ()
501 expression; only file names that match the regexp are considered." 501 expression; only file names that match the regexp are considered."
502 (interactive 502 (interactive
503 (let ((dir-A (ediff-get-default-directory-name)) 503 (let ((dir-A (ediff-get-default-directory-name))
504 f) 504 f)
505 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) 505 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil))
506 (ediff-read-file-name "Directory B to compare:" 506 (ediff-read-file-name "Directory B to compare:"
507 (if ediff-use-last-dir 507 (if ediff-use-last-dir
508 ediff-last-dir-B 508 ediff-last-dir-B
509 (ediff-strip-last-dir f)) 509 (ediff-strip-last-dir f))
510 nil) 510 nil)
511 (read-string "Filter through regular expression: " 511 (read-string "Filter through regular expression: "
512 nil 'ediff-filtering-regexp-history) 512 nil 'ediff-filtering-regexp-history)
513 ))) 513 )))
547 547
548 (interactive 548 (interactive
549 (let ((dir-A (ediff-get-default-directory-name)) 549 (let ((dir-A (ediff-get-default-directory-name))
550 f) 550 f)
551 (list (setq f (ediff-read-file-name "Directory A to compare:" dir-A nil)) 551 (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:" 552 (setq f (ediff-read-file-name "Directory B to compare:"
553 (if ediff-use-last-dir 553 (if ediff-use-last-dir
554 ediff-last-dir-B 554 ediff-last-dir-B
555 (ediff-strip-last-dir f)) 555 (ediff-strip-last-dir f))
556 nil)) 556 nil))
557 (ediff-read-file-name "Directory C to compare:" 557 (ediff-read-file-name "Directory C to compare:"
558 (if ediff-use-last-dir 558 (if ediff-use-last-dir
559 ediff-last-dir-C 559 ediff-last-dir-C
560 (ediff-strip-last-dir f)) 560 (ediff-strip-last-dir f))
561 nil) 561 nil)
562 (read-string "Filter through regular expression: " 562 (read-string "Filter through regular expression: "
563 nil 'ediff-filtering-regexp-history) 563 nil 'ediff-filtering-regexp-history)
564 ))) 564 )))
576 expression; only file names that match the regexp are considered." 576 expression; only file names that match the regexp are considered."
577 (interactive 577 (interactive
578 (let ((dir-A (ediff-get-default-directory-name)) 578 (let ((dir-A (ediff-get-default-directory-name))
579 f) 579 f)
580 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) 580 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil))
581 (ediff-read-file-name "Directory B to merge:" 581 (ediff-read-file-name "Directory B to merge:"
582 (if ediff-use-last-dir 582 (if ediff-use-last-dir
583 ediff-last-dir-B 583 ediff-last-dir-B
584 (ediff-strip-last-dir f)) 584 (ediff-strip-last-dir f))
585 nil) 585 nil)
586 (read-string "Filter through regular expression: " 586 (read-string "Filter through regular expression: "
587 nil 'ediff-filtering-regexp-history) 587 nil 'ediff-filtering-regexp-history)
588 ))) 588 )))
605 only file names that match the regexp are considered." 605 only file names that match the regexp are considered."
606 (interactive 606 (interactive
607 (let ((dir-A (ediff-get-default-directory-name)) 607 (let ((dir-A (ediff-get-default-directory-name))
608 f) 608 f)
609 (list (setq f (ediff-read-file-name "Directory A to merge:" dir-A nil)) 609 (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:" 610 (setq f (ediff-read-file-name "Directory B to merge:"
611 (if ediff-use-last-dir 611 (if ediff-use-last-dir
612 ediff-last-dir-B 612 ediff-last-dir-B
613 (ediff-strip-last-dir f)) 613 (ediff-strip-last-dir f))
614 nil)) 614 nil))
615 (ediff-read-file-name "Ancestor directory:" 615 (ediff-read-file-name "Ancestor directory:"
616 (if ediff-use-last-dir 616 (if ediff-use-last-dir
617 ediff-last-dir-C 617 ediff-last-dir-C
618 (ediff-strip-last-dir f)) 618 (ediff-strip-last-dir f))
619 nil) 619 nil)
620 (read-string "Filter through regular expression: " 620 (read-string "Filter through regular expression: "
621 nil 'ediff-filtering-regexp-history) 621 nil 'ediff-filtering-regexp-history)
622 ))) 622 )))
668 )) 668 ))
669 669
670 ;;;###autoload 670 ;;;###autoload
671 (defalias 671 (defalias
672 'edir-merge-revisions-with-ancestor 672 'edir-merge-revisions-with-ancestor
673 'ediff-merge-directory-revisions-with-ancestor) 673 'ediff-merge-directory-revisions-with-ancestor)
674 674
675 ;;;###autoload 675 ;;;###autoload
676 (defalias 'edirs-merge-with-ancestor 'ediff-merge-directories-with-ancestor) 676 (defalias 'edirs-merge-with-ancestor 'ediff-merge-directories-with-ancestor)
677 677
678 ;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors) 678 ;; Run ediff-action (ediff-files, ediff-merge, ediff-merge-with-ancestors)
679 ;; on a pair of directories (three directories, in case of ancestor). 679 ;; on a pair of directories (three directories, in case of ancestor).
680 ;; The third argument, REGEXP, is nil or a regular expression; 680 ;; The third argument, REGEXP, is nil or a regular expression;
681 ;; only file names that match the regexp are considered. 681 ;; only file names that match the regexp are considered.
682 ;; JOBNAME is the symbol indicating the meta-job to be performed. 682 ;; JOBNAME is the symbol indicating the meta-job to be performed.
683 ;; MERGE-AUTOSTORE-DIR is the directory in which to store merged files. 683 ;; MERGE-AUTOSTORE-DIR is the directory in which to store merged files.
684 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname 684 (defun ediff-directories-internal (dir1 dir2 dir3 regexp action jobname
685 &optional startup-hooks 685 &optional startup-hooks
686 merge-autostore-dir) 686 merge-autostore-dir)
687 ;; ediff-read-file-name is set to attach a previously entered file name if 687 ;; ediff-read-file-name is set to attach a previously entered file name if
688 ;; the currently entered file is a directory. This code takes care of that. 688 ;; the currently entered file is a directory. This code takes care of that.
689 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)) 689 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))
703 703
704 (if merge-autostore-dir 704 (if merge-autostore-dir
705 (or (stringp merge-autostore-dir) 705 (or (stringp merge-autostore-dir)
706 (error "%s: Directory for storing merged files must be a string" 706 (error "%s: Directory for storing merged files must be a string"
707 jobname))) 707 jobname)))
708 (let (;; dir-diff-struct is of the form (common-list diff-list) 708 (let (;; dir-diff-struct is of the form (common-list diff-list)
709 ;; It is a structure where ediff-intersect-directories returns 709 ;; It is a structure where ediff-intersect-directories returns
710 ;; commonalities and differences among directories 710 ;; commonalities and differences among directories
711 dir-diff-struct 711 dir-diff-struct
712 meta-buf) 712 meta-buf)
713 (if (and ediff-autostore-merges 713 (if (and ediff-autostore-merges
714 (ediff-merge-metajob jobname) 714 (ediff-merge-metajob jobname)
715 (not merge-autostore-dir)) 715 (not merge-autostore-dir))
716 (setq merge-autostore-dir 716 (setq merge-autostore-dir
717 (read-file-name "Save merged files in directory: " 717 (read-file-name "Save merged files in directory: "
718 (if ediff-use-last-dir 718 (if ediff-use-last-dir
719 ediff-last-merge-autostore-dir 719 ediff-last-merge-autostore-dir
720 (ediff-strip-last-dir dir1)) 720 (ediff-strip-last-dir dir1))
721 nil 721 nil
732 (error "Directory merge aborted"))) 732 (error "Directory merge aborted")))
733 ((and (stringp dir3) (string= merge-autostore-dir dir3)) 733 ((and (stringp dir3) (string= merge-autostore-dir dir3))
734 (or (y-or-n-p 734 (or (y-or-n-p
735 "Directory for saving merged files = Ancestor Directory. Sure? ") 735 "Directory for saving merged files = Ancestor Directory. Sure? ")
736 (error "Directory merge aborted"))))) 736 (error "Directory merge aborted")))))
737 737
738 (setq dir-diff-struct (ediff-intersect-directories 738 (setq dir-diff-struct (ediff-intersect-directories
739 jobname 739 jobname
740 regexp dir1 dir2 dir3 merge-autostore-dir)) 740 regexp dir1 dir2 dir3 merge-autostore-dir))
741 (setq startup-hooks 741 (setq startup-hooks
742 ;; this sets various vars in the meta buffer inside 742 ;; this sets various vars in the meta buffer inside
743 ;; ediff-prepare-meta-buffer 743 ;; ediff-prepare-meta-buffer
744 (cons `(lambda () 744 (cons `(lambda ()
745 ;; tell what to do if the user clicks on a session record 745 ;; tell what to do if the user clicks on a session record
746 (setq ediff-session-action-function (quote ,action)) 746 (setq ediff-session-action-function (quote ,action))
747 ;; set ediff-dir-difference-list 747 ;; set ediff-dir-difference-list
748 (setq ediff-dir-difference-list 748 (setq ediff-dir-difference-list
749 (cdr (quote ,dir-diff-struct)))) 749 (cdr (quote ,dir-diff-struct))))
750 startup-hooks)) 750 startup-hooks))
751 (setq meta-buf (ediff-prepare-meta-buffer 751 (setq meta-buf (ediff-prepare-meta-buffer
752 'ediff-filegroup-action 752 'ediff-filegroup-action
753 (car dir-diff-struct) 753 (car dir-diff-struct)
754 "*Ediff Session Group Panel" 754 "*Ediff Session Group Panel"
755 'ediff-redraw-directory-group-buffer 755 'ediff-redraw-directory-group-buffer
756 jobname 756 jobname
758 (ediff-show-meta-buffer meta-buf) 758 (ediff-show-meta-buffer meta-buf)
759 )) 759 ))
760 760
761 ;; MERGE-AUTOSTORE-DIR can be given to tell ediff where to store the merged 761 ;; MERGE-AUTOSTORE-DIR can be given to tell ediff where to store the merged
762 ;; files 762 ;; files
763 (defun ediff-directory-revisions-internal (dir1 regexp action jobname 763 (defun ediff-directory-revisions-internal (dir1 regexp action jobname
764 &optional startup-hooks 764 &optional startup-hooks
765 merge-autostore-dir) 765 merge-autostore-dir)
766 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1))) 766 (setq dir1 (if (file-directory-p dir1) dir1 (file-name-directory dir1)))
767 767
768 (if merge-autostore-dir 768 (if merge-autostore-dir
769 (or (stringp merge-autostore-dir) 769 (or (stringp merge-autostore-dir)
770 (error "%S: Directory for storing merged files must be a string" 770 (error "%S: Directory for storing merged files must be a string"
771 jobname))) 771 jobname)))
772 (let (file-list meta-buf) 772 (let (file-list meta-buf)
773 (if (and ediff-autostore-merges 773 (if (and ediff-autostore-merges
774 (ediff-merge-metajob jobname) 774 (ediff-merge-metajob jobname)
775 (not merge-autostore-dir)) 775 (not merge-autostore-dir))
776 (setq merge-autostore-dir 776 (setq merge-autostore-dir
777 (read-file-name "Save merged files in directory: " 777 (read-file-name "Save merged files in directory: "
778 (if ediff-use-last-dir 778 (if ediff-use-last-dir
779 ediff-last-merge-autostore-dir 779 ediff-last-merge-autostore-dir
780 (ediff-strip-last-dir dir1)) 780 (ediff-strip-last-dir dir1))
781 nil 781 nil
785 (stringp dir1) 785 (stringp dir1)
786 (string= merge-autostore-dir dir1)) 786 (string= merge-autostore-dir dir1))
787 (or (y-or-n-p 787 (or (y-or-n-p
788 "Directory for saving merged file = directory A. Sure? ") 788 "Directory for saving merged file = directory A. Sure? ")
789 (error "Merge of directory revisions aborted"))) 789 (error "Merge of directory revisions aborted")))
790 790
791 (setq file-list 791 (setq file-list
792 (ediff-get-directory-files-under-revision 792 (ediff-get-directory-files-under-revision
793 jobname regexp dir1 merge-autostore-dir)) 793 jobname regexp dir1 merge-autostore-dir))
794 (setq startup-hooks 794 (setq startup-hooks
795 ;; this sets various vars in the meta buffer inside 795 ;; this sets various vars in the meta buffer inside
796 ;; ediff-prepare-meta-buffer 796 ;; ediff-prepare-meta-buffer
797 (cons `(lambda () 797 (cons `(lambda ()
798 ;; tell what to do if the user clicks on a session record 798 ;; tell what to do if the user clicks on a session record
799 (setq ediff-session-action-function (quote ,action))) 799 (setq ediff-session-action-function (quote ,action)))
800 startup-hooks)) 800 startup-hooks))
801 (setq meta-buf (ediff-prepare-meta-buffer 801 (setq meta-buf (ediff-prepare-meta-buffer
802 'ediff-filegroup-action 802 'ediff-filegroup-action
803 file-list 803 file-list
804 "*Ediff Session Group Panel" 804 "*Ediff Session Group Panel"
805 'ediff-redraw-directory-group-buffer 805 'ediff-redraw-directory-group-buffer
806 jobname 806 jobname
819 If WIND-A is nil, use selected window. 819 If WIND-A is nil, use selected window.
820 If WIND-B is nil, use window next to WIND-A." 820 If WIND-B is nil, use window next to WIND-A."
821 (interactive "P") 821 (interactive "P")
822 (ediff-windows dumb-mode wind-A wind-B 822 (ediff-windows dumb-mode wind-A wind-B
823 startup-hooks 'ediff-windows-wordwise 'word-mode)) 823 startup-hooks 'ediff-windows-wordwise 'word-mode))
824 824
825 ;;;###autoload 825 ;;;###autoload
826 (defun ediff-windows-linewise (dumb-mode &optional wind-A wind-B startup-hooks) 826 (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. 827 "Compare WIND-A and WIND-B, which are selected by clicking, linewise.
828 With prefix argument, DUMB-MODE, or on a non-windowing display, works as 828 With prefix argument, DUMB-MODE, or on a non-windowing display, works as
829 follows: 829 follows:
830 If WIND-A is nil, use selected window. 830 If WIND-A is nil, use selected window.
831 If WIND-B is nil, use window next to WIND-A." 831 If WIND-B is nil, use window next to WIND-A."
832 (interactive "P") 832 (interactive "P")
833 (ediff-windows dumb-mode wind-A wind-B 833 (ediff-windows dumb-mode wind-A wind-B
834 startup-hooks 'ediff-windows-linewise nil)) 834 startup-hooks 'ediff-windows-linewise nil))
835 835
836 ;; Compare WIND-A and WIND-B, which are selected by clicking. 836 ;; Compare WIND-A and WIND-B, which are selected by clicking.
837 ;; With prefix argument, DUMB-MODE, or on a non-windowing display, 837 ;; With prefix argument, DUMB-MODE, or on a non-windowing display,
838 ;; works as follows: 838 ;; works as follows:
839 ;; If WIND-A is nil, use selected window. 839 ;; If WIND-A is nil, use selected window.
840 ;; If WIND-B is nil, use window next to WIND-A. 840 ;; If WIND-B is nil, use window next to WIND-A.
842 (if (or dumb-mode (not (ediff-window-display-p))) 842 (if (or dumb-mode (not (ediff-window-display-p)))
843 (setq wind-A (ediff-get-next-window wind-A nil) 843 (setq wind-A (ediff-get-next-window wind-A nil)
844 wind-B (ediff-get-next-window wind-B wind-A)) 844 wind-B (ediff-get-next-window wind-B wind-A))
845 (setq wind-A (ediff-get-window-by-clicking wind-A nil 1) 845 (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))) 846 wind-B (ediff-get-window-by-clicking wind-B wind-A 2)))
847 847
848 (let ((buffer-A (window-buffer wind-A)) 848 (let ((buffer-A (window-buffer wind-A))
849 (buffer-B (window-buffer wind-B)) 849 (buffer-B (window-buffer wind-B))
850 beg-A end-A beg-B end-B) 850 beg-A end-A beg-B end-B)
851 851
852 (save-excursion 852 (save-excursion
853 (save-window-excursion 853 (save-window-excursion
854 (sit-for 0) ; sync before using window-start/end -- a precaution 854 (sit-for 0) ; sync before using window-start/end -- a precaution
855 (select-window wind-A) 855 (select-window wind-A)
856 (setq beg-A (window-start) 856 (setq beg-A (window-start)
865 (ediff-clone-buffer-for-window-comparison 865 (ediff-clone-buffer-for-window-comparison
866 buffer-B wind-B "-Window.B-")) 866 buffer-B wind-B "-Window.B-"))
867 (ediff-regions-internal 867 (ediff-regions-internal
868 buffer-A beg-A end-A buffer-B beg-B end-B 868 buffer-A beg-A end-A buffer-B beg-B end-B
869 startup-hooks job-name word-mode nil))) 869 startup-hooks job-name word-mode nil)))
870 870
871 871
872 ;;;###autoload 872 ;;;###autoload
873 (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks) 873 (defun ediff-regions-wordwise (buffer-A buffer-B &optional startup-hooks)
874 "Run Ediff on a pair of regions in specified buffers. 874 "Run Ediff on a pair of regions in specified buffers.
875 Regions \(i.e., point and mark\) are assumed to be set in advance except 875 Regions \(i.e., point and mark\) are assumed to be set in advance except
876 for the second region in the case both regions are from the same buffer. 876 for the second region in the case both regions are from the same buffer.
877 In such a case the user is asked to interactively establish the second 877 In such a case the user is asked to interactively establish the second
878 region. 878 region.
879 This function is effective only for relatively small regions, up to 200 879 This function is effective only for relatively small regions, up to 200
880 lines. For large regions, use `ediff-regions-linewise'." 880 lines. For large regions, use `ediff-regions-linewise'."
881 (interactive 881 (interactive
882 (let (bf) 882 (let (bf)
883 (list (setq bf (read-buffer "Region's A buffer: " 883 (list (setq bf (read-buffer "Region's A buffer: "
884 (ediff-other-buffer "") t)) 884 (ediff-other-buffer "") t))
885 (read-buffer "Region's B buffer: " 885 (read-buffer "Region's B buffer: "
886 (progn 886 (progn
891 t)))) 891 t))))
892 (if (not (ediff-buffer-live-p buffer-A)) 892 (if (not (ediff-buffer-live-p buffer-A))
893 (error "Buffer %S doesn't exist" buffer-A)) 893 (error "Buffer %S doesn't exist" buffer-A))
894 (if (not (ediff-buffer-live-p buffer-B)) 894 (if (not (ediff-buffer-live-p buffer-B))
895 (error "Buffer %S doesn't exist" buffer-B)) 895 (error "Buffer %S doesn't exist" buffer-B))
896 896
897 897
898 (let ((buffer-A 898 (let ((buffer-A
899 (ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-")) 899 (ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-"))
900 (buffer-B 900 (buffer-B
901 (ediff-clone-buffer-for-region-comparison buffer-B "-Region.B-")) 901 (ediff-clone-buffer-for-region-comparison buffer-B "-Region.B-"))
902 reg-A-beg reg-A-end reg-B-beg reg-B-end) 902 reg-A-beg reg-A-end reg-B-beg reg-B-end)
905 (setq reg-A-beg (region-beginning) 905 (setq reg-A-beg (region-beginning)
906 reg-A-end (region-end)) 906 reg-A-end (region-end))
907 (set-buffer buffer-B) 907 (set-buffer buffer-B)
908 (setq reg-B-beg (region-beginning) 908 (setq reg-B-beg (region-beginning)
909 reg-B-end (region-end))) 909 reg-B-end (region-end)))
910 910
911 (ediff-regions-internal 911 (ediff-regions-internal
912 (get-buffer buffer-A) reg-A-beg reg-A-end 912 (get-buffer buffer-A) reg-A-beg reg-A-end
913 (get-buffer buffer-B) reg-B-beg reg-B-end 913 (get-buffer buffer-B) reg-B-beg reg-B-end
914 startup-hooks 'ediff-regions-wordwise 'word-mode nil))) 914 startup-hooks 'ediff-regions-wordwise 'word-mode nil)))
915 915
916 ;;;###autoload 916 ;;;###autoload
917 (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks) 917 (defun ediff-regions-linewise (buffer-A buffer-B &optional startup-hooks)
918 "Run Ediff on a pair of regions in specified buffers. 918 "Run Ediff on a pair of regions in specified buffers.
919 Regions \(i.e., point and mark\) are assumed to be set in advance except 919 Regions \(i.e., point and mark\) are assumed to be set in advance except
920 for the second region in the case both regions are from the same buffer. 920 for the second region in the case both regions are from the same buffer.
921 In such a case the user is asked to interactively establish the second 921 In such a case the user is asked to interactively establish the second
922 region. 922 region.
923 Each region is enlarged to contain full lines. 923 Each region is enlarged to contain full lines.
924 This function is effective for large regions, over 100-200 924 This function is effective for large regions, over 100-200
925 lines. For small regions, use `ediff-regions-wordwise'." 925 lines. For small regions, use `ediff-regions-wordwise'."
926 (interactive 926 (interactive
927 (let (bf) 927 (let (bf)
928 (list (setq bf (read-buffer "Region A's buffer: " 928 (list (setq bf (read-buffer "Region A's buffer: "
929 (ediff-other-buffer "") t)) 929 (ediff-other-buffer "") t))
930 (read-buffer "Region B's buffer: " 930 (read-buffer "Region B's buffer: "
931 (progn 931 (progn
936 t)))) 936 t))))
937 (if (not (ediff-buffer-live-p buffer-A)) 937 (if (not (ediff-buffer-live-p buffer-A))
938 (error "Buffer %S doesn't exist" buffer-A)) 938 (error "Buffer %S doesn't exist" buffer-A))
939 (if (not (ediff-buffer-live-p buffer-B)) 939 (if (not (ediff-buffer-live-p buffer-B))
940 (error "Buffer %S doesn't exist" buffer-B)) 940 (error "Buffer %S doesn't exist" buffer-B))
941 941
942 (let ((buffer-A 942 (let ((buffer-A
943 (ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-")) 943 (ediff-clone-buffer-for-region-comparison buffer-A "-Region.A-"))
944 (buffer-B 944 (buffer-B
945 (ediff-clone-buffer-for-region-comparison buffer-B "-Region.B-")) 945 (ediff-clone-buffer-for-region-comparison buffer-B "-Region.B-"))
946 reg-A-beg reg-A-end reg-B-beg reg-B-end) 946 reg-A-beg reg-A-end reg-B-beg reg-B-end)
947 (save-excursion 947 (save-excursion
948 (set-buffer buffer-A) 948 (set-buffer buffer-A)
949 (setq reg-A-beg (region-beginning) 949 (setq reg-A-beg (region-beginning)
950 reg-A-end (region-end)) 950 reg-A-end (region-end))
951 ;; enlarge the region to hold full lines 951 ;; enlarge the region to hold full lines
952 (goto-char reg-A-beg) 952 (goto-char reg-A-beg)
953 (beginning-of-line) 953 (beginning-of-line)
954 (setq reg-A-beg (point)) 954 (setq reg-A-beg (point))
955 (goto-char reg-A-end) 955 (goto-char reg-A-end)
956 (end-of-line) 956 (end-of-line)
957 (or (eobp) (forward-char)) ; include the newline char 957 (or (eobp) (forward-char)) ; include the newline char
958 (setq reg-A-end (point)) 958 (setq reg-A-end (point))
959 959
960 (set-buffer buffer-B) 960 (set-buffer buffer-B)
961 (setq reg-B-beg (region-beginning) 961 (setq reg-B-beg (region-beginning)
962 reg-B-end (region-end)) 962 reg-B-end (region-end))
963 ;; enlarge the region to hold full lines 963 ;; enlarge the region to hold full lines
964 (goto-char reg-B-beg) 964 (goto-char reg-B-beg)
965 (beginning-of-line) 965 (beginning-of-line)
966 (setq reg-B-beg (point)) 966 (setq reg-B-beg (point))
967 (goto-char reg-B-end) 967 (goto-char reg-B-end)
968 (end-of-line) 968 (end-of-line)
969 (or (eobp) (forward-char)) ; include the newline char 969 (or (eobp) (forward-char)) ; include the newline char
970 (setq reg-B-end (point)) 970 (setq reg-B-end (point))
971 ) ; save excursion 971 ) ; save excursion
972 972
973 (ediff-regions-internal 973 (ediff-regions-internal
974 (get-buffer buffer-A) reg-A-beg reg-A-end 974 (get-buffer buffer-A) reg-A-beg reg-A-end
975 (get-buffer buffer-B) reg-B-beg reg-B-end 975 (get-buffer buffer-B) reg-B-beg reg-B-end
976 startup-hooks 'ediff-regions-linewise nil nil))) ; no word mode 976 startup-hooks 'ediff-regions-linewise nil nil))) ; no word mode
977 977
978 ;; compare region beg-A to end-A of buffer-A 978 ;; compare region beg-A to end-A of buffer-A
979 ;; to regions beg-B -- end-B in buffer-B. 979 ;; 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 980 (defun ediff-regions-internal (buffer-A beg-A end-A buffer-B beg-B end-B
981 startup-hooks job-name word-mode 981 startup-hooks job-name word-mode
982 setup-parameters) 982 setup-parameters)
983 (let ((tmp-buffer (get-buffer-create ediff-tmp-buffer)) 983 (let ((tmp-buffer (get-buffer-create ediff-tmp-buffer))
984 overl-A overl-B 984 overl-A overl-B
985 file-A file-B) 985 file-A file-B)
986 986
987 ;; in case beg/end-A/B aren't markers--make them into markers 987 ;; in case beg/end-A/B aren't markers--make them into markers
988 (ediff-with-current-buffer buffer-A 988 (ediff-with-current-buffer buffer-A
989 (setq beg-A (move-marker (make-marker) beg-A) 989 (setq beg-A (move-marker (make-marker) beg-A)
990 end-A (move-marker (make-marker) end-A))) 990 end-A (move-marker (make-marker) end-A)))
991 (ediff-with-current-buffer buffer-B 991 (ediff-with-current-buffer buffer-B
992 (setq beg-B (move-marker (make-marker) beg-B) 992 (setq beg-B (move-marker (make-marker) beg-B)
993 end-B (move-marker (make-marker) end-B))) 993 end-B (move-marker (make-marker) end-B)))
994 994
995 ;; make file-A 995 ;; make file-A
996 (if word-mode 996 (if word-mode
997 (ediff-wordify beg-A end-A buffer-A tmp-buffer) 997 (ediff-wordify beg-A end-A buffer-A tmp-buffer)
998 (ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer)) 998 (ediff-copy-to-buffer beg-A end-A buffer-A tmp-buffer))
999 (setq file-A (ediff-make-temp-file tmp-buffer "regA")) 999 (setq file-A (ediff-make-temp-file tmp-buffer "regA"))
1000 1000
1001 ;; make file-B 1001 ;; make file-B
1002 (if word-mode 1002 (if word-mode
1003 (ediff-wordify beg-B end-B buffer-B tmp-buffer) 1003 (ediff-wordify beg-B end-B buffer-B tmp-buffer)
1004 (ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer)) 1004 (ediff-copy-to-buffer beg-B end-B buffer-B tmp-buffer))
1005 (setq file-B (ediff-make-temp-file tmp-buffer "regB")) 1005 (setq file-B (ediff-make-temp-file tmp-buffer "regB"))
1006 1006
1007 (setq overl-A (ediff-make-bullet-proof-overlay beg-A end-A buffer-A)) 1007 (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)) 1008 (setq overl-B (ediff-make-bullet-proof-overlay beg-B end-B buffer-B))
1009 (ediff-setup buffer-A file-A 1009 (ediff-setup buffer-A file-A
1010 buffer-B file-B 1010 buffer-B file-B
1011 nil nil ; buffer & file C 1011 nil nil ; buffer & file C
1017 (list (cons 'ediff-word-mode word-mode) 1017 (list (cons 'ediff-word-mode word-mode)
1018 (cons 'ediff-narrow-bounds (list overl-A overl-B)) 1018 (cons 'ediff-narrow-bounds (list overl-A overl-B))
1019 (cons 'ediff-job-name job-name)) 1019 (cons 'ediff-job-name job-name))
1020 setup-parameters)) 1020 setup-parameters))
1021 )) 1021 ))
1022 1022
1023 1023
1024 ;;; Merge files and buffers 1024 ;;; Merge files and buffers
1025 1025
1026 ;;;###autoload 1026 ;;;###autoload
1027 (defalias 'ediff-merge 'ediff-merge-files) 1027 (defalias 'ediff-merge 'ediff-merge-files)
1028 1028
1029 (defsubst ediff-merge-on-startup () 1029 (defsubst ediff-merge-on-startup ()
1030 (ediff-do-merge 0) 1030 (ediff-do-merge 0)
1031 (ediff-with-current-buffer ediff-buffer-C 1031 (ediff-with-current-buffer ediff-buffer-C
1032 (set-buffer-modified-p nil))) 1032 (set-buffer-modified-p nil)))
1033 1033
1034 ;;;###autoload 1034 ;;;###autoload
1035 (defun ediff-merge-files (file-A file-B 1035 (defun ediff-merge-files (file-A file-B
1036 ;; MERGE-BUFFER-FILE is the file to be 1036 ;; MERGE-BUFFER-FILE is the file to be
1037 ;; associated with the merge buffer 1037 ;; associated with the merge buffer
1038 &optional startup-hooks merge-buffer-file) 1038 &optional startup-hooks merge-buffer-file)
1039 "Merge two files without ancestor." 1039 "Merge two files without ancestor."
1040 (interactive 1040 (interactive
1041 (let ((dir-A (if ediff-use-last-dir 1041 (let ((dir-A (if ediff-use-last-dir
1042 ediff-last-dir-A 1042 ediff-last-dir-A
1045 (list (setq f (ediff-read-file-name 1045 (list (setq f (ediff-read-file-name
1046 "File A to merge" 1046 "File A to merge"
1047 dir-A 1047 dir-A
1048 (ediff-get-default-file-name) 1048 (ediff-get-default-file-name)
1049 'no-dirs)) 1049 'no-dirs))
1050 (ediff-read-file-name "File B to merge" 1050 (ediff-read-file-name "File B to merge"
1051 (setq dir-B 1051 (setq dir-B
1052 (if ediff-use-last-dir 1052 (if ediff-use-last-dir
1053 ediff-last-dir-B 1053 ediff-last-dir-B
1054 (file-name-directory f))) 1054 (file-name-directory f)))
1055 (progn 1055 (progn
1056 (setq file-name-history 1056 (setq file-name-history
1057 (cons (ediff-abbreviate-file-name 1057 (cons (ediff-abbreviate-file-name
1058 (expand-file-name 1058 (expand-file-name
1060 dir-B)) 1060 dir-B))
1061 file-name-history)) 1061 file-name-history))
1062 (ediff-get-default-file-name f 1))) 1062 (ediff-get-default-file-name f 1)))
1063 ))) 1063 )))
1064 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) 1064 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks))
1065 (ediff-files-internal file-A 1065 (ediff-files-internal file-A
1066 (if (file-directory-p file-B) 1066 (if (file-directory-p file-B)
1067 (expand-file-name 1067 (expand-file-name
1068 (file-name-nondirectory file-A) file-B) 1068 (file-name-nondirectory file-A) file-B)
1069 file-B) 1069 file-B)
1070 nil ; file-C 1070 nil ; file-C
1071 startup-hooks 1071 startup-hooks
1072 'ediff-merge-files 1072 'ediff-merge-files
1073 merge-buffer-file)) 1073 merge-buffer-file))
1074 1074
1075 ;;;###autoload 1075 ;;;###autoload
1076 (defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor 1076 (defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor
1077 &optional 1077 &optional
1078 startup-hooks 1078 startup-hooks
1079 ;; MERGE-BUFFER-FILE is the file 1079 ;; MERGE-BUFFER-FILE is the file
1089 (list (setq f (ediff-read-file-name 1089 (list (setq f (ediff-read-file-name
1090 "File A to merge" 1090 "File A to merge"
1091 dir-A 1091 dir-A
1092 (ediff-get-default-file-name) 1092 (ediff-get-default-file-name)
1093 'no-dirs)) 1093 'no-dirs))
1094 (setq ff (ediff-read-file-name "File B to merge" 1094 (setq ff (ediff-read-file-name "File B to merge"
1095 (setq dir-B 1095 (setq dir-B
1096 (if ediff-use-last-dir 1096 (if ediff-use-last-dir
1097 ediff-last-dir-B 1097 ediff-last-dir-B
1098 (file-name-directory f))) 1098 (file-name-directory f)))
1099 (progn 1099 (progn
1100 (setq file-name-history 1100 (setq file-name-history
1101 (cons 1101 (cons
1102 (ediff-abbreviate-file-name 1102 (ediff-abbreviate-file-name
1103 (expand-file-name 1103 (expand-file-name
1104 (file-name-nondirectory f) 1104 (file-name-nondirectory f)
1105 dir-B)) 1105 dir-B))
1106 file-name-history)) 1106 file-name-history))
1107 (ediff-get-default-file-name f 1)))) 1107 (ediff-get-default-file-name f 1))))
1108 (ediff-read-file-name "Ancestor file" 1108 (ediff-read-file-name "Ancestor file"
1109 (setq dir-ancestor 1109 (setq dir-ancestor
1110 (if ediff-use-last-dir 1110 (if ediff-use-last-dir
1111 ediff-last-dir-ancestor 1111 ediff-last-dir-ancestor
1112 (file-name-directory ff))) 1112 (file-name-directory ff)))
1113 (progn 1113 (progn
1118 dir-ancestor)) 1118 dir-ancestor))
1119 file-name-history)) 1119 file-name-history))
1120 (ediff-get-default-file-name ff 2))) 1120 (ediff-get-default-file-name ff 2)))
1121 ))) 1121 )))
1122 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) 1122 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks))
1123 (ediff-files-internal file-A 1123 (ediff-files-internal file-A
1124 (if (file-directory-p file-B) 1124 (if (file-directory-p file-B)
1125 (expand-file-name 1125 (expand-file-name
1126 (file-name-nondirectory file-A) file-B) 1126 (file-name-nondirectory file-A) file-B)
1127 file-B) 1127 file-B)
1128 file-ancestor 1128 file-ancestor
1129 startup-hooks 1129 startup-hooks
1130 'ediff-merge-files-with-ancestor 1130 'ediff-merge-files-with-ancestor
1131 merge-buffer-file)) 1131 merge-buffer-file))
1132 1132
1133 ;;;###autoload 1133 ;;;###autoload
1134 (defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor) 1134 (defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor)
1135 1135
1136 ;;;###autoload 1136 ;;;###autoload
1137 (defun ediff-merge-buffers (buffer-A buffer-B 1137 (defun ediff-merge-buffers (buffer-A buffer-B
1138 &optional 1138 &optional
1139 ;; MERGE-BUFFER-FILE is the file to be 1139 ;; MERGE-BUFFER-FILE is the file to be
1140 ;; associated with the merge buffer 1140 ;; associated with the merge buffer
1141 startup-hooks job-name merge-buffer-file) 1141 startup-hooks job-name merge-buffer-file)
1142 "Merge buffers without ancestor." 1142 "Merge buffers without ancestor."
1143 (interactive 1143 (interactive
1144 (let (bf) 1144 (let (bf)
1145 (list (setq bf (read-buffer "Buffer A to merge: " 1145 (list (setq bf (read-buffer "Buffer A to merge: "
1146 (ediff-other-buffer "") t)) 1146 (ediff-other-buffer "") t))
1147 (read-buffer "Buffer B to merge: " 1147 (read-buffer "Buffer B to merge: "
1148 (progn 1148 (progn
1149 ;; realign buffers so that two visible bufs will be 1149 ;; realign buffers so that two visible bufs will be
1150 ;; at the top 1150 ;; at the top
1151 (save-window-excursion (other-window 1)) 1151 (save-window-excursion (other-window 1))
1152 (ediff-other-buffer bf)) 1152 (ediff-other-buffer bf))
1153 t)))) 1153 t))))
1154 1154
1155 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) 1155 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks))
1156 (or job-name (setq job-name 'ediff-merge-buffers)) 1156 (or job-name (setq job-name 'ediff-merge-buffers))
1157 (ediff-buffers-internal 1157 (ediff-buffers-internal
1158 buffer-A buffer-B nil startup-hooks job-name merge-buffer-file)) 1158 buffer-A buffer-B nil startup-hooks job-name merge-buffer-file))
1159 1159
1160 ;;;###autoload 1160 ;;;###autoload
1161 (defun ediff-merge-buffers-with-ancestor (buffer-A buffer-B buffer-ancestor 1161 (defun ediff-merge-buffers-with-ancestor (buffer-A buffer-B buffer-ancestor
1162 &optional 1162 &optional
1163 startup-hooks 1163 startup-hooks
1164 job-name 1164 job-name
1165 ;; MERGE-BUFFER-FILE is the 1165 ;; MERGE-BUFFER-FILE is the
1166 ;; file to be associated 1166 ;; file to be associated
1167 ;; with the merge buffer 1167 ;; with the merge buffer
1168 merge-buffer-file) 1168 merge-buffer-file)
1169 "Merge buffers with ancestor." 1169 "Merge buffers with ancestor."
1170 (interactive 1170 (interactive
1171 (let (bf bff) 1171 (let (bf bff)
1172 (list (setq bf (read-buffer "Buffer A to merge: " 1172 (list (setq bf (read-buffer "Buffer A to merge: "
1173 (ediff-other-buffer "") t)) 1173 (ediff-other-buffer "") t))
1174 (setq bff (read-buffer "Buffer B to merge: " 1174 (setq bff (read-buffer "Buffer B to merge: "
1175 (progn 1175 (progn
1184 ;; bufs will be at the top 1184 ;; bufs will be at the top
1185 (save-window-excursion (other-window 1)) 1185 (save-window-excursion (other-window 1))
1186 (ediff-other-buffer (list bf bff))) 1186 (ediff-other-buffer (list bf bff)))
1187 t) 1187 t)
1188 ))) 1188 )))
1189 1189
1190 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) 1190 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks))
1191 (or job-name (setq job-name 'ediff-merge-buffers-with-ancestor)) 1191 (or job-name (setq job-name 'ediff-merge-buffers-with-ancestor))
1192 (ediff-buffers-internal 1192 (ediff-buffers-internal
1193 buffer-A buffer-B buffer-ancestor startup-hooks job-name merge-buffer-file)) 1193 buffer-A buffer-B buffer-ancestor startup-hooks job-name merge-buffer-file))
1194 1194
1195 1195
1196 ;;;###autoload 1196 ;;;###autoload
1197 (defun ediff-merge-revisions (&optional file startup-hooks merge-buffer-file) 1197 (defun ediff-merge-revisions (&optional file startup-hooks merge-buffer-file)
1198 ;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer 1198 ;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer
1199 "Run Ediff by merging two revisions of a file. 1199 "Run Ediff by merging two revisions of a file.
1217 (ediff-load-version-control) 1217 (ediff-load-version-control)
1218 ;; ancestor-revision=nil 1218 ;; ancestor-revision=nil
1219 (funcall 1219 (funcall
1220 (intern (format "ediff-%S-merge-internal" ediff-version-control-package)) 1220 (intern (format "ediff-%S-merge-internal" ediff-version-control-package))
1221 rev1 rev2 nil startup-hooks merge-buffer-file))) 1221 rev1 rev2 nil startup-hooks merge-buffer-file)))
1222 1222
1223 1223
1224 ;;;###autoload 1224 ;;;###autoload
1225 (defun ediff-merge-revisions-with-ancestor (&optional 1225 (defun ediff-merge-revisions-with-ancestor (&optional
1226 file startup-hooks 1226 file startup-hooks
1227 ;; MERGE-BUFFER-FILE is the file to 1227 ;; MERGE-BUFFER-FILE is the file to
1267 (ediff-load-version-control) 1267 (ediff-load-version-control)
1268 (let ((tin (tin-locate cvs-cookie-handle pos))) 1268 (let ((tin (tin-locate cvs-cookie-handle pos)))
1269 (if tin 1269 (if tin
1270 (cvs-run-ediff-on-file-descriptor tin) 1270 (cvs-run-ediff-on-file-descriptor tin)
1271 (error "There is no file to merge")))) 1271 (error "There is no file to merge"))))
1272 1272
1273 1273
1274 ;;; Apply patch 1274 ;;; Apply patch
1275 1275
1276 ;;;###autoload 1276 ;;;###autoload
1277 (defun ediff-patch-file (&optional arg patch-buf) 1277 (defun ediff-patch-file (&optional arg patch-buf)
1278 "Run Ediff by patching SOURCE-FILENAME. 1278 "Run Ediff by patching SOURCE-FILENAME.
1292 (file-name-directory 1292 (file-name-directory
1293 (expand-file-name 1293 (expand-file-name
1294 (buffer-file-name patch-buf)))) 1294 (buffer-file-name patch-buf))))
1295 (t default-directory))) 1295 (t default-directory)))
1296 (setq source-file 1296 (setq source-file
1297 (read-file-name 1297 (read-file-name
1298 "File to patch (directory, if multifile patch): " 1298 "File to patch (directory, if multifile patch): "
1299 ;; use an explicit initial file 1299 ;; use an explicit initial file
1300 source-dir nil nil (ediff-get-default-file-name))) 1300 source-dir nil nil (ediff-get-default-file-name)))
1301 (ediff-dispatch-file-patching-job patch-buf source-file))) 1301 (ediff-dispatch-file-patching-job patch-buf source-file)))
1302 1302
1315 (ediff-patch-buffer-internal 1315 (ediff-patch-buffer-internal
1316 patch-buf 1316 patch-buf
1317 (read-buffer 1317 (read-buffer
1318 "Which buffer to patch? " 1318 "Which buffer to patch? "
1319 (current-buffer)))) 1319 (current-buffer))))
1320 1320
1321 1321
1322 ;;;###autoload 1322 ;;;###autoload
1323 (defalias 'epatch 'ediff-patch-file) 1323 (defalias 'epatch 'ediff-patch-file)
1324 ;;;###autoload 1324 ;;;###autoload
1325 (defalias 'epatch-buffer 'ediff-patch-buffer) 1325 (defalias 'epatch-buffer 'ediff-patch-buffer)
1326 1326
1327 1327
1328 1328
1329 1329
1330 ;;; Versions Control functions 1330 ;;; Versions Control functions
1331 1331
1332 ;;;###autoload 1332 ;;;###autoload
1333 (defun ediff-revision (&optional file startup-hooks) 1333 (defun ediff-revision (&optional file startup-hooks)
1334 "Run Ediff by comparing versions of a file. 1334 "Run Ediff by comparing versions of a file.
1335 The file is an optional FILE argument or the file entered at the prompt. 1335 The file is an optional FILE argument or the file entered at the prompt.
1336 Default: the file visited by the current buffer. 1336 Default: the file visited by the current buffer.
1342 (ediff-read-file-name "Compare revisions for file" 1342 (ediff-read-file-name "Compare revisions for file"
1343 (if ediff-use-last-dir 1343 (if ediff-use-last-dir
1344 ediff-last-dir-A 1344 ediff-last-dir-A
1345 default-directory) 1345 default-directory)
1346 (ediff-get-default-file-name) 1346 (ediff-get-default-file-name)
1347 'no-dirs))) 1347 'no-dirs)))
1348 (find-file file) 1348 (find-file file)
1349 (if (and (buffer-modified-p) 1349 (if (and (buffer-modified-p)
1350 (y-or-n-p (message "Buffer %s is modified. Save buffer? " 1350 (y-or-n-p (message "Buffer %s is modified. Save buffer? "
1351 (buffer-name)))) 1351 (buffer-name))))
1352 (save-buffer (current-buffer))) 1352 (save-buffer (current-buffer)))
1354 (setq rev1 1354 (setq rev1
1355 (read-string 1355 (read-string
1356 (format "Revision 1 to compare (default: %s's latest revision): " 1356 (format "Revision 1 to compare (default: %s's latest revision): "
1357 (file-name-nondirectory file))) 1357 (file-name-nondirectory file)))
1358 rev2 1358 rev2
1359 (read-string 1359 (read-string
1360 (format "Revision 2 to compare (default: %s's current state): " 1360 (format "Revision 2 to compare (default: %s's current state): "
1361 (file-name-nondirectory file)))) 1361 (file-name-nondirectory file))))
1362 (ediff-load-version-control) 1362 (ediff-load-version-control)
1363 (funcall 1363 (funcall
1364 (intern (format "ediff-%S-internal" ediff-version-control-package)) 1364 (intern (format "ediff-%S-internal" ediff-version-control-package))
1366 )) 1366 ))
1367 1367
1368 1368
1369 ;;;###autoload 1369 ;;;###autoload
1370 (defalias 'erevision 'ediff-revision) 1370 (defalias 'erevision 'ediff-revision)
1371 1371
1372 1372
1373 ;; Test if version control package is loaded and load if not 1373 ;; 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. 1374 ;; Is SILENT is non-nil, don't report error if package is not found.
1375 (defun ediff-load-version-control (&optional silent) 1375 (defun ediff-load-version-control (&optional silent)
1376 (require 'ediff-vers) 1376 (require 'ediff-vers)
1377 (or (featurep ediff-version-control-package) 1377 (or (featurep ediff-version-control-package)
1418 (princ ediff-BAD-INFO)) 1418 (princ ediff-BAD-INFO))
1419 (if (window-live-p ctl-window) 1419 (if (window-live-p ctl-window)
1420 (progn 1420 (progn
1421 (select-window ctl-window) 1421 (select-window ctl-window)
1422 (set-window-buffer ctl-window ctl-buf))))))) 1422 (set-window-buffer ctl-window ctl-buf)))))))
1423 1423
1424 1424
1425 1425
1426 1426
1427 ;;; Local Variables: 1427 ;;; Local Variables:
1428 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun) 1428 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)