update packages

This commit is contained in:
2026-06-27 11:34:21 +02:00
parent 4be4f859c4
commit 1aaef48596
246 changed files with 7997 additions and 4359 deletions

View File

@@ -1,13 +1,13 @@
;;; diff-hl.el --- Highlight uncommitted changes using VC -*- lexical-binding: t -*-
;; Copyright (C) 2012-2025 Free Software Foundation, Inc.
;; Copyright (C) 2012-2026 Free Software Foundation, Inc.
;; Author: Dmitry Gutov <dmitry@gutov.dev>
;; URL: https://github.com/dgutov/diff-hl
;; Keywords: vc, diff
;; Package-Version: 20260328.1925
;; Package-Revision: b965e19e6e7f
;; Package-Requires: ((cl-lib "0.2") (emacs "26.1"))
;; Package-Version: 20260627.208
;; Package-Revision: 2d7d0714d963
;; Package-Requires: ((cl-lib "0.2") (emacs "27.1"))
;; This file is part of GNU Emacs.
@@ -315,6 +315,16 @@ It can be a relative expression as well, such as \"HEAD^\" with Git, or
(lambda (value)
(or (null value) (stringp value))))
(defun diff-hl--target-buffer (&optional buf)
"Return the correct buffer for the situation, preferring the base buffer."
(let ((buf (or buf (current-buffer))))
(or (buffer-base-buffer buf) buf)))
(defun diff-hl--buffer-file-name (&optional buffer)
"Return the file name of the BUFFER or its base buffer.
BUFFER defaults to the current buffer."
(buffer-file-name (diff-hl--target-buffer buffer)))
(defun diff-hl-define-bitmaps ()
(let* ((scale (if (and (boundp 'text-scale-mode-amount)
(numberp text-scale-mode-amount))
@@ -486,7 +496,7 @@ It can be a relative expression as well, such as \"HEAD^\" with Git, or
buffer)
(defun diff-hl-changes ()
(let* ((file buffer-file-name)
(let* ((file (diff-hl--buffer-file-name))
(backend (vc-backend file))
(hide-staged (and (eq backend 'Git) (not diff-hl-show-staged-changes))))
(when backend
@@ -531,7 +541,7 @@ It can be a relative expression as well, such as \"HEAD^\" with Git, or
(or (assoc-default backend diff-hl-head-revision-alist)
;; It's usually cached already (e.g. for mode-line).
;; So this is basically an optimization for rare cases.
(vc-working-revision buffer-file-name backend)))
(vc-working-revision (diff-hl--buffer-file-name) backend)))
(defun diff-hl-adjust-changes (old new)
"Adjust changesets in OLD using changes in NEW.
@@ -596,15 +606,7 @@ contents as they are (or would be) after applying the changes in NEW."
(let (res)
(goto-char (point-min))
(unless (eobp)
;; TODO: When 27.1 is the minimum requirement, we can drop
;; these bindings: that version, in addition to switching over
;; called-interactively-p check, so refinement can't be
;; triggered by code calling the navigation functions, only by
;; direct interactive invocations.
(ignore-errors
(with-no-warnings
(let (diff-auto-refine-mode)
(diff-beginning-of-hunk t))))
(diff-beginning-of-hunk t)
(while (looking-at diff-hunk-header-re-unified)
(let ((line (string-to-number (match-string 3)))
(beg (point)))
@@ -637,7 +639,7 @@ contents as they are (or would be) after applying the changes in NEW."
;; TODO: debounce if a thread is already running.
(let ((buf (current-buffer))
(temp-buffer
(if (< emacs-major-version 28)
(static-if (< emacs-major-version 28)
(generate-new-buffer " *temp*")
(generate-new-buffer " *temp*" t))))
;; Switch buffer temporarily, to "unlock" it for other threads.
@@ -731,27 +733,35 @@ Return a list of line overlays used."
(diff-hl--resolve
reference
(lambda (ref-changes)
(let ((ref-changes (diff-hl-adjust-changes ref-changes changes))
reuse)
(with-current-buffer orig
(diff-hl-remove-overlays)
(let ((diff-hl-highlight-function
diff-hl-highlight-reference-function)
(diff-hl-fringe-face-function
diff-hl-fringe-reference-face-function))
(setq reuse (diff-hl--update-overlays ref-changes nil)))
(diff-hl--update-overlays changes reuse)
(when (not (or changes ref-changes))
(diff-hl--autohide-margin))))))))))
(when (buffer-live-p orig)
(let ((ref-changes (diff-hl-adjust-changes ref-changes changes))
(base (diff-hl--target-buffer orig)))
(dolist (buf (buffer-list))
(when (and (eq (diff-hl--target-buffer buf) base)
(buffer-local-value 'diff-hl-mode buf))
(with-current-buffer buf
(diff-hl-remove-overlays)
(let (reuse)
(when ref-changes
(let ((diff-hl-highlight-function
diff-hl-highlight-reference-function)
(diff-hl-fringe-face-function
diff-hl-fringe-reference-face-function))
(setq reuse (diff-hl--update-overlays ref-changes nil))))
(when changes
(diff-hl--update-overlays changes reuse)))
(unless (or changes ref-changes)
(diff-hl--autohide-margin)))))))))))))
(defun diff-hl--resolve (value-or-buffer cb)
(if (listp value-or-buffer)
(funcall cb value-or-buffer)
(static-if (fboundp 'vc-run-delayed-success)
;; Emacs 31.
(with-current-buffer value-or-buffer
(vc-run-delayed-success 1
(funcall cb (diff-hl-changes-from-buffer (current-buffer)))))
(when (get-buffer value-or-buffer)
(with-current-buffer value-or-buffer
(vc-run-delayed-success 1
(funcall cb (diff-hl-changes-from-buffer (current-buffer))))))
(diff-hl--when-done value-or-buffer
#'diff-hl-changes-from-buffer
cb))))
@@ -844,7 +854,8 @@ Return a list of line overlays used."
(defun diff-hl-diff-goto-hunk-1 (historic rev1)
(defvar vc-sentinel-movepoint)
(vc-buffer-sync)
(with-current-buffer (diff-hl--target-buffer)
(vc-buffer-sync))
(let* ((line (line-number-at-pos))
(buffer (current-buffer))
rev2)
@@ -868,7 +879,7 @@ Return a list of line overlays used."
With double prefix argument (C-u C-u), the diff is made against the
reference revision."
(interactive (list current-prefix-arg))
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(with-current-buffer (current-buffer)
(if (equal historic '(16))
(diff-hl-diff-reference-goto-hunk)
(diff-hl-diff-goto-hunk-1 historic nil))))
@@ -876,7 +887,7 @@ reference revision."
(defun diff-hl-diff-reference-goto-hunk ()
"Run VC diff command against the reference and go to the corresponding line."
(interactive)
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(with-current-buffer (current-buffer)
(diff-hl-diff-goto-hunk-1 nil diff-hl-reference-revision)))
(defun diff-hl-root-diff-reference-goto-hunk ()
@@ -885,7 +896,7 @@ And if the current buffer is visiting a file, and it has changes, the diff
buffer will show the position corresponding to its current line."
(interactive)
(defvar vc-sentinel-movepoint)
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(with-current-buffer (current-buffer)
(let ((backend (vc-deduce-backend))
(default-directory default-directory)
rootdir fileset
@@ -894,11 +905,14 @@ buffer will show the position corresponding to its current line."
(setq rootdir (vc-call-backend backend 'root default-directory)
default-directory rootdir
fileset `(,backend (,rootdir))
relname (if buffer-file-name (file-relative-name buffer-file-name
rootdir)))
relname (let ((file (diff-hl--buffer-file-name)))
(when file
(file-relative-name file rootdir))))
(error "Directory is not version controlled"))
(setq fileset (or fileset (vc-deduce-fileset)))
(vc-buffer-sync-fileset fileset t)
(static-if (< emacs-major-version 28)
(when buffer-file-name (vc-buffer-sync t))
(vc-buffer-sync-fileset fileset t))
(let* ((line (line-number-at-pos)))
(vc-diff-internal
(if (boundp 'vc-allow-async-diff)
@@ -910,7 +924,7 @@ buffer will show the position corresponding to its current line."
(setq vc-sentinel-movepoint (point))))))))
(defun diff-hl-diff-read-revisions (rev1-default)
(let* ((file buffer-file-name)
(let* ((file (diff-hl--buffer-file-name))
(files (list file))
(backend (vc-backend file))
(rev2-default nil))
@@ -1002,7 +1016,8 @@ that file, if it's present."
(defun diff-hl-revert-hunk-1 ()
(save-restriction
(widen)
(vc-buffer-sync)
(with-current-buffer (diff-hl--target-buffer)
(vc-buffer-sync))
(let* ((diff-buffer (get-buffer-create
(generate-new-buffer-name "*diff-hl-revert*")))
(buffer (current-buffer))
@@ -1010,7 +1025,7 @@ that file, if it's present."
(line (save-excursion
(diff-hl-find-current-hunk)
(line-number-at-pos)))
(file buffer-file-name)
(file (diff-hl--buffer-file-name))
(backend (vc-backend file)))
(unwind-protect
(progn
@@ -1029,9 +1044,7 @@ that file, if it's present."
(when (eobp)
(with-current-buffer buffer (diff-hl-remove-overlays))
(user-error "Buffer is up-to-date"))
(with-no-warnings
(let (diff-auto-refine-mode)
(diff-hl-diff-skip-to line)))
(diff-hl-diff-skip-to line)
(setq m-end (diff-hl-split-away-changes 3))
(setq m-beg (point-marker))
(funcall diff-hl-highlight-revert-hunk-function m-end)
@@ -1041,9 +1054,8 @@ that file, if it's present."
(if (>= wbh (- end-line beg-line))
(recenter (/ (+ wbh (- beg-line end-line) 2) 2))
(recenter 1)))
(with-no-warnings
(when diff-auto-refine-mode
(diff-refine-hunk)))
(when (eq diff-refine 'navigation)
(diff-refine-hunk))
(if diff-hl-ask-before-revert-hunk
(unless (yes-or-no-p (format "Revert current hunk in %s? "
file))
@@ -1090,7 +1102,7 @@ its end position."
(defun diff-hl-revert-hunk ()
"Revert the diff hunk with changes at or above the point."
(interactive)
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(with-current-buffer (current-buffer)
(diff-hl-revert-hunk-1)))
(defun diff-hl-hunk-overlay-at (pos)
@@ -1146,7 +1158,7 @@ its end position."
(push-mark (overlay-end hunk) nil t)))
(defun diff-hl--ensure-staging-supported ()
(let ((backend (vc-backend buffer-file-name)))
(let ((backend (vc-backend (diff-hl--buffer-file-name))))
(unless (eq backend 'Git)
(user-error "Only Git supports staging; this file is controlled by %s" backend))))
@@ -1173,7 +1185,7 @@ Only supported with Git."
(diff-hl--ensure-staging-supported)
(diff-hl-find-current-hunk)
(let* ((line (line-number-at-pos))
(file buffer-file-name)
(file (diff-hl--buffer-file-name))
(dest-buffer (get-buffer-create " *diff-hl-stage*"))
(orig-buffer (current-buffer))
;; FIXME: If the file name has double quotes, these need to be quoted.
@@ -1186,9 +1198,7 @@ Only supported with Git."
diff-hl-update-async)
(diff-hl-diff-buffer-with-reference file dest-buffer nil 3))
(with-current-buffer dest-buffer
(with-no-warnings
(let (diff-auto-refine-mode)
(diff-hl-diff-skip-to line)))
(diff-hl-diff-skip-to line)
(let ((inhibit-read-only t))
(diff-hl-split-away-changes 3)
(save-excursion
@@ -1214,13 +1224,14 @@ Only supported with Git."
Only supported with Git."
(interactive)
(unless buffer-file-name
(user-error "No current file"))
(diff-hl--ensure-staging-supported)
(vc-git-command nil 0 buffer-file-name "reset")
(message "Unstaged all")
(unless diff-hl-show-staged-changes
(diff-hl-update)))
(let ((file (diff-hl--buffer-file-name)))
(unless file
(user-error "No current file"))
(diff-hl--ensure-staging-supported)
(vc-git-command nil 0 file "reset")
(message "Unstaged all")
(unless diff-hl-show-staged-changes
(diff-hl-update))))
(defun diff-hl-stage-dwim (&optional with-edit)
"Stage the current hunk or choose the hunks to stage.
@@ -1247,7 +1258,7 @@ Pops up a diff buffer that can be edited to choose the changes to stage."
(diff-hl--ensure-staging-supported)
(let* ((line-beg (and beg (line-number-at-pos beg t)))
(line-end (and end (line-number-at-pos end t)))
(file buffer-file-name)
(file (diff-hl--buffer-file-name))
(dest-buffer (get-buffer-create "*diff-hl-stage-some*"))
(orig-buffer (current-buffer))
(diff-hl-update-async nil)
@@ -1391,14 +1402,14 @@ The value of this variable is a mode line template as in
(declare-function smartrep-define-key 'smartrep)
(let (smart-keys)
(cl-labels ((scan (map)
(map-keymap
(lambda (event binding)
(if (consp binding)
(scan binding)
(when (and (characterp event)
(not (memq binding diff-hl-repeat-exceptions)))
(push (cons (string event) binding) smart-keys))))
map)))
(map-keymap
(lambda (event binding)
(if (consp binding)
(scan binding)
(when (and (characterp event)
(not (memq binding diff-hl-repeat-exceptions)))
(push (cons (string event) binding) smart-keys))))
map)))
(scan diff-hl-command-map)
(smartrep-define-key diff-hl-mode-map diff-hl-command-prefix smart-keys))))
@@ -1423,22 +1434,24 @@ The value of this variable is a mode line template as in
(let* ((topdir (magit-toplevel))
(modified-files
(magit-git-items "diff-tree" "-z" "--name-only" "-r" "HEAD~" "HEAD"))
(unmodified-states '(up-to-date ignored unregistered)))
(unmodified-states '(up-to-date ignored unregistered))
file)
(dolist (buf (buffer-list))
(when (and (buffer-local-value 'diff-hl-mode buf)
(not (buffer-modified-p buf))
;; Solve the "cloned indirect buffer" problem
;; (diff-hl-mode could be non-nil there, even if
;; buffer-file-name is nil):
(buffer-file-name buf)
(file-in-directory-p (buffer-file-name buf) topdir)
(file-exists-p (buffer-file-name buf)))
(setq file (diff-hl--buffer-file-name buf))
(when (and
(buffer-local-value 'diff-hl-mode buf)
(not (buffer-modified-p buf))
;; Solve the "cloned indirect buffer" problem
;; (diff-hl-mode could be non-nil there, even if
;; buffer-file-name is nil):
file
(file-in-directory-p file topdir)
(file-exists-p file))
(with-current-buffer buf
(let* ((file buffer-file-name)
(backend (vc-backend file)))
(let* ((backend (vc-backend file)))
(when backend
(cond
((member file modified-files)
((member (file-relative-name file topdir) modified-files)
(when (memq (vc-state file) unmodified-states)
(vc-state-refresh file backend))
(diff-hl-update))
@@ -1519,11 +1532,15 @@ The diffs are computed in the buffer DEST-BUFFER. This requires
the `diff-program' to be in your `exec-path'.
CONTEXT-LINES is the size of the unified diff context, defaults to 0."
(require 'diff)
(vc-ensure-vc-buffer)
(unless file
(error "Buffer %s is not visiting a file" (buffer-name)))
(setq backend (or backend (vc-backend file)))
(unless backend
(error "File %s is not under version control" file))
(save-current-buffer
(let* ((dest-buffer (or dest-buffer "*diff-hl-diff-buffer-with-reference*"))
(backend (or backend (vc-backend file)))
(temporary-file-directory diff-hl-temporary-directory)
(enable-local-variables nil)
(rev
(if (and (eq backend 'Git)
(not diff-hl-reference-revision)
@@ -1537,7 +1554,7 @@ CONTEXT-LINES is the size of the unified diff context, defaults to 0."
backend
(or diff-hl-reference-revision
(assoc-default backend diff-hl-head-revision-alist)))
(diff-hl-working-revision buffer-file-name backend)))))
(diff-hl-working-revision (diff-hl--buffer-file-name) backend)))))
(switches (format "-U %d --strip-trailing-cr" (or context-lines 0))))
(diff-no-select rev (current-buffer) switches (not (diff-hl--use-async-p))
(get-buffer-create dest-buffer))
@@ -1566,7 +1583,8 @@ CONTEXT-LINES is the size of the unified diff context, defaults to 0."
(goto-char (point-min))
(buffer-substring-no-properties (point) (line-end-position))))
((eq backend 'JJ)
(car (last (vc-jj--process-lines "log" "--no-graph"
(car (last (vc-jj--process-lines nil
"log" "--no-graph"
"-r" revision
"-T" "change_id" "-n" "1"))))
(t
@@ -1605,13 +1623,14 @@ CONTEXT-LINES is the size of the unified diff context, defaults to 0."
;;;###autoload
(defun turn-on-diff-hl-mode ()
"Turn on `diff-hl-mode' or `diff-hl-dir-mode' in a buffer if appropriate."
(cond
(buffer-file-name
(unless (and diff-hl-disable-on-remote
(file-remote-p buffer-file-name))
(diff-hl-mode 1)))
((eq major-mode 'vc-dir-mode)
(diff-hl-dir-mode 1))))
(let ((file (diff-hl--buffer-file-name)))
(cond
(file
(unless (and diff-hl-disable-on-remote
(file-remote-p file))
(diff-hl-mode 1)))
((eq major-mode 'vc-dir-mode)
(diff-hl-dir-mode 1)))))
;;;###autoload
(defun diff-hl--global-turn-on ()
@@ -1729,11 +1748,15 @@ effect."
(message "Showing changes against %s (project %s)" rev name)))))
(defun diff-hl--project-root (proj)
;; Emacs 26 and 27 don't have `project-root'.
;; Emacs 27 does not have `project-root'.
(expand-file-name (static-if (>= emacs-major-version 28)
(project-root proj)
(project-roots proj))))
;; Commands below will only work with recent enough project.el.
(declare-function project-name "project")
(declare-function project-buffers "project")
(defun diff-hl-set-reference-rev-in-project-internal (rev proj)
(let* ((root (diff-hl--project-root proj)))
;; newly opened files will share this value