diff options
| -rw-r--r-- | etc/NEWS | 2 | ||||
| -rw-r--r-- | lisp/vc/smerge-mode.el | 93 |
2 files changed, 51 insertions, 44 deletions
| @@ -415,6 +415,8 @@ line. | |||
| 415 | 415 | ||
| 416 | * Changes in Specialized Modes and Packages in Emacs 26.1 | 416 | * Changes in Specialized Modes and Packages in Emacs 26.1 |
| 417 | 417 | ||
| 418 | *** smerge-refine-regions can refine regions in separate buffers | ||
| 419 | |||
| 418 | *** Info menu and index completion uses substring completion by default. | 420 | *** Info menu and index completion uses substring completion by default. |
| 419 | This can be customized via the info-menu category in | 421 | This can be customized via the info-menu category in |
| 420 | completion-category-override. | 422 | completion-category-override. |
diff --git a/lisp/vc/smerge-mode.el b/lisp/vc/smerge-mode.el index de40b99b941..21c39c85ca8 100644 --- a/lisp/vc/smerge-mode.el +++ b/lisp/vc/smerge-mode.el | |||
| @@ -911,7 +911,7 @@ Point is moved to the end of the conflict." | |||
| 911 | 911 | ||
| 912 | ;;; Refined change highlighting | 912 | ;;; Refined change highlighting |
| 913 | 913 | ||
| 914 | (defvar smerge-refine-forward-function 'smerge-refine-forward | 914 | (defvar smerge-refine-forward-function #'smerge--refine-forward |
| 915 | "Function used to determine an \"atomic\" element. | 915 | "Function used to determine an \"atomic\" element. |
| 916 | You can set it to `forward-char' to get char-level granularity. | 916 | You can set it to `forward-char' to get char-level granularity. |
| 917 | Its behavior has mainly two restrictions: | 917 | Its behavior has mainly two restrictions: |
| @@ -941,7 +941,7 @@ It has the following disadvantages: | |||
| 941 | - may in degenerate cases take a 1KB input region and turn it into a 1MB | 941 | - may in degenerate cases take a 1KB input region and turn it into a 1MB |
| 942 | file to pass to diff.") | 942 | file to pass to diff.") |
| 943 | 943 | ||
| 944 | (defun smerge-refine-forward (n) | 944 | (defun smerge--refine-forward (n) |
| 945 | (let ((case-fold-search nil) | 945 | (let ((case-fold-search nil) |
| 946 | (re "[[:upper:]]?[[:lower:]]+\\|[[:upper:]]+\\|[[:digit:]]+\\|.\\|\n")) | 946 | (re "[[:upper:]]?[[:lower:]]+\\|[[:upper:]]+\\|[[:digit:]]+\\|.\\|\n")) |
| 947 | (when (and smerge-refine-ignore-whitespace | 947 | (when (and smerge-refine-ignore-whitespace |
| @@ -954,7 +954,7 @@ It has the following disadvantages: | |||
| 954 | (unless (looking-at re) (error "Smerge refine internal error")) | 954 | (unless (looking-at re) (error "Smerge refine internal error")) |
| 955 | (goto-char (match-end 0))))) | 955 | (goto-char (match-end 0))))) |
| 956 | 956 | ||
| 957 | (defun smerge-refine-chopup-region (beg end file &optional preproc) | 957 | (defun smerge--refine-chopup-region (beg end file &optional preproc) |
| 958 | "Chopup the region into small elements, one per line. | 958 | "Chopup the region into small elements, one per line. |
| 959 | Save the result into FILE. | 959 | Save the result into FILE. |
| 960 | If non-nil, PREPROC is called with no argument in a buffer that contains | 960 | If non-nil, PREPROC is called with no argument in a buffer that contains |
| @@ -966,44 +966,45 @@ chars to try and eliminate some spurious differences." | |||
| 966 | ;; there aren't any, so the resulting "change" didn't make much sense. | 966 | ;; there aren't any, so the resulting "change" didn't make much sense. |
| 967 | ;; You can still get this behavior by setting | 967 | ;; You can still get this behavior by setting |
| 968 | ;; `smerge-refine-forward-function' to `forward-char'. | 968 | ;; `smerge-refine-forward-function' to `forward-char'. |
| 969 | (let ((buf (current-buffer))) | 969 | (with-temp-buffer |
| 970 | (with-temp-buffer | 970 | (insert-buffer-substring (marker-buffer beg) beg end) |
| 971 | (insert-buffer-substring buf beg end) | 971 | (when preproc (goto-char (point-min)) (funcall preproc)) |
| 972 | (when preproc (goto-char (point-min)) (funcall preproc)) | 972 | (when smerge-refine-ignore-whitespace |
| 973 | (when smerge-refine-ignore-whitespace | 973 | ;; It doesn't make much of a difference for diff-fine-highlight |
| 974 | ;; It doesn't make much of a difference for diff-fine-highlight | 974 | ;; because we still have the _/+/</>/! prefix anyway. Can still be |
| 975 | ;; because we still have the _/+/</>/! prefix anyway. Can still be | 975 | ;; useful in other circumstances. |
| 976 | ;; useful in other circumstances. | 976 | (subst-char-in-region (point-min) (point-max) ?\n ?\s)) |
| 977 | (subst-char-in-region (point-min) (point-max) ?\n ?\s)) | 977 | (goto-char (point-min)) |
| 978 | (goto-char (point-min)) | 978 | (while (not (eobp)) |
| 979 | (while (not (eobp)) | 979 | (funcall smerge-refine-forward-function 1) |
| 980 | (funcall smerge-refine-forward-function 1) | 980 | (let ((s (if (prog2 (forward-char -1) (bolp) (forward-char 1)) |
| 981 | (let ((s (if (prog2 (forward-char -1) (bolp) (forward-char 1)) | 981 | nil |
| 982 | nil | 982 | (buffer-substring (line-beginning-position) (point))))) |
| 983 | (buffer-substring (line-beginning-position) (point))))) | 983 | ;; We add \n after each char except after \n, so we get |
| 984 | ;; We add \n after each char except after \n, so we get | 984 | ;; one line per text char, where each line contains |
| 985 | ;; one line per text char, where each line contains | 985 | ;; just one char, except for \n chars which are |
| 986 | ;; just one char, except for \n chars which are | 986 | ;; represented by the empty line. |
| 987 | ;; represented by the empty line. | 987 | (unless (eq (char-before) ?\n) (insert ?\n)) |
| 988 | (unless (eq (char-before) ?\n) (insert ?\n)) | 988 | ;; HACK ALERT!! |
| 989 | ;; HACK ALERT!! | 989 | (if smerge-refine-weight-hack |
| 990 | (if smerge-refine-weight-hack | 990 | (dotimes (_i (1- (length s))) (insert s "\n"))))) |
| 991 | (dotimes (_i (1- (length s))) (insert s "\n"))))) | 991 | (unless (bolp) (error "Smerge refine internal error")) |
| 992 | (unless (bolp) (error "Smerge refine internal error")) | 992 | (let ((coding-system-for-write 'emacs-internal)) |
| 993 | (let ((coding-system-for-write 'emacs-mule)) | 993 | (write-region (point-min) (point-max) file nil 'nomessage)))) |
| 994 | (write-region (point-min) (point-max) file nil 'nomessage))))) | 994 | |
| 995 | 995 | (defun smerge--refine-highlight-change (beg match-num1 match-num2 props) | |
| 996 | (defun smerge-refine-highlight-change (buf beg match-num1 match-num2 props) | 996 | ;; TODO: Add a property pointing to the corresponding text in the |
| 997 | (with-current-buffer buf | 997 | ;; other region. |
| 998 | (with-current-buffer (marker-buffer beg) | ||
| 998 | (goto-char beg) | 999 | (goto-char beg) |
| 999 | (let* ((startline (- (string-to-number match-num1) 1)) | 1000 | (let* ((startline (- (string-to-number match-num1) 1)) |
| 1000 | (beg (progn (funcall (if smerge-refine-weight-hack | 1001 | (beg (progn (funcall (if smerge-refine-weight-hack |
| 1001 | 'forward-char | 1002 | #'forward-char |
| 1002 | smerge-refine-forward-function) | 1003 | smerge-refine-forward-function) |
| 1003 | startline) | 1004 | startline) |
| 1004 | (point))) | 1005 | (point))) |
| 1005 | (end (progn (funcall (if smerge-refine-weight-hack | 1006 | (end (progn (funcall (if smerge-refine-weight-hack |
| 1006 | 'forward-char | 1007 | #'forward-char |
| 1007 | smerge-refine-forward-function) | 1008 | smerge-refine-forward-function) |
| 1008 | (if match-num2 | 1009 | (if match-num2 |
| 1009 | (- (string-to-number match-num2) | 1010 | (- (string-to-number match-num2) |
| @@ -1023,7 +1024,8 @@ chars to try and eliminate some spurious differences." | |||
| 1023 | (dolist (x props) (overlay-put ol (car x) (cdr x))) | 1024 | (dolist (x props) (overlay-put ol (car x) (cdr x))) |
| 1024 | ol))))) | 1025 | ol))))) |
| 1025 | 1026 | ||
| 1026 | (defun smerge-refine-subst (beg1 end1 beg2 end2 props-c &optional preproc props-r props-a) | 1027 | ;;;###autoload |
| 1028 | (defun smerge-refine-regions (beg1 end1 beg2 end2 props-c &optional preproc props-r props-a) | ||
| 1027 | "Show fine differences in the two regions BEG1..END1 and BEG2..END2. | 1029 | "Show fine differences in the two regions BEG1..END1 and BEG2..END2. |
| 1028 | PROPS-C is an alist of properties to put (via overlays) on the changes. | 1030 | PROPS-C is an alist of properties to put (via overlays) on the changes. |
| 1029 | PROPS-R is an alist of properties to put on removed characters. | 1031 | PROPS-R is an alist of properties to put on removed characters. |
| @@ -1037,19 +1039,20 @@ PROPS-A on added characters, and PROPS-R on removed characters. | |||
| 1037 | If non-nil, PREPROC is called with no argument in a buffer that contains | 1039 | If non-nil, PREPROC is called with no argument in a buffer that contains |
| 1038 | a copy of a region, just before preparing it to for `diff'. It can be | 1040 | a copy of a region, just before preparing it to for `diff'. It can be |
| 1039 | used to replace chars to try and eliminate some spurious differences." | 1041 | used to replace chars to try and eliminate some spurious differences." |
| 1040 | (let* ((buf (current-buffer)) | 1042 | (let* ((pos (point)) |
| 1041 | (pos (point)) | ||
| 1042 | deactivate-mark ; The code does not modify any visible buffer. | 1043 | deactivate-mark ; The code does not modify any visible buffer. |
| 1043 | (file1 (make-temp-file "diff1")) | 1044 | (file1 (make-temp-file "diff1")) |
| 1044 | (file2 (make-temp-file "diff2"))) | 1045 | (file2 (make-temp-file "diff2"))) |
| 1046 | (unless (markerp beg1) (setq beg1 (copy-marker beg1))) | ||
| 1047 | (unless (markerp beg2) (setq beg2 (copy-marker beg2))) | ||
| 1045 | ;; Chop up regions into smaller elements and save into files. | 1048 | ;; Chop up regions into smaller elements and save into files. |
| 1046 | (smerge-refine-chopup-region beg1 end1 file1 preproc) | 1049 | (smerge--refine-chopup-region beg1 end1 file1 preproc) |
| 1047 | (smerge-refine-chopup-region beg2 end2 file2 preproc) | 1050 | (smerge--refine-chopup-region beg2 end2 file2 preproc) |
| 1048 | 1051 | ||
| 1049 | ;; Call diff on those files. | 1052 | ;; Call diff on those files. |
| 1050 | (unwind-protect | 1053 | (unwind-protect |
| 1051 | (with-temp-buffer | 1054 | (with-temp-buffer |
| 1052 | (let ((coding-system-for-read 'emacs-mule)) | 1055 | (let ((coding-system-for-read 'emacs-internal)) |
| 1053 | (call-process diff-command nil t nil | 1056 | (call-process diff-command nil t nil |
| 1054 | (if (and smerge-refine-ignore-whitespace | 1057 | (if (and smerge-refine-ignore-whitespace |
| 1055 | (not smerge-refine-weight-hack)) | 1058 | (not smerge-refine-weight-hack)) |
| @@ -1077,16 +1080,16 @@ used to replace chars to try and eliminate some spurious differences." | |||
| 1077 | (m5 (match-string 5))) | 1080 | (m5 (match-string 5))) |
| 1078 | (when (memq op '(?d ?c)) | 1081 | (when (memq op '(?d ?c)) |
| 1079 | (setq last1 | 1082 | (setq last1 |
| 1080 | (smerge-refine-highlight-change | 1083 | (smerge--refine-highlight-change |
| 1081 | buf beg1 m1 m2 | 1084 | beg1 m1 m2 |
| 1082 | ;; Try to use props-c only for changed chars, | 1085 | ;; Try to use props-c only for changed chars, |
| 1083 | ;; fallback to props-r for changed/removed chars, | 1086 | ;; fallback to props-r for changed/removed chars, |
| 1084 | ;; but if props-r is nil then fallback to props-c. | 1087 | ;; but if props-r is nil then fallback to props-c. |
| 1085 | (or (and (eq op '?c) props-c) props-r props-c)))) | 1088 | (or (and (eq op '?c) props-c) props-r props-c)))) |
| 1086 | (when (memq op '(?a ?c)) | 1089 | (when (memq op '(?a ?c)) |
| 1087 | (setq last2 | 1090 | (setq last2 |
| 1088 | (smerge-refine-highlight-change | 1091 | (smerge--refine-highlight-change |
| 1089 | buf beg2 m4 m5 | 1092 | beg2 m4 m5 |
| 1090 | ;; Same logic as for removed chars above. | 1093 | ;; Same logic as for removed chars above. |
| 1091 | (or (and (eq op '?c) props-c) props-a props-c))))) | 1094 | (or (and (eq op '?c) props-c) props-a props-c))))) |
| 1092 | (forward-line 1) ;Skip hunk header. | 1095 | (forward-line 1) ;Skip hunk header. |
| @@ -1110,6 +1113,8 @@ used to replace chars to try and eliminate some spurious differences." | |||
| 1110 | (goto-char pos) | 1113 | (goto-char pos) |
| 1111 | (delete-file file1) | 1114 | (delete-file file1) |
| 1112 | (delete-file file2)))) | 1115 | (delete-file file2)))) |
| 1116 | (define-obsolete-function-alias 'smerge-refine-subst | ||
| 1117 | #'smerge-refine-regions "26.1") | ||
| 1113 | 1118 | ||
| 1114 | (defun smerge-refine (&optional part) | 1119 | (defun smerge-refine (&optional part) |
| 1115 | "Highlight the words of the conflict that are different. | 1120 | "Highlight the words of the conflict that are different. |