dev: merge branch 'master' of github.com:doomemacs

This commit is contained in:
Matt Nish-Lapidus 2024-07-26 16:12:59 -04:00
commit d00f642a4c
9 changed files with 179 additions and 180 deletions

View file

@ -121,16 +121,16 @@ list remains lean."
nil (mapcar (doom-rpartial #'gethash straight--repo-cache)
(mapcar #'symbol-name straight-recipe-repositories)))
(recipe package type local-repo)
(let ((esc (unless init-file-debug "\033[1A"))
(let ((esc (if init-file-debug "" "\033[1A"))
(ref (straight-vc-get-commit type local-repo))
newref output)
(print! (start "\033[KUpdating recipes for %s...%s") package esc)
(print! (start "\rUpdating recipes for %s...%s") package esc)
(doom-packages--straight-with (straight-vc-fetch-from-remote recipe)
(when .it
(setq output .output)
(straight-merge-package package)
(unless (equal ref (setq newref (straight-vc-get-commit type local-repo)))
(print! (success "\033[K%s updated (%s -> %s)")
(print! (success "\r%s updated (%s -> %s)")
package
(doom-packages--abbrev-commit ref)
(doom-packages--abbrev-commit newref))
@ -214,7 +214,7 @@ list remains lean."
(comp-async-runnings)))
while (not (zerop pending))
if (/= previous pending) do
(print! (start "\033[KNatively compiling %d files...\033[1A" pending))
(print! (start "\rNatively compiling %d files...\033[1A" pending))
(setq previous pending
timer 0)
else do
@ -362,7 +362,7 @@ list remains lean."
;; and causing a rebuild of those packages each time `doom sync'
;; or similar is run, so we clean it up ourselves:
(delete-directory (straight--modified-dir) 'recursive)
(print! (success "\033[KBuilt %d package(s)") (length built)))
(print! (success "\rBuilt %d package(s)") (length built)))
(print! (item "No packages need attention"))
nil))))
@ -378,7 +378,7 @@ list remains lean."
(packages-to-rebuild (make-hash-table :test 'equal))
(repos-to-rebuild (make-hash-table :test 'equal))
(total (length recipes))
(esc (unless init-file-debug "\033[1A"))
(esc (if init-file-debug "" "\033[1A"))
(i 0))
(if pinned-only-p
(print! (start "Updating pinned packages..."))
@ -411,7 +411,7 @@ list remains lean."
output)
(or (cond
((not (stringp target-ref))
(print! (start "\033[K(%d/%d) Fetching %s...%s") i total package esc)
(print! (start "\r(%d/%d) Fetching %s...%s") i total package esc)
(doom-packages--straight-with (straight-vc-fetch-from-remote recipe)
(when .it
(straight-merge-package package)
@ -422,13 +422,13 @@ list remains lean."
(cl-return)))))
((doom-packages--same-commit-p target-ref ref)
(print! (item "\033[K(%d/%d) %s is up-to-date...%s") i total package esc)
(print! (item "\r(%d/%d) %s is up-to-date...%s") i total package esc)
(cl-return))
((if (straight-vc-commit-present-p recipe target-ref)
(print! (start "\033[K(%d/%d) Checking out %s (%s)...%s")
(print! (start "\r(%d/%d) Checking out %s (%s)...%s")
i total package (doom-packages--abbrev-commit target-ref) esc)
(print! (start "\033[K(%d/%d) Fetching %s...%s") i total package esc)
(print! (start "\r(%d/%d) Fetching %s...%s") i total package esc)
(and (straight-vc-fetch-from-remote recipe)
(straight-vc-commit-present-p recipe target-ref)))
(straight-vc-check-out-commit recipe target-ref)
@ -437,7 +437,7 @@ list remains lean."
commits (length (split-string output "\n" t))))
(doom-packages--same-commit-p target-ref (straight-vc-get-commit type local-repo)))
((print! (start "\033[K(%d/%d) Re-cloning %s...") i total local-repo esc)
((print! (start "\r(%d/%d) Re-cloning %s...") i total local-repo esc)
(let ((repo (straight--repos-dir local-repo))
(straight-vc-git-default-clone-depth 'full))
(delete-directory repo 'recursive)
@ -448,7 +448,7 @@ list remains lean."
(setq output (doom-packages--commit-log-between ref target-ref)
commits (length (split-string output "\n" t))))))))
(progn
(print! (warn "\033[K(%d/%d) Failed to fetch %s")
(print! (warn "\r(%d/%d) Failed to fetch %s")
i total local-repo)
(unless (string-empty-p output)
(print-group! (print! (item "%s" output))))
@ -472,7 +472,7 @@ list remains lean."
(add-to-rebuild (cdr tree))))))
(add-to-rebuild dependents)
(puthash package t packages-to-rebuild)
(print! (success "\033[K(%d/%d) %s: %s -> %s%s%s")
(print! (success "\r(%d/%d) %s: %s -> %s%s%s")
i total local-repo
(doom-packages--abbrev-commit ref)
(doom-packages--abbrev-commit target-ref)
@ -495,15 +495,14 @@ list remains lean."
(error
(signal 'doom-package-error (list package e)))))))
(print-group!
(princ "\033[K")
(if (hash-table-empty-p packages-to-rebuild)
(ignore (print! (success "All %d packages are up-to-date") total))
(ignore (print! (success "\rAll %d packages are up-to-date") total))
(doom-packages--cli-recipes-update)
(straight--transaction-finalize)
(let ((default-directory (straight--build-dir)))
(mapc (doom-rpartial #'delete-directory 'recursive)
(hash-table-keys packages-to-rebuild)))
(print! (success "Updated %d package(s)")
(print! (success "\rUpdated %d package(s)")
(hash-table-count packages-to-rebuild))
(doom-packages-ensure)
t))))
@ -532,22 +531,22 @@ list remains lean."
(error "No repo specified for regrafting"))
(let ((default-directory (straight--repos-dir repo)))
(unless (file-directory-p ".git")
(print! (warn "\033[Krepos/%s is not a git repo, skipping" repo))
(print! (warn "\rrepos/%s is not a git repo, skipping" repo))
(cl-return))
(unless (file-in-directory-p default-directory straight-base-dir)
(print! (warn "\033[KSkipping repos/%s because it is local" repo))
(print! (warn "\rSkipping repos/%s because it is local" repo))
(cl-return))
(let ((before-size (doom-directory-size default-directory)))
(doom-call-process "git" "reset" "--hard")
(doom-call-process "git" "clean" "-ffd")
(if (not (zerop (car (doom-call-process "git" "replace" "--graft" "HEAD"))))
(print! (item "\033[Krepos/%s is already compact\033[1A" repo))
(print! (item "\rrepos/%s is already compact\033[1A" repo))
(doom-call-process "git" "reflog" "expire" "--expire=all" "--all")
(doom-call-process "git" "gc" "--prune=now")
(let ((after-size (doom-directory-size default-directory)))
(if (equal after-size before-size)
(print! (success "\033[Krepos/%s cannot be compacted further" repo))
(print! (success "\033[KRegrafted repos/%s (from %0.1fKB to %0.1fKB)")
(print! (success "\rrepos/%s cannot be compacted further" repo))
(print! (success "\rRegrafted repos/%s (from %0.1fKB to %0.1fKB)")
repo before-size after-size)))))
t))
@ -559,9 +558,9 @@ list remains lean."
(let ((before-size (doom-directory-size (straight--repos-dir))))
(print-group!
(prog1 (delq nil (mapcar #'doom-packages--regraft-repo repos))
(princ "\033[K")
;; (princ "\r\033[K")
(let ((after-size (doom-directory-size (straight--repos-dir))))
(print! (success "Finished regrafting. Size before: %0.1fKB and after: %0.1fKB (%0.1fKB)")
(print! (success "\rFinished regrafting. Size before: %0.1fKB and after: %0.1fKB (%0.1fKB)")
before-size after-size
(- after-size before-size))))))))
@ -831,5 +830,37 @@ However, in batch mode, print to stdout instead of stderr."
(error "Package was not properly cloned due to a connection failure, please try again later")
(signal (car e) (cdr e))))))
;; HACK: Fix an issue where straight wasn't byte-compiling some packages (or
;; some files in packages) due to missing (invisible) dependencies.
(defadvice! doom-cli--straight-byte-compile-a (recipe)
"See https://github.com/radian-software/straight.el/pull/1132"
:override #'straight--build-compile
(let* ((pkg (plist-get recipe :package))
(dir (straight--build-dir pkg))
(emacs (concat invocation-directory invocation-name))
(buffer straight-byte-compilation-buffer)
(deps
(let (tmp)
(dolist (dep (straight--flatten (straight-dependencies pkg)) tmp)
(let ((build-dir (straight--build-dir dep)))
(when (file-exists-p build-dir)
(push build-dir tmp))))))
(print-circle nil)
(print-length nil)
(program
(format "%S" `(let ((default-directory ,(straight--build-dir))
(lp load-path))
(setq load-path (list default-directory))
(normal-top-level-add-subdirs-to-load-path)
(setq load-path (append '(,dir) ',deps load-path lp))
(byte-recompile-directory ,dir 0 'force))))
(args (list "-Q" "--batch" "--eval" program)))
(when buffer
(with-current-buffer (get-buffer-create buffer)
(insert (format "\n$ %s %s \\\n %S\n" emacs
(string-join (butlast args) " ")
program))))
(apply #'call-process `(,emacs nil ,buffer nil ,@args))))
(provide 'doom-cli-packages)
;;; packages.el ends here

View file

@ -308,18 +308,25 @@ based on the print level of the message. For example:
(defun doom-print--indent (text &optional prefix)
"Indent TEXT by WIDTH spaces. If ARGS, format TEXT with them."
(with-temp-buffer
(let ((width
(cond ((null prefix)
doom-print-indent-increment)
((integerp prefix)
prefix)
((length (ansi-color-filter-apply (format "%s" prefix)))))))
(insert (format "%s" (or text "")))
(let* ((re "^\\( *\\)\r")
(line-feed (if (stringp text) (string-match-p re text)))
(width (cond ((null prefix) doom-print-indent-increment)
((integerp prefix) prefix)
((length (ansi-color-filter-apply (format "%s" prefix)))))))
(insert
(if text
(replace-regexp-in-string re "\\1\033[K" (format "%s" text))
""))
(indent-rigidly (point-min) (point-max) width)
(when (stringp prefix)
(goto-char (point-min))
(delete-char width)
(insert prefix))
(save-excursion
(when line-feed
(goto-char (point-min))
(insert "\r")))
(save-excursion
(when (stringp prefix)
(goto-char (point-min))
(delete-char (+ width (if line-feed 1 0)))
(insert prefix)))
(buffer-string))))
;;;###autoload

View file

@ -1,4 +1,4 @@
;; -*- no-byte-compile: t; -*-
;;; app/emms/packages.el
(package! emms :pin "cead7b435a679690fd4bbe91fa2f57739a1e0077")
(package! emms :pin "b5567be2176dcbdf42aa2d0ccad32a44f245dd09")

View file

@ -88,79 +88,62 @@ Use ~set-irc-server! SERVER PLIST~ to configure IRC servers. Its second argument
#+end_src
However, *it is a obviously a bad idea to store your password in plaintext,* so
here are ways to avoid that:
[[https://github.com/emacs-circe/circe/wiki/Configuration#safer-password-management][it's recommend]] that you use ~auth-source~ (built into Emacs) to safely pull
passwords from a password manager or OS keychain (remember to enable the :os
macos or :tools pass modules if you want integration into the MacOS keychain or
[[https://www.passwordstore.org/][Pass]]):
#+begin_src emacs-lisp
;;; in $DOOMDIR/config.el
(after! circe
(defun fetch-password (&rest params)
(require 'auth-source)
(if-let* ((match (car (apply #'auth-source-search params)))
(secret (plist-get match :secret)))
(if (functionp secret)
(funcall secret)
secret)
(user-error "Password not found for %S" params)))
(set-irc-server! "irc.libera.chat"
'(:tls t
:port 6697
:nick "doom"
:sasl-password
(lambda (server)
(fetch-password :user "forcer" :host "irc.libera.chat"))
:channels ("#emacs"))))
#+end_src
If Doom's [[doom-module::tools pass]] module is enabled, ~auth-source~ can integrate
with [[https://www.passwordstore.org/][Pass]].
** TODO Pass: the unix password manager
#+begin_quote
󱌣 /This section is outdated and needs to be rewritten./ [[doom-contrib-module:][Rewrite it?]]
 A common mistake is to interpolate the return value of your secrets retrieval
function into the plist you pass to ~set-irc-server!~. This means that not
only will your secrets will be stored, in plaintext, somewhere in Emacs
state, but your password manager (or GnuPG) will likely prompt you for your
GPG key passphrase when the ~set-irc-server!~ call is made! For example,
don't do this!
(set-irc-server! "irc.libera.chat"
`(:tls t
:port 6697
:nick "doom"
:sasl-username ,(fetch-password "irc/libera.chat")
:sasl-password ,(fetch-password "irc/libera.chat")
:channels ("#emacs")))
Do this, instead:
(set-irc-server! "irc.libera.chat"
'(:tls t
:port 6697
:nick "doom"
:sasl-username (+pass-get-user "irc/libera.chat")
:sasl-password (+pass-get-secret "irc/libera.chat")
:channels ("#emacs")))
#+end_quote
[[https://www.passwordstore.org/][Pass]] is my tool of choice. I use it to manage my passwords. If you activate the
[[doom-module::tools pass]] module you get an elisp API through which to access your password
store.
~set-irc-server!~ accepts a plist can use functions instead of strings.
~+pass-get-user~ and ~+pass-get-secret~ can help here:
#+begin_src emacs-lisp
(set-irc-server! "irc.libera.chat"
`(:tls t
:port 6697
:nick "doom"
:sasl-username ,(+pass-get-user "irc/libera.chat")
:sasl-password ,(+pass-get-secret "irc/libera.chat")
:channels ("#emacs")))
#+end_src
But wait, there's more! This stores your password in a public variable which
could be accessed or appear in backtraces. Not good! So we go a step further:
#+begin_src emacs-lisp
(set-irc-server! "irc.libera.chat"
`(:tls t
:port 6697
:nick "doom"
:sasl-username ,(+pass-get-user "irc/libera.chat")
:sasl-password (lambda (&rest _) (+pass-get-secret "irc/libera.chat"))
:channels ("#emacs")))
#+end_src
And you're good to go!
Note that ~+pass-get-user~ tries to find your username by looking for the fields
listed in ~+pass-user-fields~ (by default =login=, =user==, =username== and
=email=)=). An example configuration looks like
#+begin_example
mysecretpassword
username: myusername
#+end_example
** Emacs' auth-source API
~auth-source~ is built into Emacs. As suggested [[https://github.com/jorgenschaefer/circe/wiki/Configuration#safer-password-management][in the circe wiki]], you can store
(and retrieve) encrypted passwords with it.
#+begin_src emacs-lisp
(setq auth-sources '("~/.authinfo.gpg"))
(defun my-fetch-password (&rest params)
(require 'auth-source)
(let ((match (car (apply #'auth-source-search params))))
(if match
(let ((secret (plist-get match :secret)))
(if (functionp secret)
(funcall secret)
secret))
(error "Password not found for %S" params))))
(defun my-nickserv-password (server)
(my-fetch-password :user "forcer" :host "irc.libera.chat"))
(set-irc-server! "irc.libera.chat"
'(:tls t
:port 6697
:nick "doom"
:sasl-password my-nickserver-password
:channels ("#emacs")))
#+end_src
* TODO Troubleshooting
/There are no known problems with this module./ [[doom-report:][Report one?]]

View file

@ -19,20 +19,9 @@ Useful for scenarios where an instant reconnect will not be successful.")
(defvar +irc-bot-list '("fsbot" "rudybot")
"Nicks listed have `circe-fool-face' applied and will not be tracked.")
(defvar +irc-time-stamp-format "%H:%M"
"The format of time stamps.
See `format-time-string' for a full description of available
formatting directives. ")
(defvar +irc-notifications-watch-strings nil
"A list of strings which can trigger a notification. You don't need to put
your nick here.
See `circe-notifications-watch-strings'.")
(defvar +irc-defer-notifications nil
"How long to defer enabling notifications, in seconds (e.g. 5min = 300).
Useful for ZNC users who want to avoid the deluge of notifications during buffer
playback.")
@ -42,12 +31,15 @@ playback.")
(format (format "%%%ds | %%s" +irc-left-padding)
(concat "*** " left) right))
(define-obsolete-variable-alias '+irc-notifications-watch-strings 'circe-notifications-watch-strings "v3.0.0")
(define-obsolete-variable-alias '+irc-time-stamp-format 'lui-time-stamp-format "v3.0.0")
;;
;; Packages
;;; Packages
(use-package! circe
:commands circe circe-server-buffers
:commands circe-server-buffers
:config
(setq circe-default-quit-message nil
circe-default-part-message nil
@ -94,42 +86,11 @@ playback.")
(add-hook 'circe-mode-hook #'+irc--add-circe-buffer-to-persp-h)
(add-hook 'circe-mode-hook #'turn-off-smartparens-mode)
;; HACK Fix #1862: circe hangs on TLS connections when using OpenSSL versions
;; > 1.1.0, where tls.el does not correctly determine the end of the info
;; block. This fixes proposed in jorgenschaefer/circe#340
(setq-hook! 'circe-mode-hook
tls-end-of-info
(concat "\\("
;; `openssl s_client' regexp. See ssl/ssl_txt.c lines 219-220.
;; According to apps/s_client.c line 1515 `---' is always the last
;; line that is printed by s_client before the real data.
"^ Verify return code: .+\n\\(\\|^ Extended master secret: .+\n\\)\\(\\|^ Max Early Data: .+\n\\)---\n\\|"
;; `gnutls' regexp. See src/cli.c lines 721-.
"^- Simple Client Mode:\n"
"\\(\n\\|" ; ignore blank lines
;; According to GnuTLS v2.1.5 src/cli.c lines 640-650 and 705-715 in
;; `main' the handshake will start after this message. If the
;; handshake fails, the programs will abort.
"^\\*\\*\\* Starting TLS handshake\n\\)*"
"\\)"))
(defadvice! +irc--circe-run-disconnect-hook-a (&rest _)
"Runs `+irc-disconnect-hook' after circe disconnects."
:after #'circe--irc-conn-disconnected
(run-hooks '+irc-disconnect-hook))
(add-hook! 'lui-pre-output-hook
(defun +irc-circe-truncate-nicks-h ()
"Truncate long nicknames in chat output non-destructively."
(when-let (beg (text-property-any (point-min) (point-max) 'lui-format-argument 'nick))
(goto-char beg)
(let ((end (next-single-property-change beg 'lui-format-argument))
(nick (plist-get (plist-get (text-properties-at beg) 'lui-keywords)
:nick)))
(when (> (length nick) +irc-left-padding)
(compose-region (+ beg +irc-left-padding -1) end
+irc-truncate-nick-char))))))
(add-hook! 'circe-message-option-functions
(defun +irc-circe-message-option-bot-h (nick &rest ignored)
"Fontify known bots and mark them to not be tracked."
@ -159,14 +120,21 @@ playback.")
(use-package! circe-color-nicks
:hook (circe-channel-mode . enable-circe-color-nicks)
:defer t
;; NOTE: I avoid `:after' on purpose, because it convolutes load order and
;; makes it harder for users to know what to target with `after!' or
;; `with-eval-after-load' when trying to configure packages.
:init (after! circe (require 'circe-color-nicks))
:config
(setq circe-color-nicks-min-constrast-ratio 4.5
circe-color-nicks-everywhere t))
circe-color-nicks-everywhere t)
(enable-circe-color-nicks))
(use-package! circe-new-day-notifier
:after circe
:defer t
;; NOTE: See NOTE in `circe-color-nicks' above.
:init (after! circe (require 'circe-new-day-notifier))
:config
(enable-circe-new-day-notifier)
(setq circe-new-day-notifier-format-message
@ -174,7 +142,7 @@ playback.")
(use-package! circe-notifications
:commands enable-circe-notifications
:defer t
:init
(add-hook! 'circe-server-connected-hook
(defun +irc-init-circe-notifications-h ()
@ -184,8 +152,7 @@ playback.")
#'enable-circe-notifications))
(enable-circe-notifications))))
:config
(setq circe-notifications-watch-strings +irc-notifications-watch-strings
circe-notifications-emacs-focused nil
(setq circe-notifications-emacs-focused nil
circe-notifications-alert-style
(cond ((featurep :system 'macos) 'osx-notifier)
((featurep :system 'linux) 'libnotify)
@ -197,9 +164,26 @@ playback.")
:config
(define-key lui-mode-map "\C-u" #'lui-kill-to-beginning-of-line)
(setq lui-fill-type nil)
(setq lui-flyspell-p (modulep! :checkers spell +flyspell))
(when (modulep! :checkers spell)
(setq lui-flyspell-p t))
(setq lui-time-stamp-format "%H:%M"
lui-time-stamp-position 'right-margin)
(enable-lui-autopaste) ; prompt to use paste service for large pastes
(enable-lui-track) ; horizontal line marking last read message
(enable-lui-irc-colors) ; enable IRC colors (see https://www.mirc.co.uk/colors.html)
(add-hook! 'lui-pre-output-hook
(defun +irc-truncate-nicks-h ()
"Truncate long nicknames in chat output non-destructively."
(when-let (beg (text-property-any (point-min) (point-max) 'lui-format-argument 'nick))
(goto-char beg)
(let ((end (next-single-property-change beg 'lui-format-argument))
(nick (plist-get (plist-get (text-properties-at beg) 'lui-keywords)
:nick)))
(when (> (length nick) +irc-left-padding)
(compose-region (+ beg +irc-left-padding -1) end
+irc-truncate-nick-char))))))
(after! evil
(defun +irc-evil-insert-h ()
@ -215,7 +199,6 @@ after prompt marker."
(mapc (lambda (cmd) (push cmd +irc-scroll-to-bottom-on-commands))
'(evil-paste-after evil-paste-before evil-open-above evil-open-below)))
(defun +irc-preinput-scroll-to-bottom-h ()
"Go to the end of the buffer in all windows showing it.
Courtesy of esh-mode.el"
@ -235,14 +218,11 @@ Courtesy of esh-mode.el"
(add-hook! 'lui-mode-hook
(add-hook 'pre-command-hook #'+irc-preinput-scroll-to-bottom-h nil t))
;; enable a horizontal line marking the last read message
(add-hook 'lui-mode-hook #'enable-lui-track-bar)
(add-hook! 'lui-mode-hook
(defun +irc-init-lui-margins-h ()
(setq lui-time-stamp-position 'right-margin
lui-time-stamp-format +irc-time-stamp-format
right-margin-width (length (format-time-string lui-time-stamp-format))))
(pcase lui-time-stamp-position
(`right-margin (setq right-margin-width (length (format-time-string lui-time-stamp-format))))
(`left-margin (setq left-margin-width (length (format-time-string lui-time-stamp-format))))))
(defun +irc-init-lui-wrapping-a ()
(setq fringes-outside-margins t
word-wrap t
@ -251,8 +231,5 @@ Courtesy of esh-mode.el"
(use-package! lui-logging
:after lui
:init (setq lui-logging-directory (file-name-concat doom-profile-state-dir "lui"))
:config (enable-lui-logging))
(use-package! lui-autopaste
:hook (circe-channel-mode . enable-lui-autopaste))

View file

@ -1,5 +1,5 @@
;; -*- no-byte-compile: t; -*-
;;; app/irc/packages.el
(package! circe :pin "9d703f481a2c65f2b17edcc2b05412f9865d24af")
(package! circe :pin "3ae38790506311fd32b2d499804af69b16307652")
(package! circe-notifications :pin "291149ac12877bbd062da993479d3533a26862b0")

View file

@ -462,8 +462,7 @@ directives. By default, this only recognizes C directives.")
:nv "gd" #'+lookup/definition
:nv "gD" #'+lookup/references
:nv "gf" #'+lookup/file
:nv "gI" #'+lookup/implementations
:nv "gA" #'+lookup/assignments)
:nv "gI" #'+lookup/implementations)
(:when (modulep! :tools eval)
:nv "gr" #'+eval:region
:n "gR" #'+eval/buffer

View file

@ -42,12 +42,6 @@
(doom-modeline-set-modeline 'magit)
(hide-mode-line-mode))))
;; Some functions modify the buffer, causing the modeline to show a false
;; modified state, so force them to behave.
(defadvice! +modeline--inhibit-modification-hooks-a (fn &rest args)
:around #'ws-butler-after-save
(with-silent-modifications (apply fn args)))
;;
;;; Extensions

View file

@ -60,11 +60,19 @@
;;; diff-hl
(use-package! diff-hl
:hook (find-file . diff-hl-mode)
:hook (vc-dir-mode . diff-hl-dir-mode)
:hook (dired-mode . diff-hl-dired-mode)
:hook (doom-first-file . global-diff-hl-mode)
:hook (vc-dir-mode . turn-on-diff-hl-mode)
:hook (diff-hl-mode . diff-hl-flydiff-mode)
:commands diff-hl-stage-current-hunk diff-hl-revert-hunk diff-hl-next-hunk diff-hl-previous-hunk
:init
(add-hook! 'dired-mode-hook
(defun +vc-gutter-enable-maybe-h ()
"Conditionally enable `diff-hl-dired-mode' in dired buffers.
Respects `diff-hl-disable-on-remote'."
(unless (and diff-hl-disable-on-remote
(file-remote-p default-directory))
(diff-hl-dired-mode +1))))
:config
(set-popup-rule! "^\\*diff-hl" :select nil :size '+popup-shrink-to-fit)