diff options
author | Stefan Monnier <[email protected]> | 2007-10-09 03:38:57 +0000 |
---|---|---|
committer | Stefan Monnier <[email protected]> | 2007-10-09 03:38:57 +0000 |
commit | 9f2e22a06dfa082f6519ff3c5b1403d66e848a8f (patch) | |
tree | 85b50d7339bac4d8590241259757b1d8b7043d32 /lisp/smerge-mode.el | |
parent | f30ff926ecd347afd93e4f80b193c8ccff814dfd (diff) |
(smerge-refine-chopup-region): Add `preproc' argument.
(smerge-refine-highlight-change): Add `props' argument.
(smerge-refine-subst): New function holding most of smerge-refine.
(smerge-refine): Use it.
Diffstat (limited to 'lisp/smerge-mode.el')
-rw-r--r-- | lisp/smerge-mode.el | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/lisp/smerge-mode.el b/lisp/smerge-mode.el index e3484bb0a4..5d4400958d 100644 --- a/lisp/smerge-mode.el +++ b/lisp/smerge-mode.el @@ -645,8 +645,12 @@ Point is moved to the end of the conflict." (error nil))) found)) -(defun smerge-refine-chopup-region (beg end file) - "Chopup the region into small elements, one per line." +(defun smerge-refine-chopup-region (beg end file &optional preproc) + "Chopup the region into small elements, one per line. +Save the result into FILE. +If non-nil, PREPROC is called with no argument in a buffer that contains +a copy of the text, just before chopping it up. It can be used to replace +chars to try and eliminate some spurious differences." ;; ediff chops up into words, where the definition of a word is ;; customizable. Instead we here keep only one char per line. ;; The advantages are that there's nothing to configure, that we get very @@ -661,14 +665,18 @@ Point is moved to the end of the conflict." (let ((buf (current-buffer))) (with-temp-buffer (insert-buffer-substring buf beg end) + (when preproc (goto-char (point-min)) (funcall preproc)) (goto-char (point-min)) (while (not (eobp)) (forward-char 1) + ;; We add \n after each char except after \n, so we get one line per + ;; text char, where each line contains just one char, except for \n + ;; chars which are represented by the empty line. (unless (eq (char-before) ?\n) (insert ?\n))) (let ((coding-system-for-write 'emacs-mule)) (write-region (point-min) (point-max) file nil 'nomessage))))) -(defun smerge-refine-highlight-change (buf beg match-num1 match-num2) +(defun smerge-refine-highlight-change (buf beg match-num1 match-num2 props) (let* ((startline (string-to-number (match-string match-num1))) (ol (make-overlay (+ beg startline -1) @@ -676,30 +684,25 @@ Point is moved to the end of the conflict." (string-to-number (match-string match-num2)) startline)) buf + ;; Make them tend to shrink rather than spread when editing. 'front-advance nil))) - (overlay-put ol 'smerge 'refine) (overlay-put ol 'evaporate t) - (overlay-put ol 'face 'smerge-refined-change))) - - -(defun smerge-refine () - "Highlight the parts of the conflict that are different." - (interactive) - ;; FIXME: make it work with 3-way conflicts. - (smerge-match-conflict) - (remove-overlays (match-beginning 0) (match-end 0) 'smerge 'refine) - (smerge-ensure-match 1) - (smerge-ensure-match 3) - (let ((buf (current-buffer)) - ;; Read them before the match-data gets clobbered. - (beg1 (match-beginning 1)) (end1 (match-end 1)) - (beg2 (match-beginning 3)) (end2 (match-end 3)) - (file1 (make-temp-file "smerge1")) - (file2 (make-temp-file "smerge2"))) + (dolist (x props) + (overlay-put ol (car x) (cdr x))))) + +(defun smerge-refine-subst (beg1 end1 beg2 end2 props &optional preproc) + "Show fine differences in the two regions BEG1..END1 and BEG2..END2. +PROPS is an alist of properties to put (via overlays) on the changes. +If non-nil, PREPROC is called with no argument in a buffer that contains +a copy of a region, just before preparing it to for `diff'. It can be used to +replace chars to try and eliminate some spurious differences." + (let* ((buf (current-buffer)) + (file1 (make-temp-file "diff1")) + (file2 (make-temp-file "diff2"))) ;; Chop up regions into smaller elements and save into files. - (smerge-refine-chopup-region beg1 end1 file1) - (smerge-refine-chopup-region beg2 end2 file2) + (smerge-refine-chopup-region beg1 end1 file1 preproc) + (smerge-refine-chopup-region beg2 end2 file2 preproc) ;; Call diff on those files. (unwind-protect @@ -716,15 +719,28 @@ Point is moved to the end of the conflict." (buffer-substring (point) (line-end-position))) (let ((op (char-after (match-beginning 3)))) (when (memq op '(?d ?c)) - (smerge-refine-highlight-change buf beg1 1 2)) + (smerge-refine-highlight-change buf beg1 1 2 props)) (when (memq op '(?a ?c)) - (smerge-refine-highlight-change buf beg2 4 5))) + (smerge-refine-highlight-change buf beg2 4 5 props))) (forward-line 1) ;Skip hunk header. (and (re-search-forward "^[0-9]" nil 'move) ;Skip hunk body. (goto-char (match-beginning 0)))))) (delete-file file1) (delete-file file2)))) +(defun smerge-refine () + "Highlight the parts of the conflict that are different." + (interactive) + ;; FIXME: make it work with 3-way conflicts. + (smerge-match-conflict) + (remove-overlays (match-beginning 0) (match-end 0) 'smerge 'refine) + (smerge-ensure-match 1) + (smerge-ensure-match 3) + (smerge-refine-subst (match-beginning 1) (match-end 1) + (match-beginning 3) (match-end 3) + '((smerge . refine) + (face . smerge-refined-change)))) + (defun smerge-diff (n1 n2) (smerge-match-conflict) (smerge-ensure-match n1) |