aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiles Bader2000-09-18 08:18:36 +0000
committerMiles Bader2000-09-18 08:18:36 +0000
commit2b612b1f55d36c88bee571f2b536153b7cb520a2 (patch)
treec10a0d1b800235d405f594e4bec35a18498e4c13
parent8ec8f673fab973455f8a7e6b471144cb91cf806a (diff)
downloademacs-2b612b1f55d36c88bee571f2b536153b7cb520a2.tar.gz
emacs-2b612b1f55d36c88bee571f2b536153b7cb520a2.zip
(diff-hunk-text):
Add new optional arg LINE-OFFSET, and return a cons if it's non-nil. (diff-apply-hunk): Try to jump to the exact line in the source text corresponding to the position of point in the in the hunk.
-rw-r--r--lisp/ChangeLog5
-rw-r--r--lisp/diff-mode.el203
2 files changed, 117 insertions, 91 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 4cb997f98a9..3eeea98e512 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,10 @@
12000-09-18 Miles Bader <miles@lsi.nec.co.jp> 12000-09-18 Miles Bader <miles@lsi.nec.co.jp>
2 2
3 * diff-mode.el (diff-hunk-text): Add new optional arg LINE-OFFSET,
4 and return a cons if it's non-nil.
5 (diff-apply-hunk): Try to jump to the line in the source text
6 corresponding to the position of point in the in the hunk.
7
3 * info.el (Info-title-3-face, Info-title-2-face) 8 * info.el (Info-title-3-face, Info-title-2-face)
4 (Info-title-1-face): Use face inheritance and relative sizes 9 (Info-title-1-face): Use face inheritance and relative sizes
5 instead of hard-wiring things. 10 instead of hard-wiring things.
diff --git a/lisp/diff-mode.el b/lisp/diff-mode.el
index f0d52b679a1..cc91877251d 100644
--- a/lisp/diff-mode.el
+++ b/lisp/diff-mode.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Stefan Monnier <monnier@cs.yale.edu> 5;; Author: Stefan Monnier <monnier@cs.yale.edu>
6;; Keywords: patch diff 6;; Keywords: patch diff
7;; Revision: $Id: diff-mode.el,v 1.12 2000/09/11 13:49:38 miles Exp $ 7;; Revision: $Id: diff-mode.el,v 1.13 2000/09/12 11:24:28 miles Exp $
8 8
9;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
10 10
@@ -881,75 +881,86 @@ Only works for unified diffs."
881 nil t) 881 nil t)
882 (equal (match-string 1) (match-string 2))))) 882 (equal (match-string 1) (match-string 2)))))
883 883
884(defun diff-hunk-text (hunk dest) 884(defun diff-hunk-text (hunk destp &optional line-offset)
885 "Returns the literal source text from HUNK, if DEST is nil, otherwise 885 "Returns the literal source text from HUNK, if DESTP is nil, otherwise the
886the destination text." 886destination text. If LINE-OFFSET is non-nil, it should be a line-offset in
887HUNK, and instead of a string, a cons cell is returned who's car is the
888appropriate text, and who's cdr is the corresponding line-offset."
887 (with-temp-buffer 889 (with-temp-buffer
888 (erase-buffer) 890 (erase-buffer)
889 (insert hunk) 891 (insert hunk)
890 (goto-char (point-min)) 892 (goto-char (point-min))
891 (let ((src nil) 893 (let ((src-pos nil)
892 (dst nil) 894 (dst-pos nil)
893 (divider nil) 895 (divider-pos nil)
894 (num-pfx-chars 2)) 896 (num-pfx-chars 2))
895 (cond ((looking-at "^@@") 897 ;; Set the following variables:
896 ;; unified diff 898 ;; SRC-POS buffer pos of the source part of the hunk or nil if none
897 (setq num-pfx-chars 1) 899 ;; DST-POS buffer pos of the destination part of the hunk or nil
898 (forward-line 1) 900 ;; DIVIDER-POS buffer pos of any divider line separating the src & dst
899 (setq src (point) dst (point))) 901 ;; NUM-PFX-CHARS number of line-prefix characters used by this format"
900 ((looking-at "^\\*\\*") 902 (cond ((looking-at "^@@")
901 ;; context diff 903 ;; unified diff
902 (forward-line 2) 904 (setq num-pfx-chars 1)
903 (setq src (point)) 905 (forward-line 1)
904 (re-search-forward "^--- " nil t) 906 (setq src-pos (point) dst-pos (point)))
905 (forward-line 0) 907 ((looking-at "^\\*\\*")
906 (setq divider (point)) 908 ;; context diff
907 (forward-line 1) 909 (forward-line 2)
908 (setq dst (point))) 910 (setq src-pos (point))
909 ((looking-at "^[0-9]+a[0-9,]+$") 911 (re-search-forward "^--- " nil t)
910 ;; normal diff, insert 912 (forward-line 0)
911 (forward-line 1) 913 (setq divider-pos (point))
912 (setq dst (point))) 914 (forward-line 1)
913 ((looking-at "^[0-9,]+d[0-9]+$") 915 (setq dst-pos (point)))
914 ;; normal diff, delete 916 ((looking-at "^[0-9]+a[0-9,]+$")
915 (forward-line 1) 917 ;; normal diff, insert
916 (setq src (point))) 918 (forward-line 1)
917 ((looking-at "^[0-9,]+c[0-9,]+$") 919 (setq dst-pos (point)))
918 ;; normal diff, change 920 ((looking-at "^[0-9,]+d[0-9]+$")
919 (forward-line 1) 921 ;; normal diff, delete
920 (setq src (point)) 922 (forward-line 1)
921 (re-search-forward "^---$" nil t) 923 (setq src-pos (point)))
922 (forward-line 0) 924 ((looking-at "^[0-9,]+c[0-9,]+$")
923 (setq divider (point)) 925 ;; normal diff, change
924 (forward-line 1) 926 (forward-line 1)
925 (setq dst (point))) 927 (setq src-pos (point))
926 (t 928 (re-search-forward "^---$" nil t)
927 (error "Unknown diff hunk type"))) 929 (forward-line 0)
928 930 (setq divider-pos (point))
929 (if (if dest (null dst) (null src)) 931 (forward-line 1)
930 ;; Implied empty text 932 (setq dst-pos (point)))
931 "" 933 (t
932 934 (error "Unknown diff hunk type")))
933 ;; Explicit text 935 (if (if destp (null dst-pos) (null src-pos))
934 936 ;; Implied empty text
937 (if line-offset '("" . 0) "")
938
939 (when line-offset
940 (goto-char (point-min))
941 (forward-line line-offset))
942
943 ;; Get rid of anything except the desired text.
944 (save-excursion
935 ;; Delete unused text region 945 ;; Delete unused text region
936 (let ((keep (if dest dst src)) 946 (let ((keep (if destp dst-pos src-pos))
937 (kill (or divider (if dest src dst)))) 947 (kill (or divider-pos (if destp src-pos dst-pos))))
938 (when (and kill (> kill keep)) 948 (when (and kill (> kill keep))
939 (delete-region kill (point-max))) 949 (delete-region kill (point-max)))
940 (delete-region (point-min) keep)) 950 (delete-region (point-min) keep))
941 951 ;; Remove line-prefix characters, and unneeded lines (unified diffs).
942 ;; Remove line-prefix characters, and unneeded lines (for 952 (let ((kill-char (if destp ?- ?+)))
943 ;; unified diffs). 953 (goto-char (point-min))
944 (let ((kill-char (if dest ?- ?+))) 954 (while (not (eobp))
945 (goto-char (point-min))
946 (while (not (eobp))
947 (if (eq (char-after) kill-char) 955 (if (eq (char-after) kill-char)
948 (delete-region (point) (progn (forward-line 1) (point))) 956 (delete-region (point) (progn (forward-line 1) (point)))
949 (delete-char num-pfx-chars) 957 (delete-char num-pfx-chars)
950 (forward-line 1)))) 958 (forward-line 1)))))
951 959
952 (buffer-substring-no-properties (point-min) (point-max)))))) 960 (let ((text (buffer-substring-no-properties (point-min) (point-max))))
961 (if line-offset
962 (cons text (count-lines (point-min) (point)))
963 text))))))
953 964
954(defun diff-find-text (text line) 965(defun diff-find-text (text line)
955 "Return the buffer position of the nearest occurance of TEXT to line LINE. 966 "Return the buffer position of the nearest occurance of TEXT to line LINE.
@@ -1000,19 +1011,23 @@ was non-nil."
1000 (let* ((loc (diff-find-source-location other-file)) 1011 (let* ((loc (diff-find-source-location other-file))
1001 (buf (find-file-noselect (car loc))) 1012 (buf (find-file-noselect (car loc)))
1002 (patch-line (cadr loc)) 1013 (patch-line (cadr loc))
1014 hunk-line-offset
1003 (hunk 1015 (hunk
1004 (save-excursion 1016 (let ((orig-point (point)))
1005 (diff-beginning-of-hunk) 1017 (save-excursion
1006 (unless (looking-at diff-hunk-header-re) 1018 (diff-beginning-of-hunk)
1007 (error "Malformed hunk")) 1019 (setq hunk-line-offset (count-lines (point) orig-point))
1008 (buffer-substring (point) (progn (diff-end-of-hunk) (point))))) 1020 (unless (looking-at diff-hunk-header-re)
1009 (src (diff-hunk-text hunk reverse)) 1021 (error "Malformed hunk"))
1010 (dst (diff-hunk-text hunk (not reverse))) 1022 (buffer-substring (point) (progn (diff-end-of-hunk) (point))))))
1023 (old (diff-hunk-text hunk reverse hunk-line-offset))
1024 (new (diff-hunk-text hunk (not reverse) hunk-line-offset))
1011 (pos 1025 (pos
1012 (with-current-buffer buf (diff-find-text src patch-line))) 1026 (with-current-buffer buf (diff-find-text (car old) patch-line)))
1013 (reversed-pos 1027 (reversed-pos
1014 (and (null pos) 1028 (and (null pos)
1015 (with-current-buffer buf (diff-find-text dst patch-line))))) 1029 (with-current-buffer buf
1030 (diff-find-text (car new) patch-line)))))
1016 1031
1017 (when (and reversed-pos popup) 1032 (when (and reversed-pos popup)
1018 ;; A reversed patch was detected, perhaps apply it in reverse 1033 ;; A reversed patch was detected, perhaps apply it in reverse
@@ -1021,16 +1036,17 @@ was non-nil."
1021 (save-window-excursion 1036 (save-window-excursion
1022 (pop-to-buffer buf) 1037 (pop-to-buffer buf)
1023 (goto-char reversed-pos) 1038 (goto-char reversed-pos)
1039 (forward-line (cdr new))
1024 (if reverse 1040 (if reverse
1025 (y-or-n-p 1041 (y-or-n-p
1026 "Hunk hasn't been applied yet, so can't reverse it; apply it now? ") 1042 "Hunk hasn't been applied yet, so can't reverse it; apply it now? ")
1027 (y-or-n-p "Hunk has already been applied; undo it? ")))) 1043 (y-or-n-p "Hunk has already been applied; undo it? "))))
1028 1044
1029 ;; Set up things to reverse the diff 1045 ;; Set up things to reverse the diff
1030 (let ((swap dst)) 1046 (let ((swap new))
1031 (setq pos reversed-pos) 1047 (setq pos reversed-pos)
1032 (setq src dst) 1048 (setq old new)
1033 (setq dst swap)) 1049 (setq new swap))
1034 1050
1035 ;; The user has chosen not to apply the reversed hunk, but we 1051 ;; The user has chosen not to apply the reversed hunk, but we
1036 ;; don't want to given an error message, so set things up so 1052 ;; don't want to given an error message, so set things up so
@@ -1048,25 +1064,30 @@ was non-nil."
1048 ;; Apply the hunk 1064 ;; Apply the hunk
1049 (with-current-buffer buf 1065 (with-current-buffer buf
1050 (goto-char pos) 1066 (goto-char pos)
1051 (delete-char (length src)) 1067 (delete-char (length (car old)))
1052 (insert dst))) 1068 (insert (car new))))
1053 1069
1054 (when popup 1070 (when popup
1055 ;; Show a message describing what was done 1071 (with-current-buffer buf
1056 (let ((real-line 1072 ;; Show a message describing what was done
1057 (1+ (with-current-buffer buf (count-lines (point-min) pos)))) 1073 (let ((real-line (1+ (count-lines (point-min) pos)))
1058 (msg 1074 (msg
1059 (if dry-run 1075 (if dry-run
1060 (if reversed "already applied" "not yet applied") 1076 (if reversed "already applied" "not yet applied")
1061 (if reversed "undone" "applied")))) 1077 (if reversed "undone" "applied"))))
1062 (cond ((= real-line patch-line) 1078 (cond ((= real-line patch-line)
1063 (message "Hunk %s" msg)) 1079 (message "Hunk %s" msg))
1064 ((= real-line (1+ patch-line)) 1080 ((= real-line (1+ patch-line))
1065 (message "Hunk %s at offset 1 line" msg)) 1081 (message "Hunk %s at offset 1 line" msg))
1066 (t 1082 (t
1067 (message "Hunk %s at offset %d lines" 1083 (message "Hunk %s at offset %d lines"
1068 msg 1084 msg
1069 (- real-line patch-line))))) 1085 (- real-line patch-line)))))
1086
1087 ;; fixup POS to reflect the hunk line offset
1088 (goto-char pos)
1089 (forward-line (cdr new))
1090 (setq pos (point)))
1070 1091
1071 ;; Display BUF in a window, and maybe select it 1092 ;; Display BUF in a window, and maybe select it
1072 (let ((win (display-buffer buf))) 1093 (let ((win (display-buffer buf)))