aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMichael Kifer1995-10-06 00:59:04 +0000
committerMichael Kifer1995-10-06 00:59:04 +0000
commit651342bcb1b4e21d1f944d9b5bf44534834cd189 (patch)
treeb555977650b28a346da2f5de58820f27c21564f0 /lisp
parentfa2eb9acd26cf81b9a70796511e64592e973952d (diff)
downloademacs-651342bcb1b4e21d1f944d9b5bf44534834cd189.tar.gz
emacs-651342bcb1b4e21d1f944d9b5bf44534834cd189.zip
(ediff-toggle-read-only,ediff-read-file-name):
replaced abbreviate-file-name with ediff-abbreviate-file-name. (ediff-documentation): bug fix. (ediff-setup,ediff-really-quit): modified to work with Ediff session groups. (ediff-quit,ediff-really-quit): now ask if the user wants to delete buffers.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ediff-util.el932
1 files changed, 608 insertions, 324 deletions
diff --git a/lisp/ediff-util.el b/lisp/ediff-util.el
index 8c8f4dc2c1f..bf15d5d500a 100644
--- a/lisp/ediff-util.el
+++ b/lisp/ediff-util.el
@@ -23,13 +23,14 @@
23;;; Code: 23;;; Code:
24 24
25(require 'ediff-init) 25(require 'ediff-init)
26(require 'ediff-meta)
26 27
27 28
28;;; Functions 29;;; Functions
29 30
30(defun ediff-mode () 31(defun ediff-mode ()
31 "Ediff mode is used by the Ediff file-difference package. 32 "Ediff mode controls all operations in a single Ediff session.
32It is entered only through one of the following commands: 33This mode is entered through one of the following commands:
33 `ediff' 34 `ediff'
34 `ediff-files' 35 `ediff-files'
35 `ediff-buffers' 36 `ediff-buffers'
@@ -58,7 +59,7 @@ Commands:
58 (kill-all-local-variables) 59 (kill-all-local-variables)
59 (setq major-mode 'ediff-mode) 60 (setq major-mode 'ediff-mode)
60 (setq mode-name "Ediff") 61 (setq mode-name "Ediff")
61 (run-hooks 'ediff-mode-hooks)) 62 (run-hooks 'ediff-mode-hook))
62 63
63(defun ediff-version () 64(defun ediff-version ()
64 "Return string describing the version of Ediff. 65 "Return string describing the version of Ediff.
@@ -105,10 +106,6 @@ to invocation.")
105 (define-key ediff-mode-map [delete] 'ediff-previous-difference) 106 (define-key ediff-mode-map [delete] 'ediff-previous-difference)
106 (define-key ediff-mode-map "\C-h" (if ediff-no-emacs-help-in-control-buffer 107 (define-key ediff-mode-map "\C-h" (if ediff-no-emacs-help-in-control-buffer
107 'ediff-previous-difference nil)) 108 'ediff-previous-difference nil))
108 (define-key ediff-mode-map [f1] (if ediff-no-emacs-help-in-control-buffer
109 'ediff-previous-difference nil))
110 (define-key ediff-mode-map [help] (if ediff-no-emacs-help-in-control-buffer
111 'ediff-previous-difference nil))
112 (define-key ediff-mode-map "n" 'ediff-next-difference) 109 (define-key ediff-mode-map "n" 'ediff-next-difference)
113 (define-key ediff-mode-map " " 'ediff-next-difference) 110 (define-key ediff-mode-map " " 'ediff-next-difference)
114 (define-key ediff-mode-map "j" 'ediff-jump-to-difference) 111 (define-key ediff-mode-map "j" 'ediff-jump-to-difference)
@@ -116,6 +113,7 @@ to invocation.")
116 (define-key ediff-mode-map "ga" 'ediff-jump-to-difference-at-point) 113 (define-key ediff-mode-map "ga" 'ediff-jump-to-difference-at-point)
117 (define-key ediff-mode-map "gb" 'ediff-jump-to-difference-at-point) 114 (define-key ediff-mode-map "gb" 'ediff-jump-to-difference-at-point)
118 (define-key ediff-mode-map "q" 'ediff-quit) 115 (define-key ediff-mode-map "q" 'ediff-quit)
116 (define-key ediff-mode-map "D" 'ediff-show-diff-output)
119 (define-key ediff-mode-map "z" 'ediff-suspend) 117 (define-key ediff-mode-map "z" 'ediff-suspend)
120 (define-key ediff-mode-map "\C-l" 'ediff-recenter) 118 (define-key ediff-mode-map "\C-l" 'ediff-recenter)
121 (define-key ediff-mode-map "|" 'ediff-toggle-split) 119 (define-key ediff-mode-map "|" 'ediff-toggle-split)
@@ -133,15 +131,19 @@ to invocation.")
133 (define-key ediff-mode-map "<" 'ediff-scroll-horizontally) 131 (define-key ediff-mode-map "<" 'ediff-scroll-horizontally)
134 (define-key ediff-mode-map ">" 'ediff-scroll-horizontally) 132 (define-key ediff-mode-map ">" 'ediff-scroll-horizontally)
135 (define-key ediff-mode-map "i" 'ediff-status-info) 133 (define-key ediff-mode-map "i" 'ediff-status-info)
136 (define-key ediff-mode-map "D" 'ediff-documentation) 134 (define-key ediff-mode-map "E" 'ediff-documentation)
137 (define-key ediff-mode-map "?" 'ediff-toggle-help) 135 (define-key ediff-mode-map "?" 'ediff-toggle-help)
138 (define-key ediff-mode-map "!" 'ediff-update-diffs) 136 (define-key ediff-mode-map "!" 'ediff-update-diffs)
137 (define-key ediff-mode-map "M" 'ediff-show-meta-buffer)
138 (define-key ediff-mode-map "R" 'ediff-show-registry)
139 (or ediff-word-mode 139 (or ediff-word-mode
140 (define-key ediff-mode-map "*" 'ediff-make-or-kill-fine-diffs)) 140 (define-key ediff-mode-map "*" 'ediff-make-or-kill-fine-diffs))
141 (define-key ediff-mode-map "a" nil) 141 (define-key ediff-mode-map "a" nil)
142 (define-key ediff-mode-map "b" nil) 142 (define-key ediff-mode-map "b" nil)
143 (define-key ediff-mode-map "r" nil) 143 (define-key ediff-mode-map "r" nil)
144 (cond (ediff-merge-job 144 (cond (ediff-merge-job
145 ;; Will barf if no ancestor
146 (define-key ediff-mode-map "/" 'ediff-show-ancestor)
145 ;; In merging, we allow only A->C and B->C copying. 147 ;; In merging, we allow only A->C and B->C copying.
146 (define-key ediff-mode-map "a" (function 148 (define-key ediff-mode-map "a" (function
147 (lambda (arg) 149 (lambda (arg)
@@ -204,18 +206,18 @@ to invocation.")
204 206
205 (define-key ediff-mode-map "m" 'ediff-toggle-wide-display) 207 (define-key ediff-mode-map "m" 'ediff-toggle-wide-display)
206 208
207 (define-key ediff-mode-map "k" nil)
208 (define-key ediff-mode-map "kkk" 'ediff-reload-keymap) ; for debugging
209
210 ;; Allow ediff-mode-map to be referenced indirectly 209 ;; Allow ediff-mode-map to be referenced indirectly
211 (fset 'ediff-mode-map ediff-mode-map) 210 (fset 'ediff-mode-map ediff-mode-map)
212 (run-hooks 'ediff-keymap-setup-hooks)) 211 (run-hooks 'ediff-keymap-setup-hook))
213 212
214 213
215;;; Setup functions 214;;; Setup functions
216 215
217(require 'ediff-wind) 216(require 'ediff-wind)
218 217
218(or (boundp 'synchronize-minibuffers)
219 (defvar synchronize-minibuffers nil))
220
219;; Common startup entry for all Ediff functions 221;; Common startup entry for all Ediff functions
220;; It now returns control buffer so other functions can do post-processing 222;; It now returns control buffer so other functions can do post-processing
221(defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C 223(defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C
@@ -252,13 +254,35 @@ to invocation.")
252 (make-local-variable 'ediff-default-variant) 254 (make-local-variable 'ediff-default-variant)
253 (make-local-variable 'ediff-merge-window-share) 255 (make-local-variable 'ediff-merge-window-share)
254 (make-local-variable 'ediff-window-setup-function) 256 (make-local-variable 'ediff-window-setup-function)
257 (make-local-variable 'ediff-keep-variants)
258
259 ;; Don't delete variants in case of ediff-buffer-* jobs without asking.
260 ;; This is because u may loose work---dangerous.
261 (if (string-match "buffer" (symbol-name ediff-job-name))
262 (setq ediff-keep-variants t))
263
264 ;; XEmacs has local-pre-command-hook
265 (if ediff-emacs-p
266 (make-local-variable 'pre-command-hook))
267
268 (if ediff-emacs-p
269 (add-hook 'pre-command-hook 'ediff-spy-after-mouse)
270 (add-hook 'local-pre-command-hook 'ediff-spy-after-mouse))
271 (setq ediff-mouse-pixel-position (mouse-pixel-position))
255 272
256 ;; adjust for merge jobs 273 ;; adjust for merge jobs
257 (if ediff-merge-job 274 (if ediff-merge-job
258 (let ((buf 275 (let ((buf
259 ;; Use buf A even if `combined'. The right stuff is 276 ;; If default variant is `combined', the right stuff is
260 ;; inserted by ediff-do-merge 277 ;; inserted by ediff-do-merge
261 (if (eq ediff-default-variant 'default-B) buffer-B buffer-A))) 278 ;; Note: at some point, we tried to put ancestor buffer here
279 ;; (which is currently buffer C. This didn't work right
280 ;; because the merge buffer will contain lossage: diff regions
281 ;; in the ancestor, which correspond to revisions that agree
282 ;; in both buf A and B.
283 (cond ((eq ediff-default-variant 'default-B)
284 buffer-B)
285 (t buffer-A))))
262 286
263 (setq ediff-split-window-function 287 (setq ediff-split-window-function
264 ediff-merge-split-window-function) 288 ediff-merge-split-window-function)
@@ -298,13 +322,16 @@ to invocation.")
298 (string-match "[0-9]+" ediff-control-buffer-suffix) 322 (string-match "[0-9]+" ediff-control-buffer-suffix)
299 0)))))) 323 0))))))
300 324
301 (setq ediff-error-buffer (get-buffer-create (ediff-unique-buffer-name 325 (setq ediff-error-buffer
302 "*ediff-errors" "*"))) 326 (get-buffer-create (ediff-unique-buffer-name "*ediff-errors" "*")))
303 327
304 (ediff-eval-in-buffer buffer-A (ediff-strip-mode-line-format)) 328 (ediff-eval-in-buffer buffer-A (ediff-strip-mode-line-format))
305 (ediff-eval-in-buffer buffer-B (ediff-strip-mode-line-format)) 329 (ediff-eval-in-buffer buffer-B (ediff-strip-mode-line-format))
306 (if ediff-3way-job 330 (if ediff-3way-job
307 (ediff-eval-in-buffer buffer-C (ediff-strip-mode-line-format))) 331 (ediff-eval-in-buffer buffer-C (ediff-strip-mode-line-format)))
332 (if (ediff-buffer-live-p ediff-ancestor-buffer)
333 (ediff-eval-in-buffer ediff-ancestor-buffer
334 (ediff-strip-mode-line-format)))
308 335
309 (ediff-save-protected-variables) ; save variables to be restored on exit 336 (ediff-save-protected-variables) ; save variables to be restored on exit
310 337
@@ -341,34 +368,45 @@ to invocation.")
341 ;; These won't run if there are errors in diff 368 ;; These won't run if there are errors in diff
342 (ediff-eval-in-buffer ediff-buffer-A 369 (ediff-eval-in-buffer ediff-buffer-A
343 (ediff-nuke-selective-display) 370 (ediff-nuke-selective-display)
344 (run-hooks 'ediff-prepare-buffer-hooks) 371 (run-hooks 'ediff-prepare-buffer-hook)
345 (if (ediff-eval-in-buffer control-buffer ediff-merge-job) 372 (if (ediff-eval-in-buffer control-buffer ediff-merge-job)
346 (setq buffer-read-only t)) 373 (setq buffer-read-only t))
347 ;; add control-buffer to the list of sessions--no longer used, but may 374 ;; add control-buffer to the list of sessions--no longer used, but may
348 ;; be used again in the future 375 ;; be used again in the future
349 (or (memq control-buffer ediff-this-buffer-control-sessions) 376 (or (memq control-buffer ediff-this-buffer-ediff-sessions)
350 (setq ediff-this-buffer-control-sessions 377 (setq ediff-this-buffer-ediff-sessions
351 (cons control-buffer ediff-this-buffer-control-sessions))) 378 (cons control-buffer ediff-this-buffer-ediff-sessions)))
352 ) 379 )
353 (ediff-eval-in-buffer ediff-buffer-B 380 (ediff-eval-in-buffer ediff-buffer-B
354 (ediff-nuke-selective-display) 381 (ediff-nuke-selective-display)
355 (run-hooks 'ediff-prepare-buffer-hooks) 382 (run-hooks 'ediff-prepare-buffer-hook)
356 (if (ediff-eval-in-buffer control-buffer ediff-merge-job) 383 (if (ediff-eval-in-buffer control-buffer ediff-merge-job)
357 (setq buffer-read-only t)) 384 (setq buffer-read-only t))
358 ;; add control-buffer to the list of sessions 385 ;; add control-buffer to the list of sessions
359 (or (memq control-buffer ediff-this-buffer-control-sessions) 386 (or (memq control-buffer ediff-this-buffer-ediff-sessions)
360 (setq ediff-this-buffer-control-sessions 387 (setq ediff-this-buffer-ediff-sessions
361 (cons control-buffer ediff-this-buffer-control-sessions))) 388 (cons control-buffer ediff-this-buffer-ediff-sessions)))
362 ) 389 )
363 (if ediff-3way-job 390 (if ediff-3way-job
364 (ediff-eval-in-buffer ediff-buffer-C 391 (ediff-eval-in-buffer ediff-buffer-C
365 (ediff-nuke-selective-display) 392 (ediff-nuke-selective-display)
366 (run-hooks 'ediff-prepare-buffer-hooks) 393 (run-hooks 'ediff-prepare-buffer-hook)
367 ;; add control-buffer to the list of sessions 394 ;; add control-buffer to the list of sessions
368 (or (memq control-buffer ediff-this-buffer-control-sessions) 395 (or (memq control-buffer ediff-this-buffer-ediff-sessions)
369 (setq ediff-this-buffer-control-sessions 396 (setq ediff-this-buffer-ediff-sessions
370 (cons control-buffer 397 (cons control-buffer
371 ediff-this-buffer-control-sessions))) 398 ediff-this-buffer-ediff-sessions)))
399 ))
400
401 (if (ediff-buffer-live-p ediff-ancestor-buffer)
402 (ediff-eval-in-buffer ediff-ancestor-buffer
403 (ediff-nuke-selective-display)
404 (setq buffer-read-only t)
405 (run-hooks 'ediff-prepare-buffer-hook)
406 (or (memq control-buffer ediff-this-buffer-ediff-sessions)
407 (setq ediff-this-buffer-ediff-sessions
408 (cons control-buffer
409 ediff-this-buffer-ediff-sessions)))
372 )) 410 ))
373 411
374 ;; must come after setting up ediff-narrow-bounds AND after 412 ;; must come after setting up ediff-narrow-bounds AND after
@@ -381,9 +419,8 @@ to invocation.")
381 (ediff-make-current-diff-overlay 'B) 419 (ediff-make-current-diff-overlay 'B)
382 (if ediff-3way-job 420 (if ediff-3way-job
383 (ediff-make-current-diff-overlay 'C)) 421 (ediff-make-current-diff-overlay 'C))
384 422 (if ediff-merge-with-ancestor-job
385 (if (ediff-window-display-p) 423 (ediff-make-current-diff-overlay 'Ancestor))
386 (ediff-init-var-faces))
387 424
388 (ediff-setup-windows buffer-A buffer-B buffer-C control-buffer) 425 (ediff-setup-windows buffer-A buffer-B buffer-C control-buffer)
389 426
@@ -413,25 +450,16 @@ to invocation.")
413 (select-window ediff-control-window) 450 (select-window ediff-control-window)
414 (ediff-visible-region) 451 (ediff-visible-region)
415 452
416 ;; The following is a hack to placate OS/2 453 (run-hooks 'startup-hooks)
417 ;; The problem is that OS/2 doesn't let us delete files used by other
418 ;; processes. Thus, in ediff-buffers and other functions, we can't
419 ;; delete temp files because they might be used by the asynchronous
420 ;; process that computes custom diffs. So, under OS/1 we have to wait
421 ;; for some time until custom diffs are done.
422 (if (eq system-type 'emx)
423 (ediff-eval-in-buffer ediff-custom-diff-buffer
424 (let ((proc (get-buffer-process (current-buffer))))
425 (while (and (processp proc)
426 (eq (process-status proc) 'run))
427 (message "Waiting for the diff program to quit")
428 (sleep-for 1))
429 (message "")
430 )))
431
432 (run-hooks 'startup-hooks 'ediff-startup-hooks)
433 (ediff-refresh-mode-lines) 454 (ediff-refresh-mode-lines)
434 (setq buffer-read-only t)) 455 (setq buffer-read-only t)
456 (setq ediff-session-registry
457 (cons control-buffer ediff-session-registry))
458 (ediff-update-registry)
459 (if (ediff-buffer-live-p ediff-meta-buffer)
460 (ediff-update-meta-buffer ediff-meta-buffer))
461 (run-hooks 'ediff-startup-hook)
462 ) ; eval in control-buffer
435 control-buffer)) 463 control-buffer))
436 464
437 465
@@ -490,10 +518,10 @@ to invocation.")
490 518
491(defun ediff-set-help-message () 519(defun ediff-set-help-message ()
492 (setq ediff-long-help-message 520 (setq ediff-long-help-message
493 (cond ((and ediff-long-help-message-custom 521 (cond ((and ediff-long-help-message-function
494 (or (symbolp ediff-long-help-message-custom) 522 (or (symbolp ediff-long-help-message-function)
495 (consp ediff-long-help-message-custom))) 523 (consp ediff-long-help-message-function)))
496 (funcall ediff-long-help-message-custom)) 524 (funcall ediff-long-help-message-function))
497 (ediff-word-mode 525 (ediff-word-mode
498 (concat ediff-long-help-message-head 526 (concat ediff-long-help-message-head
499 ediff-long-help-message-word-mode 527 ediff-long-help-message-word-mode
@@ -515,12 +543,12 @@ to invocation.")
515 ediff-long-help-message-compare2 543 ediff-long-help-message-compare2
516 ediff-long-help-message-tail)))) 544 ediff-long-help-message-tail))))
517 (setq ediff-brief-help-message 545 (setq ediff-brief-help-message
518 (cond ((and ediff-brief-help-message-custom 546 (cond ((and ediff-brief-help-message-function
519 (or (symbolp ediff-brief-help-message-custom) 547 (or (symbolp ediff-brief-help-message-function)
520 (consp ediff-brief-help-message-custom))) 548 (consp ediff-brief-help-message-function)))
521 (funcall ediff-brief-help-message-custom)) 549 (funcall ediff-brief-help-message-function))
522 ((stringp ediff-brief-help-message-custom) 550 ((stringp ediff-brief-help-message-function)
523 ediff-brief-help-message-custom) 551 ediff-brief-help-message-function)
524 ((ediff-multiframe-setup-p) ediff-brief-message-string) 552 ((ediff-multiframe-setup-p) ediff-brief-message-string)
525 (t ; long brief msg, not multiframe --- put in the middle 553 (t ; long brief msg, not multiframe --- put in the middle
526 ediff-brief-message-string) 554 ediff-brief-message-string)
@@ -528,9 +556,7 @@ to invocation.")
528 (setq ediff-help-message (if ediff-prefer-long-help-message 556 (setq ediff-help-message (if ediff-prefer-long-help-message
529 ediff-long-help-message 557 ediff-long-help-message
530 ediff-brief-help-message)) 558 ediff-brief-help-message))
531 (run-hooks 'ediff-display-help-hooks) 559 (run-hooks 'ediff-display-help-hook))
532 )
533
534 560
535 561
536 562
@@ -542,6 +568,11 @@ Buffers are not synchronized with their respective files, so changes done
542to these buffers are not saved at this point---the user can do this later, 568to these buffers are not saved at this point---the user can do this later,
543if necessary." 569if necessary."
544 (interactive) 570 (interactive)
571 (ediff-barf-if-not-control-buffer)
572 (if (and (ediff-buffer-live-p ediff-ancestor-buffer)
573 (not (y-or-n-p "Recompute differences during merge, really? ")))
574 (error "God forbid!"))
575
545 (let ((point-A (ediff-eval-in-buffer ediff-buffer-A (point))) 576 (let ((point-A (ediff-eval-in-buffer ediff-buffer-A (point)))
546 ;;(point-B (ediff-eval-in-buffer ediff-buffer-B (point))) 577 ;;(point-B (ediff-eval-in-buffer ediff-buffer-B (point)))
547 (tmp-buffer (get-buffer-create ediff-tmp-buffer)) 578 (tmp-buffer (get-buffer-create ediff-tmp-buffer))
@@ -580,38 +611,46 @@ if necessary."
580 (if ediff-word-mode 611 (if ediff-word-mode
581 (progn 612 (progn
582 (ediff-wordify beg-A end-A ediff-buffer-A tmp-buffer) 613 (ediff-wordify beg-A end-A ediff-buffer-A tmp-buffer)
583 (ediff-eval-in-buffer tmp-buffer 614 (setq file-A (ediff-make-temp-file tmp-buffer "regA"))
584 (setq file-A (ediff-make-temp-file "regA")))
585 (ediff-wordify beg-B end-B ediff-buffer-B tmp-buffer) 615 (ediff-wordify beg-B end-B ediff-buffer-B tmp-buffer)
586 (ediff-eval-in-buffer tmp-buffer 616 (setq file-B (ediff-make-temp-file tmp-buffer "regB"))
587 (setq file-B (ediff-make-temp-file "regB")))
588 (if ediff-3way-job 617 (if ediff-3way-job
589 (progn 618 (progn
590 (ediff-wordify beg-C end-C ediff-buffer-C tmp-buffer) 619 (ediff-wordify beg-C end-C ediff-buffer-C tmp-buffer)
591 (ediff-eval-in-buffer tmp-buffer 620 (setq file-C (ediff-make-temp-file tmp-buffer "regC"))))
592 (setq file-C (ediff-make-temp-file "regC")))))
593 ) 621 )
594 ;; not word-mode 622 ;; not word-mode
595 (ediff-eval-in-buffer ediff-buffer-A 623 (setq file-A (ediff-make-temp-file ediff-buffer-A buf-A-file-name))
596 (setq file-A (ediff-make-temp-file buf-A-file-name))) 624 (setq file-B (ediff-make-temp-file ediff-buffer-B buf-B-file-name))
597 (ediff-eval-in-buffer ediff-buffer-B
598 (setq file-B (ediff-make-temp-file buf-B-file-name)))
599 (if ediff-3way-job 625 (if ediff-3way-job
600 (ediff-eval-in-buffer ediff-buffer-C 626 (setq file-C (ediff-make-temp-file ediff-buffer-C buf-C-file-name)))
601 (setq file-C (ediff-make-temp-file buf-C-file-name))))
602 ) 627 )
603 628
604 (ediff-clear-diff-vector 'ediff-difference-vector-A 'fine-diffs-also) 629 (ediff-clear-diff-vector 'ediff-difference-vector-A 'fine-diffs-also)
605 (ediff-clear-diff-vector 'ediff-difference-vector-B 'fine-diffs-also) 630 (ediff-clear-diff-vector 'ediff-difference-vector-B 'fine-diffs-also)
606 (ediff-clear-diff-vector 'ediff-difference-vector-C 'fine-diffs-also) 631 (ediff-clear-diff-vector 'ediff-difference-vector-C 'fine-diffs-also)
632 (ediff-clear-diff-vector
633 'ediff-difference-vector-Ancestor 'fine-diffs-also)
634 ;; let them garbage collect. we can't use the ancestor after recomputing
635 ;; the diffs.
636 (setq ediff-difference-vector-Ancestor nil
637 ediff-ancestor-buffer nil
638 ediff-state-of-merge nil)
639
607 (setq ediff-killed-diffs-alist nil) ; invalidate saved killed diff regions 640 (setq ediff-killed-diffs-alist nil) ; invalidate saved killed diff regions
608 641
609 ;; In case of merge job, full it into thinking that it is just doing 642 ;; In case of merge job, fool it into thinking that it is just doing
610 ;; comparison 643 ;; comparison
611 (let ((ediff-setup-diff-regions-function ediff-setup-diff-regions-function) 644 (let ((ediff-setup-diff-regions-function ediff-setup-diff-regions-function)
645 (ediff-3way-comparison-job ediff-3way-comparison-job)
646 (ediff-merge-job ediff-merge-job)
647 (ediff-merge-with-ancestor-job ediff-merge-with-ancestor-job)
612 (ediff-job-name ediff-job-name)) 648 (ediff-job-name ediff-job-name))
613 (if ediff-merge-job 649 (if ediff-merge-job
614 (setq ediff-setup-diff-regions-function 'ediff-setup-diff-regions3 650 (setq ediff-setup-diff-regions-function 'ediff-setup-diff-regions3
651 ediff-3way-comparison-job t
652 ediff-merge-job nil
653 ediff-merge-with-ancestor-job nil
615 ediff-job-name 'ediff-files3)) 654 ediff-job-name 'ediff-files3))
616 (funcall ediff-setup-diff-regions-function file-A file-B file-C)) 655 (funcall ediff-setup-diff-regions-function file-A file-B file-C))
617 656
@@ -632,10 +671,12 @@ if necessary."
632(defun ediff-revert-buffers-then-recompute-diffs (noconfirm) 671(defun ediff-revert-buffers-then-recompute-diffs (noconfirm)
633 "Revert buffers A, B and C. Then rerun Ediff on file A and file B." 672 "Revert buffers A, B and C. Then rerun Ediff on file A and file B."
634 (interactive "P") 673 (interactive "P")
674 (ediff-barf-if-not-control-buffer)
635 (let ((bufA ediff-buffer-A) 675 (let ((bufA ediff-buffer-A)
636 (bufB ediff-buffer-B) 676 (bufB ediff-buffer-B)
637 (bufC ediff-buffer-C) 677 (bufC ediff-buffer-C)
638 (ctl-buf ediff-control-buffer) 678 (ctl-buf ediff-control-buffer)
679 (keep-variants ediff-keep-variants)
639 (ancestor-buf ediff-ancestor-buffer) 680 (ancestor-buf ediff-ancestor-buffer)
640 (ancestor-job ediff-merge-with-ancestor-job) 681 (ancestor-job ediff-merge-with-ancestor-job)
641 (merge ediff-merge-job) 682 (merge ediff-merge-job)
@@ -651,7 +692,10 @@ if necessary."
651 (if merge 692 (if merge
652 (progn 693 (progn
653 (set-buffer ctl-buf) 694 (set-buffer ctl-buf)
654 (ediff-really-quit) 695 ;; the argument says whether to reverse the meaning of
696 ;; ediff-keep-variants, i.e., ediff-really-quit runs here with
697 ;; variants kept.
698 (ediff-really-quit (not keep-variants))
655 (kill-buffer bufC) 699 (kill-buffer bufC)
656 (if ancestor-job 700 (if ancestor-job
657 (ediff-merge-buffers-with-ancestor bufA bufB ancestor-buf) 701 (ediff-merge-buffers-with-ancestor bufA bufB ancestor-buf)
@@ -664,6 +708,7 @@ if necessary."
664 "Bring the highlighted region of all buffers being compared into view. 708 "Bring the highlighted region of all buffers being compared into view.
665Reestablish the default three-window display." 709Reestablish the default three-window display."
666 (interactive) 710 (interactive)
711 (ediff-barf-if-not-control-buffer)
667 712
668 ;; force all minibuffer to display ediff's messages. 713 ;; force all minibuffer to display ediff's messages.
669 ;; when xemacs implements minibufferless frames, this won't be necessary 714 ;; when xemacs implements minibufferless frames, this won't be necessary
@@ -682,10 +727,9 @@ Reestablish the default three-window display."
682 "You've killed an essential Ediff buffer---Please quit Ediff" 727 "You've killed an essential Ediff buffer---Please quit Ediff"
683 (beep 1))) 728 (beep 1)))
684 )) 729 ))
685 730
686 ;; set visibility range appropriate to this invocation of Ediff. 731 ;; set visibility range appropriate to this invocation of Ediff.
687 (ediff-visible-region) 732 (ediff-visible-region)
688
689 ;; raise 733 ;; raise
690 (if (and (ediff-window-display-p) 734 (if (and (ediff-window-display-p)
691 (symbolp this-command) 735 (symbolp this-command)
@@ -693,6 +737,8 @@ Reestablish the default three-window display."
693 ;; Either one of the display-changing commands 737 ;; Either one of the display-changing commands
694 (or (memq this-command 738 (or (memq this-command
695 '(ediff-recenter 739 '(ediff-recenter
740 ediff-dir-action ediff-registry-action
741 ediff-patch-action
696 ediff-toggle-wide-display ediff-toggle-multiframe)) 742 ediff-toggle-wide-display ediff-toggle-multiframe))
697 ;; Or one of the movement cmds and prev cmd was an Ediff cmd 743 ;; Or one of the movement cmds and prev cmd was an Ediff cmd
698 ;; This avoids rasing frames unnecessarily. 744 ;; This avoids rasing frames unnecessarily.
@@ -712,35 +758,37 @@ Reestablish the default three-window display."
712 (raise-frame (window-frame ediff-window-C))))) 758 (raise-frame (window-frame ediff-window-C)))))
713 (if (and (ediff-window-display-p) 759 (if (and (ediff-window-display-p)
714 (frame-live-p ediff-control-frame) 760 (frame-live-p ediff-control-frame)
761 (not ediff-prefer-long-help-message)
715 (not (ediff-frame-iconified-p ediff-control-frame))) 762 (not (ediff-frame-iconified-p ediff-control-frame)))
716 (raise-frame ediff-control-frame)) 763 (raise-frame ediff-control-frame))
717 764
718 ;; Redisplay whatever buffers are showing, if there is a selected difference 765 ;; Redisplay whatever buffers are showing, if there is a selected difference
719 (let* ((control-frame ediff-control-frame) 766 (let ((control-frame ediff-control-frame)
720 (control-buf ediff-control-buffer)) 767 (control-buf ediff-control-buffer))
721 (if (and (ediff-buffer-live-p ediff-buffer-A) 768 (if (and (ediff-buffer-live-p ediff-buffer-A)
722 (ediff-buffer-live-p ediff-buffer-B) 769 (ediff-buffer-live-p ediff-buffer-B)
723 (or (not ediff-3way-job) 770 (or (not ediff-3way-job)
724 (ediff-buffer-live-p ediff-buffer-C)) 771 (ediff-buffer-live-p ediff-buffer-C))
725 (ediff-valid-difference-p)) 772 )
726 (progn 773 (progn
727 (or no-rehighlight 774 (or no-rehighlight
728 (ediff-select-difference ediff-current-difference)) 775 (ediff-select-difference ediff-current-difference))
729 776
730 (ediff-recenter-one-window 'A) 777 (ediff-recenter-one-window 'A)
731 (ediff-recenter-one-window 'B) 778 (ediff-recenter-one-window 'B)
732 (if ediff-3way-job 779 (if ediff-3way-job
733 (ediff-recenter-one-window 'C)) 780 (ediff-recenter-one-window 'C))
734 781
735 (if (and (ediff-multiframe-setup-p) 782 (ediff-eval-in-buffer control-buf
736 (not (ediff-frame-iconified-p ediff-control-frame))) 783 (ediff-recenter-ancestor) ; it checks if ancestor is alive
737 (progn 784
738 (ediff-reset-mouse control-frame) 785 (if (and (ediff-multiframe-setup-p)
739 (or ediff-xemacs-p 786 (not ediff-prefer-long-help-message)
740 (cond ((eq (ediff-device-type) 'ns) 787 (not (ediff-frame-iconified-p ediff-control-frame)))
741 (unfocus-frame (selected-frame))) 788 ;; never grab mouse on quit in this place
742 (t (unfocus-frame)))) 789 (ediff-reset-mouse
743 )) 790 control-frame
791 (eq this-command 'ediff-quit))))
744 )) 792 ))
745 (ediff-eval-in-buffer control-buf 793 (ediff-eval-in-buffer control-buf
746 (ediff-refresh-mode-lines)) 794 (ediff-refresh-mode-lines))
@@ -749,31 +797,54 @@ Reestablish the default three-window display."
749;; this function returns to the window it was called from 797;; this function returns to the window it was called from
750;; (which was the control window) 798;; (which was the control window)
751(defun ediff-recenter-one-window (buf-type) 799(defun ediff-recenter-one-window (buf-type)
752 (let* (;; context must be saved before switching to windows A/B/C 800 (if (ediff-valid-difference-p)
753 (ctl-wind (selected-window)) 801 ;; context must be saved before switching to windows A/B/C
754 (shift (ediff-overlay-start 802 (let* ((ctl-wind (selected-window))
755 (ediff-get-value-according-to-buffer-type 803 (shift (ediff-overlay-start
756 buf-type ediff-narrow-bounds))) 804 (ediff-get-value-according-to-buffer-type
757 (job-name ediff-job-name) 805 buf-type ediff-narrow-bounds)))
758 (control-buf ediff-control-buffer) 806 (job-name ediff-job-name)
759 (window-name (intern (format "ediff-window-%S" buf-type))) 807 (control-buf ediff-control-buffer)
760 (window (if (window-live-p (symbol-value window-name)) 808 (window-name (intern (format "ediff-window-%S" buf-type)))
761 (symbol-value window-name)))) 809 (window (if (window-live-p (symbol-value window-name))
762 810 (symbol-value window-name))))
763 (if (and window ediff-windows-job) 811
764 (set-window-start window shift)) 812 (if (and window ediff-windows-job)
765 (if window 813 (set-window-start window shift))
766 (progn 814 (if window
767 (select-window window) 815 (progn
768 (ediff-deactivate-mark) 816 (select-window window)
769 (ediff-position-region 817 (ediff-deactivate-mark)
770 (ediff-get-diff-posn buf-type 'beg nil control-buf) 818 (ediff-position-region
771 (ediff-get-diff-posn buf-type 'end nil control-buf) 819 (ediff-get-diff-posn buf-type 'beg nil control-buf)
772 (ediff-get-diff-posn buf-type 'beg nil control-buf) 820 (ediff-get-diff-posn buf-type 'end nil control-buf)
773 job-name 821 (ediff-get-diff-posn buf-type 'beg nil control-buf)
774 ))) 822 job-name
775 (select-window ctl-wind) 823 )))
776 )) 824 (select-window ctl-wind)
825 )))
826
827(defun ediff-recenter-ancestor ()
828 ;; do half-hearted job by recentering the ancestor buffer, if it is alive and
829 ;; visible.
830 (if (and (ediff-buffer-live-p ediff-ancestor-buffer)
831 (ediff-valid-difference-p))
832 (let ((window (ediff-get-visible-buffer-window ediff-ancestor-buffer))
833 (ctl-wind (selected-window))
834 (job-name ediff-job-name)
835 (ctl-buf ediff-control-buffer))
836 (ediff-eval-in-buffer ediff-ancestor-buffer
837 (goto-char (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf))
838 (if window
839 (progn
840 (select-window window)
841 (ediff-position-region
842 (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf)
843 (ediff-get-diff-posn 'Ancestor 'end nil ctl-buf)
844 (ediff-get-diff-posn 'Ancestor 'beg nil ctl-buf)
845 job-name))))
846 (select-window ctl-wind)
847 )))
777 848
778 849
779;; This will have to be refined for 3way jobs 850;; This will have to be refined for 3way jobs
@@ -781,6 +852,7 @@ Reestablish the default three-window display."
781 "Toggle vertical/horizontal window split. 852 "Toggle vertical/horizontal window split.
782Does nothing if file-A and file-B are in different frames." 853Does nothing if file-A and file-B are in different frames."
783 (interactive) 854 (interactive)
855 (ediff-barf-if-not-control-buffer)
784 (let* ((wind-A (if (window-live-p ediff-window-A) ediff-window-A)) 856 (let* ((wind-A (if (window-live-p ediff-window-A) ediff-window-A))
785 (wind-B (if (window-live-p ediff-window-B) ediff-window-B)) 857 (wind-B (if (window-live-p ediff-window-B) ediff-window-B))
786 (wind-C (if (window-live-p ediff-window-C) ediff-window-C)) 858 (wind-C (if (window-live-p ediff-window-C) ediff-window-C))
@@ -804,6 +876,7 @@ Does nothing if file-A and file-B are in different frames."
804 "Switch between highlighting using ASCII flags and highlighting using faces. 876 "Switch between highlighting using ASCII flags and highlighting using faces.
805On a dumb terminal, switches between ASCII highlighting and no highlighting." 877On a dumb terminal, switches between ASCII highlighting and no highlighting."
806 (interactive) 878 (interactive)
879 (ediff-barf-if-not-control-buffer)
807 (if (not (ediff-window-display-p)) 880 (if (not (ediff-window-display-p))
808 (if (eq ediff-highlighting-style 'ascii) 881 (if (eq ediff-highlighting-style 'ascii)
809 (progn 882 (progn
@@ -828,21 +901,8 @@ On a dumb terminal, switches between ASCII highlighting and no highlighting."
828 ediff-highlight-all-diffs t))) 901 ediff-highlight-all-diffs t)))
829 902
830 (if (and ediff-use-faces ediff-highlight-all-diffs) 903 (if (and ediff-use-faces ediff-highlight-all-diffs)
831 (if (not (face-differs-from-default-p 'ediff-odd-diff-face-A-var)) 904 (ediff-color-background-regions)
832 (progn 905 (ediff-color-background-regions 'unhighlight))
833 (copy-face ediff-odd-diff-face-A 'ediff-odd-diff-face-A-var)
834 (copy-face ediff-odd-diff-face-B 'ediff-odd-diff-face-B-var)
835 (copy-face ediff-odd-diff-face-C 'ediff-odd-diff-face-C-var)
836 (copy-face ediff-even-diff-face-A 'ediff-even-diff-face-A-var)
837 (copy-face ediff-even-diff-face-B 'ediff-even-diff-face-B-var)
838 (copy-face ediff-even-diff-face-C 'ediff-even-diff-face-C-var)
839 ))
840 (copy-face 'default 'ediff-odd-diff-face-A-var)
841 (copy-face 'default 'ediff-odd-diff-face-B-var)
842 (copy-face 'default 'ediff-odd-diff-face-C-var)
843 (copy-face 'default 'ediff-even-diff-face-A-var)
844 (copy-face 'default 'ediff-even-diff-face-B-var)
845 (copy-face 'default 'ediff-even-diff-face-C-var))
846 906
847 (ediff-unselect-and-select-difference 907 (ediff-unselect-and-select-difference
848 ediff-current-difference 'select-only)) 908 ediff-current-difference 'select-only))
@@ -851,6 +911,7 @@ On a dumb terminal, switches between ASCII highlighting and no highlighting."
851(defun ediff-toggle-autorefine () 911(defun ediff-toggle-autorefine ()
852 "Toggle auto-refine mode." 912 "Toggle auto-refine mode."
853 (interactive) 913 (interactive)
914 (ediff-barf-if-not-control-buffer)
854 (if ediff-word-mode 915 (if ediff-word-mode
855 (error "No fine differences in this mode")) 916 (error "No fine differences in this mode"))
856 (cond ((eq ediff-auto-refine 'nix) 917 (cond ((eq ediff-auto-refine 'nix)
@@ -865,11 +926,25 @@ On a dumb terminal, switches between ASCII highlighting and no highlighting."
865 (message "Refinements are HIDDEN") 926 (message "Refinements are HIDDEN")
866 (setq ediff-auto-refine 'nix)) 927 (setq ediff-auto-refine 'nix))
867 )) 928 ))
929
930(defun ediff-show-ancestor ()
931 "Show the ancestor buffer in a suitable window."
932 (interactive)
933 (ediff-recenter)
934 (or (ediff-buffer-live-p ediff-ancestor-buffer)
935 (if ediff-merge-with-ancestor-job
936 (error "Lost connection to ancestor buffer...sorry")
937 (error "Not merging with ancestor")))
938 (let (wind)
939 (cond ((setq wind (ediff-get-visible-buffer-window ediff-ancestor-buffer))
940 (raise-frame (window-frame wind)))
941 (t (set-window-buffer ediff-window-C ediff-ancestor-buffer)))))
868 942
869(defun ediff-make-or-kill-fine-diffs (arg) 943(defun ediff-make-or-kill-fine-diffs (arg)
870 "Compute fine diffs. With negative prefix arg, kill fine diffs. 944 "Compute fine diffs. With negative prefix arg, kill fine diffs.
871In both cases, operates on the currrent difference region." 945In both cases, operates on the currrent difference region."
872 (interactive "P") 946 (interactive "P")
947 (ediff-barf-if-not-control-buffer)
873 (cond ((eq arg '-) 948 (cond ((eq arg '-)
874 (ediff-clear-fine-differences ediff-current-difference)) 949 (ediff-clear-fine-differences ediff-current-difference))
875 ((and (numberp arg) (< arg 0)) 950 ((and (numberp arg) (< arg 0))
@@ -880,6 +955,7 @@ In both cases, operates on the currrent difference region."
880(defun ediff-toggle-help () 955(defun ediff-toggle-help ()
881 "Toggle short/long help message." 956 "Toggle short/long help message."
882 (interactive) 957 (interactive)
958 (ediff-barf-if-not-control-buffer)
883 (let (buffer-read-only) 959 (let (buffer-read-only)
884 (erase-buffer) 960 (erase-buffer)
885 (setq ediff-prefer-long-help-message (not ediff-prefer-long-help-message)) 961 (setq ediff-prefer-long-help-message (not ediff-prefer-long-help-message))
@@ -901,6 +977,7 @@ If buffer is under version control and locked, check it out first.
901If optional argument BUF is specified, toggle read-only in that buffer instead 977If optional argument BUF is specified, toggle read-only in that buffer instead
902of the current buffer." 978of the current buffer."
903 (interactive) 979 (interactive)
980 (ediff-barf-if-not-control-buffer)
904 (let ((ctl-buf (if (null buf) (current-buffer)))) 981 (let ((ctl-buf (if (null buf) (current-buffer))))
905 (or buf (ediff-recenter)) 982 (or buf (ediff-recenter))
906 (or buf 983 (or buf
@@ -931,7 +1008,7 @@ of the current buffer."
931 (y-or-n-p 1008 (y-or-n-p
932 (format 1009 (format
933 "File %s is under version control. Check it out? " 1010 "File %s is under version control. Check it out? "
934 (abbreviate-file-name file)))) 1011 (ediff-abbreviate-file-name file))))
935 ;; if we checked the file out, we should also change the 1012 ;; if we checked the file out, we should also change the
936 ;; original state of buffer-read-only to nil. If we don't 1013 ;; original state of buffer-read-only to nil. If we don't
937 ;; do this, the mode line will show %%, since the file was 1014 ;; do this, the mode line will show %%, since the file was
@@ -946,7 +1023,7 @@ of the current buffer."
946 (beep 1) (beep 1) 1023 (beep 1) (beep 1)
947 (message 1024 (message
948 "Boy, this is risky! Better don't change this file...") 1025 "Boy, this is risky! Better don't change this file...")
949 (sit-for 3)))) 1026 (sit-for 3)))) ; let the user see the warning
950 (if (and toggle-ro-cmd 1027 (if (and toggle-ro-cmd
951 (string-match "toggle-read-only" (symbol-name toggle-ro-cmd))) 1028 (string-match "toggle-read-only" (symbol-name toggle-ro-cmd)))
952 (save-excursion 1029 (save-excursion
@@ -961,7 +1038,7 @@ of the current buffer."
961 (file-exists-p file) 1038 (file-exists-p file)
962 (not (file-writable-p file))) 1039 (not (file-writable-p file)))
963 (message "Warning: file %s is read-only" 1040 (message "Warning: file %s is read-only"
964 (abbreviate-file-name file) (beep 1))) 1041 (ediff-abbreviate-file-name file) (beep 1)))
965 )))) 1042 ))))
966 1043
967 1044
@@ -985,6 +1062,7 @@ of the current buffer."
985(defun ediff-swap-buffers () 1062(defun ediff-swap-buffers ()
986 "Rotate the display of buffers A, B, and C." 1063 "Rotate the display of buffers A, B, and C."
987 (interactive) 1064 (interactive)
1065 (ediff-barf-if-not-control-buffer)
988 (if (and (window-live-p ediff-window-A) (window-live-p ediff-window-B)) 1066 (if (and (window-live-p ediff-window-A) (window-live-p ediff-window-B))
989 (let ((buf ediff-buffer-A) 1067 (let ((buf ediff-buffer-A)
990 (values ediff-buffer-values-orig-A) 1068 (values ediff-buffer-values-orig-A)
@@ -1089,6 +1167,7 @@ of the current buffer."
1089 "Toggle wide/regular display. 1167 "Toggle wide/regular display.
1090This is especially useful when comparing buffers side-by-side." 1168This is especially useful when comparing buffers side-by-side."
1091 (interactive) 1169 (interactive)
1170 (ediff-barf-if-not-control-buffer)
1092 (or (ediff-window-display-p) 1171 (or (ediff-window-display-p)
1093 (error "%sEmacs is not running as a window application" 1172 (error "%sEmacs is not running as a window application"
1094 (if ediff-emacs-p "" "X"))) 1173 (if ediff-emacs-p "" "X")))
@@ -1099,7 +1178,7 @@ This is especially useful when comparing buffers side-by-side."
1099 (ediff-eval-in-buffer ctl-buf 1178 (ediff-eval-in-buffer ctl-buf
1100 (modify-frame-parameters 1179 (modify-frame-parameters
1101 ediff-wide-display-frame ediff-wide-display-orig-parameters) 1180 ediff-wide-display-frame ediff-wide-display-orig-parameters)
1102 (sit-for (if ediff-xemacs-p 0.4 0)) 1181 ;;(sit-for (if ediff-xemacs-p 0.4 0))
1103 ;; restore control buf, since ctl window may have been deleted 1182 ;; restore control buf, since ctl window may have been deleted
1104 ;; during resizing 1183 ;; during resizing
1105 (set-buffer ctl-buf) 1184 (set-buffer ctl-buf)
@@ -1107,7 +1186,7 @@ This is especially useful when comparing buffers side-by-side."
1107 ediff-window-B nil) ; force update of window config 1186 ediff-window-B nil) ; force update of window config
1108 (ediff-recenter 'no-rehighlight)) 1187 (ediff-recenter 'no-rehighlight))
1109 (funcall ediff-make-wide-display-function) 1188 (funcall ediff-make-wide-display-function)
1110 (sit-for (if ediff-xemacs-p 0.4 0)) 1189 ;;(sit-for (if ediff-xemacs-p 0.4 0))
1111 (ediff-eval-in-buffer ctl-buf 1190 (ediff-eval-in-buffer ctl-buf
1112 (setq ediff-window-B nil) ; force update of window config 1191 (setq ediff-window-B nil) ; force update of window config
1113 (ediff-recenter 'no-rehighlight))))) 1192 (ediff-recenter 'no-rehighlight)))))
@@ -1116,6 +1195,7 @@ This is especially useful when comparing buffers side-by-side."
1116 "Switch from the multiframe display to single-frame display and back. 1195 "Switch from the multiframe display to single-frame display and back.
1117This is primarily for debugging, but one can use it for fun, too." 1196This is primarily for debugging, but one can use it for fun, too."
1118 (interactive) 1197 (interactive)
1198 (ediff-barf-if-not-control-buffer)
1119 (or (ediff-window-display-p) 1199 (or (ediff-window-display-p)
1120 (error "%sEmacs is not running as a window application" 1200 (error "%sEmacs is not running as a window application"
1121 (if ediff-emacs-p "" "X"))) 1201 (if ediff-emacs-p "" "X")))
@@ -1131,6 +1211,7 @@ This is primarily for debugging, but one can use it for fun, too."
1131(defun ediff-toggle-show-clashes-only () 1211(defun ediff-toggle-show-clashes-only ()
1132 "Toggle the mode where only the regions where both buffers differ with the ancestor are shown." 1212 "Toggle the mode where only the regions where both buffers differ with the ancestor are shown."
1133 (interactive) 1213 (interactive)
1214 (ediff-barf-if-not-control-buffer)
1134 (if (not ediff-merge-with-ancestor-job) 1215 (if (not ediff-merge-with-ancestor-job)
1135 (error "This command makes sense only when merging with an ancestor")) 1216 (error "This command makes sense only when merging with an ancestor"))
1136 (setq ediff-show-clashes-only (not ediff-show-clashes-only)) 1217 (setq ediff-show-clashes-only (not ediff-show-clashes-only))
@@ -1209,23 +1290,26 @@ Used in ediff-windows/regions only."
1209 (wind-A ediff-window-A) 1290 (wind-A ediff-window-A)
1210 (wind-B ediff-window-B) 1291 (wind-B ediff-window-B)
1211 (wind-C ediff-window-C) 1292 (wind-C ediff-window-C)
1212 (three-way ediff-3way-job)) 1293 (coefA (ediff-get-region-size-coefficient 'A operation))
1294 (coefB (ediff-get-region-size-coefficient 'B operation))
1295 (three-way ediff-3way-job)
1296 (coefC (if three-way
1297 (ediff-get-region-size-coefficient 'C operation))))
1213 1298
1214 (select-window wind-A) 1299 (select-window wind-A)
1215 (condition-case nil 1300 (condition-case nil
1216 (funcall operation arg) 1301 (funcall operation (round (* coefA arg)))
1217 (error)) 1302 (error))
1218 (select-window wind-B) 1303 (select-window wind-B)
1219 (condition-case nil 1304 (condition-case nil
1220 (funcall operation arg) 1305 (funcall operation (round (* coefB arg)))
1221 (error)) 1306 (error))
1222 (if three-way 1307 (if three-way
1223 (progn 1308 (progn
1224 (select-window wind-C) 1309 (select-window wind-C)
1225 (condition-case nil 1310 (condition-case nil
1226 (funcall operation arg) 1311 (funcall operation (round (* coefC arg)))
1227 (error)))) 1312 (error))))
1228
1229 (select-window wind))) 1313 (select-window wind)))
1230 1314
1231(defun ediff-scroll-vertically (&optional arg) 1315(defun ediff-scroll-vertically (&optional arg)
@@ -1233,6 +1317,7 @@ Used in ediff-windows/regions only."
1233With optional argument ARG, scroll ARG lines; otherwise scroll by nearly 1317With optional argument ARG, scroll ARG lines; otherwise scroll by nearly
1234the height of window-A." 1318the height of window-A."
1235 (interactive "P") 1319 (interactive "P")
1320 (ediff-barf-if-not-control-buffer)
1236 1321
1237 ;; make sure windows aren't dead 1322 ;; make sure windows aren't dead
1238 (if (not (and (window-live-p ediff-window-A) (window-live-p ediff-window-B))) 1323 (if (not (and (window-live-p ediff-window-A) (window-live-p ediff-window-B)))
@@ -1254,14 +1339,14 @@ the height of window-A."
1254 ;; use it 1339 ;; use it
1255 (prefix-numeric-value arg) 1340 (prefix-numeric-value arg)
1256 ;; if not, see if we can determine a default amount (the window height) 1341 ;; if not, see if we can determine a default amount (the window height)
1257 (let* (default-amount) 1342 (let (default-amount)
1258 (setq default-amount 1343 (setq default-amount
1259 (- (min (window-height ediff-window-A) 1344 (- (/ (min (window-height ediff-window-A)
1260 (window-height ediff-window-B) 1345 (window-height ediff-window-B)
1261 (if ediff-3way-job 1346 (if ediff-3way-job
1262 (window-height ediff-window-C) 1347 (window-height ediff-window-C)
1263 123) ; some large number 1348 500)) ; some large number
1264 ) 1349 2)
1265 1 next-screen-context-lines)) 1350 1 next-screen-context-lines))
1266 ;; window found 1351 ;; window found
1267 (if arg 1352 (if arg
@@ -1276,6 +1361,7 @@ the height of window-A."
1276If an argument is given, that is how many columns are scrolled, else nearly 1361If an argument is given, that is how many columns are scrolled, else nearly
1277the width of the A/B/C windows." 1362the width of the A/B/C windows."
1278 (interactive "P") 1363 (interactive "P")
1364 (ediff-barf-if-not-control-buffer)
1279 1365
1280 ;; make sure windows aren't dead 1366 ;; make sure windows aren't dead
1281 (if (not (and (window-live-p ediff-window-A) (window-live-p ediff-window-B))) 1367 (if (not (and (window-live-p ediff-window-A) (window-live-p ediff-window-B)))
@@ -1356,11 +1442,61 @@ the width of the A/B/C windows."
1356 (goto-char pos) 1442 (goto-char pos)
1357 )) 1443 ))
1358 1444
1445;; get number of lines from window start to region end
1446(defun ediff-get-lines-to-region-end (buf-type &optional n ctl-buf)
1447 (or n (setq n ediff-current-difference))
1448 (or ctl-buf (setq ctl-buf ediff-control-buffer))
1449 (ediff-eval-in-buffer ctl-buf
1450 (let* ((buf (ediff-get-buffer buf-type))
1451 (wind (eval (intern (format "ediff-window-%S" buf-type))))
1452 (beg (window-start wind))
1453 (end (ediff-get-diff-posn buf-type 'end))
1454 lines)
1455 (ediff-eval-in-buffer buf
1456 (if (< beg end)
1457 (setq lines (count-lines beg end))
1458 (setq lines 0))
1459 lines
1460 ))))
1461
1462;; get number of lines from window end to region start
1463(defun ediff-get-lines-to-region-start (buf-type &optional n ctl-buf)
1464 (or n (setq n ediff-current-difference))
1465 (or ctl-buf (setq ctl-buf ediff-control-buffer))
1466 (ediff-eval-in-buffer ctl-buf
1467 (let* ((buf (ediff-get-buffer buf-type))
1468 (wind (eval (intern (format "ediff-window-%S" buf-type))))
1469 (end (window-end wind))
1470 (beg (ediff-get-diff-posn buf-type 'beg)))
1471 (ediff-eval-in-buffer buf
1472 (if (< beg end) (count-lines beg end) 0))
1473 )))
1474
1475
1476(defun ediff-get-region-size-coefficient (buf-type op &optional n ctl-buf)
1477 (ediff-eval-in-buffer (or ctl-buf ediff-control-buffer)
1478 (let* ((func (cond ((eq op 'scroll-down) 'ediff-get-lines-to-region-start)
1479 ((eq op 'scroll-up) 'ediff-get-lines-to-region-end)
1480 (t '(lambda (a b c) 0))))
1481 (max-lines (max (funcall func 'A n ctl-buf)
1482 (funcall func 'B n ctl-buf)
1483 (if (ediff-buffer-live-p ediff-buffer-C)
1484 (funcall func 'C n ctl-buf)
1485 0))))
1486 ;; this covers the horizontal coefficient as well:
1487 ;; if max-lines = 0 then coef = 1
1488 (if (> max-lines 0)
1489 (/ (+ (funcall func buf-type n ctl-buf) 0.0)
1490 (+ max-lines 0.0))
1491 1)
1492 )))
1493
1359 1494
1360(defun ediff-next-difference (&optional arg) 1495(defun ediff-next-difference (&optional arg)
1361 "Advance to the next difference. 1496 "Advance to the next difference.
1362With a prefix argument, go back that many differences." 1497With a prefix argument, go back that many differences."
1363 (interactive "P") 1498 (interactive "P")
1499 (ediff-barf-if-not-control-buffer)
1364 (if (< ediff-current-difference ediff-number-of-differences) 1500 (if (< ediff-current-difference ediff-number-of-differences)
1365 (let ((n (min ediff-number-of-differences 1501 (let ((n (min ediff-number-of-differences
1366 (+ ediff-current-difference (if arg arg 1)))) 1502 (+ ediff-current-difference (if arg arg 1))))
@@ -1397,6 +1533,7 @@ With a prefix argument, go back that many differences."
1397 "Go to the previous difference. 1533 "Go to the previous difference.
1398With a prefix argument, go back that many differences." 1534With a prefix argument, go back that many differences."
1399 (interactive "P") 1535 (interactive "P")
1536 (ediff-barf-if-not-control-buffer)
1400 (if (> ediff-current-difference -1) 1537 (if (> ediff-current-difference -1)
1401 (let ((n (max -1 (- ediff-current-difference (if arg arg 1)))) 1538 (let ((n (max -1 (- ediff-current-difference (if arg arg 1))))
1402 regexp-skip) 1539 regexp-skip)
@@ -1431,6 +1568,7 @@ With a prefix argument, go back that many differences."
1431(defun ediff-jump-to-difference (difference-number) 1568(defun ediff-jump-to-difference (difference-number)
1432 "Go to the difference specified as a prefix argument." 1569 "Go to the difference specified as a prefix argument."
1433 (interactive "p") 1570 (interactive "p")
1571 (ediff-barf-if-not-control-buffer)
1434 (setq difference-number (1- difference-number)) 1572 (setq difference-number (1- difference-number))
1435 (if (and (>= difference-number -1) 1573 (if (and (>= difference-number -1)
1436 (< difference-number (1+ ediff-number-of-differences))) 1574 (< difference-number (1+ ediff-number-of-differences)))
@@ -1442,6 +1580,7 @@ With a prefix argument, go back that many differences."
1442The type of buffer depends on last command character \(a, b, or c\) that 1580The type of buffer depends on last command character \(a, b, or c\) that
1443invoked this command." 1581invoked this command."
1444 (interactive) 1582 (interactive)
1583 (ediff-barf-if-not-control-buffer)
1445 (let ((buf-type (ediff-char-to-buftype last-command-char))) 1584 (let ((buf-type (ediff-char-to-buftype last-command-char)))
1446 (ediff-jump-to-difference (ediff-diff-at-point buf-type)))) 1585 (ediff-jump-to-difference (ediff-diff-at-point buf-type))))
1447 1586
@@ -1489,17 +1628,20 @@ the source buffer and the second specifies the target.
1489If the second optional argument, a 2-character string, is given, use it to 1628If the second optional argument, a 2-character string, is given, use it to
1490determine the source and the target buffers instead of the command keys." 1629determine the source and the target buffers instead of the command keys."
1491 (interactive "P") 1630 (interactive "P")
1631 (ediff-barf-if-not-control-buffer)
1492 (or keys (setq keys (this-command-keys))) 1632 (or keys (setq keys (this-command-keys)))
1493 (if arg 1633 (if arg
1494 (ediff-jump-to-difference arg)) 1634 (ediff-jump-to-difference arg))
1495 (let* ((key1 (aref keys 0)) 1635 (let* ((key1 (aref keys 0))
1496 (key2 (aref keys 1)) 1636 (key2 (aref keys 1))
1497 (char1 (if (and ediff-xemacs-p (eventp key1)) (event-key key1) key1)) 1637 (char1 (if (and ediff-xemacs-p (eventp key1)) (event-key key1) key1))
1498 (char2 (if (and ediff-xemacs-p (eventp key1)) (event-key key2) key2))) 1638 (char2 (if (and ediff-xemacs-p (eventp key1)) (event-key key2) key2))
1639 ediff-verbose-p)
1499 (ediff-copy-diff ediff-current-difference 1640 (ediff-copy-diff ediff-current-difference
1500 (ediff-char-to-buftype char1) 1641 (ediff-char-to-buftype char1)
1501 (ediff-char-to-buftype char2)) 1642 (ediff-char-to-buftype char2))
1502 (ediff-recenter 'no-rehighlight))) 1643 ;; recenter with rehighlighting, but no messages
1644 (ediff-recenter)))
1503 1645
1504 1646
1505;; Copy diff N from FROM-BUF-TYPE \(given as A, B or C\) to TO-BUF-TYPE. 1647;; Copy diff N from FROM-BUF-TYPE \(given as A, B or C\) to TO-BUF-TYPE.
@@ -1544,6 +1686,7 @@ determine the source and the target buffers instead of the command keys."
1544 ;; these two insert a dummy char to overcome a bug in 1686 ;; these two insert a dummy char to overcome a bug in
1545 ;; XEmacs, which sometimes prevents 0-length extents 1687 ;; XEmacs, which sometimes prevents 0-length extents
1546 ;; from sensing insertion at its end-points. 1688 ;; from sensing insertion at its end-points.
1689 ;; (need to check if 19.12 still has the bug)
1547 (if ediff-xemacs-p 1690 (if ediff-xemacs-p
1548 (progn 1691 (progn
1549 (goto-char reg-to-delete-end) 1692 (goto-char reg-to-delete-end)
@@ -1573,7 +1716,7 @@ determine the source and the target buffers instead of the command keys."
1573 (car conds) 1716 (car conds)
1574 (mapconcat 'prin1-to-string (cdr conds) " ")) 1717 (mapconcat 'prin1-to-string (cdr conds) " "))
1575 (beep 1) 1718 (beep 1)
1576 (sit-for 2) 1719 (sit-for 2) ; let the user see the error msg
1577 (setq saved-p nil) 1720 (setq saved-p nil)
1578 ))) 1721 )))
1579 ) 1722 )
@@ -1665,6 +1808,7 @@ determine the source and the target buffers instead of the command keys."
1665 ;; these two insert a dummy char to overcome a bug in XEmacs, 1808 ;; these two insert a dummy char to overcome a bug in XEmacs,
1666 ;; which sometimes prevents 0-length extents from sensing 1809 ;; which sometimes prevents 0-length extents from sensing
1667 ;; insertion at its end-points. 1810 ;; insertion at its end-points.
1811 ;; (need to check if 19.12 still has the bug)
1668 (if ediff-xemacs-p 1812 (if ediff-xemacs-p
1669 (progn 1813 (progn
1670 (goto-char reg-end) 1814 (goto-char reg-end)
@@ -1720,30 +1864,35 @@ ARG is a prefix argument. If ARG is nil, restore current-difference.
1720If the second optional argument, a character, is given, use it to 1864If the second optional argument, a character, is given, use it to
1721determine the target buffer instead of last-command-char" 1865determine the target buffer instead of last-command-char"
1722 (interactive "P") 1866 (interactive "P")
1867 (ediff-barf-if-not-control-buffer)
1723 (if arg 1868 (if arg
1724 (ediff-jump-to-difference arg)) 1869 (ediff-jump-to-difference arg))
1725 (ediff-pop-diff ediff-current-difference 1870 (ediff-pop-diff ediff-current-difference
1726 (ediff-char-to-buftype (or key last-command-char))) 1871 (ediff-char-to-buftype (or key last-command-char)))
1727 (ediff-recenter 'no-rehighlight)) 1872 ;; recenter with rehighlighting, but no messages
1873 (let (ediff-verbose-p)
1874 (ediff-recenter)))
1728 1875
1729(defun ediff-toggle-regexp-match () 1876(defun ediff-toggle-regexp-match ()
1730 "Toggle between focusing and hiding of difference regions that match 1877 "Toggle between focusing and hiding of difference regions that match
1731a regular expression typed in by the user." 1878a regular expression typed in by the user."
1732 (interactive) 1879 (interactive)
1880 (ediff-barf-if-not-control-buffer)
1733 (let ((regexp-A "") 1881 (let ((regexp-A "")
1734 (regexp-B "") 1882 (regexp-B "")
1735 (regexp-C "") 1883 (regexp-C "")
1736 msg-connective alt-msg-connective alt-connective) 1884 msg-connective alt-msg-connective alt-connective)
1737 (cond 1885 (cond
1738 ((or (and (eq ediff-skip-diff-region-function 1886 ((or (and (eq ediff-skip-diff-region-function
1739 'ediff-focus-on-regexp-matches) 1887 'ediff-focus-on-regexp-matches-function)
1740 (eq last-command-char ?f)) 1888 (eq last-command-char ?f))
1741 (and (eq ediff-skip-diff-region-function 'ediff-hide-regexp-matches) 1889 (and (eq ediff-skip-diff-region-function
1890 ediff-hide-regexp-matches-function)
1742 (eq last-command-char ?h))) 1891 (eq last-command-char ?h)))
1743 (message "Selective browsing by regexp turned off") 1892 (message "Selective browsing by regexp turned off")
1744 (setq ediff-skip-diff-region-function 'ediff-show-all-diffs)) 1893 (setq ediff-skip-diff-region-function 'ediff-show-all-diffs))
1745 ((eq last-command-char ?h) 1894 ((eq last-command-char ?h)
1746 (setq ediff-skip-diff-region-function 'ediff-hide-regexp-matches 1895 (setq ediff-skip-diff-region-function ediff-hide-regexp-matches-function
1747 regexp-A 1896 regexp-A
1748 (read-string 1897 (read-string
1749 (format 1898 (format
@@ -1769,18 +1918,20 @@ a regular expression typed in by the user."
1769 alt-connective 'and)) 1918 alt-connective 'and))
1770 (if (y-or-n-p 1919 (if (y-or-n-p
1771 (format 1920 (format
1772 "Hiding diff regions that match %s regexps. Use %s instead? " 1921 "Ignore regions that match %s regexps, OK? "
1773 msg-connective alt-msg-connective)) 1922 msg-connective alt-msg-connective))
1774 (progn 1923 (message "Will ignore regions that match %s regexps" msg-connective)
1775 (setq ediff-hide-regexp-connective alt-connective) 1924 (setq ediff-hide-regexp-connective alt-connective)
1776 (message "Hiding diff regions that match %s regexps" 1925 (message "Will ignore regions that match %s regexps"
1777 alt-msg-connective)) 1926 alt-msg-connective))
1778 (message "Hiding diff regions that match %s regexps" msg-connective)) 1927
1779 (or (string= regexp-A "") (setq ediff-regexp-hide-A regexp-A)) 1928 (or (string= regexp-A "") (setq ediff-regexp-hide-A regexp-A))
1780 (or (string= regexp-B "") (setq ediff-regexp-hide-B regexp-B)) 1929 (or (string= regexp-B "") (setq ediff-regexp-hide-B regexp-B))
1781 (or (string= regexp-C "") (setq ediff-regexp-hide-C regexp-C))) 1930 (or (string= regexp-C "") (setq ediff-regexp-hide-C regexp-C)))
1931
1782 ((eq last-command-char ?f) 1932 ((eq last-command-char ?f)
1783 (setq ediff-skip-diff-region-function 'ediff-focus-on-regexp-matches 1933 (setq ediff-skip-diff-region-function
1934 ediff-focus-on-regexp-matches-function
1784 regexp-A 1935 regexp-A
1785 (read-string 1936 (read-string
1786 (format 1937 (format
@@ -1806,20 +1957,21 @@ a regular expression typed in by the user."
1806 alt-connective 'and)) 1957 alt-connective 'and))
1807 (if (y-or-n-p 1958 (if (y-or-n-p
1808 (format 1959 (format
1809 "Focusing on diff regions that match %s regexps. Use %s instead? " 1960 "Focus on regions that match %s regexps, OK? "
1810 msg-connective alt-msg-connective)) 1961 msg-connective alt-msg-connective))
1811 (progn 1962 (message "Will focus on regions that match %s regexps"
1812 (setq ediff-focus-regexp-connective alt-connective) 1963 msg-connective)
1813 (message "Focusing on diff regions that match %s regexps" 1964 (setq ediff-focus-regexp-connective alt-connective)
1814 alt-msg-connective)) 1965 (message "Will focus on regions that match %s regexps"
1815 (message "Focusing on diff regions that match %s regexps" 1966 alt-msg-connective))
1816 msg-connective)) 1967
1817 (or (string= regexp-A "") (setq ediff-regexp-focus-A regexp-A)) 1968 (or (string= regexp-A "") (setq ediff-regexp-focus-A regexp-A))
1818 (or (string= regexp-B "") (setq ediff-regexp-focus-B regexp-B)) 1969 (or (string= regexp-B "") (setq ediff-regexp-focus-B regexp-B))
1819 (or (string= regexp-C "") (setq ediff-regexp-focus-C regexp-C)))))) 1970 (or (string= regexp-C "") (setq ediff-regexp-focus-C regexp-C))))))
1820 1971
1821(defun ediff-toggle-skip-similar () 1972(defun ediff-toggle-skip-similar ()
1822 (interactive) 1973 (interactive)
1974 (ediff-barf-if-not-control-buffer)
1823 (if (not (eq ediff-auto-refine 'on)) 1975 (if (not (eq ediff-auto-refine 'on))
1824 (error 1976 (error
1825 "Can't skip over whitespace regions: first turn auto-refining on")) 1977 "Can't skip over whitespace regions: first turn auto-refining on"))
@@ -1915,25 +2067,35 @@ the number seen by the user."
1915 2067
1916;;; Quitting, suspending, etc. 2068;;; Quitting, suspending, etc.
1917 2069
1918(defun ediff-quit () 2070(defun ediff-quit (reverse-default-keep-variants)
1919 "Finish an Ediff session and exit Ediff. 2071 "Finish an Ediff session and exit Ediff.
1920Unselects the selected difference, if any, restores the read-only and modified 2072Unselects the selected difference, if any, restores the read-only and modified
1921flags of the compared file buffers, kills Ediff buffers for this session 2073flags of the compared file buffers, kills Ediff buffers for this session
1922\(but not buffers A, B, C\)." 2074\(but not buffers A, B, C\).
1923 (interactive) 2075
2076If `ediff-keep-variants' is nil, the user will be asked whether the buffers
2077containing the variants should be removed \(if they haven't been modified\).
2078If it is t, they will be preserved unconditionally. A prefix argument,
2079temporarily reverses the meaning of this variable."
2080 (interactive "P")
2081 (ediff-barf-if-not-control-buffer)
1924 (if (prog1 2082 (if (prog1
1925 (y-or-n-p "Do you really want to exit Ediff? ") 2083 (y-or-n-p
2084 (format "Quit this Ediff session%s? "
2085 (if (ediff-buffer-live-p ediff-meta-buffer)
2086 " & show containing session group" "")))
1926 (message "")) 2087 (message ""))
1927 (ediff-really-quit))) 2088 (ediff-really-quit reverse-default-keep-variants)))
1928 2089
1929 2090
1930;; Perform the quit operations. 2091;; Perform the quit operations.
1931(defun ediff-really-quit () 2092(defun ediff-really-quit (reverse-default-keep-variants)
1932 (ediff-unhighlight-diffs-totally) 2093 (ediff-unhighlight-diffs-totally)
1933 (ediff-clear-diff-vector 'ediff-difference-vector-A 'fine-diffs-also) 2094 (ediff-clear-diff-vector 'ediff-difference-vector-A 'fine-diffs-also)
1934 (ediff-clear-diff-vector 'ediff-difference-vector-B 'fine-diffs-also) 2095 (ediff-clear-diff-vector 'ediff-difference-vector-B 'fine-diffs-also)
1935 (ediff-clear-diff-vector 'ediff-difference-vector-C 'fine-diffs-also) 2096 (ediff-clear-diff-vector 'ediff-difference-vector-C 'fine-diffs-also)
1936 2097 (ediff-clear-diff-vector 'ediff-difference-vector-Ancestor 'fine-diffs-also)
2098
1937 (ediff-delete-temp-files) 2099 (ediff-delete-temp-files)
1938 2100
1939 ;; Restore visibility range. This affects only ediff-*-regions/windows. 2101 ;; Restore visibility range. This affects only ediff-*-regions/windows.
@@ -1956,11 +2118,12 @@ flags of the compared file buffers, kills Ediff buffers for this session
1956 ediff-narrow-bounds) 2118 ediff-narrow-bounds)
1957 2119
1958 ;; restore buffer mode line id's in buffer-A/B/C 2120 ;; restore buffer mode line id's in buffer-A/B/C
1959 (let ((control-buffer ediff-control-buffer)) 2121 (let ((control-buffer ediff-control-buffer)
2122 (meta-buffer ediff-meta-buffer))
1960 (condition-case nil 2123 (condition-case nil
1961 (ediff-eval-in-buffer ediff-buffer-A 2124 (ediff-eval-in-buffer ediff-buffer-A
1962 (setq ediff-this-buffer-control-sessions 2125 (setq ediff-this-buffer-ediff-sessions
1963 (delq control-buffer ediff-this-buffer-control-sessions)) 2126 (delq control-buffer ediff-this-buffer-ediff-sessions))
1964 (kill-local-variable 'mode-line-buffer-identification) 2127 (kill-local-variable 'mode-line-buffer-identification)
1965 (kill-local-variable 'mode-line-format) 2128 (kill-local-variable 'mode-line-format)
1966 ) 2129 )
@@ -1968,8 +2131,8 @@ flags of the compared file buffers, kills Ediff buffers for this session
1968 2131
1969 (condition-case nil 2132 (condition-case nil
1970 (ediff-eval-in-buffer ediff-buffer-B 2133 (ediff-eval-in-buffer ediff-buffer-B
1971 (setq ediff-this-buffer-control-sessions 2134 (setq ediff-this-buffer-ediff-sessions
1972 (delq control-buffer ediff-this-buffer-control-sessions)) 2135 (delq control-buffer ediff-this-buffer-ediff-sessions))
1973 (kill-local-variable 'mode-line-buffer-identification) 2136 (kill-local-variable 'mode-line-buffer-identification)
1974 (kill-local-variable 'mode-line-format) 2137 (kill-local-variable 'mode-line-format)
1975 ) 2138 )
@@ -1977,16 +2140,39 @@ flags of the compared file buffers, kills Ediff buffers for this session
1977 2140
1978 (condition-case nil 2141 (condition-case nil
1979 (ediff-eval-in-buffer ediff-buffer-C 2142 (ediff-eval-in-buffer ediff-buffer-C
2143 (setq ediff-this-buffer-ediff-sessions
2144 (delq control-buffer ediff-this-buffer-ediff-sessions))
2145 (kill-local-variable 'mode-line-buffer-identification)
2146 (kill-local-variable 'mode-line-format)
2147 )
2148 (error))
2149
2150 (condition-case nil
2151 (ediff-eval-in-buffer ediff-ancestor-buffer
2152 (setq ediff-this-buffer-ediff-sessions
2153 (delq control-buffer ediff-this-buffer-ediff-sessions))
1980 (kill-local-variable 'mode-line-buffer-identification) 2154 (kill-local-variable 'mode-line-buffer-identification)
1981 (kill-local-variable 'mode-line-format) 2155 (kill-local-variable 'mode-line-format)
1982 ) 2156 )
1983 (error)) 2157 (error))
1984 ) 2158
2159 (setq ediff-session-registry
2160 (delq ediff-control-buffer ediff-session-registry))
2161 (ediff-update-registry)
1985 ;; restore state of buffers to what it was before ediff 2162 ;; restore state of buffers to what it was before ediff
1986 (ediff-restore-protected-variables) 2163 (ediff-restore-protected-variables)
1987 ;; good place to kill buffers A/B/C 2164 ;; good place to kill buffers A/B/C
1988 (run-hooks 'ediff-cleanup-hooks) 2165 (run-hooks 'ediff-cleanup-hook)
1989 (run-hooks 'ediff-quit-hooks)) 2166 (let ((ediff-keep-variants ediff-keep-variants))
2167 (if reverse-default-keep-variants
2168 (setq ediff-keep-variants (not ediff-keep-variants)))
2169 (or ediff-keep-variants (ediff-janitor 'ask)))
2170
2171 (run-hooks 'ediff-quit-hook)
2172 (ediff-cleanup-meta-buffer meta-buffer)
2173 (if (ediff-buffer-live-p meta-buffer)
2174 (ediff-show-meta-buffer meta-buffer))
2175 ))
1990 2176
1991 2177
1992(defun ediff-delete-temp-files () 2178(defun ediff-delete-temp-files ()
@@ -2049,7 +2235,7 @@ flags of the compared file buffers, kills Ediff buffers for this session
2049 (message "") 2235 (message "")
2050 )) 2236 ))
2051 2237
2052(defun ediff-janitor () 2238(defun ediff-janitor (&optional ask)
2053 "Kill buffers A, B, and, possibly, C, if these buffers aren't modified. 2239 "Kill buffers A, B, and, possibly, C, if these buffers aren't modified.
2054In merge jobs, buffer C is never deleted. 2240In merge jobs, buffer C is never deleted.
2055However, the side effect of cleaning up may be that you cannot compare the same 2241However, the side effect of cleaning up may be that you cannot compare the same
@@ -2057,21 +2243,32 @@ buffer in two separate Ediff sessions: quitting one of them will delete this
2057buffer in another session as well." 2243buffer in another session as well."
2058 (or (not (ediff-buffer-live-p ediff-buffer-A)) 2244 (or (not (ediff-buffer-live-p ediff-buffer-A))
2059 (buffer-modified-p ediff-buffer-A) 2245 (buffer-modified-p ediff-buffer-A)
2246 (and ask
2247 (not (y-or-n-p (format "Kill buffer A [%s]? "
2248 (buffer-name ediff-buffer-A)))))
2060 (ediff-kill-buffer-carefully ediff-buffer-A)) 2249 (ediff-kill-buffer-carefully ediff-buffer-A))
2061 (or (not (ediff-buffer-live-p ediff-buffer-B)) 2250 (or (not (ediff-buffer-live-p ediff-buffer-B))
2062 (buffer-modified-p ediff-buffer-B) 2251 (buffer-modified-p ediff-buffer-B)
2252 (and ask
2253 (not (y-or-n-p (format "Kill buffer B [%s]? "
2254 (buffer-name ediff-buffer-B)))))
2063 (ediff-kill-buffer-carefully ediff-buffer-B)) 2255 (ediff-kill-buffer-carefully ediff-buffer-B))
2064 (if ediff-merge-job ; don't del buf C if merging--del ancestor buf instead 2256 (if ediff-merge-job ; don't del buf C if merging--del ancestor buf instead
2065 (or (not (ediff-buffer-live-p ediff-ancestor-buffer)) 2257 (or (not (ediff-buffer-live-p ediff-ancestor-buffer))
2066 (buffer-modified-p ediff-ancestor-buffer) 2258 (buffer-modified-p ediff-ancestor-buffer)
2259 (and ask
2260 (not (y-or-n-p (format "Kill the ancestor buffer [%s]? "
2261 (buffer-name ediff-ancestor-buffer)))))
2067 (ediff-kill-buffer-carefully ediff-ancestor-buffer)) 2262 (ediff-kill-buffer-carefully ediff-ancestor-buffer))
2068 (or (not (ediff-buffer-live-p ediff-buffer-C)) 2263 (or (not (ediff-buffer-live-p ediff-buffer-C))
2069 (buffer-modified-p ediff-buffer-C) 2264 (buffer-modified-p ediff-buffer-C)
2265 (and ask (not (y-or-n-p (format "Kill buffer C [%s]? "
2266 (buffer-name ediff-buffer-C)))))
2070 (ediff-kill-buffer-carefully ediff-buffer-C)))) 2267 (ediff-kill-buffer-carefully ediff-buffer-C))))
2071 2268
2072;; The default way of suspending Ediff. 2269;; The default way of suspending Ediff.
2073;; Buries Ediff buffers, kills all windows. 2270;; Buries Ediff buffers, kills all windows.
2074(defun ediff-default-suspend-hook () 2271(defun ediff-default-suspend-function ()
2075 (let* ((buf-A ediff-buffer-A) 2272 (let* ((buf-A ediff-buffer-A)
2076 (buf-B ediff-buffer-B) 2273 (buf-B ediff-buffer-B)
2077 (buf-C ediff-buffer-C) 2274 (buf-C ediff-buffer-C)
@@ -2123,16 +2320,19 @@ To resume, switch to the appropriate `Ediff Control Panel'
2123buffer and then type \\[ediff-recenter]. Ediff will automatically set 2320buffer and then type \\[ediff-recenter]. Ediff will automatically set
2124up an appropriate window config." 2321up an appropriate window config."
2125 (interactive) 2322 (interactive)
2126 (let ((key (substitute-command-keys "\\[ediff-recenter]"))) 2323 (ediff-barf-if-not-control-buffer)
2127 (run-hooks 'ediff-suspend-hooks) 2324 (run-hooks 'ediff-suspend-hook)
2128 (message 2325 (message
2129 "To resume, switch to Ediff Control Panel and hit `%s'" key))) 2326 "To resume, type M-x eregistry and select the desired Ediff session"))
2130 2327
2131 2328
2132(defun ediff-status-info () 2329(defun ediff-status-info ()
2133 "Show the names of the buffers or files being operated on by Ediff. 2330 "Show the names of the buffers or files being operated on by Ediff.
2134Hit \\[ediff-recenter] to reset the windows afterward." 2331Hit \\[ediff-recenter] to reset the windows afterward."
2135 (interactive) 2332 (interactive)
2333 (ediff-barf-if-not-control-buffer)
2334 (save-excursion
2335 (ediff-skip-unsuitable-frames))
2136 (with-output-to-temp-buffer " *ediff-info*" 2336 (with-output-to-temp-buffer " *ediff-info*"
2137 (princ (ediff-version)) 2337 (princ (ediff-version))
2138 (princ "\n\n") 2338 (princ "\n\n")
@@ -2155,6 +2355,16 @@ Hit \\[ediff-recenter] to reset the windows afterward."
2155 (format "File C = %S\n" buffer-file-name)) 2355 (format "File C = %S\n" buffer-file-name))
2156 (princ 2356 (princ
2157 (format "Buffer C = %S\n" (buffer-name)))))) 2357 (format "Buffer C = %S\n" (buffer-name))))))
2358 (princ (format "Customized diff output %s\n"
2359 (if (ediff-buffer-live-p ediff-custom-diff-buffer)
2360 (concat "\tin buffer "
2361 (buffer-name ediff-custom-diff-buffer))
2362 "is not available")))
2363 (princ (format "Plain diff output %s\n"
2364 (if (ediff-buffer-live-p ediff-diff-buffer)
2365 (concat "\tin buffer "
2366 (buffer-name ediff-diff-buffer))
2367 "is not available")))
2158 2368
2159 (let* ((A-line (ediff-eval-in-buffer ediff-buffer-A 2369 (let* ((A-line (ediff-eval-in-buffer ediff-buffer-A
2160 (1+ (count-lines (point-min) (point))))) 2370 (1+ (count-lines (point-min) (point)))))
@@ -2182,7 +2392,8 @@ Hit \\[ediff-recenter] to reset the windows afterward."
2182 2392
2183 (cond ((eq ediff-skip-diff-region-function 'ediff-show-all-diffs) 2393 (cond ((eq ediff-skip-diff-region-function 'ediff-show-all-diffs)
2184 (princ "\nSelective browsing by regexp is off.\n")) 2394 (princ "\nSelective browsing by regexp is off.\n"))
2185 ((eq ediff-skip-diff-region-function 'ediff-hide-regexp-matches) 2395 ((eq ediff-skip-diff-region-function
2396 ediff-hide-regexp-matches-function)
2186 (princ 2397 (princ
2187 "\nIgnoring regions that match") 2398 "\nIgnoring regions that match")
2188 (princ 2399 (princ
@@ -2190,7 +2401,8 @@ Hit \\[ediff-recenter] to reset the windows afterward."
2190 "\n\t regexp `%s' in buffer A %S\n\t regexp `%s' in buffer B\n" 2401 "\n\t regexp `%s' in buffer A %S\n\t regexp `%s' in buffer B\n"
2191 ediff-regexp-hide-A ediff-hide-regexp-connective 2402 ediff-regexp-hide-A ediff-hide-regexp-connective
2192 ediff-regexp-hide-B))) 2403 ediff-regexp-hide-B)))
2193 ((eq ediff-skip-diff-region-function 'ediff-focus-on-regexp-matches) 2404 ((eq ediff-skip-diff-region-function
2405 ediff-focus-on-regexp-matches-function)
2194 (princ 2406 (princ
2195 "\nFocusing on regions that match") 2407 "\nFocusing on regions that match")
2196 (princ 2408 (princ
@@ -2203,7 +2415,11 @@ Hit \\[ediff-recenter] to reset the windows afterward."
2203 (princ 2415 (princ
2204 (format "\nBugs/suggestions: type `%s' while in Ediff Control Panel." 2416 (format "\nBugs/suggestions: type `%s' while in Ediff Control Panel."
2205 (substitute-command-keys "\\[ediff-submit-report]"))) 2417 (substitute-command-keys "\\[ediff-submit-report]")))
2206 )) 2418 ) ; with output
2419 (if (frame-live-p ediff-control-frame)
2420 (ediff-reset-mouse ediff-control-frame))
2421 (if (window-live-p ediff-control-window)
2422 (select-window ediff-control-window)))
2207 2423
2208(defun ediff-documentation () 2424(defun ediff-documentation ()
2209 "Jump to Ediff's Info file." 2425 "Jump to Ediff's Info file."
@@ -2215,7 +2431,7 @@ Hit \\[ediff-recenter] to reset the windows afterward."
2215 (condition-case nil 2431 (condition-case nil
2216 (progn 2432 (progn
2217 (pop-to-buffer (get-buffer-create "*info*")) 2433 (pop-to-buffer (get-buffer-create "*info*"))
2218 (info "ediff") 2434 (info "ediff.info")
2219 (message "Type `i' to search for a specific topic")) 2435 (message "Type `i' to search for a specific topic"))
2220 (error (beep 1) 2436 (error (beep 1)
2221 (with-output-to-temp-buffer " *ediff-info*" 2437 (with-output-to-temp-buffer " *ediff-info*"
@@ -2228,7 +2444,7 @@ Please contact your system administrator. "
2228 (if (window-live-p ctl-window) 2444 (if (window-live-p ctl-window)
2229 (progn 2445 (progn
2230 (select-window ctl-window) 2446 (select-window ctl-window)
2231 (switch-to-buffer ctl-buf))))))) 2447 (set-window-buffer ctl-window ctl-buf)))))))
2232 2448
2233 2449
2234 2450
@@ -2255,10 +2471,14 @@ Please contact your system administrator. "
2255 (if ediff-3way-job 2471 (if ediff-3way-job
2256 (ediff-place-flags-in-buffer 2472 (ediff-place-flags-in-buffer
2257 'C ediff-buffer-C ediff-control-buffer n)) 2473 'C ediff-buffer-C ediff-control-buffer n))
2474 (if (ediff-buffer-live-p ediff-ancestor-buffer)
2475 (ediff-place-flags-in-buffer
2476 'Ancestor ediff-ancestor-buffer
2477 ediff-control-buffer n))
2258 ) 2478 )
2259 2479
2260 (ediff-install-fine-diff-if-necessary n) 2480 (ediff-install-fine-diff-if-necessary n)
2261 (run-hooks 'ediff-select-hooks)))) 2481 (run-hooks 'ediff-select-hook))))
2262 2482
2263 2483
2264;; Unselect a difference by removing the ASCII flags in the buffers. 2484;; Unselect a difference by removing the ASCII flags in the buffers.
@@ -2279,12 +2499,16 @@ Please contact your system administrator. "
2279 (ediff-remove-flags-from-buffer 2499 (ediff-remove-flags-from-buffer
2280 ediff-buffer-C 2500 ediff-buffer-C
2281 (ediff-get-diff-overlay n 'C))) 2501 (ediff-get-diff-overlay n 'C)))
2502 (if (ediff-buffer-live-p ediff-ancestor-buffer)
2503 (ediff-remove-flags-from-buffer
2504 ediff-ancestor-buffer
2505 (ediff-get-diff-overlay n 'Ancestor)))
2282 )) 2506 ))
2283 (setq ediff-highlighting-style nil) 2507 (setq ediff-highlighting-style nil)
2284 2508
2285 ;; unhighlight fine diffs 2509 ;; unhighlight fine diffs
2286 (ediff-set-fine-diff-properties ediff-current-difference 'default) 2510 (ediff-set-fine-diff-properties ediff-current-difference 'default)
2287 (run-hooks 'ediff-unselect-hooks)))) 2511 (run-hooks 'ediff-unselect-hook))))
2288 2512
2289 2513
2290;; Unselects prev diff and selects a new one, if FLAG has value other than 2514;; Unselects prev diff and selects a new one, if FLAG has value other than
@@ -2293,7 +2517,6 @@ Please contact your system administrator. "
2293;; unselected. If FLAG is 'unselect-only then the current selection is 2517;; unselected. If FLAG is 'unselect-only then the current selection is
2294;; unselected, but the next one is not selected. If NO-RECENTER is non-nil, 2518;; unselected, but the next one is not selected. If NO-RECENTER is non-nil,
2295;; don't recenter buffers after selecting/unselecting. 2519;; don't recenter buffers after selecting/unselecting.
2296;;
2297(defun ediff-unselect-and-select-difference (n &optional flag no-recenter) 2520(defun ediff-unselect-and-select-difference (n &optional flag no-recenter)
2298 (let ((ediff-current-difference n)) 2521 (let ((ediff-current-difference n))
2299 (or no-recenter 2522 (or no-recenter
@@ -2326,7 +2549,7 @@ Please contact your system administrator. "
2326 ;; hack default-dir if it is not set 2549 ;; hack default-dir if it is not set
2327 (setq default-dir 2550 (setq default-dir
2328 (file-name-as-directory 2551 (file-name-as-directory
2329 (abbreviate-file-name 2552 (ediff-abbreviate-file-name
2330 (expand-file-name (or default-dir 2553 (expand-file-name (or default-dir
2331 (and default-file 2554 (and default-file
2332 (file-name-directory default-file)) 2555 (file-name-directory default-file))
@@ -2363,11 +2586,11 @@ Please contact your system administrator. "
2363 f)) 2586 f))
2364 2587
2365;; If `prefix' is given, then it is used as a prefix for the temp file 2588;; If `prefix' is given, then it is used as a prefix for the temp file
2366;; name. Otherwise, `_buffer-name' is used. If `file' is given, use this 2589;; name. Otherwise, `ediff_' is used. If `file' is given, use this
2367;; file and don't create a new one. 2590;; file and don't create a new one.
2368;; Also, save buffer from START to END in the file. 2591;; Also, save buffer from START to END in the file.
2369;; START defaults to (point-min), END to (point-max) 2592;; START defaults to (point-min), END to (point-max)
2370(defun ediff-make-temp-file (&optional prefix given-file start end) 2593(defun ediff-make-temp-file (buff &optional prefix given-file start end)
2371 (let ((f (or given-file 2594 (let ((f (or given-file
2372 (make-temp-name (concat 2595 (make-temp-name (concat
2373 ediff-temp-file-prefix 2596 ediff-temp-file-prefix
@@ -2375,25 +2598,26 @@ Please contact your system administrator. "
2375 (concat prefix "_") 2598 (concat prefix "_")
2376 "ediff_")))))) 2599 "ediff_"))))))
2377 ;; create the file 2600 ;; create the file
2378 (write-region (if start start (point-min)) 2601 (ediff-eval-in-buffer buff
2379 (if end end (point-max)) 2602 (write-region (if start start (point-min))
2380 f 2603 (if end end (point-max))
2381 nil ; don't append---erase 2604 f
2382 'no-message) 2605 nil ; don't append---erase
2383 (set-file-modes f ediff-temp-file-mode) 2606 'no-message)
2384 f)) 2607 (set-file-modes f ediff-temp-file-mode)
2608 f)))
2385 2609
2386;; Quote metacharacters (using \) when executing diff in Unix, but not in 2610;; Quote metacharacters (using \) when executing diff in Unix, but not in
2387;; EMX OS/2 2611;; EMX OS/2
2388(defun ediff-protect-metachars (str) 2612;;(defun ediff-protect-metachars (str)
2389 (or (memq system-type '(emx vax-vms axp-vms)) 2613;; (or (memq system-type '(emx vax-vms axp-vms))
2390 (let ((limit 0)) 2614;; (let ((limit 0))
2391 (while (string-match ediff-metachars str limit) 2615;; (while (string-match ediff-metachars str limit)
2392 (setq str (concat (substring str 0 (match-beginning 0)) 2616;; (setq str (concat (substring str 0 (match-beginning 0))
2393 "\\" 2617;; "\\"
2394 (substring str (match-beginning 0)))) 2618;; (substring str (match-beginning 0))))
2395 (setq limit (1+ (match-end 0)))))) 2619;; (setq limit (1+ (match-end 0))))))
2396 str) 2620;; str)
2397 2621
2398;; Make sure the current buffer (for a file) has the same contents as the 2622;; Make sure the current buffer (for a file) has the same contents as the
2399;; file on disk, and attempt to remedy the situation if not. 2623;; file on disk, and attempt to remedy the situation if not.
@@ -2433,15 +2657,6 @@ Please contact your system administrator. "
2433 2657
2434 2658
2435 2659
2436(defun ediff-check-for-ascii-flags ()
2437 (eval
2438 (cons 'or
2439 (mapcar (function (lambda (buf)
2440 (if (ediff-buffer-live-p buf)
2441 (ediff-eval-in-buffer buf
2442 (eq ediff-highlighting-style 'ascii)))))
2443 ediff-this-buffer-control-sessions))))
2444
2445;; It would be nice to use these two functions as hooks instead of 2660;; It would be nice to use these two functions as hooks instead of
2446;; ediff-insert-in-front and ediff-move-disturbed-overlays. 2661;; ediff-insert-in-front and ediff-move-disturbed-overlays.
2447;; However, Emacs has a bug that causes BEG and END, below, to be 2662;; However, Emacs has a bug that causes BEG and END, below, to be
@@ -2451,14 +2666,14 @@ Please contact your system administrator. "
2451;; the overlay end. 2666;; the overlay end.
2452;; Either this bug is fixed, or (better) use sticky overlays when they will 2667;; Either this bug is fixed, or (better) use sticky overlays when they will
2453;; be implemented in Emacs, like they are in XEmacs. 2668;; be implemented in Emacs, like they are in XEmacs.
2454;;(defun ediff-capture-inserts-in-front (overl beg end) 2669;;(defun ediff-capture-inserts-in-front (overl flag beg end &optional len)
2455;; (if (ediff-overlay-get overl 'ediff-diff-num) 2670;; (if (and flag (ediff-overlay-get overl 'ediff-diff-num))
2456;; (ediff-move-overlay 2671;; (ediff-move-overlay overl beg (ediff-overlay-end overl))
2457;; overl beg (+ (- end beg) (ediff-overlay-end overl))) 2672;; ))
2458;; )) 2673;;
2459;;(defun ediff-capture-inserts-behind (overl beg end) 2674;;(defun ediff-capture-inserts-behind (overl flag beg end &optional len)
2460;; (if (ediff-overlay-get overl 'ediff-diff-num) 2675;; (if (and flag (ediff-overlay-get overl 'ediff-diff-num))
2461;; (ediff-move-overlay overl (ediff-overlay-start overl) end)) 2676;; (ediff-move-overlay overl (ediff-overlay-start overl) (point))
2462;; )) 2677;; ))
2463 2678
2464;; to be deleted in due time 2679;; to be deleted in due time
@@ -2487,17 +2702,70 @@ Please contact your system administrator. "
2487(defun ediff-save-buffer (arg) 2702(defun ediff-save-buffer (arg)
2488 "Safe way of saving buffers A, B, C, and the diff output. 2703 "Safe way of saving buffers A, B, C, and the diff output.
2489`wa' saves buffer A, `wb' saves buffer B, `wc' saves buffer C, 2704`wa' saves buffer A, `wb' saves buffer B, `wc' saves buffer C,
2490and `wd' saves the diff output." 2705and `wd' saves the diff output.
2706
2707With prefix argument, `wd' saves plain diff output.
2708Without an argument, it saves customized diff argument, if available
2709\(and plain output, if customized output was not generated\)."
2491 (interactive "P") 2710 (interactive "P")
2711 (ediff-barf-if-not-control-buffer)
2712 (ediff-compute-custom-diffs-maybe)
2492 (ediff-eval-in-buffer 2713 (ediff-eval-in-buffer
2493 (cond ((memq last-command-char '(?a ?b ?c)) 2714 (cond ((memq last-command-char '(?a ?b ?c))
2494 (ediff-get-buffer 2715 (ediff-get-buffer
2495 (ediff-char-to-buftype last-command-char))) 2716 (ediff-char-to-buftype last-command-char)))
2496 ((eq last-command-char ?d) 2717 ((eq last-command-char ?d)
2497 (message "Saving diff output ...")(sit-for 1) 2718 (message "Saving diff output ...")
2498 (if arg ediff-diff-buffer ediff-custom-diff-buffer) 2719 (sit-for 1) ; let the user see the message
2499 )) 2720 (cond ((and arg (ediff-buffer-live-p ediff-diff-buffer))
2721 ediff-diff-buffer)
2722 ((ediff-buffer-live-p ediff-custom-diff-buffer)
2723 ediff-custom-diff-buffer)
2724 ((ediff-buffer-live-p ediff-diff-buffer)
2725 ediff-diff-buffer)
2726 (t (error "Output from `diff' not found"))))
2727 )
2500 (save-buffer))) 2728 (save-buffer)))
2729
2730(defun ediff-compute-custom-diffs-maybe ()
2731 (or ediff-3way-job
2732 (let ((file-A (ediff-make-temp-file ediff-buffer-A))
2733 (file-B (ediff-make-temp-file ediff-buffer-B)))
2734 (or (ediff-buffer-live-p ediff-custom-diff-buffer)
2735 (setq ediff-custom-diff-buffer
2736 (get-buffer-create
2737 (ediff-unique-buffer-name "*ediff-custom-diff" "*"))))
2738 (ediff-exec-process
2739 ediff-custom-diff-program ediff-custom-diff-buffer 'synchronize
2740 ediff-custom-diff-options file-A file-B))))
2741
2742(defun ediff-show-diff-output (arg)
2743 (interactive "P")
2744 (ediff-barf-if-not-control-buffer)
2745 (ediff-compute-custom-diffs-maybe)
2746 (save-excursion
2747 (ediff-skip-unsuitable-frames ' ok-unsplittable))
2748 (let ((buf (cond ((and arg (ediff-buffer-live-p ediff-diff-buffer))
2749 ediff-diff-buffer)
2750 ((ediff-buffer-live-p ediff-custom-diff-buffer)
2751 ediff-custom-diff-buffer)
2752 ((ediff-buffer-live-p ediff-diff-buffer)
2753 ediff-diff-buffer)
2754 (t
2755 (beep)
2756 (message "Output from `diff' not found")
2757 nil))))
2758 (if buf
2759 (progn
2760 (ediff-eval-in-buffer buf
2761 (goto-char (point-min)))
2762 (switch-to-buffer buf)
2763 (raise-frame (selected-frame)))))
2764 (if (frame-live-p ediff-control-frame)
2765 (ediff-reset-mouse ediff-control-frame))
2766 (if (window-live-p ediff-control-window)
2767 (select-window ediff-control-window)))
2768
2501 2769
2502 2770
2503;; will simplify it in due time, when emacs acquires before/after strings 2771;; will simplify it in due time, when emacs acquires before/after strings
@@ -2585,7 +2853,9 @@ buffer."
2585 (1+ n) ediff-number-of-differences) 2853 (1+ n) ediff-number-of-differences)
2586 (error "No differences found"))) 2854 (error "No differences found")))
2587 (setq diff-overlay (ediff-get-diff-overlay n buf-type))) 2855 (setq diff-overlay (ediff-get-diff-overlay n buf-type)))
2588 2856 (if (not (ediff-buffer-live-p (ediff-overlay-buffer diff-overlay)))
2857 (error
2858 "You have killed an essential Ediff buffer---Please exit Ediff"))
2589 (if (eq pos 'beg) 2859 (if (eq pos 'beg)
2590 (ediff-overlay-start diff-overlay) 2860 (ediff-overlay-start diff-overlay)
2591 (ediff-overlay-end diff-overlay)) 2861 (ediff-overlay-end diff-overlay))
@@ -2604,16 +2874,6 @@ buffer."
2604 (current-diff-overlay 2874 (current-diff-overlay
2605 (symbol-value 2875 (symbol-value
2606 (intern (format "ediff-current-diff-overlay-%S" buf-type)))) 2876 (intern (format "ediff-current-diff-overlay-%S" buf-type))))
2607 (odd-diff-face
2608 (symbol-value
2609 (intern (format "ediff-odd-diff-face-%S" buf-type))))
2610 (even-diff-face
2611 (symbol-value
2612 (intern (format "ediff-even-diff-face-%S" buf-type))))
2613 (odd-diff-face-var
2614 (intern (format "ediff-odd-diff-face-%S-var" buf-type)))
2615 (even-diff-face-var
2616 (intern (format "ediff-even-diff-face-%S-var" buf-type)))
2617 ) 2877 )
2618 2878
2619 (if ediff-xemacs-p 2879 (if ediff-xemacs-p
@@ -2624,16 +2884,11 @@ buffer."
2624 (ediff-overlay-put current-diff-overlay 'priority 0) 2884 (ediff-overlay-put current-diff-overlay 'priority 0)
2625 (ediff-overlay-put current-diff-overlay 'priority 2885 (ediff-overlay-put current-diff-overlay 'priority
2626 (ediff-highest-priority begin end-hilit buff)) 2886 (ediff-highest-priority begin end-hilit buff))
2887 (ediff-overlay-put current-diff-overlay 'ediff-diff-num n)
2627 2888
2628 (or (face-differs-from-default-p odd-diff-face-var) 2889 ;; unhighlight the background overlay for diff n so it won't
2629 (not ediff-highlight-all-diffs)
2630 (progn
2631 (copy-face odd-diff-face odd-diff-face-var)
2632 (copy-face even-diff-face even-diff-face-var)))
2633
2634 ;; unhighlight the background overlay for diff n so they won't
2635 ;; interfere with the current diff overlay 2890 ;; interfere with the current diff overlay
2636 (ediff-overlay-put (ediff-get-diff-overlay n buf-type) 'face nil) 2891 (ediff-set-overlay-face (ediff-get-diff-overlay n buf-type) nil)
2637 ))) 2892 )))
2638 2893
2639 2894
@@ -2642,10 +2897,6 @@ buffer."
2642 (let ((current-diff-overlay 2897 (let ((current-diff-overlay
2643 (symbol-value 2898 (symbol-value
2644 (intern (format "ediff-current-diff-overlay-%S" buf-type)))) 2899 (intern (format "ediff-current-diff-overlay-%S" buf-type))))
2645 (odd-diff-face-var
2646 (intern (format "ediff-odd-diff-face-%S-var" buf-type)))
2647 (even-diff-face-var
2648 (intern (format "ediff-even-diff-face-%S-var" buf-type)))
2649 (overlay 2900 (overlay
2650 (ediff-get-diff-overlay ediff-current-difference buf-type)) 2901 (ediff-get-diff-overlay ediff-current-difference buf-type))
2651 ) 2902 )
@@ -2654,10 +2905,11 @@ buffer."
2654 2905
2655 ;; rehighlight the overlay in the background of the 2906 ;; rehighlight the overlay in the background of the
2656 ;; current difference region 2907 ;; current difference region
2657 (ediff-overlay-put overlay 2908 (ediff-set-overlay-face
2658 'face (if (ediff-odd-p ediff-current-difference) 2909 overlay
2659 odd-diff-face-var 2910 (if (and (ediff-window-display-p)
2660 even-diff-face-var)) 2911 ediff-use-faces ediff-highlight-all-diffs)
2912 (ediff-background-face buf-type ediff-current-difference)))
2661 ))) 2913 )))
2662 2914
2663(defun ediff-unhighlight-diffs-totally-in-one-buffer (buf-type) 2915(defun ediff-unhighlight-diffs-totally-in-one-buffer (buf-type)
@@ -2666,15 +2918,8 @@ buffer."
2666 (let* ((inhibit-quit t) 2918 (let* ((inhibit-quit t)
2667 (current-diff-overlay-var 2919 (current-diff-overlay-var
2668 (intern (format "ediff-current-diff-overlay-%S" buf-type))) 2920 (intern (format "ediff-current-diff-overlay-%S" buf-type)))
2669 (current-diff-overlay (symbol-value current-diff-overlay-var)) 2921 (current-diff-overlay (symbol-value current-diff-overlay-var)))
2670 (odd-diff-face-var 2922 (ediff-color-background-regions 'unhighlight)
2671 (intern (format "ediff-odd-diff-face-%S-var" buf-type)))
2672 (even-diff-face-var
2673 (intern (format "ediff-even-diff-face-%S-var" buf-type))))
2674 (if (face-differs-from-default-p odd-diff-face-var)
2675 (progn
2676 (copy-face 'default odd-diff-face-var)
2677 (copy-face 'default even-diff-face-var)))
2678 (if (ediff-overlayp current-diff-overlay) 2923 (if (ediff-overlayp current-diff-overlay)
2679 (ediff-delete-overlay current-diff-overlay)) 2924 (ediff-delete-overlay current-diff-overlay))
2680 (set current-diff-overlay-var nil) 2925 (set current-diff-overlay-var nil)
@@ -2696,7 +2941,31 @@ buffer."
2696 (symbol-value vec-var))) 2941 (symbol-value vec-var)))
2697 ;; allow them to be garbage collected 2942 ;; allow them to be garbage collected
2698 (set vec-var nil)) 2943 (set vec-var nil))
2699 2944
2945(defun ediff-color-background-regions (&optional unhighlight)
2946 (ediff-color-background-regions-in-one-buffer
2947 'A unhighlight)
2948 (ediff-color-background-regions-in-one-buffer
2949 'B unhighlight)
2950 (ediff-color-background-regions-in-one-buffer
2951 'C unhighlight)
2952 (ediff-color-background-regions-in-one-buffer
2953 'Ancestor unhighlight))
2954
2955(defun ediff-color-background-regions-in-one-buffer (buf-type unhighlight)
2956 (let ((diff-vector
2957 (eval (intern (format "ediff-difference-vector-%S" buf-type))))
2958 overl diff-num)
2959 (mapcar (function
2960 (lambda (rec)
2961 (setq overl (ediff-get-diff-overlay-from-diff-record rec)
2962 diff-num (ediff-overlay-get overl 'ediff-diff-num))
2963 (ediff-set-overlay-face
2964 overl
2965 (if (not unhighlight)
2966 (ediff-background-face buf-type diff-num))
2967 )))
2968 diff-vector)))
2700 2969
2701 2970
2702;;; Misc 2971;;; Misc
@@ -2746,19 +3015,23 @@ Checks if overlay's buffer exists."
2746 (if ediff-xemacs-p 3015 (if ediff-xemacs-p
2747 (progn 3016 (progn
2748 ;; take precautions against detached extents 3017 ;; take precautions against detached extents
2749 (ediff-overlay-put overl 'detachable nil) 3018 (ediff-overlay-put overl 'detachable nil)
2750 ;; chars inserted at both ends will be inside extent 3019 ;; chars inserted at both ends will be inside extent
2751 (ediff-overlay-put overl 'start-open nil) 3020 (ediff-overlay-put overl 'start-open nil)
2752 (ediff-overlay-put overl 'end-open nil)) 3021 (ediff-overlay-put overl 'end-open nil))
2753 (ediff-overlay-put overl 'ediff-diff-num 0) 3022 (ediff-overlay-put overl 'evaporate nil) ; don't detach
3023 ;; doesn't work since emacs buggily doesn't call these functions
3024 ;; after the change
2754 ;;(ediff-overlay-put overl 'insert-in-front-hooks 3025 ;;(ediff-overlay-put overl 'insert-in-front-hooks
2755 ;; (list 'ediff-capture-inserts-in-front)) 3026 ;; '(ediff-capture-inserts-in-front))
2756 ;;(ediff-overlay-put overl 'insert-behind-hooks 3027 ;;(ediff-overlay-put overl 'insert-behind-hooks
2757 ;; (list 'ediff-capture-inserts-behind)) 3028 ;; '(ediff-capture-inserts-behind))
3029
2758 ;; These two are not yet implemented in Emacs 3030 ;; These two are not yet implemented in Emacs
2759 ;;(ediff-overlay-put overl 'rear-sticky t) 3031 (ediff-overlay-put overl 'rear-sticky t)
2760 ;;(ediff-overlay-put overl 'front-sticky t) 3032 (ediff-overlay-put overl 'front-sticky t)
2761 ) 3033 )
3034 (ediff-overlay-put overl 'ediff-diff-num 0)
2762 overl)))) 3035 overl))))
2763 3036
2764(defsubst ediff-overlay-start (overl) 3037(defsubst ediff-overlay-start (overl)
@@ -2823,9 +3096,26 @@ Checks if overlay's buffer exists."
2823 (format "%s<%d>%s" prefix n suffix)))) 3096 (format "%s<%d>%s" prefix n suffix))))
2824 3097
2825 3098
3099;; splits at a white space, returns a list
3100(defun ediff-split-string (string)
3101 (let ((start 0)
3102 (result '())
3103 substr)
3104 (while (string-match "[ \t]+" string start)
3105 (let ((match (string-match "[ \t]+" string start)))
3106 (setq substr (substring string start match))
3107 (if (> (length substr) 0)
3108 (setq result (cons substr result)))
3109 (setq start (match-end 0))))
3110 (setq substr (substring string start nil))
3111 (if (> (length substr) 0)
3112 (setq result (cons substr result)))
3113 (nreverse result)))
3114
2826(defun ediff-submit-report () 3115(defun ediff-submit-report ()
2827 "Submit bug report on Ediff." 3116 "Submit bug report on Ediff."
2828 (interactive) 3117 (interactive)
3118 (ediff-barf-if-not-control-buffer)
2829 (let ((reporter-prompt-for-summary-p t) 3119 (let ((reporter-prompt-for-summary-p t)
2830 (ctl-buf ediff-control-buffer) 3120 (ctl-buf ediff-control-buffer)
2831 (ediff-device-type (ediff-device-type)) 3121 (ediff-device-type (ediff-device-type))
@@ -2916,24 +3206,6 @@ Mail anyway? (y or n) ")
2916 )) 3206 ))
2917 3207
2918 3208
2919(defun ediff-union (list1 list2)
2920 "Combine LIST1 and LIST2 using a set-union operation.
2921The result list contains all items that appear in either LIST1 or LIST2.
2922This is a non-destructive function; it makes a copy of the data if necessary
2923to avoid corrupting the original LIST1 and LIST2.
2924This is a slightly simplified version from `cl-seq.el'. Added here to
2925avoid loading cl-*."
2926 (cond ((null list1) list2) ((null list2) list1)
2927 ((equal list1 list2) list1)
2928 (t
2929 (or (>= (length list1) (length list2))
2930 (setq list1 (prog1 list2 (setq list2 list1))))
2931 (while list2
2932 (or (memq (car list2) list1)
2933 (setq list1 (cons (car list2) list1)))
2934 (setq list2 (cdr list2)))
2935 list1)))
2936
2937(defun ediff-deactivate-mark () 3209(defun ediff-deactivate-mark ()
2938 (if ediff-xemacs-p 3210 (if ediff-xemacs-p
2939 (zmacs-deactivate-region) 3211 (zmacs-deactivate-region)
@@ -2974,6 +3246,7 @@ avoid loading cl-*."
2974 (while vars 3246 (while vars
2975 (set (car vars) (cdr (assoc (car vars) assoc-list))) 3247 (set (car vars) (cdr (assoc (car vars) assoc-list)))
2976 (setq vars (cdr vars)))) 3248 (setq vars (cdr vars))))
3249
2977(defun ediff-change-saved-variable (var value buf-type) 3250(defun ediff-change-saved-variable (var value buf-type)
2978 (let* ((assoc-list 3251 (let* ((assoc-list
2979 (symbol-value (intern 3252 (symbol-value (intern
@@ -2995,20 +3268,29 @@ avoid loading cl-*."
2995 (if ediff-3way-comparison-job 3268 (if ediff-3way-comparison-job
2996 (setq ediff-buffer-values-orig-C 3269 (setq ediff-buffer-values-orig-C
2997 (ediff-eval-in-buffer ediff-buffer-C 3270 (ediff-eval-in-buffer ediff-buffer-C
3271 (ediff-save-variables ediff-protected-variables))))
3272 (if (ediff-buffer-live-p ediff-ancestor-buffer)
3273 (setq ediff-buffer-values-orig-Ancestor
3274 (ediff-eval-in-buffer ediff-ancestor-buffer
2998 (ediff-save-variables ediff-protected-variables))))) 3275 (ediff-save-variables ediff-protected-variables)))))
2999 3276
3000;; must execute in control buf 3277;; must execute in control buf
3001(defun ediff-restore-protected-variables () 3278(defun ediff-restore-protected-variables ()
3002 (let ((values-A ediff-buffer-values-orig-A) 3279 (let ((values-A ediff-buffer-values-orig-A)
3003 (values-B ediff-buffer-values-orig-B) 3280 (values-B ediff-buffer-values-orig-B)
3004 (values-C ediff-buffer-values-orig-C)) 3281 (values-C ediff-buffer-values-orig-C)
3005 (ediff-eval-in-buffer ediff-buffer-A 3282 (values-Ancestor ediff-buffer-values-orig-Ancestor))
3006 (ediff-restore-variables ediff-protected-variables values-A)) 3283 (ediff-eval-in-buffer ediff-buffer-A
3007 (ediff-eval-in-buffer ediff-buffer-B 3284 (ediff-restore-variables ediff-protected-variables values-A))
3008 (ediff-restore-variables ediff-protected-variables values-B)) 3285 (ediff-eval-in-buffer ediff-buffer-B
3009 (if ediff-3way-comparison-job 3286 (ediff-restore-variables ediff-protected-variables values-B))
3010 (ediff-eval-in-buffer ediff-buffer-C 3287 (if ediff-3way-comparison-job
3011 (ediff-restore-variables ediff-protected-variables values-C))))) 3288 (ediff-eval-in-buffer ediff-buffer-C
3289 (ediff-restore-variables ediff-protected-variables values-C)))
3290 (if (ediff-buffer-live-p ediff-ancestor-buffer)
3291 (ediff-eval-in-buffer ediff-ancestor-buffer
3292 (ediff-restore-variables ediff-protected-variables values-Ancestor)))
3293 ))
3012 3294
3013 3295
3014;;; Debug 3296;;; Debug
@@ -3033,18 +3315,20 @@ avoid loading cl-*."
3033(defun ediff-profile () 3315(defun ediff-profile ()
3034 "Toggle profiling Ediff commands." 3316 "Toggle profiling Ediff commands."
3035 (interactive) 3317 (interactive)
3036 (or (ediff-buffer-live-p ediff-control-buffer) 3318 (ediff-barf-if-not-control-buffer)
3037 (error "This command runs only out of Ediff Control Buffer")) 3319 (if ediff-emacs-p
3038 (make-local-hook 'pre-command-hook) 3320 (make-local-variable 'post-command-hook))
3039 (make-local-hook 'post-command-hook) 3321 (let ((pre-hook (if ediff-emacs-p 'pre-command-hook 'local-pre-command-hook))
3040 (if (memq 'ediff-save-time pre-command-hook) 3322 (post-hook
3041 (progn (remove-hook 'pre-command-hook 'ediff-save-time t) 3323 (if ediff-emacs-p 'post-command-hook 'local-post-command-hook)))
3042 (remove-hook 'post-command-hook 'ediff-calc-command-time t) 3324 (if (not (equal ediff-command-begin-time '(0 0 0)))
3043 (setq ediff-command-begin-time '(0 0 0)) 3325 (progn (remove-hook pre-hook 'ediff-save-time)
3044 (message "Ediff profiling disabled")) 3326 (remove-hook post-hook 'ediff-calc-command-time)
3045 (add-hook 'pre-command-hook 'ediff-save-time t t) 3327 (setq ediff-command-begin-time '(0 0 0))
3046 (add-hook 'post-command-hook 'ediff-calc-command-time nil t) 3328 (message "Ediff profiling disabled"))
3047 (message "Ediff profiling enabled"))) 3329 (add-hook pre-hook 'ediff-save-time t)
3330 (add-hook post-hook 'ediff-calc-command-time)
3331 (message "Ediff profiling enabled"))))
3048 3332
3049(defun ediff-print-diff-vector (diff-vector-var) 3333(defun ediff-print-diff-vector (diff-vector-var)
3050 (princ (format "\n*** %S ***\n" diff-vector-var)) 3334 (princ (format "\n*** %S ***\n" diff-vector-var))
@@ -3075,19 +3359,19 @@ avoid loading cl-*."
3075 3359
3076(defun ediff-debug-info () 3360(defun ediff-debug-info ()
3077 (interactive) 3361 (interactive)
3078 (or (ediff-buffer-live-p ediff-control-buffer) 3362 (ediff-barf-if-not-control-buffer)
3079 (error "This command runs only out of Ediff Control Buffer"))
3080 (with-output-to-temp-buffer ediff-debug-buffer 3363 (with-output-to-temp-buffer ediff-debug-buffer
3081 (princ (format "\nCtl buffer: %S\n" ediff-control-buffer)) 3364 (princ (format "\nCtl buffer: %S\n" ediff-control-buffer))
3082 (ediff-print-diff-vector (intern (concat "ediff-difference-vector-" "A"))) 3365 (ediff-print-diff-vector (intern "ediff-difference-vector-A"))
3083 (ediff-print-diff-vector (intern (concat "ediff-difference-vector-" "B"))) 3366 (ediff-print-diff-vector (intern "ediff-difference-vector-B"))
3084 (ediff-print-diff-vector (intern (concat "ediff-difference-vector-" "C"))) 3367 (ediff-print-diff-vector (intern "ediff-difference-vector-C"))
3368 (ediff-print-diff-vector (intern "ediff-difference-vector-Ancestor"))
3085 )) 3369 ))
3086 3370
3087;; don't report error if version control package wasn't found 3371;; don't report error if version control package wasn't found
3088;;(ediff-load-version-control 'silent) 3372;;(ediff-load-version-control 'silent)
3089 3373
3090(run-hooks 'ediff-load-hooks) 3374(run-hooks 'ediff-load-hook)
3091 3375
3092 3376
3093;;; Local Variables: 3377;;; Local Variables: