From 3fd6384b3ba58fb786527a9a933b2e34aa24c69f Mon Sep 17 00:00:00 2001 From: Jens Luedicke Date: Mon, 19 Jan 2026 16:34:33 +0100 Subject: [PATCH] Improve startup performance and reduce resource usage - 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 --- lisp/elfeed-config.el | 36 ++++++++++++++++++++---------------- lisp/init-dired.el | 27 +++++++++++++++++++++++++-- lisp/init-project.el | 5 ++++- lisp/init-treemacs.el | 6 +++--- lisp/init-ui.el | 3 +-- lisp/init-vcs.el | 2 +- 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/lisp/elfeed-config.el b/lisp/elfeed-config.el index 9b271b1..964dad1 100644 --- a/lisp/elfeed-config.el +++ b/lisp/elfeed-config.el @@ -51,15 +51,16 @@ (lambda () (message "Feed update complete!")))) - ;; Store timer references so we can cancel them + ;; Timer references for auto-updates (started lazily on first elfeed use) (defvar elfeed-update-timer-30min nil "Timer for 30-minute elfeed updates.") - - ;; Auto-update feeds every 30 minutes in the background - ;; Delayed start to avoid impacting startup performance - (setq elfeed-update-timer-30min - (run-with-timer (* 5 60) (* 30 60) #'elfeed-update-async)) - + + (defvar elfeed-update-timer-hourly nil + "Timer for hourly elfeed updates.") + + (defvar elfeed-timers-initialized nil + "Whether elfeed auto-update timers have been started.") + ;; Custom function for fuzzy relative timestamps (defun my-elfeed-search-format-date (date) "Format DATE as a fuzzy relative time string." @@ -181,6 +182,9 @@ ;; Keybindings for elfeed (with-eval-after-load 'elfeed + ;; Start auto-update timers when elfeed is first opened (lazy initialization) + (add-hook 'elfeed-search-mode-hook #'elfeed-maybe-start-auto-updates) + ;; Disable CUA mode in elfeed buffers to allow single-key commands (add-hook 'elfeed-search-mode-hook (lambda () @@ -213,14 +217,6 @@ (rmh-elfeed-org-process rmh-elfeed-org-files rmh-elfeed-org-tree-id) (message "Elfeed feeds reloaded from org files. %d feeds loaded." (length elfeed-feeds)))) -;; Store timer reference for hourly updates -(defvar elfeed-update-timer-hourly nil - "Timer for hourly elfeed updates.") - -;; Update feeds every hour -(setq elfeed-update-timer-hourly - (run-at-time 0 (* 60 60) 'elfeed-update)) - ;; Functions to control auto-updates (defun elfeed-stop-auto-updates () "Stop all automatic elfeed feed updates." @@ -231,6 +227,7 @@ (when (timerp elfeed-update-timer-hourly) (cancel-timer elfeed-update-timer-hourly) (setq elfeed-update-timer-hourly nil)) + (setq elfeed-timers-initialized nil) (message "Elfeed auto-updates stopped.")) (defun elfeed-start-auto-updates () @@ -240,9 +237,16 @@ (setq elfeed-update-timer-30min (run-with-timer (* 5 60) (* 30 60) #'elfeed-update-async)) (setq elfeed-update-timer-hourly - (run-at-time 0 (* 60 60) 'elfeed-update)) + (run-at-time (* 5 60) (* 60 60) 'elfeed-update)) + (setq elfeed-timers-initialized t) (message "Elfeed auto-updates started.")) +(defun elfeed-maybe-start-auto-updates () + "Start auto-updates if not already initialized. +This is called when elfeed is first opened." + (unless elfeed-timers-initialized + (elfeed-start-auto-updates))) + ;; Sorting functions (defun elfeed-sort-by-date-ascending () "Sort elfeed entries by date ascending (oldest first)." diff --git a/lisp/init-dired.el b/lisp/init-dired.el index 68c2ab3..296f856 100644 --- a/lisp/init-dired.el +++ b/lisp/init-dired.el @@ -28,8 +28,13 @@ (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)) @@ -84,8 +89,26 @@ (insert line "\n"))))) (set-buffer-modified-p nil))) -;; Apply custom sorting after dired reads directory -(add-hook 'dired-after-readin-hook 'dired-sort-dotfiles-first) +(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 \ No newline at end of file diff --git a/lisp/init-project.el b/lisp/init-project.el index ccd20dd..30e8ea5 100644 --- a/lisp/init-project.el +++ b/lisp/init-project.el @@ -98,7 +98,10 @@ ;; Integration with consult if available (with-eval-after-load 'consult - (setq consult-project-function #'project-root)) + (setq consult-project-function + (lambda (_may-prompt) + (when-let ((proj (project-current))) + (project-root proj))))) ;; Keybindings - Main project map on C-x p (built-in) ;; Additional compatibility bindings for muscle memory diff --git a/lisp/init-treemacs.el b/lisp/init-treemacs.el index dfbb981..18564f5 100644 --- a/lisp/init-treemacs.el +++ b/lisp/init-treemacs.el @@ -26,7 +26,7 @@ treemacs-directory-name-transformer #'identity treemacs-display-in-side-window t treemacs-eldoc-display 'simple - treemacs-file-event-delay 2000 + treemacs-file-event-delay 5000 ; Increased from 2000 for less CPU usage treemacs-file-follow-delay 0.2 treemacs-follow-after-init t treemacs-expand-after-init t @@ -35,7 +35,7 @@ treemacs-indentation 2 treemacs-indentation-string " " treemacs-is-never-other-window nil - treemacs-max-git-entries 5000 + treemacs-max-git-entries 500 ; Reduced from 5000 for faster git status treemacs-missing-project-action 'ask treemacs-move-forward-on-expand nil treemacs-no-delete-other-windows t @@ -59,7 +59,7 @@ treemacs-workspace-switch-cleanup nil) (treemacs-follow-mode t) - (treemacs-filewatch-mode t) + (treemacs-filewatch-mode nil) ; Disabled by default - use M-x treemacs-filewatch-mode to enable (treemacs-fringe-indicator-mode 'always) (when treemacs-python-executable (treemacs-git-commit-diff-mode t)) diff --git a/lisp/init-ui.el b/lisp/init-ui.el index 7dee26d..9fb98db 100644 --- a/lisp/init-ui.el +++ b/lisp/init-ui.el @@ -156,9 +156,8 @@ (princ " M-x ensure-cua-bindings\n") (princ " M-x cua-mode (toggle off and on)\n"))) -;; Trailing whitespace +;; Trailing whitespace visualization (deletion handled in init-editor.el) (setq show-trailing-whitespace t) -(add-hook 'before-save-hook 'delete-trailing-whitespace) ;; Fill column indicator (setq-default display-fill-column-indicator-column 80) diff --git a/lisp/init-vcs.el b/lisp/init-vcs.el index b90fc0c..1d9198f 100644 --- a/lisp/init-vcs.el +++ b/lisp/init-vcs.el @@ -48,9 +48,9 @@ (setq diff-hl-flydiff-delay 0.3) ;; Make sure diff-hl updates on various events + ;; Note: find-file-hook not needed as global-diff-hl-mode handles it (add-hook 'after-save-hook 'diff-hl-update) (add-hook 'after-revert-hook 'diff-hl-update) - (add-hook 'find-file-hook 'diff-hl-update) (add-hook 'vc-checkin-hook 'diff-hl-update) ;; Enable globally with a slight delay to speed up initial startup