aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2018-04-03 23:17:30 -0400
committerStefan Monnier2018-04-03 23:17:30 -0400
commitfbd025a667b2361db30c3cb723b4f0ca15413d4a (patch)
treee8af8ea6589f7b4d6b64b2af0a6d578cb199423c
parent9b0e8a4c6b540dcb962607763846040942858c5a (diff)
downloademacs-fbd025a667b2361db30c3cb723b4f0ca15413d4a.tar.gz
emacs-fbd025a667b2361db30c3cb723b4f0ca15413d4a.zip
* lisp/vc/emerge.el: Use lexical-binding
Replace all `(lambda ...) with closures. Use inhibit-read-only. (emerge-mode): Use define-minor-mode. (emerge-setup, emerge-setup-with-ancestor): Don't use 'run-hooks' on local var. (emerge-files, emerge-files-with-ancestor): Don't use 'add-hook' on local var. (emerge-convert-diffs-to-markers): Remove unused var 'B-point-min'. Simplify 'offset'. (emerge--current-beg, emerge--current-end): New macros. (emerge-select-version): Pass 'diff-vector' to the function it calls. Change all callers to use it instead of dyn-bound vars.
-rw-r--r--lisp/vc/emerge.el602
1 files changed, 250 insertions, 352 deletions
diff --git a/lisp/vc/emerge.el b/lisp/vc/emerge.el
index 0da14d07fd3..fc8c318e3af 100644
--- a/lisp/vc/emerge.el
+++ b/lisp/vc/emerge.el
@@ -1,6 +1,6 @@
1;;; emerge.el --- merge diffs under Emacs control 1;;; emerge.el --- merge diffs under Emacs control -*- lexical-binding:t -*-
2 2
3;;; The author has placed this file in the public domain. 3;; The author has placed this file in the public domain.
4 4
5;; This file is part of GNU Emacs. 5;; This file is part of GNU Emacs.
6 6
@@ -24,42 +24,20 @@
24 24
25;;; Code: 25;;; Code:
26 26
27;; There aren't really global variables, just dynamic bindings
28(defvar A-begin)
29(defvar A-end)
30(defvar B-begin)
31(defvar B-end)
32(defvar diff-vector)
33(defvar merge-begin)
34(defvar merge-end)
35(defvar valid-diff)
36
37;;; Macros 27;;; Macros
38 28
39(defmacro emerge-defvar-local (var value doc) 29(defmacro emerge-defvar-local (var value doc)
40 "Defines SYMBOL as an advertised variable. 30 "Define SYMBOL as an advertised buffer-local variable.
41Performs a defvar, then executes `make-variable-buffer-local' on 31Performs a defvar, then executes `make-variable-buffer-local' on
42the variable. Also sets the `permanent-local' property, so that 32the variable. Also sets the `permanent-local' property, so that
43`kill-all-local-variables' (called by major-mode setting commands) 33`kill-all-local-variables' (called by major-mode setting commands)
44won't destroy Emerge control variables." 34won't destroy Emerge control variables."
45 `(progn 35 `(progn
46 (defvar ,var ,value ,doc) 36 (defvar-local ,var ,value ,doc)
47 (make-variable-buffer-local ',var) 37 (put ',var 'permanent-local t)))
48 (put ',var 'permanent-local t)))
49
50;; Add entries to minor-mode-alist so that emerge modes show correctly
51(defvar emerge-minor-modes-list
52 '((emerge-mode " Emerge")
53 (emerge-fast-mode " F")
54 (emerge-edit-mode " E")
55 (emerge-auto-advance " A")
56 (emerge-skip-prefers " S")))
57(if (not (assq 'emerge-mode minor-mode-alist))
58 (setq minor-mode-alist (append emerge-minor-modes-list
59 minor-mode-alist)))
60 38
61;; We need to define this function so describe-mode can describe Emerge mode. 39;; We need to define this function so describe-mode can describe Emerge mode.
62(defun emerge-mode () 40(define-minor-mode emerge-mode
63 "Emerge mode is used by the Emerge file-merging package. 41 "Emerge mode is used by the Emerge file-merging package.
64It is entered only through one of the functions: 42It is entered only through one of the functions:
65 `emerge-files' 43 `emerge-files'
@@ -74,7 +52,13 @@ It is entered only through one of the functions:
74Commands: 52Commands:
75\\{emerge-basic-keymap} 53\\{emerge-basic-keymap}
76Commands must be prefixed by \\<emerge-fast-keymap>\\[emerge-basic-keymap] in `edit' mode, 54Commands must be prefixed by \\<emerge-fast-keymap>\\[emerge-basic-keymap] in `edit' mode,
77but can be invoked directly in `fast' mode.") 55but can be invoked directly in `fast' mode."
56 :lighter (" Emerge"
57 (emerge-fast-mode " F")
58 (emerge-edit-mode " E")
59 (emerge-auto-advance " A")
60 (emerge-skip-prefers " S")))
61(put 'emerge-mode 'permanent-local t)
78 62
79;;; Emerge configuration variables 63;;; Emerge configuration variables
80 64
@@ -453,8 +437,6 @@ Must be set before Emerge is loaded."
453;; Variables which control each merge. They are local to the merge buffer. 437;; Variables which control each merge. They are local to the merge buffer.
454 438
455;; Mode variables 439;; Mode variables
456(emerge-defvar-local emerge-mode nil
457 "Indicator for emerge-mode.")
458(emerge-defvar-local emerge-fast-mode nil 440(emerge-defvar-local emerge-fast-mode nil
459 "Indicator for emerge-mode fast submode.") 441 "Indicator for emerge-mode fast submode.")
460(emerge-defvar-local emerge-edit-mode nil 442(emerge-defvar-local emerge-edit-mode nil
@@ -556,7 +538,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
556 (if temp 538 (if temp
557 (setq file-A temp 539 (setq file-A temp
558 startup-hooks 540 startup-hooks
559 (cons `(lambda () (delete-file ,file-A)) 541 (cons (lambda () (delete-file file-A))
560 startup-hooks)) 542 startup-hooks))
561 ;; Verify that the file matches the buffer 543 ;; Verify that the file matches the buffer
562 (emerge-verify-file-buffer)))) 544 (emerge-verify-file-buffer))))
@@ -567,7 +549,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
567 (if temp 549 (if temp
568 (setq file-B temp 550 (setq file-B temp
569 startup-hooks 551 startup-hooks
570 (cons `(lambda () (delete-file ,file-B)) 552 (cons (lambda () (delete-file file-B))
571 startup-hooks)) 553 startup-hooks))
572 ;; Verify that the file matches the buffer 554 ;; Verify that the file matches the buffer
573 (emerge-verify-file-buffer)))) 555 (emerge-verify-file-buffer))))
@@ -584,48 +566,49 @@ This is *not* a user option, since Emerge uses it for its own processing.")
584 ;; create the merge buffer from buffer A, so it inherits buffer A's 566 ;; create the merge buffer from buffer A, so it inherits buffer A's
585 ;; default directory, etc. 567 ;; default directory, etc.
586 (merge-buffer (with-current-buffer 568 (merge-buffer (with-current-buffer
587 buffer-A 569 buffer-A
588 (get-buffer-create merge-buffer-name)))) 570 (get-buffer-create merge-buffer-name))))
589 (with-current-buffer 571 (with-current-buffer
590 merge-buffer 572 merge-buffer
591 (emerge-copy-modes buffer-A) 573 (emerge-copy-modes buffer-A)
592 (setq buffer-read-only nil) 574 (setq buffer-read-only nil)
593 (auto-save-mode 1) 575 (auto-save-mode 1)
594 (setq emerge-mode t) 576 (setq emerge-mode t)
595 (setq emerge-A-buffer buffer-A) 577 (setq emerge-A-buffer buffer-A)
596 (setq emerge-B-buffer buffer-B) 578 (setq emerge-B-buffer buffer-B)
597 (setq emerge-ancestor-buffer nil) 579 (setq emerge-ancestor-buffer nil)
598 (setq emerge-merge-buffer merge-buffer) 580 (setq emerge-merge-buffer merge-buffer)
599 (setq emerge-output-description 581 (setq emerge-output-description
600 (if output-file 582 (if output-file
601 (concat "Output to file: " output-file) 583 (concat "Output to file: " output-file)
602 (concat "Output to buffer: " (buffer-name merge-buffer)))) 584 (concat "Output to buffer: " (buffer-name merge-buffer))))
603 (save-excursion (insert-buffer-substring emerge-A-buffer)) 585 (save-excursion (insert-buffer-substring emerge-A-buffer))
604 (emerge-set-keys) 586 (emerge-set-keys)
605 (setq emerge-difference-list (emerge-make-diff-list file-A file-B)) 587 (setq emerge-difference-list (emerge-make-diff-list file-A file-B))
606 (setq emerge-number-of-differences (length emerge-difference-list)) 588 (setq emerge-number-of-differences (length emerge-difference-list))
607 (setq emerge-current-difference -1) 589 (setq emerge-current-difference -1)
608 (setq emerge-quit-hook quit-hooks) 590 (setq emerge-quit-hook quit-hooks)
609 (emerge-remember-buffer-characteristics) 591 (emerge-remember-buffer-characteristics)
610 (emerge-handle-local-variables)) 592 (emerge-handle-local-variables))
611 (emerge-setup-windows buffer-A buffer-B merge-buffer t) 593 (emerge-setup-windows buffer-A buffer-B merge-buffer t)
612 (with-current-buffer merge-buffer 594 (with-current-buffer merge-buffer
613 (run-hooks 'startup-hooks 'emerge-startup-hook) 595 (mapc #'funcall startup-hooks)
614 (setq buffer-read-only t)))) 596 (run-hooks 'emerge-startup-hook)
597 (setq buffer-read-only t))))
615 598
616;; Generate the Emerge difference list between two files 599;; Generate the Emerge difference list between two files
617(defun emerge-make-diff-list (file-A file-B) 600(defun emerge-make-diff-list (file-A file-B)
618 (setq emerge-diff-buffer (get-buffer-create "*emerge-diff*")) 601 (setq emerge-diff-buffer (get-buffer-create "*emerge-diff*"))
619 (with-current-buffer 602 (with-current-buffer
620 emerge-diff-buffer 603 emerge-diff-buffer
621 (erase-buffer) 604 (erase-buffer)
622 (shell-command 605 (shell-command
623 (format "%s %s %s %s" 606 (format "%s %s %s %s"
624 (shell-quote-argument emerge-diff-program) 607 (shell-quote-argument emerge-diff-program)
625 emerge-diff-options 608 emerge-diff-options
626 (shell-quote-argument file-A) 609 (shell-quote-argument file-A)
627 (shell-quote-argument file-B)) 610 (shell-quote-argument file-B))
628 t)) 611 t))
629 (emerge-prepare-error-list emerge-diff-ok-lines-regexp) 612 (emerge-prepare-error-list emerge-diff-ok-lines-regexp)
630 (emerge-convert-diffs-to-markers 613 (emerge-convert-diffs-to-markers
631 emerge-A-buffer emerge-B-buffer emerge-merge-buffer 614 emerge-A-buffer emerge-B-buffer emerge-merge-buffer
@@ -711,7 +694,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
711 (if temp 694 (if temp
712 (setq file-A temp 695 (setq file-A temp
713 startup-hooks 696 startup-hooks
714 (cons `(lambda () (delete-file ,file-A)) 697 (cons (lambda () (delete-file file-A))
715 startup-hooks)) 698 startup-hooks))
716 ;; Verify that the file matches the buffer 699 ;; Verify that the file matches the buffer
717 (emerge-verify-file-buffer)))) 700 (emerge-verify-file-buffer))))
@@ -722,7 +705,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
722 (if temp 705 (if temp
723 (setq file-B temp 706 (setq file-B temp
724 startup-hooks 707 startup-hooks
725 (cons `(lambda () (delete-file ,file-B)) 708 (cons (lambda () (delete-file file-B))
726 startup-hooks)) 709 startup-hooks))
727 ;; Verify that the file matches the buffer 710 ;; Verify that the file matches the buffer
728 (emerge-verify-file-buffer)))) 711 (emerge-verify-file-buffer))))
@@ -733,7 +716,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
733 (if temp 716 (if temp
734 (setq file-ancestor temp 717 (setq file-ancestor temp
735 startup-hooks 718 startup-hooks
736 (cons `(lambda () (delete-file ,file-ancestor)) 719 (cons (lambda () (delete-file file-ancestor))
737 startup-hooks)) 720 startup-hooks))
738 ;; Verify that the file matches the buffer 721 ;; Verify that the file matches the buffer
739 (emerge-verify-file-buffer)))) 722 (emerge-verify-file-buffer))))
@@ -746,6 +729,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
746 buffer-ancestor file-ancestor 729 buffer-ancestor file-ancestor
747 &optional startup-hooks quit-hooks 730 &optional startup-hooks quit-hooks
748 output-file) 731 output-file)
732 ;; FIXME: Duplicated code!
749 (setq file-A (expand-file-name file-A)) 733 (setq file-A (expand-file-name file-A))
750 (setq file-B (expand-file-name file-B)) 734 (setq file-B (expand-file-name file-B))
751 (setq file-ancestor (expand-file-name file-ancestor)) 735 (setq file-ancestor (expand-file-name file-ancestor))
@@ -754,36 +738,37 @@ This is *not* a user option, since Emerge uses it for its own processing.")
754 ;; create the merge buffer from buffer A, so it inherits buffer A's 738 ;; create the merge buffer from buffer A, so it inherits buffer A's
755 ;; default directory, etc. 739 ;; default directory, etc.
756 (merge-buffer (with-current-buffer 740 (merge-buffer (with-current-buffer
757 buffer-A 741 buffer-A
758 (get-buffer-create merge-buffer-name)))) 742 (get-buffer-create merge-buffer-name))))
759 (with-current-buffer 743 (with-current-buffer
760 merge-buffer 744 merge-buffer
761 (emerge-copy-modes buffer-A) 745 (emerge-copy-modes buffer-A)
762 (setq buffer-read-only nil) 746 (setq buffer-read-only nil)
763 (auto-save-mode 1) 747 (auto-save-mode 1)
764 (setq emerge-mode t) 748 (setq emerge-mode t)
765 (setq emerge-A-buffer buffer-A) 749 (setq emerge-A-buffer buffer-A)
766 (setq emerge-B-buffer buffer-B) 750 (setq emerge-B-buffer buffer-B)
767 (setq emerge-ancestor-buffer buffer-ancestor) 751 (setq emerge-ancestor-buffer buffer-ancestor)
768 (setq emerge-merge-buffer merge-buffer) 752 (setq emerge-merge-buffer merge-buffer)
769 (setq emerge-output-description 753 (setq emerge-output-description
770 (if output-file 754 (if output-file
771 (concat "Output to file: " output-file) 755 (concat "Output to file: " output-file)
772 (concat "Output to buffer: " (buffer-name merge-buffer)))) 756 (concat "Output to buffer: " (buffer-name merge-buffer))))
773 (save-excursion (insert-buffer-substring emerge-A-buffer)) 757 (save-excursion (insert-buffer-substring emerge-A-buffer))
774 (emerge-set-keys) 758 (emerge-set-keys)
775 (setq emerge-difference-list 759 (setq emerge-difference-list
776 (emerge-make-diff3-list file-A file-B file-ancestor)) 760 (emerge-make-diff3-list file-A file-B file-ancestor))
777 (setq emerge-number-of-differences (length emerge-difference-list)) 761 (setq emerge-number-of-differences (length emerge-difference-list))
778 (setq emerge-current-difference -1) 762 (setq emerge-current-difference -1)
779 (setq emerge-quit-hook quit-hooks) 763 (setq emerge-quit-hook quit-hooks)
780 (emerge-remember-buffer-characteristics) 764 (emerge-remember-buffer-characteristics)
781 (emerge-select-prefer-Bs) 765 (emerge-select-prefer-Bs)
782 (emerge-handle-local-variables)) 766 (emerge-handle-local-variables))
783 (emerge-setup-windows buffer-A buffer-B merge-buffer t) 767 (emerge-setup-windows buffer-A buffer-B merge-buffer t)
784 (with-current-buffer merge-buffer 768 (with-current-buffer merge-buffer
785 (run-hooks 'startup-hooks 'emerge-startup-hook) 769 (mapc #'funcall startup-hooks)
786 (setq buffer-read-only t)))) 770 (run-hooks 'emerge-startup-hook)
771 (setq buffer-read-only t))))
787 772
788;; Generate the Emerge difference list between two files with an ancestor 773;; Generate the Emerge difference list between two files with an ancestor
789(defun emerge-make-diff3-list (file-A file-B file-ancestor) 774(defun emerge-make-diff3-list (file-A file-B file-ancestor)
@@ -872,7 +857,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
872 (emerge-read-file-name "Output file" emerge-last-dir-output 857 (emerge-read-file-name "Output file" emerge-last-dir-output
873 f f nil))))) 858 f f nil)))))
874 (if file-out 859 (if file-out
875 (add-hook 'quit-hooks `(lambda () (emerge-files-exit ,file-out)))) 860 (push (lambda () (emerge-files-exit file-out)) quit-hooks))
876 (emerge-files-internal 861 (emerge-files-internal
877 file-A file-B startup-hooks 862 file-A file-B startup-hooks
878 quit-hooks 863 quit-hooks
@@ -894,7 +879,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
894 (emerge-read-file-name "Output file" emerge-last-dir-output 879 (emerge-read-file-name "Output file" emerge-last-dir-output
895 f f nil))))) 880 f f nil)))))
896 (if file-out 881 (if file-out
897 (add-hook 'quit-hooks `(lambda () (emerge-files-exit ,file-out)))) 882 (push (lambda () (emerge-files-exit file-out)) quit-hooks))
898 (emerge-files-with-ancestor-internal 883 (emerge-files-with-ancestor-internal
899 file-A file-B file-ancestor startup-hooks 884 file-A file-B file-ancestor startup-hooks
900 quit-hooks 885 quit-hooks
@@ -922,9 +907,9 @@ This is *not* a user option, since Emerge uses it for its own processing.")
922 (write-region (point-min) (point-max) emerge-file-B nil 'no-message)) 907 (write-region (point-min) (point-max) emerge-file-B nil 'no-message))
923 (emerge-setup (get-buffer buffer-A) emerge-file-A 908 (emerge-setup (get-buffer buffer-A) emerge-file-A
924 (get-buffer buffer-B) emerge-file-B 909 (get-buffer buffer-B) emerge-file-B
925 (cons `(lambda () 910 (cons (lambda ()
926 (delete-file ,emerge-file-A) 911 (delete-file emerge-file-A)
927 (delete-file ,emerge-file-B)) 912 (delete-file emerge-file-B))
928 startup-hooks) 913 startup-hooks)
929 quit-hooks 914 quit-hooks
930 nil))) 915 nil)))
@@ -953,11 +938,10 @@ This is *not* a user option, since Emerge uses it for its own processing.")
953 (get-buffer buffer-B) emerge-file-B 938 (get-buffer buffer-B) emerge-file-B
954 (get-buffer buffer-ancestor) 939 (get-buffer buffer-ancestor)
955 emerge-file-ancestor 940 emerge-file-ancestor
956 (cons `(lambda () 941 (cons (lambda ()
957 (delete-file ,emerge-file-A) 942 (delete-file emerge-file-A)
958 (delete-file ,emerge-file-B) 943 (delete-file emerge-file-B)
959 (delete-file 944 (delete-file emerge-file-ancestor))
960 ,emerge-file-ancestor))
961 startup-hooks) 945 startup-hooks)
962 quit-hooks 946 quit-hooks
963 nil))) 947 nil)))
@@ -972,7 +956,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
972 (setq command-line-args-left (nthcdr 3 command-line-args-left)) 956 (setq command-line-args-left (nthcdr 3 command-line-args-left))
973 (emerge-files-internal 957 (emerge-files-internal
974 file-a file-b nil 958 file-a file-b nil
975 (list `(lambda () (emerge-command-exit ,file-out)))))) 959 (list (lambda () (emerge-command-exit file-out))))))
976 960
977;;;###autoload 961;;;###autoload
978(defun emerge-files-with-ancestor-command () 962(defun emerge-files-with-ancestor-command ()
@@ -994,7 +978,7 @@ This is *not* a user option, since Emerge uses it for its own processing.")
994 (setq command-line-args-left (nthcdr 4 command-line-args-left))) 978 (setq command-line-args-left (nthcdr 4 command-line-args-left)))
995 (emerge-files-with-ancestor-internal 979 (emerge-files-with-ancestor-internal
996 file-a file-b file-anc nil 980 file-a file-b file-anc nil
997 (list `(lambda () (emerge-command-exit ,file-out)))))) 981 (list (lambda () (emerge-command-exit file-out))))))
998 982
999(defun emerge-command-exit (file-out) 983(defun emerge-command-exit (file-out)
1000 (emerge-write-and-delete file-out) 984 (emerge-write-and-delete file-out)
@@ -1007,7 +991,8 @@ This is *not* a user option, since Emerge uses it for its own processing.")
1007 (setq emerge-file-out file-out) 991 (setq emerge-file-out file-out)
1008 (emerge-files-internal 992 (emerge-files-internal
1009 file-a file-b nil 993 file-a file-b nil
1010 (list `(lambda () (emerge-remote-exit ,file-out ',emerge-exit-func))) 994 (let ((f emerge-exit-func))
995 (list (lambda () (emerge-remote-exit file-out f))))
1011 file-out) 996 file-out)
1012 (throw 'client-wait nil)) 997 (throw 'client-wait nil))
1013 998
@@ -1016,14 +1001,15 @@ This is *not* a user option, since Emerge uses it for its own processing.")
1016 (setq emerge-file-out file-out) 1001 (setq emerge-file-out file-out)
1017 (emerge-files-with-ancestor-internal 1002 (emerge-files-with-ancestor-internal
1018 file-a file-b file-anc nil 1003 file-a file-b file-anc nil
1019 (list `(lambda () (emerge-remote-exit ,file-out ',emerge-exit-func))) 1004 (let ((f emerge-exit-func))
1005 (list (lambda () (emerge-remote-exit file-out f))))
1020 file-out) 1006 file-out)
1021 (throw 'client-wait nil)) 1007 (throw 'client-wait nil))
1022 1008
1023(defun emerge-remote-exit (file-out emerge-exit-func) 1009(defun emerge-remote-exit (file-out exit-func)
1024 (emerge-write-and-delete file-out) 1010 (emerge-write-and-delete file-out)
1025 (kill-buffer emerge-merge-buffer) 1011 (kill-buffer emerge-merge-buffer)
1026 (funcall emerge-exit-func (if emerge-prefix-argument 1 0))) 1012 (funcall exit-func (if emerge-prefix-argument 1 0)))
1027 1013
1028;;; Functions to start Emerge on RCS versions 1014;;; Functions to start Emerge on RCS versions
1029 1015
@@ -1041,10 +1027,9 @@ This is *not* a user option, since Emerge uses it for its own processing.")
1041 (emerge-revisions-internal 1027 (emerge-revisions-internal
1042 file revision-A revision-B startup-hooks 1028 file revision-A revision-B startup-hooks
1043 (if arg 1029 (if arg
1044 (cons `(lambda () 1030 (let ((cmd (format "%s %s" emerge-rcs-ci-program file)))
1045 (shell-command 1031 (cons (lambda () (shell-command cmd))
1046 ,(format "%s %s" emerge-rcs-ci-program file))) 1032 quit-hooks))
1047 quit-hooks)
1048 quit-hooks))) 1033 quit-hooks)))
1049 1034
1050;;;###autoload 1035;;;###autoload
@@ -1065,12 +1050,10 @@ This is *not* a user option, since Emerge uses it for its own processing.")
1065 (emerge-revision-with-ancestor-internal 1050 (emerge-revision-with-ancestor-internal
1066 file revision-A revision-B ancestor startup-hooks 1051 file revision-A revision-B ancestor startup-hooks
1067 (if arg 1052 (if arg
1068 (let ((cmd )) 1053 (let ((cmd (format "%s %s" emerge-rcs-ci-program file)))
1069 (cons `(lambda () 1054 (cons (lambda () (shell-command cmd))
1070 (shell-command
1071 ,(format "%s %s" emerge-rcs-ci-program file)))
1072 quit-hooks)) 1055 quit-hooks))
1073 quit-hooks))) 1056 quit-hooks)))
1074 1057
1075(defun emerge-revisions-internal (file revision-A revision-B &optional 1058(defun emerge-revisions-internal (file revision-A revision-B &optional
1076 startup-hooks quit-hooks _output-file) 1059 startup-hooks quit-hooks _output-file)
@@ -1098,11 +1081,11 @@ This is *not* a user option, since Emerge uses it for its own processing.")
1098 ;; Do the merge 1081 ;; Do the merge
1099 (emerge-setup buffer-A emerge-file-A 1082 (emerge-setup buffer-A emerge-file-A
1100 buffer-B emerge-file-B 1083 buffer-B emerge-file-B
1101 (cons `(lambda () 1084 (cons (lambda ()
1102 (delete-file ,emerge-file-A) 1085 (delete-file emerge-file-A)
1103 (delete-file ,emerge-file-B)) 1086 (delete-file emerge-file-B))
1104 startup-hooks) 1087 startup-hooks)
1105 (cons `(lambda () (emerge-files-exit ,file)) 1088 (cons (lambda () (emerge-files-exit file))
1106 quit-hooks) 1089 quit-hooks)
1107 nil))) 1090 nil)))
1108 1091
@@ -1146,12 +1129,12 @@ This is *not* a user option, since Emerge uses it for its own processing.")
1146 (emerge-setup-with-ancestor 1129 (emerge-setup-with-ancestor
1147 buffer-A emerge-file-A buffer-B emerge-file-B 1130 buffer-A emerge-file-A buffer-B emerge-file-B
1148 buffer-ancestor emerge-ancestor 1131 buffer-ancestor emerge-ancestor
1149 (cons `(lambda () 1132 (cons (lambda ()
1150 (delete-file ,emerge-file-A) 1133 (delete-file emerge-file-A)
1151 (delete-file ,emerge-file-B) 1134 (delete-file emerge-file-B)
1152 (delete-file ,emerge-ancestor)) 1135 (delete-file emerge-ancestor))
1153 startup-hooks) 1136 startup-hooks)
1154 (cons `(lambda () (emerge-files-exit ,file)) 1137 (cons (lambda () (emerge-files-exit file))
1155 quit-hooks) 1138 quit-hooks)
1156 output-file))) 1139 output-file)))
1157 1140
@@ -1233,20 +1216,20 @@ Otherwise, the A or B file present is copied to the output file."
1233 file-ancestor file-out 1216 file-ancestor file-out
1234 nil 1217 nil
1235 ;; When done, return to this buffer. 1218 ;; When done, return to this buffer.
1236 (list 1219 (let ((buf (current-buffer)))
1237 `(lambda () 1220 (list (lambda ()
1238 (switch-to-buffer ,(current-buffer)) 1221 (switch-to-buffer buf)
1239 (message "Merge done."))))) 1222 (message "Merge done"))))))
1240 ;; Merge of two files without ancestor 1223 ;; Merge of two files without ancestor
1241 ((and file-A file-B) 1224 ((and file-A file-B)
1242 (message "Merging %s and %s..." file-A file-B) 1225 (message "Merging %s and %s..." file-A file-B)
1243 (emerge-files (not (not file-out)) file-A file-B file-out 1226 (emerge-files (not (not file-out)) file-A file-B file-out
1244 nil 1227 nil
1245 ;; When done, return to this buffer. 1228 ;; When done, return to this buffer.
1246 (list 1229 (let ((buf (current-buffer)))
1247 `(lambda () 1230 (list (lambda ()
1248 (switch-to-buffer ,(current-buffer)) 1231 (switch-to-buffer buf)
1249 (message "Merge done."))))) 1232 (message "Merge done"))))))
1250 ;; There is an output file (or there would have been an error above), 1233 ;; There is an output file (or there would have been an error above),
1251 ;; but only one input file. 1234 ;; but only one input file.
1252 ;; The file appears to have been deleted in one version; do nothing. 1235 ;; The file appears to have been deleted in one version; do nothing.
@@ -1456,9 +1439,8 @@ These characteristics are restored by `emerge-restore-buffer-characteristics'."
1456 merge-buffer 1439 merge-buffer
1457 lineno-list) 1440 lineno-list)
1458 (let* (marker-list 1441 (let* (marker-list
1459 (A-point-min (with-current-buffer A-buffer (point-min))) 1442 (offset (with-current-buffer A-buffer
1460 (offset (1- A-point-min)) 1443 (- (point-min) (save-restriction (widen) (point-min)))))
1461 (B-point-min (with-current-buffer B-buffer (point-min)))
1462 ;; Record current line number in each buffer 1444 ;; Record current line number in each buffer
1463 ;; so we don't have to count from the beginning. 1445 ;; so we don't have to count from the beginning.
1464 (a-line 1) 1446 (a-line 1)
@@ -1480,17 +1462,17 @@ These characteristics are restored by `emerge-restore-buffer-characteristics'."
1480 (state (aref list-element 4))) 1462 (state (aref list-element 4)))
1481 ;; place markers at the appropriate places in the buffers 1463 ;; place markers at the appropriate places in the buffers
1482 (with-current-buffer 1464 (with-current-buffer
1483 A-buffer 1465 A-buffer
1484 (setq a-line (emerge-goto-line a-begin a-line)) 1466 (setq a-line (emerge-goto-line a-begin a-line))
1485 (setq a-begin-marker (point-marker)) 1467 (setq a-begin-marker (point-marker))
1486 (setq a-line (emerge-goto-line a-end a-line)) 1468 (setq a-line (emerge-goto-line a-end a-line))
1487 (setq a-end-marker (point-marker))) 1469 (setq a-end-marker (point-marker)))
1488 (with-current-buffer 1470 (with-current-buffer
1489 B-buffer 1471 B-buffer
1490 (setq b-line (emerge-goto-line b-begin b-line)) 1472 (setq b-line (emerge-goto-line b-begin b-line))
1491 (setq b-begin-marker (point-marker)) 1473 (setq b-begin-marker (point-marker))
1492 (setq b-line (emerge-goto-line b-end b-line)) 1474 (setq b-line (emerge-goto-line b-end b-line))
1493 (setq b-end-marker (point-marker))) 1475 (setq b-end-marker (point-marker)))
1494 (setq merge-begin-marker (set-marker 1476 (setq merge-begin-marker (set-marker
1495 (make-marker) 1477 (make-marker)
1496 (- (marker-position a-begin-marker) 1478 (- (marker-position a-begin-marker)
@@ -1502,15 +1484,15 @@ These characteristics are restored by `emerge-restore-buffer-characteristics'."
1502 offset) 1484 offset)
1503 merge-buffer)) 1485 merge-buffer))
1504 ;; record all the markers for this difference 1486 ;; record all the markers for this difference
1505 (setq marker-list (cons (vector a-begin-marker a-end-marker 1487 (push (vector a-begin-marker a-end-marker
1506 b-begin-marker b-end-marker 1488 b-begin-marker b-end-marker
1507 merge-begin-marker merge-end-marker 1489 merge-begin-marker merge-end-marker
1508 state) 1490 state)
1509 marker-list))) 1491 marker-list))
1510 (setq lineno-list (cdr lineno-list))) 1492 (setq lineno-list (cdr lineno-list)))
1511 ;; convert the list of difference information into a vector for 1493 ;; convert the list of difference information into a vector for
1512 ;; fast access 1494 ;; fast access
1513 (setq emerge-difference-list (apply 'vector (nreverse marker-list))))) 1495 (setq emerge-difference-list (apply #'vector (nreverse marker-list)))))
1514 1496
1515;; If we have an ancestor, select all B variants that we prefer 1497;; If we have an ancestor, select all B variants that we prefer
1516(defun emerge-select-prefer-Bs () 1498(defun emerge-select-prefer-Bs ()
@@ -1636,7 +1618,7 @@ the height of the merge window.
1636`C-u -' alone as argument scrolls half the height of the merge window." 1618`C-u -' alone as argument scrolls half the height of the merge window."
1637 (interactive "P") 1619 (interactive "P")
1638 (emerge-operate-on-windows 1620 (emerge-operate-on-windows
1639 'scroll-up 1621 #'scroll-up
1640 ;; calculate argument to scroll-up 1622 ;; calculate argument to scroll-up
1641 ;; if there is an explicit argument 1623 ;; if there is an explicit argument
1642 (if (and arg (not (equal arg '-))) 1624 (if (and arg (not (equal arg '-)))
@@ -1663,7 +1645,7 @@ the height of the merge window.
1663`C-u -' alone as argument scrolls half the height of the merge window." 1645`C-u -' alone as argument scrolls half the height of the merge window."
1664 (interactive "P") 1646 (interactive "P")
1665 (emerge-operate-on-windows 1647 (emerge-operate-on-windows
1666 'scroll-down 1648 #'scroll-down
1667 ;; calculate argument to scroll-down 1649 ;; calculate argument to scroll-down
1668 ;; if there is an explicit argument 1650 ;; if there is an explicit argument
1669 (if (and arg (not (equal arg '-))) 1651 (if (and arg (not (equal arg '-)))
@@ -1690,7 +1672,7 @@ the width of the A and B windows. `C-u -' alone as argument scrolls half the
1690width of the A and B windows." 1672width of the A and B windows."
1691 (interactive "P") 1673 (interactive "P")
1692 (emerge-operate-on-windows 1674 (emerge-operate-on-windows
1693 'scroll-left 1675 #'scroll-left
1694 ;; calculate argument to scroll-left 1676 ;; calculate argument to scroll-left
1695 ;; if there is an explicit argument 1677 ;; if there is an explicit argument
1696 (if (and arg (not (equal arg '-))) 1678 (if (and arg (not (equal arg '-)))
@@ -1718,7 +1700,7 @@ the width of the A and B windows. `C-u -' alone as argument scrolls half the
1718width of the A and B windows." 1700width of the A and B windows."
1719 (interactive "P") 1701 (interactive "P")
1720 (emerge-operate-on-windows 1702 (emerge-operate-on-windows
1721 'scroll-right 1703 #'scroll-right
1722 ;; calculate argument to scroll-right 1704 ;; calculate argument to scroll-right
1723 ;; if there is an explicit argument 1705 ;; if there is an explicit argument
1724 (if (and arg (not (equal arg '-))) 1706 (if (and arg (not (equal arg '-)))
@@ -1745,18 +1727,18 @@ This resets the horizontal scrolling of all three merge buffers
1745to the left margin, if they are in windows." 1727to the left margin, if they are in windows."
1746 (interactive) 1728 (interactive)
1747 (emerge-operate-on-windows 1729 (emerge-operate-on-windows
1748 (lambda (x) (set-window-hscroll (selected-window) 0)) 1730 (lambda (_) (set-window-hscroll (selected-window) 0))
1749 nil)) 1731 nil))
1750 1732
1751;; Attempt to show the region nicely.
1752;; If there are min-lines lines above and below the region, then don't do
1753;; anything.
1754;; If not, recenter the region to make it so.
1755;; If that isn't possible, remove context lines evenly from top and bottom
1756;; so the entire region shows.
1757;; If that isn't possible, show the top of the region.
1758;; BEG must be at the beginning of a line.
1759(defun emerge-position-region (beg end pos) 1733(defun emerge-position-region (beg end pos)
1734 "Attempt to show the region nicely.
1735If there are min-lines lines above and below the region, then don't do
1736anything.
1737If not, recenter the region to make it so.
1738If that isn't possible, remove context lines evenly from top and bottom
1739so the entire region shows.
1740If that isn't possible, show the top of the region.
1741BEG must be at the beginning of a line."
1760 ;; First test whether the entire region is visible with 1742 ;; First test whether the entire region is visible with
1761 ;; emerge-min-visible-lines above and below it 1743 ;; emerge-min-visible-lines above and below it
1762 (if (not (and (<= (progn 1744 (if (not (and (<= (progn
@@ -1795,7 +1777,7 @@ to the left margin, if they are in windows."
1795 (memq (aref (aref emerge-difference-list n) 6) 1777 (memq (aref (aref emerge-difference-list n) 6)
1796 '(prefer-A prefer-B))) 1778 '(prefer-A prefer-B)))
1797 (setq n (1+ n))) 1779 (setq n (1+ n)))
1798 (let ((buffer-read-only nil)) 1780 (let ((inhibit-read-only t))
1799 (emerge-unselect-and-select-difference n))) 1781 (emerge-unselect-and-select-difference n)))
1800 (error "At end"))) 1782 (error "At end")))
1801 1783
@@ -1809,14 +1791,14 @@ to the left margin, if they are in windows."
1809 (memq (aref (aref emerge-difference-list n) 6) 1791 (memq (aref (aref emerge-difference-list n) 6)
1810 '(prefer-A prefer-B))) 1792 '(prefer-A prefer-B)))
1811 (setq n (1- n))) 1793 (setq n (1- n)))
1812 (let ((buffer-read-only nil)) 1794 (let ((inhibit-read-only t))
1813 (emerge-unselect-and-select-difference n))) 1795 (emerge-unselect-and-select-difference n)))
1814 (error "At beginning"))) 1796 (error "At beginning")))
1815 1797
1816(defun emerge-jump-to-difference (difference-number) 1798(defun emerge-jump-to-difference (difference-number)
1817 "Go to the N-th difference." 1799 "Go to the N-th difference."
1818 (interactive "p") 1800 (interactive "p")
1819 (let ((buffer-read-only nil)) 1801 (let ((inhibit-read-only t))
1820 (setq difference-number (1- difference-number)) 1802 (setq difference-number (1- difference-number))
1821 (if (and (>= difference-number -1) 1803 (if (and (>= difference-number -1)
1822 (< difference-number (1+ emerge-number-of-differences))) 1804 (< difference-number (1+ emerge-number-of-differences)))
@@ -1878,6 +1860,13 @@ buffer after this will cause serious problems."
1878 (let ((emerge-prefix-argument arg)) 1860 (let ((emerge-prefix-argument arg))
1879 (run-hooks 'emerge-quit-hook))) 1861 (run-hooks 'emerge-quit-hook)))
1880 1862
1863(defmacro emerge--current-beg (diff-vector side)
1864 ;; +1 because emerge-place-flags-in-buffer1 moved the marker by 1.
1865 `(1+ (aref ,diff-vector ,(pcase-exhaustive side ('A 0) ('B 2) ('merge 4)))))
1866(defmacro emerge--current-end (diff-vector side)
1867 ;; -1 because emerge-place-flags-in-buffer1 moved the marker by 1.
1868 `(1- (aref ,diff-vector ,(pcase-exhaustive side ('A 1) ('B 3) ('merge 5)))))
1869
1881(defun emerge-select-A (&optional force) 1870(defun emerge-select-A (&optional force)
1882 "Select the A variant of this difference. 1871 "Select the A variant of this difference.
1883Refuses to function if this difference has been edited, i.e., if it 1872Refuses to function if this difference has been edited, i.e., if it
@@ -1885,26 +1874,25 @@ is neither the A nor the B variant.
1885A prefix argument forces the variant to be selected 1874A prefix argument forces the variant to be selected
1886even if the difference has been edited." 1875even if the difference has been edited."
1887 (interactive "P") 1876 (interactive "P")
1888 (let ((operate 1877 (let ((operate #'emerge-select-A-edit)
1889 (lambda ()
1890 (emerge-select-A-edit merge-begin merge-end A-begin A-end)
1891 (if emerge-auto-advance
1892 (emerge-next-difference))))
1893 (operate-no-change 1878 (operate-no-change
1894 (lambda () (if emerge-auto-advance 1879 (lambda (_diff-vector)
1895 (emerge-next-difference))))) 1880 (if emerge-auto-advance (emerge-next-difference)))))
1896 (emerge-select-version force operate-no-change operate operate))) 1881 (emerge-select-version force operate-no-change operate operate)))
1897 1882
1898;; Actually select the A variant 1883;; Actually select the A variant
1899(defun emerge-select-A-edit (merge-begin merge-end A-begin A-end) 1884(defun emerge-select-A-edit (diff-vector)
1900 (with-current-buffer 1885 (with-current-buffer
1901 emerge-merge-buffer 1886 emerge-merge-buffer
1902 (delete-region merge-begin merge-end) 1887 (goto-char (emerge--current-beg diff-vector merge))
1903 (goto-char merge-begin) 1888 (delete-region (point) (emerge--current-end diff-vector merge))
1904 (insert-buffer-substring emerge-A-buffer A-begin A-end) 1889 (save-excursion
1905 (goto-char merge-begin) 1890 (insert-buffer-substring emerge-A-buffer
1906 (aset diff-vector 6 'A) 1891 (emerge--current-beg diff-vector A)
1907 (emerge-refresh-mode-line))) 1892 (emerge--current-end diff-vector A)))
1893 (aset diff-vector 6 'A)
1894 (emerge-refresh-mode-line)
1895 (if emerge-auto-advance (emerge-next-difference))))
1908 1896
1909(defun emerge-select-B (&optional force) 1897(defun emerge-select-B (&optional force)
1910 "Select the B variant of this difference. 1898 "Select the B variant of this difference.
@@ -1913,26 +1901,25 @@ is neither the A nor the B variant.
1913A prefix argument forces the variant to be selected 1901A prefix argument forces the variant to be selected
1914even if the difference has been edited." 1902even if the difference has been edited."
1915 (interactive "P") 1903 (interactive "P")
1916 (let ((operate 1904 (let ((operate #'emerge-select-B-edit)
1917 (lambda ()
1918 (emerge-select-B-edit merge-begin merge-end B-begin B-end)
1919 (if emerge-auto-advance
1920 (emerge-next-difference))))
1921 (operate-no-change 1905 (operate-no-change
1922 (lambda () (if emerge-auto-advance 1906 (lambda (_diff-vector)
1923 (emerge-next-difference))))) 1907 (if emerge-auto-advance (emerge-next-difference)))))
1924 (emerge-select-version force operate operate-no-change operate))) 1908 (emerge-select-version force operate operate-no-change operate)))
1925 1909
1926;; Actually select the B variant 1910;; Actually select the B variant
1927(defun emerge-select-B-edit (merge-begin merge-end B-begin B-end) 1911(defun emerge-select-B-edit (diff-vector)
1928 (with-current-buffer 1912 (with-current-buffer
1929 emerge-merge-buffer 1913 emerge-merge-buffer
1930 (delete-region merge-begin merge-end) 1914 (goto-char (emerge--current-beg diff-vector merge))
1931 (goto-char merge-begin) 1915 (delete-region (point) (emerge--current-end diff-vector merge))
1932 (insert-buffer-substring emerge-B-buffer B-begin B-end) 1916 (save-excursion
1933 (goto-char merge-begin) 1917 (insert-buffer-substring emerge-B-buffer
1934 (aset diff-vector 6 'B) 1918 (emerge--current-beg diff-vector B)
1935 (emerge-refresh-mode-line))) 1919 (emerge--current-end diff-vector B)))
1920 (aset diff-vector 6 'B)
1921 (emerge-refresh-mode-line)
1922 (if emerge-auto-advance (emerge-next-difference))))
1936 1923
1937(defun emerge-default-A () 1924(defun emerge-default-A ()
1938 "Make the A variant the default from here down. 1925 "Make the A variant the default from here down.
@@ -1940,7 +1927,7 @@ This selects the A variant for all differences from here down in the buffer
1940which are still defaulted, i.e., which the user has not selected and for 1927which are still defaulted, i.e., which the user has not selected and for
1941which there is no preference." 1928which there is no preference."
1942 (interactive) 1929 (interactive)
1943 (let ((buffer-read-only nil)) 1930 (let ((inhibit-read-only t))
1944 (let ((selected-difference emerge-current-difference) 1931 (let ((selected-difference emerge-current-difference)
1945 (n (max emerge-current-difference 0))) 1932 (n (max emerge-current-difference 0)))
1946 (while (< n emerge-number-of-differences) 1933 (while (< n emerge-number-of-differences)
@@ -1962,7 +1949,7 @@ This selects the B variant for all differences from here down in the buffer
1962which are still defaulted, i.e., which the user has not selected and for 1949which are still defaulted, i.e., which the user has not selected and for
1963which there is no preference." 1950which there is no preference."
1964 (interactive) 1951 (interactive)
1965 (let ((buffer-read-only nil)) 1952 (let ((inhibit-read-only t))
1966 (let ((selected-difference emerge-current-difference) 1953 (let ((selected-difference emerge-current-difference)
1967 (n (max emerge-current-difference 0))) 1954 (n (max emerge-current-difference 0)))
1968 (while (< n emerge-number-of-differences) 1955 (while (< n emerge-number-of-differences)
@@ -2071,7 +2058,7 @@ With prefix argument, puts point before, mark after."
2071 (A-begin (1+ (aref diff-vector 0))) 2058 (A-begin (1+ (aref diff-vector 0)))
2072 (A-end (1- (aref diff-vector 1))) 2059 (A-end (1- (aref diff-vector 1)))
2073 (opoint (point)) 2060 (opoint (point))
2074 (buffer-read-only nil)) 2061 (inhibit-read-only t))
2075 (insert-buffer-substring emerge-A-buffer A-begin A-end) 2062 (insert-buffer-substring emerge-A-buffer A-begin A-end)
2076 (if (not arg) 2063 (if (not arg)
2077 (set-mark opoint) 2064 (set-mark opoint)
@@ -2089,7 +2076,7 @@ With prefix argument, puts point before, mark after."
2089 (B-begin (1+ (aref diff-vector 2))) 2076 (B-begin (1+ (aref diff-vector 2)))
2090 (B-end (1- (aref diff-vector 3))) 2077 (B-end (1- (aref diff-vector 3)))
2091 (opoint (point)) 2078 (opoint (point))
2092 (buffer-read-only nil)) 2079 (inhibit-read-only t))
2093 (insert-buffer-substring emerge-B-buffer B-begin B-end) 2080 (insert-buffer-substring emerge-B-buffer B-begin B-end)
2094 (if (not arg) 2081 (if (not arg)
2095 (set-mark opoint) 2082 (set-mark opoint)
@@ -2450,28 +2437,28 @@ the nearest previous difference."
2450 (1- index) 2437 (1- index)
2451 (error "No difference contains or precedes point"))))))) 2438 (error "No difference contains or precedes point")))))))
2452 2439
2440(defvar emerge-line-diff)
2441
2453(defun emerge-line-numbers () 2442(defun emerge-line-numbers ()
2454 "Display the current line numbers. 2443 "Display the current line numbers.
2455This function displays the line numbers of the points in the A, B, and 2444This function displays the line numbers of the points in the A, B, and
2456merge buffers." 2445merge buffers."
2457 (interactive) 2446 (interactive)
2458 (let* ((valid-diff 2447 (let* ((valid-diff
2459 (and (>= emerge-current-difference 0) 2448 (and (>= emerge-current-difference 0)
2460 (< emerge-current-difference emerge-number-of-differences))) 2449 (< emerge-current-difference emerge-number-of-differences)))
2461 (emerge-line-diff (and valid-diff 2450 (emerge-line-diff (and valid-diff
2462 (aref emerge-difference-list 2451 (aref emerge-difference-list
2463 emerge-current-difference))) 2452 emerge-current-difference)))
2464 (merge-line (emerge-line-number-in-buf 4 5)) 2453 (merge-line (emerge-line-number-in-buf valid-diff 4 5))
2465 (A-line (with-current-buffer emerge-A-buffer 2454 (A-line (with-current-buffer emerge-A-buffer
2466 (emerge-line-number-in-buf 0 1))) 2455 (emerge-line-number-in-buf valid-diff 0 1)))
2467 (B-line (with-current-buffer emerge-B-buffer 2456 (B-line (with-current-buffer emerge-B-buffer
2468 (emerge-line-number-in-buf 2 3)))) 2457 (emerge-line-number-in-buf valid-diff 2 3))))
2469 (message "At lines: merge = %d, A = %d, B = %d" 2458 (message "At lines: merge = %d, A = %d, B = %d"
2470 merge-line A-line B-line))) 2459 merge-line A-line B-line)))
2471 2460
2472(defvar emerge-line-diff) 2461(defun emerge-line-number-in-buf (valid-diff begin-marker end-marker)
2473
2474(defun emerge-line-number-in-buf (begin-marker end-marker)
2475 ;; FIXME point-min rather than 1? widen? 2462 ;; FIXME point-min rather than 1? widen?
2476 (let ((temp (1+ (count-lines 1 (line-beginning-position))))) 2463 (let ((temp (1+ (count-lines 1 (line-beginning-position)))))
2477 (if valid-diff 2464 (if valid-diff
@@ -2537,46 +2524,41 @@ Interactively, reads the register using `register-read-with-preview'."
2537 (error "Register does not contain text")) 2524 (error "Register does not contain text"))
2538 (emerge-combine-versions-internal template force))) 2525 (emerge-combine-versions-internal template force)))
2539 2526
2540(defun emerge-combine-versions-internal (emerge-combine-template force) 2527(defun emerge-combine-versions-internal (combine-template force)
2541 (let ((operate 2528 (let ((operate (lambda (diff-vector)
2542 (lambda () 2529 (emerge-combine-versions-edit diff-vector
2543 (emerge-combine-versions-edit merge-begin merge-end 2530 combine-template))))
2544 A-begin A-end B-begin B-end)
2545 (if emerge-auto-advance
2546 (emerge-next-difference)))))
2547 (emerge-select-version force operate operate operate))) 2531 (emerge-select-version force operate operate operate)))
2548 2532
2549(defvar emerge-combine-template) 2533(defun emerge-combine-versions-edit (diff-vector combine-template)
2550
2551(defun emerge-combine-versions-edit (merge-begin merge-end
2552 A-begin A-end B-begin B-end)
2553 (with-current-buffer 2534 (with-current-buffer
2554 emerge-merge-buffer 2535 emerge-merge-buffer
2555 (delete-region merge-begin merge-end) 2536 (goto-char (emerge--current-beg diff-vector merge))
2556 (goto-char merge-begin) 2537 (delete-region (point) (emerge--current-end diff-vector merge))
2557 (let ((i 0)) 2538 (save-excursion
2558 (while (< i (length emerge-combine-template)) 2539 (let ((i 0))
2559 (let ((c (aref emerge-combine-template i))) 2540 (while (< i (length combine-template))
2560 (if (= c ?%) 2541 (let ((c (aref combine-template i)))
2561 (progn 2542 (if (not (= c ?%))
2562 (setq i (1+ i)) 2543 (insert c)
2563 (setq c 2544 (setq i (1+ i))
2564 (condition-case nil 2545 (pcase (condition-case nil
2565 (aref emerge-combine-template i) 2546 (aref combine-template i)
2566 (error ?%))) 2547 (error ?%))
2567 (cond ((= c ?a) 2548 (?a
2568 (insert-buffer-substring emerge-A-buffer A-begin A-end)) 2549 (insert-buffer-substring emerge-A-buffer
2569 ((= c ?b) 2550 (emerge--current-beg diff-vector A)
2570 (insert-buffer-substring emerge-B-buffer B-begin B-end)) 2551 (emerge--current-end diff-vector A)))
2571 ((= c ?%) 2552 (?b
2572 (insert ?%)) 2553 (insert-buffer-substring emerge-B-buffer
2573 (t 2554 (emerge--current-beg diff-vector B)
2574 (insert c)))) 2555 (emerge--current-end diff-vector B)))
2575 (insert c))) 2556 (?% (insert ?%))
2576 (setq i (1+ i)))) 2557 (c (insert c)))))
2577 (goto-char merge-begin) 2558 (setq i (1+ i)))))
2578 (aset diff-vector 6 'combined) 2559 (aset diff-vector 6 'combined)
2579 (emerge-refresh-mode-line))) 2560 (emerge-refresh-mode-line)
2561 (if emerge-auto-advance (emerge-next-difference))))
2580 2562
2581(defun emerge-set-merge-mode (mode) 2563(defun emerge-set-merge-mode (mode)
2582 "Set the major mode in a merge buffer. 2564 "Set the major mode in a merge buffer.
@@ -2617,7 +2599,7 @@ keymap. Leaves merge in fast mode."
2617 (emerge-place-flags-in-buffer1 difference before-index after-index))) 2599 (emerge-place-flags-in-buffer1 difference before-index after-index)))
2618 2600
2619(defun emerge-place-flags-in-buffer1 (difference before-index after-index) 2601(defun emerge-place-flags-in-buffer1 (difference before-index after-index)
2620 (let ((buffer-read-only nil)) 2602 (let ((inhibit-read-only t))
2621 ;; insert the flag before the difference 2603 ;; insert the flag before the difference
2622 (let ((before (aref (aref emerge-globalized-difference-list difference) 2604 (let ((before (aref (aref emerge-globalized-difference-list difference)
2623 before-index)) 2605 before-index))
@@ -2682,7 +2664,7 @@ keymap. Leaves merge in fast mode."
2682(defun emerge-remove-flags-in-buffer (buffer before after) 2664(defun emerge-remove-flags-in-buffer (buffer before after)
2683 (with-current-buffer 2665 (with-current-buffer
2684 buffer 2666 buffer
2685 (let ((buffer-read-only nil)) 2667 (let ((inhibit-read-only t))
2686 ;; remove the flags, if they're there 2668 ;; remove the flags, if they're there
2687 (goto-char (- before (1- emerge-before-flag-length))) 2669 (goto-char (- before (1- emerge-before-flag-length)))
2688 (if (looking-at emerge-before-flag-match) 2670 (if (looking-at emerge-before-flag-match)
@@ -2717,18 +2699,18 @@ keymap. Leaves merge in fast mode."
2717 (emerge-recenter) 2699 (emerge-recenter)
2718 (emerge-refresh-mode-line)))) 2700 (emerge-refresh-mode-line))))
2719 2701
2720;; Perform tests to see whether user should be allowed to select a version
2721;; of this difference:
2722;; a valid difference has been selected; and
2723;; the difference text in the merge buffer is:
2724;; the A version (execute a-version), or
2725;; the B version (execute b-version), or
2726;; empty (execute neither-version), or
2727;; argument FORCE is true (execute neither-version)
2728;; Otherwise, signal an error.
2729(defun emerge-select-version (force a-version b-version neither-version) 2702(defun emerge-select-version (force a-version b-version neither-version)
2703 "Perform tests to see whether user should be allowed to select a version
2704of this difference:
2705 a valid difference has been selected; and
2706 the difference text in the merge buffer is:
2707 the A version (execute a-version), or
2708 the B version (execute b-version), or
2709 empty (execute neither-version), or
2710 argument FORCE is true (execute neither-version)
2711Otherwise, signal an error."
2730 (emerge-validate-difference) 2712 (emerge-validate-difference)
2731 (let ((buffer-read-only nil)) 2713 (let ((inhibit-read-only t))
2732 (let* ((diff-vector 2714 (let* ((diff-vector
2733 (aref emerge-difference-list emerge-current-difference)) 2715 (aref emerge-difference-list emerge-current-difference))
2734 (A-begin (1+ (aref diff-vector 0))) 2716 (A-begin (1+ (aref diff-vector 0)))
@@ -2740,13 +2722,13 @@ keymap. Leaves merge in fast mode."
2740 (if (emerge-compare-buffers emerge-A-buffer A-begin A-end 2722 (if (emerge-compare-buffers emerge-A-buffer A-begin A-end
2741 emerge-merge-buffer merge-begin 2723 emerge-merge-buffer merge-begin
2742 merge-end) 2724 merge-end)
2743 (funcall a-version) 2725 (funcall a-version diff-vector)
2744 (if (emerge-compare-buffers emerge-B-buffer B-begin B-end 2726 (if (emerge-compare-buffers emerge-B-buffer B-begin B-end
2745 emerge-merge-buffer merge-begin 2727 emerge-merge-buffer merge-begin
2746 merge-end) 2728 merge-end)
2747 (funcall b-version) 2729 (funcall b-version diff-vector)
2748 (if (or force (= merge-begin merge-end)) 2730 (if (or force (= merge-begin merge-end))
2749 (funcall neither-version) 2731 (funcall neither-version diff-vector)
2750 (error "This difference region has been edited"))))))) 2732 (error "This difference region has been edited")))))))
2751 2733
2752;; Read a file name, handling all of the various defaulting rules. 2734;; Read a file name, handling all of the various defaulting rules.
@@ -2972,78 +2954,6 @@ If some prefix of KEY has a non-prefix definition, it is redefined."
2972 ;; Now define the key 2954 ;; Now define the key
2973 (define-key keymap key definition)) 2955 (define-key keymap key definition))
2974 2956
2975;;;;; Improvements to describe-mode, so that it describes minor modes as well
2976;;;;; as the major mode
2977;;(defun describe-mode (&optional minor)
2978;; "Display documentation of current major mode.
2979;;If optional arg MINOR is non-nil (or prefix argument is given if interactive),
2980;;display documentation of active minor modes as well.
2981;;For this to work correctly for a minor mode, the mode's indicator variable
2982;;\(listed in `minor-mode-alist') must also be a function whose documentation
2983;;describes the minor mode."
2984;; (interactive)
2985;; (with-output-to-temp-buffer "*Help*"
2986;; (princ mode-name)
2987;; (princ " Mode:\n")
2988;; (princ (documentation major-mode))
2989;; (let ((minor-modes minor-mode-alist)
2990;; (locals (buffer-local-variables)))
2991;; (while minor-modes
2992;; (let* ((minor-mode (car (car minor-modes)))
2993;; (indicator (car (cdr (car minor-modes))))
2994;; (local-binding (assq minor-mode locals)))
2995;; ;; Document a minor mode if it is listed in minor-mode-alist,
2996;; ;; bound locally in this buffer, non-nil, and has a function
2997;; ;; definition.
2998;; (if (and local-binding
2999;; (cdr local-binding)
3000;; (fboundp minor-mode))
3001;; (progn
3002;; (princ (format "\n\n\n%s minor mode (indicator%s):\n"
3003;; minor-mode indicator))
3004;; (princ (documentation minor-mode)))))
3005;; (setq minor-modes (cdr minor-modes))))
3006;; (with-current-buffer standard-output
3007;; (help-mode))
3008;; (help-print-return-message)))
3009
3010;; This goes with the redefinition of describe-mode.
3011;;;; Adjust things so that keyboard macro definitions are documented correctly.
3012;;(fset 'defining-kbd-macro (symbol-function 'start-kbd-macro))
3013
3014;; substitute-key-definition should work now.
3015;;;; Function to shadow a definition in a keymap with definitions in another.
3016;;(defun emerge-shadow-key-definition (olddef newdef keymap shadowmap)
3017;; "Shadow OLDDEF with NEWDEF for any keys in KEYMAP with entries in SHADOWMAP.
3018;;In other words, SHADOWMAP will now shadow all definitions of OLDDEF in KEYMAP
3019;;with NEWDEF. Does not affect keys that are already defined in SHADOWMAP,
3020;;including those whose definition is OLDDEF."
3021;; ;; loop through all keymaps accessible from keymap
3022;; (let ((maps (accessible-keymaps keymap)))
3023;; (while maps
3024;; (let ((prefix (car (car maps)))
3025;; (map (cdr (car maps))))
3026;; ;; examine a keymap
3027;; (if (arrayp map)
3028;; ;; array keymap
3029;; (let ((len (length map))
3030;; (i 0))
3031;; (while (< i len)
3032;; (if (eq (aref map i) olddef)
3033;; ;; set the shadowing definition
3034;; (let ((key (concat prefix (char-to-string i))))
3035;; (emerge-define-key-if-possible shadowmap key newdef)))
3036;; (setq i (1+ i))))
3037;; ;; sparse keymap
3038;; (while map
3039;; (if (eq (cdr-safe (car-safe map)) olddef)
3040;; ;; set the shadowing definition
3041;; (let ((key
3042;; (concat prefix (char-to-string (car (car map))))))
3043;; (emerge-define-key-if-possible shadowmap key newdef)))
3044;; (setq map (cdr map)))))
3045;; (setq maps (cdr maps)))))
3046
3047;; Define a key if it (or a prefix) is not already defined in the map. 2957;; Define a key if it (or a prefix) is not already defined in the map.
3048(defun emerge-define-key-if-possible (keymap key definition) 2958(defun emerge-define-key-if-possible (keymap key definition)
3049 ;; look up the present definition of the key 2959 ;; look up the present definition of the key
@@ -3057,18 +2967,6 @@ If some prefix of KEY has a non-prefix definition, it is redefined."
3057 (if (not present) 2967 (if (not present)
3058 (define-key keymap key definition))))) 2968 (define-key keymap key definition)))))
3059 2969
3060;; Ordinary substitute-key-definition should do this now.
3061;;(defun emerge-recursively-substitute-key-definition (olddef newdef keymap)
3062;; "Like `substitute-key-definition', but act recursively on subkeymaps.
3063;;Make sure that subordinate keymaps aren't shared with other keymaps!
3064;;\(`copy-keymap' will suffice.)"
3065;; ;; Loop through all keymaps accessible from keymap
3066;; (let ((maps (accessible-keymaps keymap)))
3067;; (while maps
3068;; ;; Substitute in this keymap
3069;; (substitute-key-definition olddef newdef (cdr (car maps)))
3070;; (setq maps (cdr maps)))))
3071
3072;; Show the name of the file in the buffer. 2970;; Show the name of the file in the buffer.
3073(defun emerge-show-file-name () 2971(defun emerge-show-file-name ()
3074 "Displays the name of the file loaded into the current buffer. 2972 "Displays the name of the file loaded into the current buffer.