- Defer elfeed auto-update timers until first use (was running at startup) - Fix consult-project-function to handle nil project gracefully - Remove duplicate delete-trailing-whitespace hook - Remove redundant diff-hl find-file-hook (global-diff-hl-mode handles it) - Reduce treemacs resource usage (lower git entries, disable filewatch) - Make dired dotfiles-first sorting opt-in (C-c s to sort, C-c S to toggle) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
114 lines
4.5 KiB
EmacsLisp
114 lines
4.5 KiB
EmacsLisp
;;; init-dired.el --- Dired configuration -*- lexical-binding: t -*-
|
|
;;; Commentary:
|
|
;;; Enhanced Dired configuration for file management
|
|
|
|
;;; Code:
|
|
|
|
(use-package diredfl
|
|
:ensure t
|
|
:defer t
|
|
:hook (dired-mode . diredfl-mode))
|
|
|
|
;; Enhanced Dired configuration for multi-file operations
|
|
(use-package dired
|
|
:ensure nil
|
|
:config
|
|
(setq dired-dwim-target t) ; Guess target directory
|
|
(setq dired-recursive-copies 'always)
|
|
(setq dired-recursive-deletes 'always)
|
|
;; Use macOS-compatible ls options (no --group-directories-first)
|
|
(setq dired-listing-switches "-alh")
|
|
|
|
;; Enable multiple file marking with mouse
|
|
(define-key dired-mode-map (kbd "<mouse-2>") 'dired-find-file)
|
|
(define-key dired-mode-map (kbd "C-<mouse-1>") 'dired-mouse-mark)
|
|
|
|
;; Quick marking shortcuts
|
|
(define-key dired-mode-map (kbd "* .") 'dired-mark-extension)
|
|
(define-key dired-mode-map (kbd "* /") 'dired-mark-directories))
|
|
|
|
;; Custom sorting: directories first (dotted first), then files (dotted first)
|
|
;; This is opt-in to avoid performance overhead on every directory open
|
|
(defvar dired-sort-dotfiles-first-enabled nil
|
|
"When non-nil, automatically sort dired buffers with dotfiles first.")
|
|
|
|
(defun dired-sort-dotfiles-first ()
|
|
"Sort dired: dirs first (dots first within), then files (dots first within)."
|
|
(interactive)
|
|
(save-excursion
|
|
(let (buffer-read-only)
|
|
(goto-char (point-min))
|
|
;; Skip past the directory header
|
|
(while (and (not (eobp))
|
|
(not (looking-at "^ \\|^\\s-*$")))
|
|
(forward-line 1))
|
|
(let ((start (point))
|
|
dirs dotdirs files dotfiles special-entries)
|
|
;; Collect all entries
|
|
(while (not (eobp))
|
|
(when (looking-at "^ \\(.*\\)$")
|
|
(let* ((line (match-string 0))
|
|
(filename (ignore-errors (dired-get-filename 'no-dir t))))
|
|
(cond
|
|
;; Keep . and .. entries separate to put at top
|
|
((member filename '("." ".."))
|
|
(push line special-entries))
|
|
;; Process other entries
|
|
(filename
|
|
(let ((fullpath (ignore-errors (dired-get-filename t))))
|
|
(when fullpath
|
|
(cond
|
|
;; Dot directory
|
|
((and (file-directory-p fullpath)
|
|
(string-prefix-p "." filename))
|
|
(push line dotdirs))
|
|
;; Regular directory
|
|
((file-directory-p fullpath)
|
|
(push line dirs))
|
|
;; Dotfile
|
|
((string-prefix-p "." filename)
|
|
(push line dotfiles))
|
|
;; Regular file
|
|
(t
|
|
(push line files)))))))))
|
|
(forward-line 1))
|
|
;; Delete old content and insert sorted
|
|
(when (or special-entries dirs dotdirs files dotfiles)
|
|
(delete-region start (point-max))
|
|
(goto-char start)
|
|
;; Insert in order: . and .., dot dirs, regular dirs, dotfiles, regular files
|
|
(dolist (line (nreverse special-entries))
|
|
(insert line "\n"))
|
|
(dolist (line (sort (nreverse dotdirs) 'string<))
|
|
(insert line "\n"))
|
|
(dolist (line (sort (nreverse dirs) 'string<))
|
|
(insert line "\n"))
|
|
(dolist (line (sort (nreverse dotfiles) 'string<))
|
|
(insert line "\n"))
|
|
(dolist (line (sort (nreverse files) 'string<))
|
|
(insert line "\n")))))
|
|
(set-buffer-modified-p nil)))
|
|
|
|
(defun dired-maybe-sort-dotfiles-first ()
|
|
"Sort dired buffer if `dired-sort-dotfiles-first-enabled' is non-nil."
|
|
(when dired-sort-dotfiles-first-enabled
|
|
(dired-sort-dotfiles-first)))
|
|
|
|
(defun dired-toggle-dotfiles-first-sorting ()
|
|
"Toggle automatic dotfiles-first sorting in dired."
|
|
(interactive)
|
|
(setq dired-sort-dotfiles-first-enabled (not dired-sort-dotfiles-first-enabled))
|
|
(if dired-sort-dotfiles-first-enabled
|
|
(progn
|
|
(add-hook 'dired-after-readin-hook 'dired-maybe-sort-dotfiles-first)
|
|
(message "Dired dotfiles-first sorting enabled"))
|
|
(remove-hook 'dired-after-readin-hook 'dired-maybe-sort-dotfiles-first)
|
|
(message "Dired dotfiles-first sorting disabled")))
|
|
|
|
;; Keybinding to manually sort current buffer or toggle auto-sorting
|
|
(with-eval-after-load 'dired
|
|
(define-key dired-mode-map (kbd "C-c s") 'dired-sort-dotfiles-first)
|
|
(define-key dired-mode-map (kbd "C-c S") 'dired-toggle-dotfiles-first-sorting))
|
|
|
|
(provide 'init-dired)
|
|
;;; init-dired.el ends here |