Files
doomemacs/modules/emacs/dired/config.el
Henrik Lissner b7f4d31218 fix(dired): dirvish: "window is dedicated to *dirvish-parent-...*"
Seems the naming convention of dirvish windows has changed at some
point, so the popup module's fallback rules were catching them, causing
each of Dirvish's side windows to be treated as implicit popups.

Fix: #8347
2025-04-08 18:13:27 -04:00

226 lines
9.1 KiB
EmacsLisp

;;; emacs/dired/config.el -*- lexical-binding: t; -*-
;;
;;; Packages
(use-package! dired
:commands dired-jump
:init
(setq dired-dwim-target t ; suggest a target for moving/copying intelligently
;; don't prompt to revert, just do it
dired-auto-revert-buffer #'dired-buffer-stale-p
;; Always copy/delete recursively
dired-recursive-copies 'always
dired-recursive-deletes 'top
;; Ask whether destination dirs should get created when copying/removing files.
dired-create-destination-dirs 'ask
;; Where to store image caches
image-dired-dir (concat doom-cache-dir "image-dired/")
image-dired-db-file (concat image-dired-dir "db.el")
image-dired-gallery-dir (concat image-dired-dir "gallery/")
image-dired-temp-image-file (concat image-dired-dir "temp-image")
image-dired-temp-rotate-image-file (concat image-dired-dir "temp-rotate-image")
;; Screens are larger nowadays, we can afford slightly larger thumbnails
image-dired-thumb-size 150)
:config
(set-popup-rule! "^\\*image-dired"
:slot 20 :size 0.8 :select t :quit nil :ttl 0)
(set-evil-initial-state! 'image-dired-display-image-mode 'emacs)
(let ((args (list "-ahl" "-v" "--group-directories-first")))
(when (featurep :system 'bsd)
;; Use GNU ls as `gls' from `coreutils' if available. Add `(setq
;; dired-use-ls-dired nil)' to your config to suppress the Dired warning
;; when not using GNU ls.
(if-let* ((gls (executable-find "gls")))
(setq insert-directory-program gls)
;; BSD ls doesn't support -v or --group-directories-first
(setq args (list (car args)))))
(setq dired-listing-switches (string-join args " "))
(add-hook! 'dired-mode-hook
(defun +dired-disable-gnu-ls-flags-maybe-h ()
"Remove extraneous switches from `dired-actual-switches' when it's
uncertain that they are supported (e.g. over TRAMP or on Windows).
Fixes #1703: dired over TRAMP displays a blank screen.
Fixes #3939: unsortable dired entries on Windows."
(when (or (file-remote-p default-directory)
(and (boundp 'ls-lisp-use-insert-directory-program)
(not ls-lisp-use-insert-directory-program)))
(setq-local dired-actual-switches (car args))))))
;; Don't complain about this command being disabled when we use it
(put 'dired-find-alternate-file 'disabled nil)
(defadvice! +dired--no-revert-in-virtual-buffers-a (&rest args)
"Don't auto-revert in dired-virtual buffers (see `dired-virtual-revert')."
:before-while #'dired-buffer-stale-p
(not (eq revert-buffer-function #'dired-virtual-revert)))
;; To be consistent with vertico/ivy/helm+wgrep integration
(define-key dired-mode-map (kbd "C-c C-e") #'wdired-change-to-wdired-mode)
;; On ESC, abort `wdired-mode' (will prompt)
(add-hook! 'doom-escape-hook
(defun +dired-wdired-exit-h ()
(when (eq major-mode 'wdired-mode)
(wdired-exit)
t))))
(use-package! dirvish
:commands dirvish-find-entry-a dirvish-dired-noselect-a
:general (dired-mode-map "C-c C-r" #'dirvish-rsync)
:init
(setq dirvish-cache-dir (file-name-concat doom-cache-dir "dirvish/"))
;; HACK: ...
(advice-add #'dired--find-file :override #'dirvish--find-entry)
(advice-add #'dired-noselect :around #'dirvish-dired-noselect-a)
:config
(dirvish-override-dired-mode)
(set-popup-rule! "^ ?\\*\\(?:[Dd]irvish\\|SIDE :: \\).*" :ignore t)
;; Fixes #8038. This setting is for folks who expect to be able to switch back
;; to dired buffers where the file is opened from. In other cases, don't
;; recycle sessions. We don't want leftover buffers lying around, especially
;; if users are reconfiguring Dirvish or trying to recover from an error. It's
;; too easy to accidentally break Dirvish (e.g. by focusing the header window)
;; at the moment. Starting from scratch isn't even that expensive, anyway.
(setq dirvish-reuse-session 'open)
(if (modulep! +dirvish)
(setq dirvish-attributes '(file-size)
dirvish-mode-line-format
'(:left (sort file-time symlink) :right (omit yank index)))
(setq dirvish-attributes nil
dirvish-use-header-line nil
dirvish-use-mode-line nil))
;; Match the height of `doom-modeline', if it's being used.
;; TODO: Make this respect user changes to these variables.
(when (modulep! :ui modeline)
(add-hook! 'dired-mode-hook
(defun +dired-update-mode-line-height-h ()
(when-let (height (bound-and-true-p doom-modeline-height))
(setq dirvish-mode-line-height height
dirvish-header-line-height height)))))
(when (modulep! :ui vc-gutter)
;; The vc-gutter module uses `diff-hl-dired-mode' + `diff-hl-margin-mode'
;; for diffs in dirvish buffers. `vc-state' uses overlays, so they won't be
;; visible in the terminal.
(when (or (daemonp) (display-graphic-p))
(push 'vc-state dirvish-attributes)))
(when (modulep! +icons)
(setq dirvish-subtree-always-show-state t)
(cl-callf append dirvish-attributes '(nerd-icons subtree-state)))
(setq dirvish-hide-details '(dirvish dirvish-side)
dirvish-hide-cursor '(dirvish dirvish-side))
(when (modulep! :ui tabs)
(after! centaur-tabs
(add-hook 'dired-mode-hook #'centaur-tabs-local-mode)
(add-hook 'dirvish-directory-view-mode-hook #'centaur-tabs-local-mode)))
;; TODO: Needs more polished keybinds for non-Evil users
(map! :map dirvish-mode-map
:n "?" #'dirvish-dispatch
:n "q" #'dirvish-quit
:n "b" #'dirvish-quick-access
:ng "f" #'dirvish-file-info-menu
:n "p" #'dirvish-yank
:ng "S" #'dirvish-quicksort
:n "F" #'dirvish-layout-toggle
:n "z" #'dirvish-history-jump
:n "gh" #'dirvish-subtree-up
:n "gl" #'dirvish-subtree-toggle
:n "h" #'dired-up-directory
:n "l" #'dired-find-file
:gm [left] #'dired-up-directory
:gm [right] #'dired-find-file
:m "[h" #'dirvish-history-go-backward
:m "]h" #'dirvish-history-go-forward
:m "[e" #'dirvish-emerge-next-group
:m "]e" #'dirvish-emerge-previous-group
:n "TAB" #'dirvish-subtree-toggle
:ng "M-b" #'dirvish-history-go-backward
:ng "M-f" #'dirvish-history-go-forward
:ng "M-n" #'dirvish-narrow
:ng "M-m" #'dirvish-mark-menu
:ng "M-s" #'dirvish-setup-menu
:ng "M-e" #'dirvish-emerge-menu
(:prefix ("y" . "yank")
:n "l" #'dirvish-copy-file-true-path
:n "n" #'dirvish-copy-file-name
:n "p" #'dirvish-copy-file-path
:n "r" #'dirvish-copy-remote-path
:n "y" #'dired-do-copy)
(:prefix ("s" . "symlinks")
:n "s" #'dirvish-symlink
:n "S" #'dirvish-relative-symlink
:n "h" #'dirvish-hardlink))
;; HACK: Kill Dirvish session before switching projects/workspaces, otherwise
;; it errors out on trying to delete/change dedicated windows.
(add-hook! '(persp-before-kill-functions
persp-before-switch-functions
projectile-before-switch-project-hook)
(defun +dired--cleanup-dirvish-h (&rest _)
(when-let ((dv (cl-loop for w in (window-list)
if (window-dedicated-p w)
if (with-current-buffer (window-buffer w) (dirvish-curr))
return it)))
(let (dirvish-reuse-session)
(with-selected-window (dv-root-window dv)
(dirvish-quit)))))))
(use-package! diredfl
:hook (dired-mode . diredfl-mode)
:hook (dirvish-directory-view-mode . diredfl-mode))
(use-package! dired-x
:hook (dired-mode . dired-omit-mode)
:config
(setq dired-omit-verbose nil
dired-omit-files
(concat dired-omit-files
"\\|^\\.DS_Store\\'"
"\\|^flycheck_.*"
"\\|^\\.project\\(?:ile\\)?\\'"
"\\|^\\.\\(?:svn\\|git\\)\\'"
"\\|^\\.ccls-cache\\'"
"\\|\\(?:\\.js\\)?\\.meta\\'"
"\\|\\.\\(?:elc\\|o\\|pyo\\|swp\\|class\\)\\'"))
;; Disable the prompt about whether I want to kill the Dired buffer for a
;; deleted directory. Of course I do!
(setq dired-clean-confirm-killing-deleted-buffers nil)
;; Let OS decide how to open certain files
(when-let (cmd (cond ((featurep :system 'macos) "open")
((featurep :system 'linux) "xdg-open")
((featurep :system 'windows) "start")))
(setq dired-guess-shell-alist-user
`(("\\.\\(?:docx\\|pdf\\|djvu\\|eps\\)\\'" ,cmd)
("\\.\\(?:jpe?g\\|png\\|gif\\|xpm\\)\\'" ,cmd)
("\\.\\(?:xcf\\)\\'" ,cmd)
("\\.csv\\'" ,cmd)
("\\.tex\\'" ,cmd)
("\\.\\(?:mp4\\|mkv\\|avi\\|flv\\|rm\\|rmvb\\|ogv\\)\\(?:\\.part\\)?\\'" ,cmd)
("\\.\\(?:mp3\\|flac\\)\\'" ,cmd)
("\\.html?\\'" ,cmd)
("\\.md\\'" ,cmd))))
(map! :map dired-mode-map
:localleader
"h" #'dired-omit-mode))
(use-package! dired-aux
:defer t
:config
(setq dired-create-destination-dirs 'ask
dired-vc-rename-file t))