aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kifer1997-11-01 01:46:51 +0000
committerMichael Kifer1997-11-01 01:46:51 +0000
commit328b4b7052a5d464e52818ff0f1a33b96e5e761c (patch)
treeed5b2b58f632de47cdcc20435b0dfeed3d5c7f4e
parent9645c179af0e934c92780525788664e42c56e07a (diff)
downloademacs-328b4b7052a5d464e52818ff0f1a33b96e5e761c.tar.gz
emacs-328b4b7052a5d464e52818ff0f1a33b96e5e761c.zip
new version
-rw-r--r--lisp/ediff-diff.el10
-rw-r--r--lisp/ediff-hook.el9
-rw-r--r--lisp/ediff-init.el78
-rw-r--r--lisp/ediff-merg.el7
-rw-r--r--lisp/ediff-mult.el515
-rw-r--r--lisp/ediff-util.el70
-rw-r--r--lisp/ediff-vers.el33
-rw-r--r--lisp/ediff.el73
-rw-r--r--lisp/emulation/viper-ex.el25
-rw-r--r--lisp/emulation/viper-init.el16
-rw-r--r--lisp/emulation/viper-keym.el3
-rw-r--r--lisp/emulation/viper-mous.el11
-rw-r--r--lisp/emulation/viper.el26
13 files changed, 627 insertions, 249 deletions
diff --git a/lisp/ediff-diff.el b/lisp/ediff-diff.el
index fffd99a96ef..a12959eea12 100644
--- a/lisp/ediff-diff.el
+++ b/lisp/ediff-diff.el
@@ -59,6 +59,11 @@ to a shell that you are not using or, better, fix your shell's startup file."
59 :type 'string 59 :type 'string
60 :group 'ediff-diff) 60 :group 'ediff-diff)
61 61
62(defcustom ediff-cmp-program "cmp"
63 "*Utility to use to determine if two files are identical.
64It must return code 0, if its arguments are identical files."
65 :type 'string
66 :group 'ediff-diff)
62 67
63(defcustom ediff-diff-program "diff" 68(defcustom ediff-diff-program "diff"
64 "*Program to use for generating the differential of the two files." 69 "*Program to use for generating the differential of the two files."
@@ -1235,6 +1240,11 @@ argument to `skip-chars-forward'."
1235 (funcall fwd-word-fun)) 1240 (funcall fwd-word-fun))
1236 (point)))) 1241 (point))))
1237 1242
1243(defun ediff-same-file-contents (f1 f2)
1244 "T if F1 and F2 have identical contents."
1245 (let ((res (call-process ediff-cmp-program nil nil nil f1 f2)))
1246 (and (numberp res) (eq res 0))))
1247
1238 1248
1239;;; Local Variables: 1249;;; Local Variables:
1240;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun) 1250;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
diff --git a/lisp/ediff-hook.el b/lisp/ediff-hook.el
index eb8f6e8c453..0d412d4d40f 100644
--- a/lisp/ediff-hook.el
+++ b/lisp/ediff-hook.el
@@ -126,10 +126,11 @@
126 )) 126 ))
127 127
128 ;; put these menus before Object-Oriented-Browser in Tools menu 128 ;; put these menus before Object-Oriented-Browser in Tools menu
129 (add-hook 'before-init-hook 'ediff-xemacs-init-menus) 129;; (add-hook 'before-init-hook 'ediff-xemacs-init-menus)
130 (if (not purify-flag) 130;; (if (not purify-flag)
131 (ediff-xemacs-init-menus)) 131;; (ediff-xemacs-init-menus))
132 ) 132;; )
133 (ediff-xemacs-init-menus))
133 134
134 ;; Emacs--only if menu-bar is loaded 135 ;; Emacs--only if menu-bar is loaded
135 ((featurep 'menu-bar) 136 ((featurep 'menu-bar)
diff --git a/lisp/ediff-init.el b/lisp/ediff-init.el
index 184a8ae5f93..77e8f1c9ad6 100644
--- a/lisp/ediff-init.el
+++ b/lisp/ediff-init.el
@@ -346,6 +346,21 @@ that Ediff doesn't know about.")
346 (error "%S: This command runs in Ediff Control Buffer only!" 346 (error "%S: This command runs in Ediff Control Buffer only!"
347 this-command))) 347 this-command)))
348 348
349(defgroup ediff-highlighting nil
350 "Hilighting of difference regions in Ediff"
351 :prefix "ediff-"
352 :group 'ediff)
353
354(defgroup ediff-merge nil
355 "Merging utilities"
356 :prefix "ediff-"
357 :group 'ediff)
358
359(defgroup ediff-hook nil
360 "Hooks called by Ediff"
361 :prefix "ediff-"
362 :group 'ediff)
363
349;; Hook variables 364;; Hook variables
350 365
351(defcustom ediff-before-setup-windows-hook nil 366(defcustom ediff-before-setup-windows-hook nil
@@ -353,74 +368,74 @@ that Ediff doesn't know about.")
353This can be used to save the previous window config, which can be restored 368This can be used to save the previous window config, which can be restored
354on ediff-quit or ediff-suspend." 369on ediff-quit or ediff-suspend."
355 :type 'hook 370 :type 'hook
356 :group 'ediff) 371 :group 'ediff-hook)
357(defcustom ediff-after-setup-windows-hook nil 372(defcustom ediff-after-setup-windows-hook nil
358 "*Hooks to run after Ediff sets its window configuration. 373 "*Hooks to run after Ediff sets its window configuration.
359This can be used to set up control window or icon in a desired place." 374This can be used to set up control window or icon in a desired place."
360 :type 'hook 375 :type 'hook
361 :group 'ediff) 376 :group 'ediff-hook)
362(defcustom ediff-before-setup-control-frame-hook nil 377(defcustom ediff-before-setup-control-frame-hook nil
363 "*Hooks run before setting up the frame to display Ediff Control Panel. 378 "*Hooks run before setting up the frame to display Ediff Control Panel.
364Can be used to change control frame parameters to position it where it 379Can be used to change control frame parameters to position it where it
365is desirable." 380is desirable."
366 :type 'hook 381 :type 'hook
367 :group 'ediff) 382 :group 'ediff-hook)
368(defcustom ediff-after-setup-control-frame-hook nil 383(defcustom ediff-after-setup-control-frame-hook nil
369 "*Hooks run after setting up the frame to display Ediff Control Panel. 384 "*Hooks run after setting up the frame to display Ediff Control Panel.
370Can be used to move the frame where it is desired." 385Can be used to move the frame where it is desired."
371 :type 'hook 386 :type 'hook
372 :group 'ediff) 387 :group 'ediff-hook)
373(defcustom ediff-startup-hook nil 388(defcustom ediff-startup-hook nil
374 "*Hooks to run in the control buffer after Ediff has been set up." 389 "*Hooks to run in the control buffer after Ediff has been set up."
375 :type 'hook 390 :type 'hook
376 :group 'ediff) 391 :group 'ediff-hook)
377(defcustom ediff-select-hook nil 392(defcustom ediff-select-hook nil
378 "*Hooks to run after a difference has been selected." 393 "*Hooks to run after a difference has been selected."
379 :type 'hook 394 :type 'hook
380 :group 'ediff) 395 :group 'ediff-hook)
381(defcustom ediff-unselect-hook nil 396(defcustom ediff-unselect-hook nil
382 "*Hooks to run after a difference has been unselected." 397 "*Hooks to run after a difference has been unselected."
383 :type 'hook 398 :type 'hook
384 :group 'ediff) 399 :group 'ediff-hook)
385(defcustom ediff-prepare-buffer-hook nil 400(defcustom ediff-prepare-buffer-hook nil
386 "*Hooks called after buffers A, B, and C are set up." 401 "*Hooks called after buffers A, B, and C are set up."
387 :type 'hook 402 :type 'hook
388 :group 'ediff) 403 :group 'ediff-hook)
389(defcustom ediff-load-hook nil 404(defcustom ediff-load-hook nil
390 "*Hook run after Ediff is loaded. Can be used to change defaults." 405 "*Hook run after Ediff is loaded. Can be used to change defaults."
391 :type 'hook 406 :type 'hook
392 :group 'ediff) 407 :group 'ediff-hook)
393 408
394(defcustom ediff-mode-hook nil 409(defcustom ediff-mode-hook nil
395 "*Hook run just after ediff-mode is set up in the control buffer. 410 "*Hook run just after ediff-mode is set up in the control buffer.
396This is done before any windows or frames are created. One can use it to 411This is done before any windows or frames are created. One can use it to
397set local variables that determine how the display looks like." 412set local variables that determine how the display looks like."
398 :type 'hook 413 :type 'hook
399 :group 'ediff) 414 :group 'ediff-hook)
400(defcustom ediff-keymap-setup-hook nil 415(defcustom ediff-keymap-setup-hook nil
401 "*Hook run just after the default bindings in Ediff keymap are set up." 416 "*Hook run just after the default bindings in Ediff keymap are set up."
402 :type 'hook 417 :type 'hook
403 :group 'ediff) 418 :group 'ediff-hook)
404 419
405(defcustom ediff-display-help-hook nil 420(defcustom ediff-display-help-hook nil
406 "*Hooks run after preparing the help message." 421 "*Hooks run after preparing the help message."
407 :type 'hook 422 :type 'hook
408 :group 'ediff) 423 :group 'ediff-hook)
409 424
410(defcustom ediff-suspend-hook (list 'ediff-default-suspend-function) 425(defcustom ediff-suspend-hook (list 'ediff-default-suspend-function)
411 "*Hooks to run in the Ediff control buffer when Ediff is suspended." 426 "*Hooks to run in the Ediff control buffer when Ediff is suspended."
412 :type 'hook 427 :type 'hook
413 :group 'ediff) 428 :group 'ediff-hook)
414(defcustom ediff-quit-hook (list 'ediff-cleanup-mess) 429(defcustom ediff-quit-hook (list 'ediff-cleanup-mess)
415 "*Hooks to run in the Ediff control buffer after finishing Ediff." 430 "*Hooks to run in the Ediff control buffer after finishing Ediff."
416 :type 'hook 431 :type 'hook
417 :group 'ediff) 432 :group 'ediff-hook)
418(defcustom ediff-cleanup-hook nil 433(defcustom ediff-cleanup-hook nil
419 "*Hooks to run on exiting Ediff but before killing the control buffer. 434 "*Hooks to run on exiting Ediff but before killing the control buffer.
420This is a place to do various cleanups, such as deleting the variant buffers. 435This is a place to do various cleanups, such as deleting the variant buffers.
421Ediff provides a function, `ediff-janitor', as one such possible hook." 436Ediff provides a function, `ediff-janitor', as one such possible hook."
422 :type 'hook 437 :type 'hook
423 :group 'ediff) 438 :group 'ediff-hook)
424 439
425;; Error messages 440;; Error messages
426(defconst ediff-KILLED-VITAL-BUFFER 441(defconst ediff-KILLED-VITAL-BUFFER
@@ -847,10 +862,6 @@ appropriate symbol: `rcs', `pcl-cvs', or `generic-sc' if you so desire."
847 (if (and (ediff-has-face-support-p) ediff-emacs-p) 862 (if (and (ediff-has-face-support-p) ediff-emacs-p)
848 (add-to-list 'facemenu-unlisted-faces face))) 863 (add-to-list 'facemenu-unlisted-faces face)))
849 864
850(defgroup ediff-highlighting nil
851 "Hilighting of difference regions in Ediff"
852 :prefix "ediff-"
853 :group 'ediff)
854 865
855;;(defvar ediff-current-diff-face-A 866;;(defvar ediff-current-diff-face-A
856;; (if (ediff-has-face-support-p) 867;; (if (ediff-has-face-support-p)
@@ -1523,11 +1534,14 @@ This property can be toggled interactively."
1523;; if nil, this silences some messages 1534;; if nil, this silences some messages
1524(defconst ediff-verbose-p t) 1535(defconst ediff-verbose-p t)
1525 1536
1526(ediff-defvar-local ediff-autostore-merges 'group-jobs-only 1537(defcustom ediff-autostore-merges 'group-jobs-only
1527 "*Save the results of merge jobs automatically. 1538 "*Save the results of merge jobs automatically.
1528Nil means don't save automatically. t means always save. Anything but nil or t 1539Nil means don't save automatically. t means always save. Anything but nil or t
1529means save automatically only if the merge job is part of a group of jobs, such 1540means save automatically only if the merge job is part of a group of jobs, such
1530as `ediff-merge-directory' or `ediff-merge-directory-revisions'.") 1541as `ediff-merge-directory' or `ediff-merge-directory-revisions'."
1542 :type '(choice (const nil) (const t) (const group-jobs-only))
1543 :group 'ediff-merge)
1544(make-variable-buffer-local 'ediff-autostore-merges)
1531 1545
1532;; file where the result of the merge is to be saved. used internally 1546;; file where the result of the merge is to be saved. used internally
1533(ediff-defvar-local ediff-merge-store-file nil "") 1547(ediff-defvar-local ediff-merge-store-file nil "")
@@ -1538,7 +1552,7 @@ Instead, C-h would jump to previous difference."
1538 :type 'boolean 1552 :type 'boolean
1539 :group 'ediff) 1553 :group 'ediff)
1540 1554
1541(defvar ediff-temp-file-prefix 1555(defcustom ediff-temp-file-prefix
1542 (let ((env (or (getenv "TMPDIR") 1556 (let ((env (or (getenv "TMPDIR")
1543 (getenv "TMP") 1557 (getenv "TMP")
1544 (getenv "TEMP"))) 1558 (getenv "TEMP")))
@@ -1549,20 +1563,26 @@ Instead, C-h would jump to previous difference."
1549 ((eq system-type 'ms-dos) "c:/") 1563 ((eq system-type 'ms-dos) "c:/")
1550 (t "/tmp")))) 1564 (t "/tmp"))))
1551 ;; The following is to make sure we get something to which we can 1565 ;; The following is to make sure we get something to which we can
1552 ;; add directory levels on VMS. 1566 ;; add directory levels under VMS.
1553 (setq d (file-name-as-directory (directory-file-name d))) 1567 (setq d (file-name-as-directory (directory-file-name d)))
1554 ) 1568 )
1555 "*Prefix to put on Ediff temporary file names. 1569 "*Prefix to put on Ediff temporary file names.
1556Do not start with `~/' or `~user-name/'.") 1570Do not start with `~/' or `~user-name/'."
1571 :type 'string
1572 :group 'ediff)
1557 1573
1558(defvar ediff-temp-file-mode 384 ; u=rw only 1574(defcustom ediff-temp-file-mode 384 ; u=rw only
1559 "*Mode for Ediff temporary files.") 1575 "*Mode for Ediff temporary files."
1576 :type 'integer
1577 :group 'ediff)
1560 1578
1561;; Metacharacters that have to be protected from the shell when executing 1579;; Metacharacters that have to be protected from the shell when executing
1562;; a diff/diff3 command. 1580;; a diff/diff3 command.
1563(defvar ediff-metachars "[ \t\n!\"#$&'()*;<=>?[\\^`{|~]" 1581(defcustom ediff-metachars "[ \t\n!\"#$&'()*;<=>?[\\^`{|~]"
1564 "Characters that must be quoted with \\ when used in a shell command line. 1582 "Regexp that matches characters that must be quoted with `\\' in shell command line.
1565More precisely, a regexp to match any one such character.") 1583This default should work without changes."
1584 :type 'string
1585 :group 'ediff)
1566 1586
1567;; needed to simulate frame-char-width in XEmacs. 1587;; needed to simulate frame-char-width in XEmacs.
1568(defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H"))) 1588(defvar ediff-H-glyph (if ediff-xemacs-p (make-glyph "H")))
diff --git a/lisp/ediff-merg.el b/lisp/ediff-merg.el
index f77d17ea7d5..188d67ebcaf 100644
--- a/lisp/ediff-merg.el
+++ b/lisp/ediff-merg.el
@@ -25,12 +25,6 @@
25 25
26(provide 'ediff-merg) 26(provide 'ediff-merg)
27 27
28(defgroup ediff-merge nil
29 "Merging utilities"
30 :prefix "ediff-"
31 :group 'ediff)
32
33
34;; compiler pacifier 28;; compiler pacifier
35(defvar ediff-window-A) 29(defvar ediff-window-A)
36(defvar ediff-window-B) 30(defvar ediff-window-B)
@@ -138,7 +132,6 @@ skiped over. Nil means show all regions.")
138 )) 132 ))
139 133
140(defun ediff-set-merge-mode () 134(defun ediff-set-merge-mode ()
141 ;; by Stig@hackvan.com
142 (normal-mode t) 135 (normal-mode t)
143 (remove-hook 'local-write-file-hooks 'ediff-set-merge-mode)) 136 (remove-hook 'local-write-file-hooks 'ediff-set-merge-mode))
144 137
diff --git a/lisp/ediff-mult.el b/lisp/ediff-mult.el
index 223573a2a25..230938ee8e4 100644
--- a/lisp/ediff-mult.el
+++ b/lisp/ediff-mult.el
@@ -120,16 +120,17 @@
120(defconst ediff-meta-buffer-message "This is an Ediff Session Group Panel: %s 120(defconst ediff-meta-buffer-message "This is an Ediff Session Group Panel: %s
121 121
122Useful commands: 122Useful commands:
123 button2, `v', RET over a session line: start that Ediff session 123 button2, v, or RET over session record: start that Ediff session
124 `M':\tin any session invoked from here, brings back this group panel 124 M:\tin sessions invoked from here, brings back this group panel
125 `R':\tdisplay the registry of active Ediff sessions 125 R:\tdisplay the registry of active Ediff sessions
126 `h':\tmark session for hiding (toggle) 126 h:\tmark session for hiding (toggle)
127 `x':\thide marked sessions; with prefix arg--unhide hidden sessions 127 x:\thide marked sessions; with prefix arg: unhide
128 `m':\tmark session for a non-hiding operation (toggle) 128 m:\tmark session for a non-hiding operation (toggle)
129 SPC:\tnext session 129 n,SPC:\tnext session
130 DEL:\tprevious session 130 p,DEL:\tprevious session
131 `E':\tbrowse Ediff on-line manual 131 E:\tbrowse Ediff on-line manual
132 `q':\tquit this session group 132 T:\ttoggle truncation of long file names
133 q:\tquit this session group
133") 134")
134 135
135(ediff-defvar-local ediff-meta-buffer-map nil 136(ediff-defvar-local ediff-meta-buffer-map nil
@@ -166,6 +167,8 @@ directories.")
166;; group. 167;; group.
167(ediff-defvar-local ediff-meta-list nil "") 168(ediff-defvar-local ediff-meta-list nil "")
168 169
170(ediff-defvar-local ediff-meta-session-number nil "")
171
169 172
170;; the difference list between directories in a directory session group 173;; the difference list between directories in a directory session group
171(ediff-defvar-local ediff-dir-difference-list nil "") 174(ediff-defvar-local ediff-dir-difference-list nil "")
@@ -174,6 +177,11 @@ directories.")
174;; The registry of Ediff sessions. A list of control buffers. 177;; The registry of Ediff sessions. A list of control buffers.
175(defvar ediff-session-registry nil) 178(defvar ediff-session-registry nil)
176 179
180(defcustom ediff-meta-truncate-filenames t
181 "*If non-nil, truncate long file names in the session group buffers.
182This can be toggled with `ediff-toggle-filename-truncation'."
183 :type 'hook
184 :group 'ediff-mult)
177(defcustom ediff-registry-setup-hook nil 185(defcustom ediff-registry-setup-hook nil
178 "*Hooks run just after the registry control panel is set up." 186 "*Hooks run just after the registry control panel is set up."
179 :type 'hook 187 :type 'hook
@@ -250,6 +258,15 @@ buffers."
250(defsubst ediff-set-file-eqstatus (elt value) 258(defsubst ediff-set-file-eqstatus (elt value)
251 (setcar (cdr elt) value)) 259 (setcar (cdr elt) value))
252 260
261;; The activity marker is either or + (active session, i.e., ediff is currently
262;; run in it), or - (finished session, i.e., we've ran ediff in it and then
263;; exited). Return nil, if session is neither active nor finished
264(defun ediff-get-session-activity-marker (session)
265 (let ((session-buf (ediff-get-session-buffer session)))
266 (cond ((null session-buf) nil) ; virgin session
267 ((ediff-buffer-live-p session-buf) ?+) ;active session
268 (t ?-))))
269
253;; checks if the session is a meta session 270;; checks if the session is a meta session
254(defun ediff-meta-session-p (session-info) 271(defun ediff-meta-session-p (session-info)
255 (and (stringp (ediff-get-session-objA-name session-info)) 272 (and (stringp (ediff-get-session-objA-name session-info))
@@ -264,12 +281,15 @@ buffers."
264 (setq ediff-meta-buffer-map (make-sparse-keymap)) 281 (setq ediff-meta-buffer-map (make-sparse-keymap))
265 (suppress-keymap ediff-meta-buffer-map) 282 (suppress-keymap ediff-meta-buffer-map)
266 (define-key ediff-meta-buffer-map "q" 'ediff-quit-meta-buffer) 283 (define-key ediff-meta-buffer-map "q" 'ediff-quit-meta-buffer)
284 (define-key ediff-meta-buffer-map "T" 'ediff-toggle-filename-truncation)
267 (define-key ediff-meta-buffer-map "R" 'ediff-show-registry) 285 (define-key ediff-meta-buffer-map "R" 'ediff-show-registry)
268 (define-key ediff-meta-buffer-map "E" 'ediff-documentation) 286 (define-key ediff-meta-buffer-map "E" 'ediff-documentation)
269 (define-key ediff-meta-buffer-map "v" ediff-meta-action-function) 287 (define-key ediff-meta-buffer-map "v" ediff-meta-action-function)
270 (define-key ediff-meta-buffer-map "\C-m" ediff-meta-action-function) 288 (define-key ediff-meta-buffer-map "\C-m" ediff-meta-action-function)
271 (define-key ediff-meta-buffer-map " " 'ediff-next-meta-item) 289 (define-key ediff-meta-buffer-map " " 'ediff-next-meta-item)
290 (define-key ediff-meta-buffer-map "n" 'ediff-next-meta-item)
272 (define-key ediff-meta-buffer-map "\C-?" 'ediff-previous-meta-item) 291 (define-key ediff-meta-buffer-map "\C-?" 'ediff-previous-meta-item)
292 (define-key ediff-meta-buffer-map "p" 'ediff-previous-meta-item)
273 (define-key ediff-meta-buffer-map [delete] 'ediff-previous-meta-item) 293 (define-key ediff-meta-buffer-map [delete] 'ediff-previous-meta-item)
274 (define-key ediff-meta-buffer-map [backspace] 'ediff-previous-meta-item) 294 (define-key ediff-meta-buffer-map [backspace] 'ediff-previous-meta-item)
275 (or (ediff-one-filegroup-metajob) 295 (or (ediff-one-filegroup-metajob)
@@ -313,7 +333,9 @@ Commands:
313(suppress-keymap ediff-dir-diffs-buffer-map) 333(suppress-keymap ediff-dir-diffs-buffer-map)
314(define-key ediff-dir-diffs-buffer-map "q" 'ediff-bury-dir-diffs-buffer) 334(define-key ediff-dir-diffs-buffer-map "q" 'ediff-bury-dir-diffs-buffer)
315(define-key ediff-dir-diffs-buffer-map " " 'next-line) 335(define-key ediff-dir-diffs-buffer-map " " 'next-line)
336(define-key ediff-dir-diffs-buffer-map "n" 'next-line)
316(define-key ediff-dir-diffs-buffer-map "\C-?" 'previous-line) 337(define-key ediff-dir-diffs-buffer-map "\C-?" 'previous-line)
338(define-key ediff-dir-diffs-buffer-map "p" 'previous-line)
317(define-key ediff-dir-diffs-buffer-map [delete] 'previous-line) 339(define-key ediff-dir-diffs-buffer-map [delete] 'previous-line)
318(define-key ediff-dir-diffs-buffer-map [backspace] 'previous-line) 340(define-key ediff-dir-diffs-buffer-map [backspace] 'previous-line)
319 341
@@ -322,20 +344,20 @@ Commands:
322Moves in circular fashion. With numeric prefix arg, skip this many items." 344Moves in circular fashion. With numeric prefix arg, skip this many items."
323 (interactive "p") 345 (interactive "p")
324 (or count (setq count 1)) 346 (or count (setq count 1))
325 (while (< 0 count) 347 (let (overl)
326 (setq count (1- count)) 348 (while (< 0 count)
327 (ediff-next-meta-item1))) 349 (setq count (1- count))
350 (ediff-next-meta-item1)
351 (setq overl (ediff-get-meta-overlay-at-pos (point)))
352 ;; skip invisible ones
353 (while (and overl (ediff-overlay-get overl 'invisible))
354 (ediff-next-meta-item1)
355 (setq overl (ediff-get-meta-overlay-at-pos (point)))))))
328 356
329;; Move to the next meta item 357;; Move to the next meta item
330(defun ediff-next-meta-item1 () 358(defun ediff-next-meta-item1 ()
331 (let (pos) 359 (let (pos)
332 (setq pos (ediff-next-meta-overlay-start (point))) 360 (setq pos (ediff-next-meta-overlay-start (point)))
333;;; ;; skip deleted
334;;; (while (memq (ediff-get-session-status
335;;; (ediff-get-meta-info (current-buffer) pos 'noerror))
336;;; '(?H ?I))
337;;; (setq pos (ediff-next-meta-overlay-start pos)))
338
339 (if pos (goto-char pos)) 361 (if pos (goto-char pos))
340 (if (eq ediff-metajob-name 'ediff-registry) 362 (if (eq ediff-metajob-name 'ediff-registry)
341 (if (and (ediff-get-meta-info (current-buffer) pos 'noerror) 363 (if (and (ediff-get-meta-info (current-buffer) pos 'noerror)
@@ -350,9 +372,15 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
350Moves in circular fashion. With numeric prefix arg, skip this many items." 372Moves in circular fashion. With numeric prefix arg, skip this many items."
351 (interactive "p") 373 (interactive "p")
352 (or count (setq count 1)) 374 (or count (setq count 1))
353 (while (< 0 count) 375 (let (overl)
354 (setq count (1- count)) 376 (while (< 0 count)
355 (ediff-previous-meta-item1))) 377 (setq count (1- count))
378 (ediff-previous-meta-item1)
379 (setq overl (ediff-get-meta-overlay-at-pos (point)))
380 ;; skip invisible ones
381 (while (and overl (ediff-overlay-get overl 'invisible))
382 (ediff-previous-meta-item1)
383 (setq overl (ediff-get-meta-overlay-at-pos (point)))))))
356 384
357(defun ediff-previous-meta-item1 () 385(defun ediff-previous-meta-item1 ()
358 (let (pos) 386 (let (pos)
@@ -376,6 +404,14 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
376 (file-name-as-directory file) 404 (file-name-as-directory file)
377 file)) 405 file))
378 406
407(defun ediff-toggle-filename-truncation ()
408 "Toggle truncation of long file names in session group buffers.
409Set `ediff-meta-truncate-filenames' variable if you want to change the default
410behavior."
411 (interactive)
412 (setq ediff-meta-truncate-filenames (not ediff-meta-truncate-filenames))
413 (ediff-update-meta-buffer (current-buffer) 'must-redraw))
414
379 415
380;; DIR1, DIR2, DIR3 are directories. DIR3 can be nil. 416;; DIR1, DIR2, DIR3 are directories. DIR3 can be nil.
381;; OUTPUT-DIR is a directory for auto-storing the results of merge jobs. 417;; OUTPUT-DIR is a directory for auto-storing the results of merge jobs.
@@ -490,11 +526,10 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
490 common)) 526 common))
491 )) 527 ))
492 528
493;; find directory files that are under revision. 529;; find directory files that are under revision. Include subdirectories, since
494;; Include subdirectories, since we may visit them recursively. 530;; we may visit them recursively. DIR1 is the directory to inspect.
495;; DIR1 is the directory to inspect. 531;; MERGE-AUTOSTORE-DIR is the directory where to auto-store the results of
496;; OUTPUT-DIR is the directory where to auto-store the results of merges. Can 532;; merges. Can be nil.
497;; be nil.
498(defun ediff-get-directory-files-under-revision (jobname 533(defun ediff-get-directory-files-under-revision (jobname
499 regexp dir1 534 regexp dir1
500 &optional merge-autostore-dir) 535 &optional merge-autostore-dir)
@@ -511,7 +546,8 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
511 lis1 (cdr lis1)) 546 lis1 (cdr lis1))
512 ;; take files under revision control 547 ;; take files under revision control
513 (cond ((file-directory-p (concat auxdir1 elt)) 548 (cond ((file-directory-p (concat auxdir1 elt))
514 (setq common (cons elt common))) 549 (setq common
550 (cons (ediff-add-slash-if-directory auxdir1 elt) common)))
515 ((file-exists-p (concat auxdir1 elt ",v")) 551 ((file-exists-p (concat auxdir1 elt ",v"))
516 (setq common (cons elt common))) 552 (setq common (cons elt common)))
517 ((file-exists-p (concat auxdir1 "RCS/" elt ",v")) 553 ((file-exists-p (concat auxdir1 "RCS/" elt ",v"))
@@ -519,8 +555,8 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
519 ) ; cond 555 ) ; cond
520 ) ; while 556 ) ; while
521 557
522 (setq common (delete "." common) 558 (setq common (delete "./" common)
523 common (delete ".." common) 559 common (delete "../" common)
524 common (delete "RCS" common)) 560 common (delete "RCS" common))
525 561
526 ;; copying is needed because sort sorts via side effects 562 ;; copying is needed because sort sorts via side effects
@@ -665,6 +701,74 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
665 ) ; eval in meta-buffer 701 ) ; eval in meta-buffer
666 meta-buffer)) 702 meta-buffer))
667 703
704;; Insert the activity marker for session SESSION in the meta buffer at point
705;; The activity marker is either SPC (untouched session), or + (active session,
706;; i.e., ediff is currently run in it), or - (finished session, i.e., we've ran
707;; ediff in it and then exited)
708(defun ediff-insert-session-activity-marker-in-meta-buffer (session)
709 (insert
710 (cond ((ediff-get-session-activity-marker session))
711 ;; virgin session
712 (t " "))))
713
714;; Insert session status at point. Status is either ?H (marked for hiding), or
715;; ?I (hidden or invalid), or ?* (meaning marked for an operation; currently,
716;; such op can only be checking for equality)), or SPC (meaning neither marked
717;; nor invalid)
718(defun ediff-insert-session-status-in-meta-buffer (session)
719 (insert
720 (cond ((ediff-get-session-status session)) ; session has status: ?H, ?I, ?*
721 ;; normal session, no marks or hidings
722 (t " "))))
723
724;; If NEW-MARKER is non-nil, use it to substitute the current activity marker
725;; in the meta buffer. If nil, use SPC
726(defun ediff-replace-session-activity-marker-in-meta-buffer (point new-marker)
727 (let* ((overl (ediff-get-meta-overlay-at-pos point))
728 (session-info (ediff-overlay-get overl 'ediff-meta-info))
729 (activity-marker (ediff-get-session-activity-marker session-info))
730 buffer-read-only)
731 (or new-marker activity-marker (setq new-marker ?\ ))
732 (goto-char (ediff-overlay-start overl))
733 (if (eq (char-after (point)) new-marker)
734 () ; if marker shown in buffer is the same as new-marker, do nothing
735 (insert new-marker)
736 (delete-char 1)
737 (set-buffer-modified-p nil))))
738
739;; If NEW-STATUS is non-nil, use it to substitute the current status marker in
740;; the meta buffer. If nil, use SPC
741(defun ediff-replace-session-status-in-meta-buffer (point new-status)
742 (let* ((overl (ediff-get-meta-overlay-at-pos point))
743 (session-info (ediff-overlay-get overl 'ediff-meta-info))
744 (status (ediff-get-session-status session-info))
745 buffer-read-only)
746 (setq new-status (or new-status status ?\ ))
747 (goto-char (ediff-overlay-start overl))
748 (forward-char 1) ; status is the second char in session record
749 (if (eq (char-after (point)) new-status)
750 () ; if marker shown in buffer is the same as new-marker, do nothing
751 (insert new-status)
752 (delete-char 1)
753 (set-buffer-modified-p nil))))
754
755;; insert all file info in meta buffer for a given session
756(defun ediff-insert-session-info-in-meta-buffer (session-info sessionNum)
757 (let ((f1 (ediff-get-session-objA session-info))
758 (f2 (ediff-get-session-objB session-info))
759 (f3 (ediff-get-session-objC session-info))
760 (pt (point))
761 (hidden (eq (ediff-get-session-status session-info) ?I)))
762 ;; insert activity marker, i.e., SPC, - or +
763 (ediff-insert-session-activity-marker-in-meta-buffer session-info)
764 ;; insert session status, i.e., *, H
765 (ediff-insert-session-status-in-meta-buffer session-info)
766 (insert " Session " (int-to-string sessionNum) ":\n")
767 (ediff-meta-insert-file-info1 f1)
768 (ediff-meta-insert-file-info1 f2)
769 (ediff-meta-insert-file-info1 f3)
770 (ediff-set-meta-overlay pt (point) session-info sessionNum hidden)))
771
668 772
669;; this is a setup function for ediff-directories 773;; this is a setup function for ediff-directories
670;; must return meta-buffer 774;; must return meta-buffer
@@ -673,42 +777,50 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
673 (let ((meta-buf (ediff-get-group-buffer meta-list)) 777 (let ((meta-buf (ediff-get-group-buffer meta-list))
674 (empty t) 778 (empty t)
675 (sessionNum 0) 779 (sessionNum 0)
676 regexp elt session-buf f1 f2 f3 pt 780 regexp elt merge-autostore-dir
677 merge-autostore-dir
678 point tmp-list buffer-read-only) 781 point tmp-list buffer-read-only)
679 (ediff-with-current-buffer meta-buf 782 (ediff-with-current-buffer meta-buf
680 (setq point (point)) 783 (setq point (point))
681 (erase-buffer) 784 (erase-buffer)
785 ;; delete phony overlays that used to represent sessions before the buff
786 ;; was redrawn
787 (if ediff-emacs-p
788 (mapcar 'delete-overlay (overlays-in 1 1))
789 (map-extents 'delete-extent))
790
682 (insert (format ediff-meta-buffer-message 791 (insert (format ediff-meta-buffer-message
683 (ediff-abbrev-jobname ediff-metajob-name))) 792 (ediff-abbrev-jobname ediff-metajob-name)))
684 793
685 (setq regexp (ediff-get-group-regexp meta-list) 794 (setq regexp (ediff-get-group-regexp meta-list)
686 merge-autostore-dir (ediff-get-group-merge-autostore-dir meta-list)) 795 merge-autostore-dir
796 (ediff-get-group-merge-autostore-dir meta-list))
687 797
688 (cond ((ediff-collect-diffs-metajob) 798 (cond ((ediff-collect-diffs-metajob)
689 (insert 799 (insert
690 " `P':\tcollect custom diffs of all marked sessions\n")) 800 " P:\tcollect custom diffs of all marked sessions\n"))
691 ((ediff-patch-metajob) 801 ((ediff-patch-metajob)
692 (insert 802 (insert
693 " `P':\tshow patch appropriately for the context (session or group)\n"))) 803 " P:\tshow patch appropriately for the context (session or group)\n")))
694 (insert 804 (insert
695 " `u':\tshow parent session group\n") 805 " u:\tshow parent session group\n")
696 (or (ediff-one-filegroup-metajob) 806 (or (ediff-one-filegroup-metajob)
697 (insert 807 (insert
698 " `D':\tshow differences among directories\n" 808 " D:\tshow differences among directories\n"
699 " `=':\tmark identical files in each session\n\n")) 809 " =:\tmark identical files in each session\n\n"))
700 810
811 (insert "\n")
701 (if (and (stringp regexp) (> (length regexp) 0)) 812 (if (and (stringp regexp) (> (length regexp) 0))
702 (insert 813 (insert
703 (format "\n*** Filter-through regular expression: %s\n" regexp))) 814 (format "*** Filter-through regular expression: %s\n" regexp)))
815 (ediff-insert-dirs-in-meta-buffer meta-list)
704 (if (and ediff-autostore-merges (ediff-merge-metajob) 816 (if (and ediff-autostore-merges (ediff-merge-metajob)
705 (stringp merge-autostore-dir)) 817 (stringp merge-autostore-dir))
706 (insert (format 818 (insert (format
707 "\nMerges are automatically stored in directory: %s\n" 819 "\nMerge results are automatically stored in:\n\t%s\n"
708 merge-autostore-dir))) 820 merge-autostore-dir)))
709 (insert "\n 821 (insert "\n
710 Size Last modified Name 822 Size Last modified Name
711 ----------------------------------------------------------------------- 823 ----------------------------------------------
712 824
713") 825")
714 826
@@ -734,27 +846,87 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
734 sessionNum (1+ sessionNum)) 846 sessionNum (1+ sessionNum))
735 (if (eq (ediff-get-session-status elt) ?I) 847 (if (eq (ediff-get-session-status elt) ?I)
736 () 848 ()
737 (setq session-buf (ediff-get-session-buffer elt) 849 (ediff-insert-session-info-in-meta-buffer elt sessionNum)))
738 f1 (ediff-get-session-objA elt)
739 f2 (ediff-get-session-objB elt)
740 f3 (ediff-get-session-objC elt))
741 (setq pt (point))
742 ;; insert markers
743 (insert (cond ((null session-buf) " ") ; virgin session
744 ((ediff-buffer-live-p session-buf) "+") ;active session
745 (t "-"))) ; finished session
746 (insert (cond ((ediff-get-session-status elt)) ; session has status,
747 ;;; e.g., ?H, ?I
748 (t " "))) ; normal session
749 (insert " Session " (int-to-string sessionNum) ":\n")
750 (ediff-meta-insert-file-info f1)
751 (ediff-meta-insert-file-info f2)
752 (ediff-meta-insert-file-info f3)
753 (ediff-set-meta-overlay pt (point) elt)))
754 (set-buffer-modified-p nil) 850 (set-buffer-modified-p nil)
755 (goto-char point) 851 (goto-char point)
756 meta-buf))) 852 meta-buf)))
757 853
854(defun ediff-update-markers-in-dir-meta-buffer (meta-list)
855 (let ((meta-buf (ediff-get-group-buffer meta-list))
856 session-info point overl buffer-read-only)
857 (ediff-with-current-buffer meta-buf
858 (setq point (point))
859 (goto-char (point-min))
860 (ediff-next-meta-item1)
861 (while (not (bobp))
862 (setq session-info (ediff-get-meta-info meta-buf (point) 'no-error)
863 overl (ediff-get-meta-overlay-at-pos (point)))
864 (if session-info
865 (progn
866 (cond ((eq (ediff-get-session-status session-info) ?I)
867 ;; Do hiding
868 (if overl (ediff-overlay-put overl 'invisible t)))
869 ((and (eq (ediff-get-session-status session-info) ?H)
870 overl (ediff-overlay-get overl 'invisible))
871 ;; Do unhiding
872 (ediff-overlay-put overl 'invisible nil))
873 (t (ediff-replace-session-activity-marker-in-meta-buffer
874 (point)
875 (ediff-get-session-activity-marker session-info))
876 (ediff-replace-session-status-in-meta-buffer
877 (point)
878 (ediff-get-session-status session-info))))))
879 (ediff-next-meta-item1) ; advance to the next item
880 ) ; end while
881 (set-buffer-modified-p nil)
882 (goto-char point))
883 meta-buf))
884
885(defun ediff-update-session-marker-in-dir-meta-buffer (session-num)
886 (let (buffer-meta-overlays session-info overl buffer-read-only)
887 (setq overl
888 (if ediff-xemacs-p
889 (map-extents
890 (function
891 (lambda (ext maparg)
892 (if (and
893 (ediff-overlay-get ext 'ediff-meta-info)
894 (eq (ediff-overlay-get ext 'ediff-meta-session-number)
895 session-num))
896 ext))))
897 ;; Emacs doesn't have map-extents, so try harder
898 ;; Splice overlay lists to get all buffer overlays
899 (setq buffer-meta-overlays (overlay-lists)
900 buffer-meta-overlays (append (car buffer-meta-overlays)
901 (cdr buffer-meta-overlays)))
902 (car
903 (delq nil
904 (mapcar
905 (function
906 (lambda (overl)
907 (if (and
908 (ediff-overlay-get overl 'ediff-meta-info)
909 (eq (ediff-overlay-get
910 overl 'ediff-meta-session-number)
911 session-num))
912 overl)))
913 buffer-meta-overlays)))))
914 (or overl
915 (error
916 "Bug in ediff-update-session-marker-in-dir-meta-buffer: no overlay with given number %S"
917 session-num))
918 (setq session-info (ediff-overlay-get overl 'ediff-meta-info))
919 (goto-char (ediff-overlay-start overl))
920 (ediff-replace-session-activity-marker-in-meta-buffer
921 (point)
922 (ediff-get-session-activity-marker session-info))
923 (ediff-replace-session-status-in-meta-buffer
924 (point)
925 (ediff-get-session-status session-info)))
926 (ediff-next-meta-item1))
927
928
929
758;; Check if this is a problematic session. 930;; Check if this is a problematic session.
759;; Return nil if not. Otherwise, return symbol representing the problem 931;; Return nil if not. Otherwise, return symbol representing the problem
760;; At present, problematic sessions occur only in -with-ancestor comparisons 932;; At present, problematic sessions occur only in -with-ancestor comparisons
@@ -773,11 +945,13 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
773 'ancestor-is-dir) 945 'ancestor-is-dir)
774 (t nil)))) 946 (t nil))))
775 947
776(defun ediff-meta-insert-file-info (fileinfo) 948(defun ediff-meta-insert-file-info1 (fileinfo)
777 (let ((fname (car fileinfo)) 949 (let ((fname (car fileinfo))
778 (feq (ediff-get-file-eqstatus fileinfo)) 950 (feq (ediff-get-file-eqstatus fileinfo))
951 (max-filename-width (if ediff-meta-truncate-filenames
952 (- (window-width) 41)
953 500))
779 file-modtime file-size) 954 file-modtime file-size)
780
781 (cond ((not (stringp fname)) (setq file-size -2)) ; file doesn't exits 955 (cond ((not (stringp fname)) (setq file-size -2)) ; file doesn't exits
782 ((not (ediff-file-remote-p fname)) 956 ((not (ediff-file-remote-p fname))
783 (if (file-exists-p fname) 957 (if (file-exists-p fname)
@@ -802,7 +976,9 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
802 ;; abbreviate the file name, if file exists 976 ;; abbreviate the file name, if file exists
803 (if (and (not (stringp fname)) (< file-size -1)) 977 (if (and (not (stringp fname)) (< file-size -1))
804 "-------" ; file doesn't exist 978 "-------" ; file doesn't exist
805 (ediff-abbreviate-file-name fname))))))) 979 (ediff-truncate-string-left
980 (ediff-abbreviate-file-name fname)
981 max-filename-width)))))))
806 982
807(defconst ediff-months '((1 . "Jan") (2 . "Feb") (3 . "Mar") (4 . "Apr") 983(defconst ediff-months '((1 . "Jan") (2 . "Feb") (3 . "Mar") (4 . "Apr")
808 (5 . "May") (6 . "Jun") (7 . "Jul") (8 . "Aug") 984 (5 . "May") (6 . "Jun") (7 . "Jul") (8 . "Aug")
@@ -826,6 +1002,18 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
826 (ediff-fill-leading-zero (nth 0 time)) ; sec 1002 (ediff-fill-leading-zero (nth 0 time)) ; sec
827 )) 1003 ))
828 1004
1005;; Draw the directories
1006(defun ediff-insert-dirs-in-meta-buffer (meta-list)
1007 (let* ((dir1 (ediff-abbreviate-file-name (ediff-get-group-objA meta-list)))
1008 (dir2 (ediff-get-group-objB meta-list))
1009 (dir2 (if (stringp dir2) (ediff-abbreviate-file-name dir2)))
1010 (dir3 (ediff-get-group-objC meta-list))
1011 (dir3 (if (stringp dir3) (ediff-abbreviate-file-name dir3))))
1012 (insert "*** Directory A: " dir1 "\n")
1013 (if dir2 (insert "*** Directory B: " dir2 "\n"))
1014 (if dir3 (insert "*** Directory C: " dir3 "\n"))
1015 (insert "\n")))
1016
829(defun ediff-draw-dir-diffs (diff-list) 1017(defun ediff-draw-dir-diffs (diff-list)
830 (if (null diff-list) (error "Lost difference info on these directories")) 1018 (if (null diff-list) (error "Lost difference info on these directories"))
831 (let* ((buf-name (ediff-unique-buffer-name 1019 (let* ((buf-name (ediff-unique-buffer-name
@@ -850,8 +1038,8 @@ Moves in circular fashion. With numeric prefix arg, skip this many items."
850 (insert " 1038 (insert "
851Useful commands: 1039Useful commands:
852 `q': hide this buffer 1040 `q': hide this buffer
853 SPC: next line 1041 n,SPC: next line
854 DEL: previous line\n\n") 1042 p,DEL: previous line\n\n")
855 1043
856 (if (and (stringp regexp) (> (length regexp) 0)) 1044 (if (and (stringp regexp) (> (length regexp) 0))
857 (insert 1045 (insert
@@ -946,7 +1134,8 @@ Useful commands:
946 "Go to the parent session group buffer." 1134 "Go to the parent session group buffer."
947 (interactive) 1135 (interactive)
948 (if (ediff-buffer-live-p ediff-parent-meta-buffer) 1136 (if (ediff-buffer-live-p ediff-parent-meta-buffer)
949 (ediff-show-meta-buffer ediff-parent-meta-buffer) 1137 (ediff-show-meta-buffer
1138 ediff-parent-meta-buffer ediff-meta-session-number)
950 (error "This session group has no parent"))) 1139 (error "This session group has no parent")))
951 1140
952 1141
@@ -957,16 +1146,22 @@ Useful commands:
957 elt bufAname bufBname bufCname cur-diff total-diffs pt 1146 elt bufAname bufBname bufCname cur-diff total-diffs pt
958 job-name meta-list registry-list buffer-read-only) 1147 job-name meta-list registry-list buffer-read-only)
959 (erase-buffer) 1148 (erase-buffer)
1149 ;; delete phony overlays that used to represent sessions before the buff
1150 ;; was redrawn
1151 (if ediff-emacs-p
1152 (mapcar 'delete-overlay (overlays-in 1 1))
1153 (map-extents 'delete-extent))
1154
960 (insert "This is a registry of all active Ediff sessions. 1155 (insert "This is a registry of all active Ediff sessions.
961 1156
962Useful commands: 1157Useful commands:
963 button2, `v', RET over a session record: switch to that session 1158 button2, `v', RET over a session record: switch to that session
964 `M' over a session record: display the associated session group 1159 M over a session record: display the associated session group
965 `R' in any Ediff session: display session registry 1160 R in any Ediff session: display session registry
966 SPC:\tnext session 1161 n,SPC: next session
967 DEL:\tprevious session 1162 p,DEL: previous session
968 `E':\tbrowse Ediff on-line manual 1163 E: browse Ediff on-line manual
969 `q':\tbury registry 1164 q: bury registry
970 1165
971 1166
972\t\tActive Ediff Sessions: 1167\t\tActive Ediff Sessions:
@@ -1048,14 +1243,19 @@ Useful commands:
1048 (goto-char point) 1243 (goto-char point)
1049 ))) 1244 )))
1050 1245
1051;; sets overlay around a meta record with 'ediff-meta-info property PROP 1246;; Sets overlay around a meta record with 'ediff-meta-info property PROP
1052(defun ediff-set-meta-overlay (b e prop) 1247;; If optional SESSION-NUMBER, make it a property of the overlay,
1248;; ediff-meta-session-number
1249(defun ediff-set-meta-overlay (b e prop &optional session-number hidden)
1053 (let (overl) 1250 (let (overl)
1054 (setq overl (ediff-make-overlay b e)) 1251 (setq overl (ediff-make-overlay b e))
1055 (if ediff-emacs-p 1252 (if ediff-emacs-p
1056 (ediff-overlay-put overl 'mouse-face 'highlight) 1253 (ediff-overlay-put overl 'mouse-face 'highlight)
1057 (ediff-overlay-put overl 'highlight t)) 1254 (ediff-overlay-put overl 'highlight t))
1058 (ediff-overlay-put overl 'ediff-meta-info prop))) 1255 (ediff-overlay-put overl 'ediff-meta-info prop)
1256 (ediff-overlay-put overl 'invisible hidden)
1257 (if (numberp session-number)
1258 (ediff-overlay-put overl 'ediff-meta-session-number session-number))))
1059 1259
1060(defun ediff-mark-for-hiding (unmark) 1260(defun ediff-mark-for-hiding (unmark)
1061 "Mark session for hiding. With prefix arg, unmark." 1261 "Mark session for hiding. With prefix arg, unmark."
@@ -1064,8 +1264,8 @@ Useful commands:
1064 (meta-buf (ediff-event-buffer last-command-event)) 1264 (meta-buf (ediff-event-buffer last-command-event))
1065 ;; ediff-get-meta-info gives error if meta-buf or pos are invalid 1265 ;; ediff-get-meta-info gives error if meta-buf or pos are invalid
1066 (info (ediff-get-meta-info meta-buf pos)) 1266 (info (ediff-get-meta-info meta-buf pos))
1067 (session-buf (ediff-get-session-buffer info))) 1267 (session-buf (ediff-get-session-buffer info))
1068 1268 (session-number (ediff-get-session-number-at-pos pos)))
1069 (if (eq (ediff-get-session-status info) ?H) 1269 (if (eq (ediff-get-session-status info) ?H)
1070 (setq unmark t)) 1270 (setq unmark t))
1071 (if unmark 1271 (if unmark
@@ -1075,7 +1275,7 @@ Useful commands:
1075 (ediff-set-session-status info ?H)) 1275 (ediff-set-session-status info ?H))
1076 (or unmark 1276 (or unmark
1077 (ediff-next-meta-item 1)) 1277 (ediff-next-meta-item 1))
1078 (ediff-update-meta-buffer meta-buf) 1278 (ediff-update-meta-buffer meta-buf nil session-number)
1079 )) 1279 ))
1080 1280
1081(defun ediff-mark-for-operation (unmark) 1281(defun ediff-mark-for-operation (unmark)
@@ -1084,8 +1284,8 @@ Useful commands:
1084 (let* ((pos (ediff-event-point last-command-event)) 1284 (let* ((pos (ediff-event-point last-command-event))
1085 (meta-buf (ediff-event-buffer last-command-event)) 1285 (meta-buf (ediff-event-buffer last-command-event))
1086 ;; ediff-get-meta-info gives error if meta-buf or pos are invalid 1286 ;; ediff-get-meta-info gives error if meta-buf or pos are invalid
1087 (info (ediff-get-meta-info meta-buf pos))) 1287 (info (ediff-get-meta-info meta-buf pos))
1088 1288 (session-number (ediff-get-session-number-at-pos pos)))
1089 (if (eq (ediff-get-session-status info) ?*) 1289 (if (eq (ediff-get-session-status info) ?*)
1090 (setq unmark t)) 1290 (setq unmark t))
1091 (if unmark 1291 (if unmark
@@ -1093,7 +1293,7 @@ Useful commands:
1093 (ediff-set-session-status info ?*)) 1293 (ediff-set-session-status info ?*))
1094 (or unmark 1294 (or unmark
1095 (ediff-next-meta-item 1)) 1295 (ediff-next-meta-item 1))
1096 (ediff-update-meta-buffer meta-buf) 1296 (ediff-update-meta-buffer meta-buf nil session-number)
1097 )) 1297 ))
1098 1298
1099(defun ediff-hide-marked-sessions (unhide) 1299(defun ediff-hide-marked-sessions (unhide)
@@ -1124,7 +1324,7 @@ Useful commands:
1124 (message "Nothing to reveal...") 1324 (message "Nothing to reveal...")
1125 (message "Nothing to hide..."))) 1325 (message "Nothing to hide...")))
1126 (if active-sessions-exist 1326 (if active-sessions-exist
1127 (message "Note: didn't hide active sessions!")) 1327 (message "Note: Ediff didn't hide active sessions!"))
1128 )) 1328 ))
1129 1329
1130;; Apply OPERATION to marked sessions. Operation expects one argument of type 1330;; Apply OPERATION to marked sessions. Operation expects one argument of type
@@ -1156,7 +1356,7 @@ Useful commands:
1156 (setq ediff-meta-diff-buffer diff-buffer) 1356 (setq ediff-meta-diff-buffer diff-buffer)
1157 ;; collect diffs in child group 1357 ;; collect diffs in child group
1158 (ediff-operate-on-marked-sessions operation))))))) 1358 (ediff-operate-on-marked-sessions operation)))))))
1159 (ediff-update-meta-buffer grp-buf) ; just in case 1359 (ediff-update-meta-buffer grp-buf 'must-redraw) ; just in case
1160 numMarked 1360 numMarked
1161 )) 1361 ))
1162 1362
@@ -1255,11 +1455,11 @@ all marked sessions must be active."
1255 (meta-buf (ediff-event-buffer last-command-event)) 1455 (meta-buf (ediff-event-buffer last-command-event))
1256 ;; ediff-get-meta-info gives error if meta-buf or pos are invalid 1456 ;; ediff-get-meta-info gives error if meta-buf or pos are invalid
1257 (info (ediff-get-meta-info meta-buf pos)) 1457 (info (ediff-get-meta-info meta-buf pos))
1258 merge-autostore-dir 1458 (session-buf (ediff-get-session-buffer info))
1259 session-buf file1 file2 file3 regexp) 1459 (session-number (ediff-get-session-number-at-pos pos))
1460 merge-autostore-dir file1 file2 file3 regexp)
1260 1461
1261 (setq session-buf (ediff-get-session-buffer info) 1462 (setq file1 (ediff-get-session-objA-name info)
1262 file1 (ediff-get-session-objA-name info)
1263 file2 (ediff-get-session-objB-name info) 1463 file2 (ediff-get-session-objB-name info)
1264 file3 (ediff-get-session-objC-name info)) 1464 file3 (ediff-get-session-objC-name info))
1265 1465
@@ -1271,7 +1471,7 @@ all marked sessions must be active."
1271 (if (y-or-n-p "This session is marked as hidden, unmark? ") 1471 (if (y-or-n-p "This session is marked as hidden, unmark? ")
1272 (progn 1472 (progn
1273 (ediff-set-session-status info nil) 1473 (ediff-set-session-status info nil)
1274 (ediff-update-meta-buffer meta-buf)) 1474 (ediff-update-meta-buffer meta-buf nil session-number))
1275 (error "Aborted")))) 1475 (error "Aborted"))))
1276 1476
1277 (ediff-with-current-buffer meta-buf 1477 (ediff-with-current-buffer meta-buf
@@ -1295,7 +1495,9 @@ all marked sessions must be active."
1295 (` (list (lambda () 1495 (` (list (lambda ()
1296 ;; child session group should know its parent 1496 ;; child session group should know its parent
1297 (setq ediff-parent-meta-buffer 1497 (setq ediff-parent-meta-buffer
1298 (quote (, ediff-meta-buffer))) 1498 (quote (, ediff-meta-buffer))
1499 ediff-meta-session-number
1500 (, session-number))
1299 ;; and parent will know its child 1501 ;; and parent will know its child
1300 (setcar (quote (, info)) ediff-meta-buffer))))))) 1502 (setcar (quote (, info)) ediff-meta-buffer)))))))
1301 1503
@@ -1312,9 +1514,12 @@ all marked sessions must be active."
1312 ediff-session-action-function ediff-metajob-name 1514 ediff-session-action-function ediff-metajob-name
1313 ;; make it update car info after startup 1515 ;; make it update car info after startup
1314 (` (list (lambda () 1516 (` (list (lambda ()
1315 ;; child session group should know its parent 1517 ;; child session group should know its parent and
1518 ;; its number
1316 (setq ediff-parent-meta-buffer 1519 (setq ediff-parent-meta-buffer
1317 (quote (, ediff-meta-buffer))) 1520 (quote (, ediff-meta-buffer))
1521 ediff-meta-session-number
1522 (, session-number))
1318 ;; and parent will know its child 1523 ;; and parent will know its child
1319 (setcar (quote (, info)) ediff-meta-buffer))))))) 1524 (setcar (quote (, info)) ediff-meta-buffer)))))))
1320 1525
@@ -1334,11 +1539,13 @@ all marked sessions must be active."
1334 file1 file2 1539 file1 file2
1335 ;; provide startup hooks 1540 ;; provide startup hooks
1336 (` (list (lambda () 1541 (` (list (lambda ()
1337 (setq ediff-meta-buffer (, (current-buffer))) 1542 (setq ediff-meta-buffer (, (current-buffer))
1543 ediff-meta-session-number
1544 (, session-number))
1338 (setq ediff-merge-store-file 1545 (setq ediff-merge-store-file
1339 (, (concat 1546 (, (concat
1340 merge-autostore-dir 1547 merge-autostore-dir
1341 "mrg_" 1548 "merge_"
1342 (file-name-nondirectory file1)))) 1549 (file-name-nondirectory file1))))
1343 ;; make ediff-startup pass 1550 ;; make ediff-startup pass
1344 ;; ediff-control-buffer back to the meta 1551 ;; ediff-control-buffer back to the meta
@@ -1351,11 +1558,13 @@ all marked sessions must be active."
1351 file1 1558 file1
1352 ;; provide startup hooks 1559 ;; provide startup hooks
1353 (` (list (lambda () 1560 (` (list (lambda ()
1354 (setq ediff-meta-buffer (, (current-buffer))) 1561 (setq ediff-meta-buffer (, (current-buffer))
1562 ediff-meta-session-number
1563 (, session-number))
1355 (setq ediff-merge-store-file 1564 (setq ediff-merge-store-file
1356 (, (concat 1565 (, (concat
1357 merge-autostore-dir 1566 merge-autostore-dir
1358 "mrg_" 1567 "merge_"
1359 (file-name-nondirectory file1)))) 1568 (file-name-nondirectory file1))))
1360 ;; make ediff-startup pass 1569 ;; make ediff-startup pass
1361 ;; ediff-control-buffer back to the meta 1570 ;; ediff-control-buffer back to the meta
@@ -1367,11 +1576,13 @@ all marked sessions must be active."
1367 file1 file2 1576 file1 file2
1368 ;; provide startup hooks 1577 ;; provide startup hooks
1369 (` (list (lambda () 1578 (` (list (lambda ()
1370 (setq ediff-meta-buffer (, (current-buffer))) 1579 (setq ediff-meta-buffer (, (current-buffer))
1580 ediff-meta-session-number
1581 (, session-number))
1371 (setq ediff-merge-store-file 1582 (setq ediff-merge-store-file
1372 (, (concat 1583 (, (concat
1373 merge-autostore-dir 1584 merge-autostore-dir
1374 "mrg_" 1585 "merge_"
1375 (file-name-nondirectory file1)))) 1586 (file-name-nondirectory file1))))
1376 ;; make ediff-startup pass 1587 ;; make ediff-startup pass
1377 ;; ediff-control-buffer back to the meta 1588 ;; ediff-control-buffer back to the meta
@@ -1386,9 +1597,11 @@ all marked sessions must be active."
1386 (setq ediff-merge-store-file 1597 (setq ediff-merge-store-file
1387 (, (concat 1598 (, (concat
1388 merge-autostore-dir 1599 merge-autostore-dir
1389 "mrg_" 1600 "merge_"
1390 (file-name-nondirectory file1)))) 1601 (file-name-nondirectory file1))))
1391 (setq ediff-meta-buffer (, (current-buffer))) 1602 (setq ediff-meta-buffer (, (current-buffer))
1603 ediff-meta-session-number
1604 (, session-number))
1392 ;; this arranges that ediff-startup will pass 1605 ;; this arranges that ediff-startup will pass
1393 ;; the value of ediff-control-buffer back to 1606 ;; the value of ediff-control-buffer back to
1394 ;; the meta level, to the record in the meta 1607 ;; the meta level, to the record in the meta
@@ -1413,7 +1626,7 @@ all marked sessions must be active."
1413 (if (ediff-with-current-buffer ctl-buf 1626 (if (ediff-with-current-buffer ctl-buf
1414 (eq (key-binding "q") 'ediff-quit-meta-buffer)) 1627 (eq (key-binding "q") 'ediff-quit-meta-buffer))
1415 ;; it's a meta-buffer -- last action should just display it 1628 ;; it's a meta-buffer -- last action should just display it
1416 (ediff-show-meta-buffer ctl-buf) 1629 (ediff-show-meta-buffer ctl-buf t)
1417 ;; it's a session buffer -- invoke go back to session 1630 ;; it's a session buffer -- invoke go back to session
1418 (ediff-with-current-buffer ctl-buf 1631 (ediff-with-current-buffer ctl-buf
1419 (setq ediff-mouse-pixel-position (mouse-pixel-position)) 1632 (setq ediff-mouse-pixel-position (mouse-pixel-position))
@@ -1426,7 +1639,8 @@ all marked sessions must be active."
1426 )) 1639 ))
1427 1640
1428 1641
1429(defun ediff-show-meta-buffer (&optional meta-buf) 1642;; If session number is t, means don't update meta buffer
1643(defun ediff-show-meta-buffer (&optional meta-buf session-number)
1430 "Show the session group buffer." 1644 "Show the session group buffer."
1431 (interactive) 1645 (interactive)
1432 (let (wind frame silent) 1646 (let (wind frame silent)
@@ -1439,7 +1653,12 @@ all marked sessions must be active."
1439 (error 1653 (error
1440 "Can't find this session's group panel -- session itself is ok"))) 1654 "Can't find this session's group panel -- session itself is ok")))
1441 1655
1442 (ediff-cleanup-meta-buffer meta-buf) 1656 (cond ((numberp session-number)
1657 (ediff-update-meta-buffer meta-buf nil session-number))
1658 ;; if session-number is t, don't update
1659 (session-number)
1660 (t (ediff-cleanup-meta-buffer meta-buf)))
1661
1443 (ediff-with-current-buffer meta-buf 1662 (ediff-with-current-buffer meta-buf
1444 (save-excursion 1663 (save-excursion
1445 (cond ((setq wind (ediff-get-visible-buffer-window meta-buf)) 1664 (cond ((setq wind (ediff-get-visible-buffer-window meta-buf))
@@ -1477,6 +1696,10 @@ all marked sessions must be active."
1477 (run-hooks 'ediff-show-session-group-hook) 1696 (run-hooks 'ediff-show-session-group-hook)
1478 )) 1697 ))
1479 1698
1699(defun ediff-show-current-session-meta-buffer ()
1700 (interactive)
1701 (ediff-show-meta-buffer nil ediff-meta-session-number))
1702
1480(defun ediff-show-meta-buff-from-registry () 1703(defun ediff-show-meta-buff-from-registry ()
1481 "Display the session group buffer for a selected session group." 1704 "Display the session group buffer for a selected session group."
1482 (interactive) 1705 (interactive)
@@ -1485,7 +1708,7 @@ all marked sessions must be active."
1485 (info (ediff-get-meta-info meta-buf pos)) 1708 (info (ediff-get-meta-info meta-buf pos))
1486 (meta-or-session-buf info)) 1709 (meta-or-session-buf info))
1487 (ediff-with-current-buffer meta-or-session-buf 1710 (ediff-with-current-buffer meta-or-session-buf
1488 (ediff-show-meta-buffer)))) 1711 (ediff-show-meta-buffer nil t))))
1489 1712
1490;;;###autoload 1713;;;###autoload
1491(defun ediff-show-registry () 1714(defun ediff-show-registry ()
@@ -1538,12 +1761,20 @@ all marked sessions must be active."
1538;; If meta-buf doesn't exist, it is created. In that case, id doesn't have a 1761;; If meta-buf doesn't exist, it is created. In that case, id doesn't have a
1539;; parent meta-buf 1762;; parent meta-buf
1540;; Check if META-BUF exists before calling this function 1763;; Check if META-BUF exists before calling this function
1541(defun ediff-update-meta-buffer (meta-buf) 1764;; Optional MUST-REDRAW, if non-nil, would force redrawal of the whole meta
1542 (ediff-with-current-buffer (current-buffer) 1765;; buffer. Otherwise, it will just go over the buffer and update activity marks
1543 (if (ediff-buffer-live-p meta-buf) 1766;; and session status.
1544 (ediff-with-current-buffer meta-buf 1767;; SESSION-NUMBER, if specified, says which session caused the update.
1545 (funcall ediff-meta-redraw-function ediff-meta-list)) 1768(defun ediff-update-meta-buffer (meta-buf &optional must-redraw session-number)
1546 ))) 1769 (if (ediff-buffer-live-p meta-buf)
1770 (ediff-with-current-buffer meta-buf
1771 (cond (must-redraw ; completely redraw the meta buffer
1772 (funcall ediff-meta-redraw-function ediff-meta-list))
1773 ((numberp session-number) ; redraw only for the given session
1774 (ediff-update-session-marker-in-dir-meta-buffer session-number))
1775 (t ; update only what's changed, but scan the entire meta buffer
1776 (ediff-update-markers-in-dir-meta-buffer ediff-meta-list)))
1777 )))
1547 1778
1548(defun ediff-update-registry () 1779(defun ediff-update-registry ()
1549 (ediff-with-current-buffer (current-buffer) 1780 (ediff-with-current-buffer (current-buffer)
@@ -1564,15 +1795,16 @@ all marked sessions must be active."
1564 (ediff-with-current-buffer meta-buffer 1795 (ediff-with-current-buffer meta-buffer
1565 (ediff-update-meta-buffer meta-buffer) 1796 (ediff-update-meta-buffer meta-buffer)
1566 (if (ediff-buffer-live-p ediff-parent-meta-buffer) 1797 (if (ediff-buffer-live-p ediff-parent-meta-buffer)
1567 (ediff-update-meta-buffer ediff-parent-meta-buffer))))) 1798 (ediff-update-meta-buffer
1799 ediff-parent-meta-buffer nil ediff-meta-session-number)))))
1568 1800
1569;; t if no session in progress 1801;; t if no session is in progress
1570(defun ediff-safe-to-quit (meta-buffer) 1802(defun ediff-safe-to-quit (meta-buffer)
1571 (if (ediff-buffer-live-p meta-buffer) 1803 (if (ediff-buffer-live-p meta-buffer)
1572 (let ((lis ediff-meta-list) 1804 (let ((lis ediff-meta-list)
1573 (cont t) 1805 (cont t)
1574 buffer-read-only) 1806 buffer-read-only)
1575 (ediff-update-meta-buffer meta-buffer) 1807 ;;(ediff-update-meta-buffer meta-buffer)
1576 (ediff-with-current-buffer meta-buffer 1808 (ediff-with-current-buffer meta-buffer
1577 (setq lis (cdr lis)) ; discard the description part of meta-list 1809 (setq lis (cdr lis)) ; discard the description part of meta-list
1578 (while (and cont lis) 1810 (while (and cont lis)
@@ -1591,11 +1823,12 @@ If this is a session registry buffer then just bury it."
1591 (let* ((buf (current-buffer)) 1823 (let* ((buf (current-buffer))
1592 (dir-diffs-buffer ediff-dir-diffs-buffer) 1824 (dir-diffs-buffer ediff-dir-diffs-buffer)
1593 (meta-diff-buffer ediff-meta-diff-buffer) 1825 (meta-diff-buffer ediff-meta-diff-buffer)
1826 (session-number ediff-meta-session-number)
1594 (parent-buf ediff-parent-meta-buffer) 1827 (parent-buf ediff-parent-meta-buffer)
1595 (dont-show-registry (eq buf ediff-registry-buffer))) 1828 (dont-show-registry (eq buf ediff-registry-buffer)))
1596 (if dont-show-registry 1829 (if dont-show-registry
1597 (bury-buffer) 1830 (bury-buffer)
1598 (ediff-cleanup-meta-buffer buf) 1831 ;;(ediff-cleanup-meta-buffer buf)
1599 (cond ((and (ediff-safe-to-quit buf) 1832 (cond ((and (ediff-safe-to-quit buf)
1600 (y-or-n-p "Quit this session group? ")) 1833 (y-or-n-p "Quit this session group? "))
1601 (run-hooks 'ediff-quit-session-group-hook) 1834 (run-hooks 'ediff-quit-session-group-hook)
@@ -1606,13 +1839,13 @@ If this is a session registry buffer then just bury it."
1606 (t 1839 (t
1607 (error 1840 (error
1608 "This session group has active sessions---cannot exit"))) 1841 "This session group has active sessions---cannot exit")))
1609 (ediff-cleanup-meta-buffer parent-buf) 1842 (ediff-update-meta-buffer parent-buf nil session-number)
1610 (ediff-kill-buffer-carefully dir-diffs-buffer) 1843 (ediff-kill-buffer-carefully dir-diffs-buffer)
1611 (ediff-kill-buffer-carefully meta-diff-buffer) 1844 (ediff-kill-buffer-carefully meta-diff-buffer)
1612 (if (ediff-buffer-live-p parent-buf) 1845 (if (ediff-buffer-live-p parent-buf)
1613 (progn 1846 (progn
1614 (setq dont-show-registry t) 1847 (setq dont-show-registry t)
1615 (ediff-show-meta-buffer parent-buf))) 1848 (ediff-show-meta-buffer parent-buf session-number)))
1616 ) 1849 )
1617 (or dont-show-registry 1850 (or dont-show-registry
1618 (ediff-show-registry)))) 1851 (ediff-show-registry))))
@@ -1653,46 +1886,58 @@ If this is a session registry buffer then just bury it."
1653 (ediff-update-registry) 1886 (ediff-update-registry)
1654 (error "No session info in this line"))))) 1887 (error "No session info in this line")))))
1655 1888
1656;; return location of the next meta overlay after point 1889
1890(defun ediff-get-meta-overlay-at-pos (point)
1891 (if ediff-xemacs-p
1892 (extent-at point (current-buffer) 'ediff-meta-info)
1893 (let* ((overl-list (overlays-at point))
1894 (overl (car overl-list)))
1895 (while (and overl (null (overlay-get overl 'ediff-meta-info)))
1896 (setq overl-list (cdr overl-list)
1897 overl (car overl-list)))
1898 overl)))
1899
1900(defsubst ediff-get-session-number-at-pos (point)
1901 (ediff-overlay-get
1902 (ediff-get-meta-overlay-at-pos point) 'ediff-meta-session-number))
1903
1904
1905;; Return location of the next meta overlay after point
1657(defun ediff-next-meta-overlay-start (point) 1906(defun ediff-next-meta-overlay-start (point)
1658 (if (eobp) 1907 (if (eobp)
1659 (goto-char (point-min)) 1908 (goto-char (point-min))
1660 (let (overl) 1909 (let ((overl (ediff-get-meta-overlay-at-pos point)))
1661 (if ediff-xemacs-p 1910 (if ediff-xemacs-p
1662 (progn 1911 (progn
1663 (setq overl (extent-at point (current-buffer) 'ediff-meta-info))
1664 (if overl 1912 (if overl
1665 (setq overl (next-extent overl)) 1913 (setq overl (next-extent overl))
1666 (setq overl (next-extent (current-buffer)))) 1914 (setq overl (next-extent (current-buffer))))
1667 (if overl 1915 (if overl
1668 (extent-start-position overl) 1916 (extent-start-position overl)
1669 (point-max))) 1917 (point-max)))
1670 (setq overl (car (overlays-at point))) 1918 (if overl
1671 (if (and overl (overlay-get overl 'ediff-meta-info))
1672 ;; note: end of current overlay is the beginning of the next one 1919 ;; note: end of current overlay is the beginning of the next one
1673 (overlay-end overl) 1920 (overlay-end overl)
1674 (next-overlay-change point)))) 1921 (next-overlay-change point))))
1675 )) 1922 ))
1676 1923
1924
1677(defun ediff-previous-meta-overlay-start (point) 1925(defun ediff-previous-meta-overlay-start (point)
1678 (if (bobp) 1926 (if (bobp)
1679 (goto-char (point-max)) 1927 (goto-char (point-max))
1680 (let (overl) 1928 (let ((overl (ediff-get-meta-overlay-at-pos point)))
1681 (if ediff-xemacs-p 1929 (if ediff-xemacs-p
1682 (progn 1930 (progn
1683 (setq overl (extent-at point (current-buffer) 'ediff-meta-info))
1684 (if overl 1931 (if overl
1685 (setq overl (previous-extent overl)) 1932 (setq overl (previous-extent overl))
1686 (setq overl (previous-extent (current-buffer)))) 1933 (setq overl (previous-extent (current-buffer))))
1687 (if overl 1934 (if overl
1688 (extent-start-position overl) 1935 (extent-start-position overl)
1689 (point-min))) 1936 (point-min)))
1690 (setq overl (car (overlays-at point))) 1937 (if overl (setq point (overlay-start overl)))
1691 (if (and overl (overlay-get overl 'ediff-meta-info))
1692 (setq point (overlay-start overl)))
1693 ;; to get to the beginning of prev overlay 1938 ;; to get to the beginning of prev overlay
1694 (if (not (bobp)) 1939 (if (not (bobp))
1695 ;; trickery to overcome an emacs bug--doesn't always find previous 1940 ;; trick to overcome an emacs bug--doesn't always find previous
1696 ;; overlay change correctly 1941 ;; overlay change correctly
1697 (setq point (1- point))) 1942 (setq point (1- point)))
1698 (setq point (previous-overlay-change point)) 1943 (setq point (previous-overlay-change point))
@@ -1701,8 +1946,7 @@ If this is a session registry buffer then just bury it."
1701 ;; goto the top of the registry buffer. 1946 ;; goto the top of the registry buffer.
1702 (or (car (overlays-at point)) 1947 (or (car (overlays-at point))
1703 (setq point (point-min))) 1948 (setq point (point-min)))
1704 point 1949 point))))
1705 ))))
1706 1950
1707;; this is the action invoked when the user selects a patch from the meta 1951;; this is the action invoked when the user selects a patch from the meta
1708;; buffer. 1952;; buffer.
@@ -1752,19 +1996,18 @@ This is used only for sessions that involve 2 or 3 files at the same time."
1752 (ediff-mark-if-equal fileinfo1 fileinfo3) 1996 (ediff-mark-if-equal fileinfo1 fileinfo3)
1753 (ediff-mark-if-equal fileinfo2 fileinfo3))) 1997 (ediff-mark-if-equal fileinfo2 fileinfo3)))
1754 (setq list (cdr list)))) 1998 (setq list (cdr list))))
1755 (ediff-update-meta-buffer (current-buffer))) 1999 (ediff-update-meta-buffer (current-buffer) 'must-redraw))
1756 2000
1757;; mark files 1 and 2 as equal, if they are. 2001;; mark files 1 and 2 as equal, if they are.
1758(defun ediff-mark-if-equal (fileinfo1 fileinfo2) 2002(defun ediff-mark-if-equal (fileinfo1 fileinfo2)
1759 (get-buffer-create ediff-tmp-buffer) 2003 (let ((f1 (car fileinfo1))
1760 (or (file-directory-p (car fileinfo1)) 2004 (f2 (car fileinfo2)))
1761 (file-directory-p (car fileinfo2)) 2005 (or (file-directory-p f1)
1762 (if (= (ediff-make-diff2-buffer 2006 (file-directory-p f2)
1763 ediff-tmp-buffer (car fileinfo1) (car fileinfo2)) 2007 (if (ediff-same-file-contents f1 f2)
1764 0) 2008 (progn
1765 (progn 2009 (ediff-set-file-eqstatus fileinfo1 t)
1766 (ediff-set-file-eqstatus fileinfo1 t) 2010 (ediff-set-file-eqstatus fileinfo2 t))))))
1767 (ediff-set-file-eqstatus fileinfo2 t)))))
1768 2011
1769 2012
1770 2013
diff --git a/lisp/ediff-util.el b/lisp/ediff-util.el
index 0887bec863e..ed7c62661f9 100644
--- a/lisp/ediff-util.el
+++ b/lisp/ediff-util.el
@@ -178,7 +178,7 @@ to invocation.")
178 (define-key ediff-mode-map "E" 'ediff-documentation) 178 (define-key ediff-mode-map "E" 'ediff-documentation)
179 (define-key ediff-mode-map "?" 'ediff-toggle-help) 179 (define-key ediff-mode-map "?" 'ediff-toggle-help)
180 (define-key ediff-mode-map "!" 'ediff-update-diffs) 180 (define-key ediff-mode-map "!" 'ediff-update-diffs)
181 (define-key ediff-mode-map "M" 'ediff-show-meta-buffer) 181 (define-key ediff-mode-map "M" 'ediff-show-current-session-meta-buffer)
182 (define-key ediff-mode-map "R" 'ediff-show-registry) 182 (define-key ediff-mode-map "R" 'ediff-show-registry)
183 (or ediff-word-mode 183 (or ediff-word-mode
184 (define-key ediff-mode-map "*" 'ediff-make-or-kill-fine-diffs)) 184 (define-key ediff-mode-map "*" 'ediff-make-or-kill-fine-diffs))
@@ -251,7 +251,8 @@ to invocation.")
251;; STARTUP-HOOKS, but these parameters are set in the new control buffer right 251;; STARTUP-HOOKS, but these parameters are set in the new control buffer right
252;; after this buf is created and before any windows are set and such. 252;; after this buf is created and before any windows are set and such.
253(defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C 253(defun ediff-setup (buffer-A file-A buffer-B file-B buffer-C file-C
254 startup-hooks setup-parameters) 254 startup-hooks setup-parameters
255 &optional merge-buffer-file)
255 ;; ediff-convert-standard-filename puts file names in the form appropriate 256 ;; ediff-convert-standard-filename puts file names in the form appropriate
256 ;; for the OS at hand. 257 ;; for the OS at hand.
257 (setq file-A (ediff-convert-standard-filename (expand-file-name file-A))) 258 (setq file-A (ediff-convert-standard-filename (expand-file-name file-A)))
@@ -259,6 +260,21 @@ to invocation.")
259 (if (stringp file-C) 260 (if (stringp file-C)
260 (setq file-C 261 (setq file-C
261 (ediff-convert-standard-filename (expand-file-name file-C)))) 262 (ediff-convert-standard-filename (expand-file-name file-C))))
263 (if (stringp merge-buffer-file)
264 (progn
265 (setq merge-buffer-file
266 (ediff-convert-standard-filename
267 (expand-file-name merge-buffer-file)))
268 ;; check the directory exists
269 (or (file-exists-p (file-name-directory merge-buffer-file))
270 (error "Directory %s given as place to save the merge doesn't exist."
271 (abbreviate-file-name
272 (file-name-directory merge-buffer-file))))
273 (if (and (file-exists-p merge-buffer-file)
274 (file-directory-p merge-buffer-file))
275 (error "The merge buffer file %s must not be a directory"
276 (abbreviate-file-name merge-buffer-file)))
277 ))
262 (let* ((control-buffer-name 278 (let* ((control-buffer-name
263 (ediff-unique-buffer-name "*Ediff Control Panel" "*")) 279 (ediff-unique-buffer-name "*Ediff Control Panel" "*"))
264 (control-buffer (ediff-with-current-buffer buffer-A 280 (control-buffer (ediff-with-current-buffer buffer-A
@@ -327,7 +343,6 @@ to invocation.")
327 (set-buffer buffer-C) 343 (set-buffer buffer-C)
328 (insert-buffer buf) 344 (insert-buffer buf)
329 (funcall (ediff-with-current-buffer buf major-mode)) 345 (funcall (ediff-with-current-buffer buf major-mode))
330 ;; after Stig@hackvan.com
331 (add-hook 'local-write-file-hooks 'ediff-set-merge-mode nil t) 346 (add-hook 'local-write-file-hooks 'ediff-set-merge-mode nil t)
332 ))) 347 )))
333 (setq buffer-read-only nil 348 (setq buffer-read-only nil
@@ -489,13 +504,16 @@ to invocation.")
489 (ediff-visible-region) 504 (ediff-visible-region)
490 505
491 (run-hooks 'startup-hooks) 506 (run-hooks 'startup-hooks)
507 (ediff-arrange-autosave-in-merge-jobs merge-buffer-file)
508
492 (ediff-refresh-mode-lines) 509 (ediff-refresh-mode-lines)
493 (setq buffer-read-only t) 510 (setq buffer-read-only t)
494 (setq ediff-session-registry 511 (setq ediff-session-registry
495 (cons control-buffer ediff-session-registry)) 512 (cons control-buffer ediff-session-registry))
496 (ediff-update-registry) 513 (ediff-update-registry)
497 (if (ediff-buffer-live-p ediff-meta-buffer) 514 (if (ediff-buffer-live-p ediff-meta-buffer)
498 (ediff-update-meta-buffer ediff-meta-buffer)) 515 (ediff-update-meta-buffer
516 ediff-meta-buffer nil ediff-meta-session-number))
499 (run-hooks 'ediff-startup-hook) 517 (run-hooks 'ediff-startup-hook)
500 ) ; eval in control-buffer 518 ) ; eval in control-buffer
501 control-buffer)) 519 control-buffer))
@@ -536,7 +554,25 @@ to invocation.")
536 (goto-char (point-min)) 554 (goto-char (point-min))
537 (skip-chars-forward ediff-whitespace))) 555 (skip-chars-forward ediff-whitespace)))
538 556
539 557;; This executes in control buffer and sets auto-save, visited file name, etc,
558;; in the merge buffer
559(defun ediff-arrange-autosave-in-merge-jobs (merge-buffer-file)
560 (if (not ediff-merge-job)
561 ()
562 (if (stringp merge-buffer-file)
563 (setq ediff-autostore-merges t
564 ediff-merge-store-file merge-buffer-file))
565 (if (stringp ediff-merge-store-file)
566 (progn
567 ;; save before leaving ctl buffer
568 (setq merge-buffer-file ediff-merge-store-file)
569 (ediff-with-current-buffer ediff-buffer-C
570 (set-visited-file-name merge-buffer-file))))
571 (ediff-with-current-buffer ediff-buffer-C
572 (setq buffer-offer-save t) ; ask before killing buffer
573 ;; make sure the contents is auto-saved
574 (auto-save-mode 1))
575 ))
540 576
541 577
542;;; Commands for working with Ediff 578;;; Commands for working with Ediff
@@ -1330,13 +1366,15 @@ Used in ediff-windows/regions only."
1330 'C ediff-visible-bounds)) 1366 'C ediff-visible-bounds))
1331 ) 1367 )
1332 (ediff-with-current-buffer ediff-buffer-A 1368 (ediff-with-current-buffer ediff-buffer-A
1333 (narrow-to-region 1369 (if (ediff-overlay-buffer overl-A)
1334 (ediff-overlay-start overl-A) (ediff-overlay-end overl-A))) 1370 (narrow-to-region
1371 (ediff-overlay-start overl-A) (ediff-overlay-end overl-A))))
1335 (ediff-with-current-buffer ediff-buffer-B 1372 (ediff-with-current-buffer ediff-buffer-B
1336 (narrow-to-region 1373 (if (ediff-overlay-buffer overl-B)
1337 (ediff-overlay-start overl-B) (ediff-overlay-end overl-B))) 1374 (narrow-to-region
1375 (ediff-overlay-start overl-B) (ediff-overlay-end overl-B))))
1338 1376
1339 (if ediff-3way-job 1377 (if (and ediff-3way-job (ediff-overlay-buffer overl-C))
1340 (ediff-with-current-buffer ediff-buffer-C 1378 (ediff-with-current-buffer ediff-buffer-C
1341 (narrow-to-region 1379 (narrow-to-region
1342 (ediff-overlay-start overl-C) (ediff-overlay-end overl-C)))) 1380 (ediff-overlay-start overl-C) (ediff-overlay-end overl-C))))
@@ -2291,6 +2329,7 @@ temporarily reverses the meaning of this variable."
2291 ;; restore buffer mode line id's in buffer-A/B/C 2329 ;; restore buffer mode line id's in buffer-A/B/C
2292 (let ((control-buffer ediff-control-buffer) 2330 (let ((control-buffer ediff-control-buffer)
2293 (meta-buffer ediff-meta-buffer) 2331 (meta-buffer ediff-meta-buffer)
2332 (session-number ediff-meta-session-number)
2294 ;; suitable working frame 2333 ;; suitable working frame
2295 (warp-frame (if (and (ediff-window-display-p) (eq ediff-grab-mouse t)) 2334 (warp-frame (if (and (ediff-window-display-p) (eq ediff-grab-mouse t))
2296 (cond ((window-live-p ediff-window-A) 2335 (cond ((window-live-p ediff-window-A)
@@ -2355,7 +2394,7 @@ temporarily reverses the meaning of this variable."
2355 (or ediff-keep-variants (ediff-janitor 'ask))) 2394 (or ediff-keep-variants (ediff-janitor 'ask)))
2356 2395
2357 (run-hooks 'ediff-quit-hook) 2396 (run-hooks 'ediff-quit-hook)
2358 (ediff-cleanup-meta-buffer meta-buffer) 2397 (ediff-update-meta-buffer meta-buffer nil session-number)
2359 2398
2360 ;; warp mouse into a working window 2399 ;; warp mouse into a working window
2361 (setq warp-frame ; if mouse is over a reasonable frame, use it 2400 (setq warp-frame ; if mouse is over a reasonable frame, use it
@@ -2368,7 +2407,7 @@ temporarily reverses the meaning of this variable."
2368 2 1)) 2407 2 1))
2369 2408
2370 (if (ediff-buffer-live-p meta-buffer) 2409 (if (ediff-buffer-live-p meta-buffer)
2371 (ediff-show-meta-buffer meta-buffer)) 2410 (ediff-show-meta-buffer meta-buffer session-number))
2372 )) 2411 ))
2373 2412
2374;; Returns frame under mouse, if this frame is not a minibuffer 2413;; Returns frame under mouse, if this frame is not a minibuffer
@@ -2391,11 +2430,11 @@ temporarily reverses the meaning of this variable."
2391 2430
2392 2431
2393(defun ediff-delete-temp-files () 2432(defun ediff-delete-temp-files ()
2394 (if (stringp ediff-temp-file-A) 2433 (if (and (stringp ediff-temp-file-A) (file-exists-p ediff-temp-file-A))
2395 (delete-file ediff-temp-file-A)) 2434 (delete-file ediff-temp-file-A))
2396 (if (stringp ediff-temp-file-B) 2435 (if (and (stringp ediff-temp-file-B) (file-exists-p ediff-temp-file-B))
2397 (delete-file ediff-temp-file-B)) 2436 (delete-file ediff-temp-file-B))
2398 (if (stringp ediff-temp-file-C) 2437 (if (and (stringp ediff-temp-file-C) (file-exists-p ediff-temp-file-C))
2399 (delete-file ediff-temp-file-C))) 2438 (delete-file ediff-temp-file-C)))
2400 2439
2401 2440
@@ -2538,6 +2577,7 @@ only if this merge job is part of a group, i.e., was invoked from within
2538 (if show-file 2577 (if show-file
2539 (progn 2578 (progn
2540 (message "Merge buffer saved in: %s" file) 2579 (message "Merge buffer saved in: %s" file)
2580 (set-buffer-modified-p nil)
2541 (sit-for 2))) 2581 (sit-for 2)))
2542 (if (and 2582 (if (and
2543 (not save-and-continue) 2583 (not save-and-continue)
diff --git a/lisp/ediff-vers.el b/lisp/ediff-vers.el
index 00b7b41f51e..1d5f5fcd008 100644
--- a/lisp/ediff-vers.el
+++ b/lisp/ediff-vers.el
@@ -146,7 +146,8 @@
146 146
147;;; Merge with Version Control 147;;; Merge with Version Control
148 148
149(defun ediff-vc-merge-internal (rev1 rev2 ancestor-rev &optional startup-hooks) 149(defun ediff-vc-merge-internal (rev1 rev2 ancestor-rev
150 &optional startup-hooks merge-buffer-file)
150;; If ANCESTOR-REV non-nil, merge with ancestor 151;; If ANCESTOR-REV non-nil, merge with ancestor
151 (let (buf1 buf2 ancestor-buf) 152 (let (buf1 buf2 ancestor-buf)
152 (save-excursion 153 (save-excursion
@@ -175,12 +176,14 @@
175 (if ancestor-rev 176 (if ancestor-rev
176 (ediff-merge-buffers-with-ancestor 177 (ediff-merge-buffers-with-ancestor
177 buf1 buf2 ancestor-buf 178 buf1 buf2 ancestor-buf
178 startup-hooks 'ediff-merge-revisions-with-ancestor) 179 startup-hooks 'ediff-merge-revisions-with-ancestor merge-buffer-file)
179 (ediff-merge-buffers buf1 buf2 startup-hooks 'ediff-merge-revisions)) 180 (ediff-merge-buffers
181 buf1 buf2 startup-hooks 'ediff-merge-revisions merge-buffer-file))
180 )) 182 ))
181 183
182(defun ediff-rcs-merge-internal (rev1 rev2 ancestor-rev 184(defun ediff-rcs-merge-internal (rev1 rev2 ancestor-rev
183 &optional startup-hooks) 185 &optional
186 startup-hooks merge-buffer-file)
184 ;; If ANCESTOR-REV non-nil, merge with ancestor 187 ;; If ANCESTOR-REV non-nil, merge with ancestor
185 (let (buf1 buf2 ancestor-buf) 188 (let (buf1 buf2 ancestor-buf)
186 (setq buf1 (rcs-ediff-view-revision rev1) 189 (setq buf1 (rcs-ediff-view-revision rev1)
@@ -196,11 +199,13 @@
196 (if ancestor-rev 199 (if ancestor-rev
197 (ediff-merge-buffers-with-ancestor 200 (ediff-merge-buffers-with-ancestor
198 buf1 buf2 ancestor-buf 201 buf1 buf2 ancestor-buf
199 startup-hooks 'ediff-merge-revisions-with-ancestor) 202 startup-hooks 'ediff-merge-revisions-with-ancestor merge-buffer-file)
200 (ediff-merge-buffers buf1 buf2 startup-hooks 'ediff-merge-revisions)))) 203 (ediff-merge-buffers
204 buf1 buf2 startup-hooks 'ediff-merge-revisions merge-buffer-file))))
201 205
202(defun ediff-generic-sc-merge-internal (rev1 rev2 ancestor-rev 206(defun ediff-generic-sc-merge-internal (rev1 rev2 ancestor-rev
203 &optional startup-hooks) 207 &optional
208 startup-hooks merge-buffer-file)
204 ;; If ANCESTOR-REV non-nil, merge with ancestor 209 ;; If ANCESTOR-REV non-nil, merge with ancestor
205 (let (buf1 buf2 ancestor-buf) 210 (let (buf1 buf2 ancestor-buf)
206 (save-excursion 211 (save-excursion
@@ -220,8 +225,9 @@
220 (if ancestor-rev 225 (if ancestor-rev
221 (ediff-merge-buffers-with-ancestor 226 (ediff-merge-buffers-with-ancestor
222 buf1 buf2 ancestor-buf 227 buf1 buf2 ancestor-buf
223 startup-hooks 'ediff-merge-revisions-with-ancestor) 228 startup-hooks 'ediff-merge-revisions-with-ancestor merge-buffer-file)
224 (ediff-merge-buffers buf1 buf2 startup-hooks 'ediff-merge-revisions)))) 229 (ediff-merge-buffers
230 buf1 buf2 startup-hooks 'ediff-merge-revisions merge-buffer-file))))
225 231
226 232
227;; PCL-CVS.el support 233;; PCL-CVS.el support
@@ -254,7 +260,8 @@
254;; Works like with other interfaces: runs ediff on versions of the file in the 260;; Works like with other interfaces: runs ediff on versions of the file in the
255;; current buffer. 261;; current buffer.
256(defun ediff-pcl-cvs-merge-internal (rev1 rev2 ancestor-rev 262(defun ediff-pcl-cvs-merge-internal (rev1 rev2 ancestor-rev
257 &optional startup-hooks) 263 &optional
264 startup-hooks merge-buffer-file)
258;; Ediff-merge appropriate revisions of the selected file. 265;; Ediff-merge appropriate revisions of the selected file.
259;; If REV1 is "" then use the latest revision. 266;; If REV1 is "" then use the latest revision.
260;; If REV2 is "" then merge current buffer's file with REV1. 267;; If REV2 is "" then merge current buffer's file with REV1.
@@ -292,9 +299,9 @@
292 (if ancestor-buf 299 (if ancestor-buf
293 (ediff-merge-buffers-with-ancestor 300 (ediff-merge-buffers-with-ancestor
294 buf1 buf2 ancestor-buf startup-hooks 301 buf1 buf2 ancestor-buf startup-hooks
295 'ediff-merge-revisions-with-ancestor) 302 'ediff-merge-revisions-with-ancestor merge-buffer-file)
296 (ediff-merge-buffers 303 (ediff-merge-buffers
297 buf1 buf2 startup-hooks 'ediff-merge-revisions)) 304 buf1 buf2 startup-hooks 'ediff-merge-revisions merge-buffer-file))
298 )) 305 ))
299 306
300(defun ediff-pcl-cvs-view-revision (file rev) 307(defun ediff-pcl-cvs-view-revision (file rev)
@@ -324,7 +331,7 @@
324 331
325(defun cvs-run-ediff-on-file-descriptor (tin) 332(defun cvs-run-ediff-on-file-descriptor (tin)
326;; This is a replacement for cvs-emerge-mode 333;; This is a replacement for cvs-emerge-mode
327;; Run after cvs-update. 334;; Runs after cvs-update.
328;; Ediff-merge appropriate revisions of the selected file. 335;; Ediff-merge appropriate revisions of the selected file.
329 (let* ((fileinfo (tin-cookie cvs-cookie-handle tin)) 336 (let* ((fileinfo (tin-cookie cvs-cookie-handle tin))
330 (type (cvs-fileinfo->type fileinfo)) 337 (type (cvs-fileinfo->type fileinfo))
diff --git a/lisp/ediff.el b/lisp/ediff.el
index 829a6bc68cd..0068ea3efeb 100644
--- a/lisp/ediff.el
+++ b/lisp/ediff.el
@@ -6,8 +6,8 @@
6;; Created: February 2, 1994 6;; Created: February 2, 1994
7;; Keywords: comparing, merging, patching, version control. 7;; Keywords: comparing, merging, patching, version control.
8 8
9(defconst ediff-version "2.671" "The current version of Ediff") 9(defconst ediff-version "2.69" "The current version of Ediff")
10(defconst ediff-date "September 23, 1997" "Date of last update") 10(defconst ediff-date "October 10, 1997" "Date of last update")
11 11
12 12
13;; This file is part of GNU Emacs. 13;; This file is part of GNU Emacs.
@@ -314,7 +314,9 @@
314 (ediff-verify-file-buffer)))) 314 (ediff-verify-file-buffer))))
315 (set file-var file))) 315 (set file-var file)))
316 316
317(defun ediff-files-internal (file-A file-B file-C startup-hooks job-name) 317;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer
318(defun ediff-files-internal (file-A file-B file-C startup-hooks job-name
319 &optional merge-buffer-file)
318 (let (buf-A buf-B buf-C) 320 (let (buf-A buf-B buf-C)
319 (message "Reading file %s ... " file-A) 321 (message "Reading file %s ... " file-A)
320 ;;(sit-for 0) 322 ;;(sit-for 0)
@@ -335,7 +337,8 @@
335 buf-B file-B 337 buf-B file-B
336 buf-C file-C 338 buf-C file-C
337 startup-hooks 339 startup-hooks
338 (list (cons 'ediff-job-name job-name))))) 340 (list (cons 'ediff-job-name job-name))
341 merge-buffer-file)))
339 342
340 343
341;;;###autoload 344;;;###autoload
@@ -394,7 +397,9 @@
394 397
395 398
396 399
397(defun ediff-buffers-internal (buf-A buf-B buf-C startup-hooks job-name) 400;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer
401(defun ediff-buffers-internal (buf-A buf-B buf-C startup-hooks job-name
402 &optional merge-buffer-file)
398 (let* ((buf-A-file-name (buffer-file-name (get-buffer buf-A))) 403 (let* ((buf-A-file-name (buffer-file-name (get-buffer buf-A)))
399 (buf-B-file-name (buffer-file-name (get-buffer buf-B))) 404 (buf-B-file-name (buffer-file-name (get-buffer buf-B)))
400 (buf-C-is-alive (ediff-buffer-live-p buf-C)) 405 (buf-C-is-alive (ediff-buffer-live-p buf-C))
@@ -432,7 +437,7 @@
432 )) 437 ))
433 startup-hooks) 438 startup-hooks)
434 (list (cons 'ediff-job-name job-name)) 439 (list (cons 'ediff-job-name job-name))
435 ))) 440 merge-buffer-file)))
436 441
437 442
438;;; Directory and file group operations 443;;; Directory and file group operations
@@ -938,8 +943,7 @@ Continue anyway? (y/n) "))
938 (list (cons 'ediff-word-mode word-mode) 943 (list (cons 'ediff-word-mode word-mode)
939 (cons 'ediff-narrow-bounds (list overl-A overl-B)) 944 (cons 'ediff-narrow-bounds (list overl-A overl-B))
940 (cons 'ediff-job-name job-name)) 945 (cons 'ediff-job-name job-name))
941 setup-parameters) 946 setup-parameters))
942 )
943 )) 947 ))
944 948
945 949
@@ -954,7 +958,10 @@ Continue anyway? (y/n) "))
954 (set-buffer-modified-p nil))) 958 (set-buffer-modified-p nil)))
955 959
956;;;###autoload 960;;;###autoload
957(defun ediff-merge-files (file-A file-B &optional startup-hooks) 961(defun ediff-merge-files (file-A file-B
962 ;; MERGE-BUFFER-FILE is the file to be
963 ;; associated with the merge buffer
964 &optional startup-hooks merge-buffer-file)
958 "Merge two files without ancestor." 965 "Merge two files without ancestor."
959 (interactive 966 (interactive
960 (let ((dir-A (if ediff-use-last-dir 967 (let ((dir-A (if ediff-use-last-dir
@@ -986,11 +993,17 @@ Continue anyway? (y/n) "))
986 file-B) 993 file-B)
987 nil ; file-C 994 nil ; file-C
988 startup-hooks 995 startup-hooks
989 'ediff-merge-files)) 996 'ediff-merge-files
997 merge-buffer-file))
990 998
991;;;###autoload 999;;;###autoload
992(defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor 1000(defun ediff-merge-files-with-ancestor (file-A file-B file-ancestor
993 &optional startup-hooks) 1001 &optional
1002 startup-hooks
1003 ;; MERGE-BUFFER-FILE is the file
1004 ;; to be associated with the
1005 ;; merge buffer
1006 merge-buffer-file)
994 "Merge two files with ancestor." 1007 "Merge two files with ancestor."
995 (interactive 1008 (interactive
996 (let ((dir-A (if ediff-use-last-dir 1009 (let ((dir-A (if ediff-use-last-dir
@@ -1036,13 +1049,18 @@ Continue anyway? (y/n) "))
1036 file-B) 1049 file-B)
1037 file-ancestor 1050 file-ancestor
1038 startup-hooks 1051 startup-hooks
1039 'ediff-merge-files-with-ancestor)) 1052 'ediff-merge-files-with-ancestor
1053 merge-buffer-file))
1040 1054
1041;;;###autoload 1055;;;###autoload
1042(defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor) 1056(defalias 'ediff-merge-with-ancestor 'ediff-merge-files-with-ancestor)
1043 1057
1044;;;###autoload 1058;;;###autoload
1045(defun ediff-merge-buffers (buffer-A buffer-B &optional startup-hooks job-name) 1059(defun ediff-merge-buffers (buffer-A buffer-B
1060 &optional
1061 ;; MERGE-BUFFER-FILE is the file to be
1062 ;; associated with the merge buffer
1063 startup-hooks job-name merge-buffer-file)
1046 "Merge buffers without ancestor." 1064 "Merge buffers without ancestor."
1047 (interactive 1065 (interactive
1048 (let (bf) 1066 (let (bf)
@@ -1059,12 +1077,17 @@ Continue anyway? (y/n) "))
1059 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) 1077 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks))
1060 (or job-name (setq job-name 'ediff-merge-buffers)) 1078 (or job-name (setq job-name 'ediff-merge-buffers))
1061 (ediff-buffers-internal 1079 (ediff-buffers-internal
1062 buffer-A buffer-B nil startup-hooks job-name)) 1080 buffer-A buffer-B nil startup-hooks job-name merge-buffer-file))
1063 1081
1064;;;###autoload 1082;;;###autoload
1065(defun ediff-merge-buffers-with-ancestor (buffer-A 1083(defun ediff-merge-buffers-with-ancestor (buffer-A buffer-B buffer-ancestor
1066 buffer-B buffer-ancestor 1084 &optional
1067 &optional startup-hooks job-name) 1085 startup-hooks
1086 job-name
1087 ;; MERGE-BUFFER-FILE is the
1088 ;; file to be associated
1089 ;; with the merge buffer
1090 merge-buffer-file)
1068 "Merge buffers with ancestor." 1091 "Merge buffers with ancestor."
1069 (interactive 1092 (interactive
1070 (let (bf bff) 1093 (let (bf bff)
@@ -1089,11 +1112,12 @@ Continue anyway? (y/n) "))
1089 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks)) 1112 (setq startup-hooks (cons 'ediff-merge-on-startup startup-hooks))
1090 (or job-name (setq job-name 'ediff-merge-buffers-with-ancestor)) 1113 (or job-name (setq job-name 'ediff-merge-buffers-with-ancestor))
1091 (ediff-buffers-internal 1114 (ediff-buffers-internal
1092 buffer-A buffer-B buffer-ancestor startup-hooks job-name)) 1115 buffer-A buffer-B buffer-ancestor startup-hooks job-name merge-buffer-file))
1093 1116
1094 1117
1095;;;###autoload 1118;;;###autoload
1096(defun ediff-merge-revisions (&optional file startup-hooks) 1119(defun ediff-merge-revisions (&optional file startup-hooks merge-buffer-file)
1120 ;; MERGE-BUFFER-FILE is the file to be associated with the merge buffer
1097 "Run Ediff by merging two revisions of a file. 1121 "Run Ediff by merging two revisions of a file.
1098The file is the optional FILE argument or the file visited by the current 1122The file is the optional FILE argument or the file visited by the current
1099buffer." 1123buffer."
@@ -1116,11 +1140,16 @@ buffer."
1116 ;; ancestor-revision=nil 1140 ;; ancestor-revision=nil
1117 (funcall 1141 (funcall
1118 (intern (format "ediff-%S-merge-internal" ediff-version-control-package)) 1142 (intern (format "ediff-%S-merge-internal" ediff-version-control-package))
1119 rev1 rev2 nil startup-hooks))) 1143 rev1 rev2 nil startup-hooks merge-buffer-file)))
1120 1144
1121 1145
1122;;;###autoload 1146;;;###autoload
1123(defun ediff-merge-revisions-with-ancestor (&optional file startup-hooks) 1147(defun ediff-merge-revisions-with-ancestor (&optional
1148 file startup-hooks
1149 ;; MERGE-BUFFER-FILE is the file to
1150 ;; be associated with the merge
1151 ;; buffer
1152 merge-buffer-file)
1124 "Run Ediff by merging two revisions of a file with a common ancestor. 1153 "Run Ediff by merging two revisions of a file with a common ancestor.
1125The file is the the optional FILE argument or the file visited by the current 1154The file is the the optional FILE argument or the file visited by the current
1126buffer." 1155buffer."
@@ -1148,7 +1177,7 @@ buffer."
1148 (ediff-load-version-control) 1177 (ediff-load-version-control)
1149 (funcall 1178 (funcall
1150 (intern (format "ediff-%S-merge-internal" ediff-version-control-package)) 1179 (intern (format "ediff-%S-merge-internal" ediff-version-control-package))
1151 rev1 rev2 ancestor-rev startup-hooks))) 1180 rev1 rev2 ancestor-rev startup-hooks merge-buffer-file)))
1152 1181
1153;;;###autoload 1182;;;###autoload
1154(defun run-ediff-from-cvs-buffer (pos) 1183(defun run-ediff-from-cvs-buffer (pos)
diff --git a/lisp/emulation/viper-ex.el b/lisp/emulation/viper-ex.el
index a08b75ce4e6..bd9ac3d3eb7 100644
--- a/lisp/emulation/viper-ex.el
+++ b/lisp/emulation/viper-ex.el
@@ -195,6 +195,7 @@ Don't put `-c' here, as it is added automatically."
195;; File containing the shell command to be executed at Ex prompt, 195;; File containing the shell command to be executed at Ex prompt,
196;; e.g., :r !date 196;; e.g., :r !date
197(defvar ex-cmdfile nil) 197(defvar ex-cmdfile nil)
198(defvar ex-cmdfile-args "")
198 199
199;; flag used in viper-ex-read-file-name to indicate that we may be reading 200;; flag used in viper-ex-read-file-name to indicate that we may be reading
200;; multiple file names. Used for :edit and :next 201;; multiple file names. Used for :edit and :next
@@ -457,7 +458,11 @@ reversed."
457 "\\|" "^[ \t]*ta.*" 458 "\\|" "^[ \t]*ta.*"
458 "\\|" "^[ \t]*una.*" 459 "\\|" "^[ \t]*una.*"
459 "\\|" "^[ \t]*su.*" 460 "\\|" "^[ \t]*su.*"
460 "\\|['`][a-z][ \t]*" 461 "\\|" "['`][a-z][ \t]*"
462 ;; r! assumes that the next one is a shell command
463 "\\|" "\\(r\\|re\\|rea\\|read\\)[ \t]*!"
464 ;; w ! assumes that the next one is a shell command
465 "\\|" "\\(w\\|wr\\|wri\\|writ.?\\)[ \t]+!"
461 "\\|" "![ \t]*[a-zA-Z].*" 466 "\\|" "![ \t]*[a-zA-Z].*"
462 "\\)" 467 "\\)"
463 "!*"))) 468 "!*")))
@@ -851,14 +856,16 @@ reversed."
851 (message "%s" ret)) 856 (message "%s" ret))
852 ret)) 857 ret))
853 858
854;; Get a file name and set ex-variant, `ex-append' and `ex-offset' if found 859;; Get a file name and set `ex-variant', `ex-append' and `ex-offset' if found
860;; If it is r!, then get the command name and whatever args
855(defun viper-get-ex-file () 861(defun viper-get-ex-file ()
856 (let (prompt) 862 (let (prompt)
857 (setq ex-file nil 863 (setq ex-file nil
858 ex-variant nil 864 ex-variant nil
859 ex-append nil 865 ex-append nil
860 ex-offset nil 866 ex-offset nil
861 ex-cmdfile nil) 867 ex-cmdfile nil
868 ex-cmdfile-args "")
862 (save-excursion 869 (save-excursion
863 (save-window-excursion 870 (save-window-excursion
864 (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name)) 871 (setq viper-ex-work-buf (get-buffer-create viper-ex-work-buf-name))
@@ -908,6 +915,8 @@ reversed."
908 ;; if file name comes from history, don't leave 915 ;; if file name comes from history, don't leave
909 ;; minibuffer when the user types space 916 ;; minibuffer when the user types space
910 (setq viper-incomplete-ex-cmd nil) 917 (setq viper-incomplete-ex-cmd nil)
918 (setq ex-cmdfile-args
919 (substring ex-file (match-end 0) nil))
911 ;; this must be the last clause in this progn 920 ;; this must be the last clause in this progn
912 (substring ex-file (match-beginning 0) (match-end 0)) 921 (substring ex-file (match-beginning 0) (match-end 0))
913 ) 922 )
@@ -958,6 +967,7 @@ reversed."
958(defun ex-cmd-accepts-multiple-files-p (token) 967(defun ex-cmd-accepts-multiple-files-p (token)
959 (member token '("edit" "next" "Next"))) 968 (member token '("edit" "next" "Next")))
960 969
970;; Read file name from the minibuffer in an ex command.
961;; If user doesn't enter anything, then "" is returned, i.e., the 971;; If user doesn't enter anything, then "" is returned, i.e., the
962;; prompt-directory is not returned. 972;; prompt-directory is not returned.
963(defun viper-ex-read-file-name (prompt) 973(defun viper-ex-read-file-name (prompt)
@@ -1548,10 +1558,12 @@ reversed."
1548 (setq ex-file buffer-file-name))) 1558 (setq ex-file buffer-file-name)))
1549 (if ex-cmdfile 1559 (if ex-cmdfile
1550 (progn 1560 (progn
1551 (setq command (ex-expand-filsyms ex-file (current-buffer))) 1561 (setq command
1562 (concat (ex-expand-filsyms ex-file (current-buffer))
1563 ex-cmdfile-args))
1552 (shell-command command t)) 1564 (shell-command command t))
1553 (insert-file-contents ex-file))) 1565 (insert-file-contents ex-file)))
1554 (ex-fixup-history viper-last-ex-prompt ex-file)) 1566 (ex-fixup-history viper-last-ex-prompt ex-file ex-cmdfile-args))
1555 1567
1556;; this function fixes ex-history for some commands like ex-read, ex-edit 1568;; this function fixes ex-history for some commands like ex-read, ex-edit
1557(defun ex-fixup-history (&rest args) 1569(defun ex-fixup-history (&rest args)
@@ -1935,7 +1947,8 @@ Please contact your system administrator. "
1935 (if ex-cmdfile 1947 (if ex-cmdfile
1936 (progn 1948 (progn
1937 (viper-enlarge-region beg end) 1949 (viper-enlarge-region beg end)
1938 (shell-command-on-region (point) (mark t) ex-file)) 1950 (shell-command-on-region (point) (mark t)
1951 (concat ex-file ex-cmdfile-args)))
1939 (if (and (string= ex-file "") (not (buffer-file-name))) 1952 (if (and (string= ex-file "") (not (buffer-file-name)))
1940 (setq ex-file 1953 (setq ex-file
1941 (read-file-name 1954 (read-file-name
diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el
index bd1bddfebb0..af9fb31ccc1 100644
--- a/lisp/emulation/viper-init.el
+++ b/lisp/emulation/viper-init.el
@@ -204,28 +204,28 @@ the Ex command :map!.")
204(viper-deflocalvar viper-replace-minor-mode nil 204(viper-deflocalvar viper-replace-minor-mode nil
205 "Minor mode in effect in replace state (cw, C, and the like commands).") 205 "Minor mode in effect in replace state (cw, C, and the like commands).")
206 206
207;; Mode for vital things like \C-z and \C-x) 207;; Mode for vital things like \C-z and \C-x) This is set to t, when viper-mode
208;; This is t, by default. So, any new buffer will have C-z defined as 208;; is invoked. So, any new buffer will have C-z defined as switch to Vi, unless
209;; switch to Vi, unless we switched states in this buffer 209;; we switched states in this buffer
210(viper-deflocalvar viper-emacs-intercept-minor-mode t) 210(viper-deflocalvar viper-emacs-intercept-minor-mode nil)
211 211
212(viper-deflocalvar viper-emacs-local-user-minor-mode t 212(viper-deflocalvar viper-emacs-local-user-minor-mode nil
213 "Minor mode for local user bindings effective in Emacs state. 213 "Minor mode for local user bindings effective in Emacs state.
214Users can use it to override Emacs bindings when Viper is in its Emacs 214Users can use it to override Emacs bindings when Viper is in its Emacs
215state.") 215state.")
216 216
217(viper-deflocalvar viper-emacs-global-user-minor-mode t 217(viper-deflocalvar viper-emacs-global-user-minor-mode nil
218 "Minor mode for global user bindings in effect in Emacs state. 218 "Minor mode for global user bindings in effect in Emacs state.
219Users can use it to override Emacs bindings when Viper is in its Emacs 219Users can use it to override Emacs bindings when Viper is in its Emacs
220state.") 220state.")
221 221
222(viper-deflocalvar viper-emacs-kbd-minor-mode t 222(viper-deflocalvar viper-emacs-kbd-minor-mode nil
223 "Minor mode for Vi style macros in Emacs state. 223 "Minor mode for Vi style macros in Emacs state.
224The corresponding keymap stores key bindings of Vi macros defined with 224The corresponding keymap stores key bindings of Vi macros defined with
225`viper-record-kbd-macro' command. There is no Ex-level command to do this 225`viper-record-kbd-macro' command. There is no Ex-level command to do this
226interactively.") 226interactively.")
227 227
228(viper-deflocalvar viper-emacs-state-modifier-minor-mode t 228(viper-deflocalvar viper-emacs-state-modifier-minor-mode nil
229 "Minor mode used to make major-mode-specific modification to Emacs state. 229 "Minor mode used to make major-mode-specific modification to Emacs state.
230For instance, a Vi purist may want to bind `dd' in Dired mode to a function 230For instance, a Vi purist may want to bind `dd' in Dired mode to a function
231that deletes a file.") 231that deletes a file.")
diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el
index 961a7d1a1cc..8cdef6f27fe 100644
--- a/lisp/emulation/viper-keym.el
+++ b/lisp/emulation/viper-keym.el
@@ -389,9 +389,6 @@ viper-insert-basic-map. Not recommended, except for novice users.")
389(define-key viper-vi-basic-map "~" 'viper-toggle-case) 389(define-key viper-vi-basic-map "~" 'viper-toggle-case)
390(define-key viper-vi-basic-map "\C-?" 'viper-backward-char) 390(define-key viper-vi-basic-map "\C-?" 'viper-backward-char)
391(define-key viper-vi-basic-map "_" 'viper-nil) 391(define-key viper-vi-basic-map "_" 'viper-nil)
392
393;;; Escape from Emacs to Vi for one command
394(global-set-key "\C-c\\" 'viper-escape-to-vi) ; everywhere
395 392
396;;; This is viper-vi-diehard-map. Used when viper-vi-diehard-minor-mode is on. 393;;; This is viper-vi-diehard-map. Used when viper-vi-diehard-minor-mode is on.
397 394
diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el
index 7a10f42a5a5..ac353ae28ad 100644
--- a/lisp/emulation/viper-mous.el
+++ b/lisp/emulation/viper-mous.el
@@ -116,10 +116,13 @@ considered related."
116 (not (viper-sit-for-short viper-multiclick-timeout t))) 116 (not (viper-sit-for-short viper-multiclick-timeout t)))
117 117
118;; Returns window where click occurs 118;; Returns window where click occurs
119(defsubst viper-mouse-click-window (click) 119(defun viper-mouse-click-window (click)
120 (if viper-xemacs-p 120 (let ((win (if viper-xemacs-p
121 (event-window click) 121 (event-window click)
122 (posn-window (event-start click)))) 122 (posn-window (event-start click)))))
123 (if (window-live-p win)
124 win
125 (error "Click was not over a live window"))))
123 126
124;; Returns window where click occurs 127;; Returns window where click occurs
125(defsubst viper-mouse-click-frame (click) 128(defsubst viper-mouse-click-frame (click)
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el
index cd821cf83a8..303c50645c9 100644
--- a/lisp/emulation/viper.el
+++ b/lisp/emulation/viper.el
@@ -8,7 +8,7 @@
8 8
9;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. 9;; Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
10 10
11(defconst viper-version "3.001 (Polyglot) of September 23, 1997" 11(defconst viper-version "3.002 (Polyglot) of October 23, 1997"
12 "The current version of Viper") 12 "The current version of Viper")
13 13
14;; This file is part of GNU Emacs. 14;; This file is part of GNU Emacs.
@@ -385,6 +385,8 @@ it comes up in a wrong Viper state."
385 385
386;;;###autoload 386;;;###autoload
387(defun toggle-viper-mode () 387(defun toggle-viper-mode ()
388 "Toggle Viper on/off.
389If Viper is enabled, turn it off. Otherwise, turn it on."
388 (interactive) 390 (interactive)
389 (if (eq viper-mode t) 391 (if (eq viper-mode t)
390 (viper-go-away) 392 (viper-go-away)
@@ -1208,6 +1210,26 @@ These two lines must come in the order given.
1208(define-key viper-vi-intercept-map viper-toggle-key 'viper-toggle-key-action) 1210(define-key viper-vi-intercept-map viper-toggle-key 'viper-toggle-key-action)
1209(define-key 1211(define-key
1210 viper-emacs-intercept-map viper-toggle-key 'viper-change-state-to-vi) 1212 viper-emacs-intercept-map viper-toggle-key 'viper-change-state-to-vi)
1213
1214;;; Escape from Emacs and Insert modes to Vi for one command
1215(define-key
1216 viper-emacs-intercept-map "\C-c\\" 'viper-escape-to-vi)
1217(define-key
1218 viper-insert-intercept-map "\C-c\\" 'viper-escape-to-vi)
1219
1220(if viper-mode
1221 (progn
1222 (setq viper-emacs-intercept-minor-mode t
1223 viper-emacs-local-user-minor-mode t
1224 viper-emacs-global-user-minor-mode t
1225 viper-emacs-kbd-minor-mode t
1226 viper-emacs-state-modifier-minor-mode t)
1227 (setq-default viper-emacs-intercept-minor-mode t
1228 viper-emacs-local-user-minor-mode t
1229 viper-emacs-global-user-minor-mode t
1230 viper-emacs-kbd-minor-mode t
1231 viper-emacs-state-modifier-minor-mode t)
1232 ))
1211 1233
1212 1234
1213(if (and viper-mode 1235(if (and viper-mode
@@ -1219,7 +1241,7 @@ These two lines must come in the order given.
1219;; this may not be enough, so we also set default minor-mode-alist. 1241;; this may not be enough, so we also set default minor-mode-alist.
1220;; Without setting the default, new buffers that come up in emacs mode have 1242;; Without setting the default, new buffers that come up in emacs mode have
1221;; minor-mode-map-alist = nil, unless we call viper-change-state-* 1243;; minor-mode-map-alist = nil, unless we call viper-change-state-*
1222(if (eq viper-current-state 'emacs-state) 1244(if (and viper-mode (eq viper-current-state 'emacs-state))
1223 (progn 1245 (progn
1224 (viper-change-state-to-emacs) 1246 (viper-change-state-to-emacs)
1225 (setq-default minor-mode-map-alist minor-mode-map-alist) 1247 (setq-default minor-mode-map-alist minor-mode-map-alist)