diff options
| author | Miles Bader | 2000-09-18 08:18:36 +0000 |
|---|---|---|
| committer | Miles Bader | 2000-09-18 08:18:36 +0000 |
| commit | 2b612b1f55d36c88bee571f2b536153b7cb520a2 (patch) | |
| tree | c10a0d1b800235d405f594e4bec35a18498e4c13 | |
| parent | 8ec8f673fab973455f8a7e6b471144cb91cf806a (diff) | |
| download | emacs-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/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/diff-mode.el | 203 |
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 @@ | |||
| 1 | 2000-09-18 Miles Bader <miles@lsi.nec.co.jp> | 1 | 2000-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 |
| 886 | the destination text." | 886 | destination text. If LINE-OFFSET is non-nil, it should be a line-offset in |
| 887 | HUNK, and instead of a string, a cons cell is returned who's car is the | ||
| 888 | appropriate 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))) |