Skip to content

Commit b42785d

Browse files
committed
Revert "use diff-no-select"
This reverts commit fcf504f.
1 parent fcf504f commit b42785d

File tree

1 file changed

+104
-64
lines changed

1 file changed

+104
-64
lines changed

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

Lines changed: 104 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -160,31 +160,55 @@ is a zero-based file offset, assuming ‘utf-8-unix’ coding."
160160
(string-to-number (match-string 3 line)))))
161161
(concat (match-string 1 line) ":" (match-string 1 line)))))
162162

163-
(defun clang-format--vc-diff-compute-diff-and-get-lines (buf-orig buf-cur)
163+
(defun clang-format--vc-diff-get-diff-lines (file-orig file-new)
164164
"Return all line regions that contain diffs between FILE-ORIG and
165165
FILE-NEW. If there is no diff ‘nil’ is returned. Otherwise the
166166
return is a ‘list’ of lines in the format ‘--lines=<start>:<end>’
167167
which can be passed directly to ‘clang-format’."
168168
;; Use temporary buffer for output of diff.
169169
(with-temp-buffer
170-
(diff-no-select buf-orig buf-cur "-a -U0" t (current-buffer))
171-
(let ((diff-lines '()))
172-
;; Iterate through all lines in diff buffer and collect all
173-
;; lines in current buffer that have a diff.
174-
(goto-char (point-min))
175-
(while (not (eobp))
176-
(let ((diff-line (clang-format--vc-diff-match-diff-line
170+
(let ((status (call-process
171+
"diff"
172+
nil
173+
(current-buffer)
174+
nil
175+
;; Binary diff has different behaviors that we
176+
;; aren't interested in.
177+
"-a"
178+
;; Get minimal diff (copy diff config for git-clang-format).
179+
"-U0"
180+
file-orig
181+
file-new))
182+
(stderr (concat (if (zerop (buffer-size)) "" ": ")
177183
(buffer-substring-no-properties
178-
(line-beginning-position)
179-
(line-end-position)))))
180-
(when diff-line
181-
;; Create list line regions with diffs to pass to
182-
;; clang-format.
183-
(push (concat "--lines=" diff-line) diff-lines)))
184-
(forward-line 1))
185-
(reverse diff-lines))))
186-
187-
(defun clang-format--vc-diff-get-diff-lines ()
184+
(point-min) (line-end-position))))
185+
(diff-lines '()))
186+
(cond
187+
((stringp status)
188+
(error "(diff killed by signal %s%s)" status stderr))
189+
;; Return of 0 indicates no diff.
190+
((= status 0) nil)
191+
;; Return of 1 indicates found diffs and no error.
192+
((= status 1)
193+
;; Iterate through all lines in diff buffer and collect all
194+
;; lines in current buffer that have a diff.
195+
(goto-char (point-min))
196+
(while (not (eobp))
197+
(let ((diff-line (clang-format--vc-diff-match-diff-line
198+
(buffer-substring-no-properties
199+
(line-beginning-position)
200+
(line-end-position)))))
201+
(when diff-line
202+
;; Create list line regions with diffs to pass to
203+
;; clang-format.
204+
(push (concat "--lines=" diff-line) diff-lines)))
205+
(forward-line 1))
206+
(reverse diff-lines))
207+
;; Any return != 0 && != 1 indicates some level of error.
208+
(t
209+
(error "(diff returned unsuccessfully %s%s)" status stderr))))))
210+
211+
(defun clang-format--vc-diff-get-vc-head-file (tmpfile-vc-head)
188212
"Stores the contents of ‘buffer-file-name’ at vc revision HEAD into
189213
‘tmpfile-vc-head’. If the current buffer is either not a file or not
190214
in a vc repo, this results in an error. Currently git is the only
@@ -193,44 +217,39 @@ supported vc."
193217
(unless (buffer-file-name)
194218
(error "Buffer is not visiting a file"))
195219

196-
(let ((inp-buf (current-buffer))
197-
(base-dir (vc-root-dir))
220+
(let ((base-dir (vc-root-dir))
198221
(backend (vc-backend (buffer-file-name))))
199-
(with-temp-buffer
200-
;; We need to be able to find version control (git) root.
201-
(unless base-dir
202-
(error "File not known to version control system"))
203-
(cond
204-
((string-equal backend "Git")
205-
;; Get the filename relative to git root.
206-
(let ((vc-file-name (substring
207-
(expand-file-name (buffer-file-name inp-buf))
208-
(string-width (expand-file-name base-dir))
209-
nil)))
210-
(let ((status (call-process
211-
"git"
212-
nil
213-
(current-buffer)
214-
nil
215-
"show" (concat "HEAD:" vc-file-name)))
216-
(stderr (concat (if (zerop (buffer-size)) "" ": ")
217-
(buffer-substring-no-properties
218-
(point-min) (line-end-position)))))
219-
(when (stringp status)
220-
(error "(git show HEAD:%s killed by signal %s%s)"
221-
vc-file-name status stderr))
222-
(unless (zerop status)
223-
(error "(git show HEAD:%s returned unsuccessfully %s%s)"
224-
vc-file-name status stderr)))))
225-
(t
226-
(error
227-
"Version control %s isn't supported, currently supported backends: git"
228-
backend)))
229-
;; Collect all lines where inp-buf (buffer we call
230-
;; clang-format-vc-diff on) differs from latest version of the
231-
;; backing file in the version control system.
232-
(clang-format--vc-diff-compute-diff-and-get-lines
233-
(current-buffer) inp-buf))))
222+
;; We need to be able to find version control (git) root.
223+
(unless base-dir
224+
(error "File not known to git"))
225+
(cond
226+
((string-equal backend "Git")
227+
;; Get the filename relative to git root.
228+
(let ((vc-file-name (substring
229+
(expand-file-name (buffer-file-name))
230+
(string-width (expand-file-name base-dir))
231+
nil)))
232+
(let ((status (call-process
233+
"git"
234+
nil
235+
`(:file, tmpfile-vc-head)
236+
nil
237+
"show" (concat "HEAD:" vc-file-name)))
238+
(stderr (with-temp-buffer
239+
(unless (zerop (cadr (insert-file-contents tmpfile-vc-head)))
240+
(insert ": "))
241+
(buffer-substring-no-properties
242+
(point-min) (line-end-position)))))
243+
(when (stringp status)
244+
(error "(git show HEAD:%s killed by signal %s%s)"
245+
vc-file-name status stderr))
246+
(unless (zerop status)
247+
(error "(git show HEAD:%s returned unsuccessfully %s%s)"
248+
vc-file-name status stderr)))))
249+
(t
250+
(error
251+
"Version control %s isn't supported, currently supported backends: git"
252+
backend)))))
234253

235254

236255
(defun clang-format--region-impl (start end &optional style assume-file-name lines)
@@ -304,6 +323,7 @@ specific locations for reformatting (i.e diff locations)."
304323
(delete-file temp-file)
305324
(when (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
306325

326+
307327
;;;###autoload
308328
(defun clang-format-vc-diff (&optional style assume-file-name)
309329
"The same as ‘clang-format-buffer’ but only operates on the vc
@@ -312,15 +332,35 @@ diffs from HEAD in the buffer. If no STYLE is given uses
312332
file. If no ASSUME-FILE-NAME is given uses the function
313333
‘buffer-file-name’."
314334
(interactive)
315-
(let ((diff-lines (clang-format--vc-diff-get-diff-lines)))
316-
;; If we have any diffs, format them.
317-
(when diff-lines
318-
(clang-format--region-impl
319-
(point-min)
320-
(point-max)
321-
style
322-
assume-file-name
323-
diff-lines))))
335+
(let ((tmpfile-vc-head nil)
336+
(tmpfile-curbuf nil))
337+
(unwind-protect
338+
(progn
339+
(setq tmpfile-vc-head
340+
(make-temp-file "clang-format-vc-tmp-head-content"))
341+
(clang-format--vc-diff-get-vc-head-file tmpfile-vc-head)
342+
;; Move the current buffer to a temporary file to take a
343+
;; diff. Even if current-buffer is backed by a file, we
344+
;; want to diff the buffer contents which might not be
345+
;; saved.
346+
(setq tmpfile-curbuf (make-temp-file "clang-format-vc-tmp"))
347+
(write-region nil nil tmpfile-curbuf nil 'nomessage)
348+
;; Get a list of lines with a diff.
349+
(let ((diff-lines
350+
(clang-format--vc-diff-get-diff-lines
351+
tmpfile-vc-head tmpfile-curbuf)))
352+
;; If we have any diffs, format them.
353+
(when diff-lines
354+
(clang-format--region-impl
355+
(point-min)
356+
(point-max)
357+
style
358+
assume-file-name
359+
diff-lines))))
360+
(progn
361+
;; Cleanup temporary files we created.
362+
(when tmpfile-vc-head (delete-file tmpfile-vc-head))
363+
(when tmpfile-curbuf (delete-file tmpfile-curbuf))))))
324364

325365

326366
;;;###autoload

0 commit comments

Comments
 (0)