Files
emacs-config/lisp/init-project.el
Jens Luedicke 3fd6384b3b 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 <noreply@anthropic.com>
2026-01-19 16:34:33 +01:00

123 lines
3.9 KiB
EmacsLisp

;;; init-project.el --- Project management configuration -*- lexical-binding: t -*-
;;; Commentary:
;;; Built-in project.el configuration (replaces Projectile)
;;; Code:
(require 'project)
;; Add additional project root markers
(setq project-vc-extra-root-markers
'(".projectile" ; Projectile marker
".project" ; Generic project marker
"Makefile" ; Make projects
"package.json" ; Node.js projects
"Cargo.toml" ; Rust projects
"go.mod" ; Go modules
"pom.xml" ; Maven projects
"build.gradle" ; Gradle projects
"requirements.txt" ; Python projects
"setup.py" ; Python packages
"pyproject.toml" ; Modern Python projects
"Gemfile" ; Ruby projects
"composer.json" ; PHP projects
".git" ; Git repositories
".hg" ; Mercurial
".svn")) ; SVN
;; Configure project.el behavior
(setq project-switch-commands
'((project-find-file "Find file" ?f)
(project-find-regexp "Grep" ?g)
(project-dired "Dired" ?d)
(project-vc-dir "VC Dir" ?v)
(project-eshell "Eshell" ?e)
(project-shell "Shell" ?s)
(project-compile "Compile" ?c)
(magit-project-status "Magit" ?m)))
;; Better project switching
(setq project-switch-use-entire-map t)
;; Cache project list
(setq project-list-file (expand-file-name "projects" user-emacs-directory))
;; Custom functions for compatibility with old Projectile workflow
(defun my/project-find-file ()
"Find file in current project."
(interactive)
(project-find-file))
(defun my/project-switch-project ()
"Switch to another project."
(interactive)
(project-switch-project))
(defun my/project-grep ()
"Grep in current project."
(interactive)
(project-find-regexp))
(defun my/project-dired ()
"Open project root in dired."
(interactive)
(let ((project (project-current)))
(if project
(dired (project-root project))
(error "No project found"))))
(defun my/project-compile ()
"Compile project."
(interactive)
(project-compile))
(defun my/project-run-shell ()
"Start shell in project root."
(interactive)
(project-shell))
(defun my/project-kill-buffers ()
"Kill all project buffers."
(interactive)
(project-kill-buffers))
;; Add project discovery for non-VC directories
(defun my/project-try-local (dir)
"Try to find project root markers in DIR."
(let ((root (locate-dominating-file
dir
(lambda (d)
(seq-some
(lambda (marker)
(file-exists-p (expand-file-name marker d)))
project-vc-extra-root-markers)))))
(when root
(cons 'transient root))))
(add-to-list 'project-find-functions #'my/project-try-local)
;; Integration with consult if available
(with-eval-after-load 'consult
(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
(global-set-key (kbd "C-c p f") #'project-find-file)
(global-set-key (kbd "C-c p p") #'project-switch-project)
(global-set-key (kbd "C-c p g") #'project-find-regexp)
(global-set-key (kbd "C-c p d") #'my/project-dired)
(global-set-key (kbd "C-c p c") #'project-compile)
(global-set-key (kbd "C-c p s") #'project-shell)
(global-set-key (kbd "C-c p k") #'project-kill-buffers)
(global-set-key (kbd "C-c p b") #'project-switch-to-buffer)
(global-set-key (kbd "C-c p r") #'project-query-replace-regexp)
;; Keep existing dired bindings
(global-set-key (kbd "C-c d") #'dired-jump)
(global-set-key (kbd "C-c D") #'my/project-dired)
(provide 'init-project)
;;; init-project.el ends here