ideasman42 wrote: Checking again and am still considering this patch too spesific/incomplete, checking vc's diff calls to git - they are considerably more involved than in this PR, meaning this PR will likely require follow up commits to fix problems _(see `vc-diff-internal`, inlined below for reference, it deals with EOL conversion, added files, coding systems... things this PR doesn't really handle)._
Attached a patch that allows for formatting line-ranges, the line range generation must be implemented externally. - The `clang-format-modified-fn` customizable function is used to return a list of "modified" line ranges, this can be set by 3rd party packages - VC implementation independent. - This function simply returns a list of integer pairs (line ranges). - An error is raised if the function isn't set. Patch files: - Patch on the main branch [pr-112792-update.diff.txt](https://github.com/user-attachments/files/18309256/pr-112792-update.diff.txt) - The whole file (for convenience). [clang-format.el.update.txt](https://github.com/user-attachments/files/18309260/clang-format.el.update.txt) - The git/diff logic extracted into a separate file - which would not be applied to the LLVM project, just use for testing. [clang-format-git-vc-diff.el.txt](https://github.com/user-attachments/files/18309263/clang-format-git-vc-diff.el.txt) ----- As mentioned earlier, calling diff can be quite involved if all corner cases are properly handled. ``` (defun vc-diff-internal (async vc-fileset rev1 rev2 &optional verbose buffer) "Report diffs between revisions REV1 and REV2 of a fileset in VC-FILESET. ASYNC non-nil means run the backend's commands asynchronously if possible. VC-FILESET should have the format described in `vc-deduce-fileset'. Output goes to the buffer BUFFER, which defaults to *vc-diff*. BUFFER, if non-nil, should be a buffer or a buffer name. Return t if the buffer had changes, nil otherwise." (unless buffer (setq buffer "*vc-diff*")) (let* ((files (cadr vc-fileset)) (messages (cons (format "Finding changes in %s..." (vc-delistify files)) (format "No changes between %s and %s" (or rev1 "working revision") (or rev2 "workfile")))) ;; Set coding system based on the first file. It's a kluge, ;; but the only way to set it for each file included would ;; be to call the back end separately for each file. (coding-system-for-read ;; Force the EOL conversion to be -unix, in case the files ;; to be compared have DOS EOLs. In that case, EOL ;; conversion will produce a patch file that will either ;; fail to apply, or will change the EOL format of some of ;; the lines in the patched file. (coding-system-change-eol-conversion (if files (vc-coding-system-for-diff (car files)) 'undecided) 'unix)) (orig-diff-buffer-clone (if revert-buffer-in-progress-p (clone-buffer (generate-new-buffer-name " *vc-diff-clone*") nil)))) ;; On MS-Windows and MS-DOS, Diff is likely to produce DOS-style ;; EOLs, which will look ugly if (car files) happens to have Unix ;; EOLs. But for Git, we must force Unix EOLs in the diffs, since ;; Git always produces Unix EOLs in the parts that didn't come ;; from the file, and wants to see any CR characters when applying ;; patches. (if (and (memq system-type '(windows-nt ms-dos)) (not (eq (car vc-fileset) 'Git))) (setq coding-system-for-read (coding-system-change-eol-conversion coding-system-for-read 'dos))) (vc-setup-buffer buffer) (message "%s" (car messages)) ;; Many backends don't handle well the case of a file that has been ;; added but not yet committed to the repo (notably CVS and Subversion). ;; Do that work here so the backends don't have to futz with it. --ESR ;; ;; Actually most backends (including CVS) have options to control the ;; behavior since which one is better depends on the user and on the ;; situation). Worse yet: this code does not handle the case where ;; `file' is a directory which contains added files. ;; I made it conditional on vc-diff-added-files but it should probably ;; just be removed (or copied/moved to specific backends). --Stef. (when vc-diff-added-files (let ((filtered '()) process-file-side-effects) (dolist (file files) (if (or (file-directory-p file) (not (string= (vc-working-revision file) "0"))) (push file filtered) ;; This file is added but not yet committed; ;; there is no repository version to diff against. (if (or rev1 rev2) (error "No revisions of %s exist" file) ;; We regard this as "changed". ;; Diff it against /dev/null. (apply #'vc-do-command buffer (if async 'async 1) "diff" file (append (vc-switches nil 'diff) `(,(null-device))))))) (setq files (nreverse filtered)))) (vc-call-backend (car vc-fileset) 'diff files rev1 rev2 buffer async) (set-buffer buffer) ;; Make the *vc-diff* buffer read only, the diff-mode key ;; bindings are nicer for read only buffers. pcl-cvs does the ;; same thing. (setq buffer-read-only t) (diff-mode) (setq-local diff-vc-backend (car vc-fileset)) (setq-local diff-vc-revisions (list rev1 rev2)) (setq-local revert-buffer-function (lambda (_ignore-auto _noconfirm) (vc-diff-internal async vc-fileset rev1 rev2 verbose))) (if (and (zerop (buffer-size)) (not (get-buffer-process (current-buffer)))) ;; Treat this case specially so as not to pop the buffer. (progn (message "%s" (cdr messages)) nil) ;; Display the buffer, but at the end because it can change point. (pop-to-buffer (current-buffer)) ;; The diff process may finish early, so call `vc-diff-finish' ;; after `pop-to-buffer'; the former assumes the diff buffer is ;; shown in some window. (let ((buf (current-buffer))) (vc-run-delayed (vc-diff-finish buf (when verbose messages) orig-diff-buffer-clone))) ;; In the async case, we return t even if there are no differences ;; because we don't know that yet. t))) ``` https://github.com/llvm/llvm-project/pull/112792 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits