Skip to content

Commit 9ae26d4

Browse files
committed
Compat Dif
1 parent 7742bd1 commit 9ae26d4

File tree

1 file changed

+34
-15
lines changed

1 file changed

+34
-15
lines changed

clang/tools/clang-format/clang-format.el

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,22 @@ is a zero-based file offset, assuming ‘utf-8-unix’ coding."
157157
(with-demoted-errors "failed to remove file: %S"
158158
(delete-file (pop ,bind-files-to-delete)))))))
159159

160+
161+
(defun clang-format--vc-diff-match-diff-line (line)
162+
;; We are matching something like:
163+
;; "@@ -80 +80 @@" or "@@ -80,2 +80,2 @@"
164+
;; Return as "<LineStart>:<LineEnd>"
165+
(when (string-match "^@@\s-[0-9,]+\s\\+\\([0-9]+\\)\\(,\\([0-9]+\\)\\)?\s@@$" line)
166+
;; If we have multi-line diff
167+
(if (match-string 3 line)
168+
(concat (match-string 1 line)
169+
":"
170+
(number-to-string
171+
(+ (string-to-number (match-string 1 line))
172+
(string-to-number (match-string 3 line)))))
173+
(concat (match-string 1 line) ":" (match-string 1 line)))))
174+
175+
160176
(defun clang-format--vc-diff-get-diff-lines (file-orig file-new)
161177
"Return all line regions that contain diffs between FILE-ORIG and
162178
FILE-NEW. If there is no diff ‘nil’ is returned. Otherwise the
@@ -175,32 +191,35 @@ which can be passed directly to ‘clang-format’."
175191
;; Binary diff has different behaviors that we
176192
;; aren't interested in.
177193
"-a"
178-
;; Print new lines in file-new formatted as
179-
;; "--lines=<StartDiff:EndDiff> "
180-
"--changed-group-format=%(N=0?:--lines=%dF:%dM )"
181-
;; Don't print anything for unchanged lines
182-
"--unchanged-group-format="
194+
;; Get minimal diff (copy diff config for git-clang-format).
195+
"-U0"
183196
file-orig
184197
file-new))
185198
(stderr (concat (if (zerop (buffer-size)) "" ": ")
186199
(buffer-substring-no-properties
187-
(point-min) (line-end-position)))))
200+
(point-min) (line-end-position))))
201+
(diff-lines '()))
188202
(cond
189203
((stringp status)
190204
(error "(diff killed by signal %s%s)" status stderr))
191205
;; Return of 0 indicates no diff.
192206
((= status 0) nil)
193207
;; Return of 1 indicates found diffs and no error.
194208
((= status 1)
195-
;; We had our diff command printout all diffs as
196-
;; "--lines=S0:E0 --lines=S1:E1 ... --lines=SN:EN " so just
197-
;; split the output into a list to pass to clang-format.
198-
(split-string
199-
(buffer-substring-no-properties (point-min) (point-max))
200-
;; All whitespace (practically only spaces).
201-
"[ \f\t\n\r\v]"
202-
;; Don't create empty entries.
203-
t))
209+
;; Iterate through all lines in diff buffer and collect all
210+
;; lines in current buffer that have a diff.
211+
(goto-char (point-min))
212+
(while (not (eobp))
213+
(let ((diff-line (clang-format--vc-diff-match-diff-line
214+
(buffer-substring-no-properties
215+
(line-beginning-position)
216+
(line-end-position)))))
217+
(when diff-line
218+
;; Create list line regions with diffs to pass to
219+
;; clang-format.
220+
(push (concat "--lines=" diff-line) diff-lines)))
221+
(forward-line 1))
222+
(reverse diff-lines))
204223
;; Any return != 0 && != 1 indicates some level of error.
205224
(t
206225
(error "(diff returned unsuccessfully %s%s)" status stderr))))))

0 commit comments

Comments
 (0)