Migrate from Projectile to built-in project.el and fix Org mode

Major changes:
- Replace Projectile with built-in project.el for project management
- Add comprehensive Org mode configuration with TODO keywords and org-kanban support
- Fix multiple parsing errors and keybinding conflicts

Key improvements:
- Faster startup with built-in project.el (no external dependencies)
- Better integration with Eglot LSP client
- Proper Org TODO keyword highlighting and kanban column ordering
- Fixed unbalanced parentheses in init-completion.el and init-utils.el
- Resolved keybinding conflicts (C-c d g → C-c G d, removed C-u C-c C-r)
- Updated all file paths in init-utils.el to use lisp/ subdirectory

The configuration now loads cleanly without errors and maintains backward
compatibility with most Projectile keybindings (C-c p prefix) while also
supporting the standard project.el bindings (C-x p prefix).

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jens Luedicke
2025-09-10 17:33:34 +02:00
parent 8644b5c469
commit 634d0674b4
13 changed files with 306 additions and 110 deletions

View File

@@ -36,6 +36,7 @@
(require 'init-eglot) ; Built-in LSP client (require 'init-eglot) ; Built-in LSP client
(require 'init-eslint-fix); Fix ESLint configuration issues (require 'init-eslint-fix); Fix ESLint configuration issues
(require 'init-terminal) ; Terminal emulator configuration (require 'init-terminal) ; Terminal emulator configuration
(require 'init-org) ; Org mode configuration with TODO keywords
;;; Load optional configurations ;;; Load optional configurations

View File

@@ -15,7 +15,6 @@
consult-eglot ; Consult integration with Eglot consult-eglot ; Consult integration with Eglot
flycheck ; Can still use alongside Flymake flycheck ; Can still use alongside Flymake
yasnippet yasnippet
projectile
ggtags ggtags
multiple-cursors expand-region multiple-cursors expand-region
hl-todo rainbow-delimiters hl-todo rainbow-delimiters
@@ -92,13 +91,14 @@
:config :config
(setq flycheck-display-errors-delay 0.3))) (setq flycheck-display-errors-delay 0.3)))
(defun dev-mode-modern-setup-projectile () (defun dev-mode-modern-setup-project ()
"Configure projectile for project management." "Configure project.el for project management."
;; Already configured in init-project.el ;; Already configured in init-project.el
;; Add development-specific configurations here ;; Add development-specific configurations here
(with-eval-after-load 'projectile (with-eval-after-load 'project
(define-key projectile-command-map (kbd "t") 'projectile-test-project) ;; Add test and compile commands to project prefix
(define-key projectile-command-map (kbd "c") 'projectile-compile-project))) (define-key project-prefix-map (kbd "t") 'project-compile)
(define-key project-prefix-map (kbd "T") 'recompile)))
(defun dev-mode-modern-setup-magit () (defun dev-mode-modern-setup-magit ()
"Configure Magit for version control." "Configure Magit for version control."
@@ -181,8 +181,8 @@
(global-set-key (kbd "<f6>") 'recompile) (global-set-key (kbd "<f6>") 'recompile)
;; Testing - use C-c C-t prefix to avoid conflict with CUA copy ;; Testing - use C-c C-t prefix to avoid conflict with CUA copy
(global-set-key (kbd "C-c C-t p") 'projectile-test-project) (global-set-key (kbd "C-c C-t p") 'project-compile)
(global-set-key (kbd "C-c C-t f") 'projectile-test-file) (global-set-key (kbd "C-c C-t r") 'recompile)
;; Navigation ;; Navigation
(global-set-key (kbd "M-.") 'xref-find-definitions) (global-set-key (kbd "M-.") 'xref-find-definitions)
@@ -203,7 +203,7 @@
(dev-mode-modern-setup-completion) (dev-mode-modern-setup-completion)
(dev-mode-modern-setup-yasnippet) (dev-mode-modern-setup-yasnippet)
(dev-mode-modern-setup-flycheck) (dev-mode-modern-setup-flycheck)
(dev-mode-modern-setup-projectile) (dev-mode-modern-setup-project)
(dev-mode-modern-setup-magit) (dev-mode-modern-setup-magit)
(dev-mode-modern-setup-debugging) (dev-mode-modern-setup-debugging)
(dev-mode-modern-setup-languages) (dev-mode-modern-setup-languages)

View File

@@ -15,7 +15,6 @@
lsp-mode lsp-ui lsp-treemacs lsp-mode lsp-ui lsp-treemacs
company company-box company company-box
flycheck yasnippet flycheck yasnippet
projectile
ggtags multiple-cursors expand-region ggtags multiple-cursors expand-region
hl-todo rainbow-delimiters hl-todo rainbow-delimiters
origami ;; Code folding origami ;; Code folding
@@ -26,7 +25,7 @@
treemacs-magit treemacs-magit
;; Helm integration for development ;; Helm integration for development
helm-lsp helm-xref helm-projectile helm-lsp helm-xref
;; Languages ;; Languages
clang-format qml-mode company-qml clang-format qml-mode company-qml
@@ -114,23 +113,14 @@
:config :config
(yas-global-mode 1))) (yas-global-mode 1)))
(defun dev-mode-setup-projectile () ;; Project management is now handled by project.el in init-project.el
"Configure projectile for project management." (defun dev-mode-setup-project ()
(use-package projectile "Configure project.el for project management."
:ensure t ;; Project configuration is in init-project.el
:init ;; Add any dev-specific project configs here
(projectile-mode +1) (with-eval-after-load 'project
:bind-keymap ("C-c p" . projectile-command-map) (define-key project-prefix-map (kbd "c") 'project-compile)
:config (define-key project-prefix-map (kbd "t") 'recompile)))
(setq projectile-completion-system 'helm)
(setq projectile-switch-project-action #'projectile-dired)
(setq projectile-enable-caching t))
(use-package helm-projectile
:ensure t
:after (helm projectile)
:config
(helm-projectile-on)))
(defun dev-mode-setup-ggtags () (defun dev-mode-setup-ggtags ()
"Configure ggtags for code navigation." "Configure ggtags for code navigation."
@@ -434,7 +424,10 @@
(defun generate-cpp-tags () (defun generate-cpp-tags ()
"Generate TAGS file for C++ project." "Generate TAGS file for C++ project."
(interactive) (interactive)
(let ((project-root (or (projectile-project-root) default-directory))) (require 'project)
(let ((project-root (or (when-let ((proj (project-current)))
(project-root proj))
default-directory)))
(shell-command (shell-command
(format "cd %s && find . -name '*.cpp' -o -name '*.hpp' -o -name '*.cc' -o -name '*.hh' -o -name '*.c' -o -name '*.h' | etags -" (format "cd %s && find . -name '*.cpp' -o -name '*.hpp' -o -name '*.cc' -o -name '*.hh' -o -name '*.c' -o -name '*.h' | etags -"
project-root)) project-root))
@@ -444,7 +437,10 @@
(defun generate-python-tags () (defun generate-python-tags ()
"Generate TAGS file for Python project." "Generate TAGS file for Python project."
(interactive) (interactive)
(let ((project-root (or (projectile-project-root) default-directory))) (require 'project)
(let ((project-root (or (when-let ((proj (project-current)))
(project-root proj))
default-directory)))
(shell-command (shell-command
(format "cd %s && find . -name '*.py' | etags -" (format "cd %s && find . -name '*.py' | etags -"
project-root)) project-root))
@@ -454,7 +450,10 @@
(defun generate-all-tags () (defun generate-all-tags ()
"Generate TAGS file for both C++ and Python files." "Generate TAGS file for both C++ and Python files."
(interactive) (interactive)
(let ((project-root (or (projectile-project-root) default-directory))) (require 'project)
(let ((project-root (or (when-let ((proj (project-current)))
(project-root proj))
default-directory)))
(shell-command (shell-command
(format "cd %s && find . -name '*.cpp' -o -name '*.hpp' -o -name '*.cc' -o -name '*.hh' -o -name '*.c' -o -name '*.h' -o -name '*.py' | etags -" (format "cd %s && find . -name '*.cpp' -o -name '*.hpp' -o -name '*.cc' -o -name '*.hh' -o -name '*.c' -o -name '*.h' -o -name '*.py' | etags -"
project-root)) project-root))
@@ -524,7 +523,8 @@
(princ " C-c C-q : Quick compile and run\n") (princ " C-c C-q : Quick compile and run\n")
(princ " C-c C-c : Recompile (C++) or Send buffer to Python\n\n") (princ " C-c C-c : Recompile (C++) or Send buffer to Python\n\n")
(princ "PROJECT MANAGEMENT:\n") (princ "PROJECT MANAGEMENT:\n")
(princ " C-c p : Projectile commands prefix\n\n") (princ " C-x p : Project commands prefix\n")
(princ " C-c p : Additional project bindings (compatibility)\n\n")
(princ "VERSION CONTROL (MAGIT):\n") (princ "VERSION CONTROL (MAGIT):\n")
(princ " C-x g : Magit status\n") (princ " C-x g : Magit status\n")
(princ " C-x M-g : Magit dispatch\n") (princ " C-x M-g : Magit dispatch\n")
@@ -568,7 +568,7 @@
(dev-mode-setup-company) (dev-mode-setup-company)
(dev-mode-setup-flycheck) (dev-mode-setup-flycheck)
(dev-mode-setup-yasnippet) (dev-mode-setup-yasnippet)
(dev-mode-setup-projectile) (dev-mode-setup-project)
(dev-mode-setup-ggtags) (dev-mode-setup-ggtags)
(dev-mode-setup-origami) (dev-mode-setup-origami)
(dev-mode-setup-editing-tools) (dev-mode-setup-editing-tools)
@@ -598,7 +598,7 @@
(global-company-mode -1) (global-company-mode -1)
(global-flycheck-mode -1) (global-flycheck-mode -1)
(yas-global-mode -1) (yas-global-mode -1)
(projectile-mode -1) ;; Project.el is built-in, no need to disable
(global-hl-todo-mode -1) (global-hl-todo-mode -1)
;; Re-enable elfeed auto-updates ;; Re-enable elfeed auto-updates
(when (fboundp 'elfeed-start-auto-updates) (when (fboundp 'elfeed-start-auto-updates)

View File

@@ -122,9 +122,9 @@
(define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
;; By default `consult-project-function' uses `project-root' from project.el. ;; By default `consult-project-function' uses `project-root' from project.el.
;; Configure a different project root function. ;; No need to override - consult will use project.el by default
(autoload 'projectile-project-root "projectile") ;; (setq consult-project-function #'project-root) ; This is the default
(setq consult-project-function (lambda (_) (projectile-project-root)))) )
;;; Embark - Contextual actions ;;; Embark - Contextual actions
(use-package embark (use-package embark
@@ -212,7 +212,9 @@
(defun consult-ripgrep-project-root () (defun consult-ripgrep-project-root ()
"Search project root with ripgrep." "Search project root with ripgrep."
(interactive) (interactive)
(let ((root (or (projectile-project-root) default-directory))) (let ((root (or (when-let ((proj (project-current)))
(project-root proj))
default-directory)))
(consult-ripgrep root))) (consult-ripgrep root)))
;; Quick access to ripgrep - C-c r for backward compatibility ;; Quick access to ripgrep - C-c r for backward compatibility
@@ -220,10 +222,8 @@
;; Additional quick binding for project search ;; Additional quick binding for project search
(global-set-key (kbd "C-c /") 'consult-ripgrep-project-root) (global-set-key (kbd "C-c /") 'consult-ripgrep-project-root)
;;; Make completion work nicely with Projectile ;;; Make completion work nicely with project.el
(with-eval-after-load 'projectile ;; These are now integrated via C-x p prefix by default
(define-key projectile-command-map (kbd "b") #'consult-project-buffer)
(define-key projectile-command-map (kbd "r") #'consult-ripgrep))
(provide 'init-completion) (provide 'init-completion)
;;; init-completion.el ends here ;;; init-completion.el ends here

View File

@@ -21,7 +21,7 @@
diff-hl diff-hl
;; File management ;; File management
treemacs treemacs-projectile treemacs-all-the-icons treemacs treemacs-all-the-icons
neotree all-the-icons all-the-icons-dired diredfl neotree all-the-icons all-the-icons-dired diredfl
;; Modern completion ecosystem (replaces Helm) ;; Modern completion ecosystem (replaces Helm)
@@ -34,16 +34,13 @@
corfu ; In-buffer completion popup corfu ; In-buffer completion popup
cape ; Completion extensions for Corfu cape ; Completion extensions for Corfu
;; Core project management
projectile
;; Markdown & Notes ;; Markdown & Notes
markdown-mode markdown-toc grip-mode markdown-mode markdown-toc grip-mode
obsidian olivetti obsidian olivetti
;; Search and navigation ;; Search and navigation
deadgrep ripgrep wgrep anzu deadgrep ripgrep wgrep anzu
ibuffer-sidebar ibuffer-projectile ibuffer-sidebar
;; Required for some functionality ;; Required for some functionality
org dash s f ht spinner lv hydra avy org dash s f ht spinner lv hydra avy

View File

@@ -7,7 +7,9 @@
;; Function to check if ESLint is configured in the current project ;; Function to check if ESLint is configured in the current project
(defun project-has-eslint-config-p () (defun project-has-eslint-config-p ()
"Check if the current project has ESLint configuration." "Check if the current project has ESLint configuration."
(let ((project-root (or (projectile-project-root) (require 'project)
(let ((project-root (or (when-let ((proj (project-current)))
(project-root proj))
(locate-dominating-file default-directory ".git") (locate-dominating-file default-directory ".git")
default-directory))) default-directory)))
(or (file-exists-p (expand-file-name ".eslintrc" project-root)) (or (file-exists-p (expand-file-name ".eslintrc" project-root))
@@ -62,7 +64,9 @@
(defun create-basic-eslintrc () (defun create-basic-eslintrc ()
"Create a basic .eslintrc.json file in the project root." "Create a basic .eslintrc.json file in the project root."
(interactive) (interactive)
(let* ((project-root (or (projectile-project-root) (require 'project)
(let* ((project-root (or (when-let ((proj (project-current)))
(project-root proj))
(locate-dominating-file default-directory ".git") (locate-dominating-file default-directory ".git")
default-directory)) default-directory))
(eslintrc-path (expand-file-name ".eslintrc.json" project-root))) (eslintrc-path (expand-file-name ".eslintrc.json" project-root)))

View File

@@ -10,8 +10,7 @@
;;; Configuration reload ;;; Configuration reload
;; Default: Non-blocking reload ;; Default: Non-blocking reload
(global-set-key (kbd "C-c C-r") 'reload-emacs-config) (global-set-key (kbd "C-c C-r") 'reload-emacs-config)
;; C-u prefix: Blocking reload (old behavior) ;; Note: Use C-u C-c C-r for blocking reload (handled in the function)
(global-set-key (kbd "C-u C-c C-r") 'reload-emacs-config-blocking)
;; Quick reload for current file only ;; Quick reload for current file only
(global-set-key (kbd "C-c r") 'reload-current-file) (global-set-key (kbd "C-c r") 'reload-current-file)
;; Fast reload using byte-compiled files ;; Fast reload using byte-compiled files

81
lisp/init-org.el Normal file
View File

@@ -0,0 +1,81 @@
;;; init-org.el --- Org mode configuration -*- lexical-binding: t -*-
;;; Commentary:
;;; This file configures Org mode with custom TODO keywords and highlighting.
;;; Code:
(require 'org)
;; Configure TODO keywords with proper format
(setq org-todo-keywords
'((sequence "OPEN" "TODO" "INPROGRESS" "POSTPONED" "FEEDBACK" "|" "DONE" "CANCELLED")))
;; Configure TODO keyword faces for highlighting
(setq org-todo-keyword-faces
'(("OPEN" . (:foreground "cyan" :weight bold))
("TODO" . (:foreground "red" :weight bold))
("INPROGRESS" . (:foreground "yellow" :weight bold))
("POSTPONED" . (:foreground "orange" :weight bold))
("FEEDBACK" . (:foreground "magenta" :weight bold))
("DONE" . (:foreground "green" :weight bold))
("CANCELLED" . (:foreground "gray" :weight bold :strike-through t))))
;; Enable org-kanban if installed
(when (require 'org-kanban nil t)
;; Configure org-kanban to use our custom TODO keywords
;; The order here determines the column order in the kanban board
(setq org-kanban-todo-keywords '("OPEN" "TODO"))
(setq org-kanban-doing-keywords '("INPROGRESS"))
(setq org-kanban-blocked-keywords '("POSTPONED" "FEEDBACK"))
(setq org-kanban-done-keywords '("DONE" "CANCELLED"))
;; Set the column order explicitly
(setq org-kanban-keyword-order '("OPEN" "TODO" "INPROGRESS" "POSTPONED" "FEEDBACK" "DONE" "CANCELLED"))
;; Configure the kanban board layout
(setq org-kanban-abbreviation t) ; Use abbreviated names in headers
(setq org-kanban-column-padding 2)
;; Include subtasks in kanban board
(setq org-kanban-subtree-toggle t))
;; Set up fast TODO selection
(setq org-use-fast-todo-selection t)
;; Configure TODO dependencies
(setq org-enforce-todo-dependencies t)
;; Log when TODO items are completed
(setq org-log-done 'time)
;; Refresh org-mode files to apply new settings
(defun refresh-org-buffers ()
"Refresh all org-mode buffers to apply new TODO settings."
(interactive)
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when (eq major-mode 'org-mode)
(org-mode)
(message "Refreshed %s" (buffer-name))))))
;; Hook to ensure settings are applied
(add-hook 'org-mode-hook
(lambda ()
;; Force refresh of TODO keywords
(setq-local org-todo-keywords
'((sequence "OPEN" "TODO" "INPROGRESS" "POSTPONED" "FEEDBACK" "|" "DONE" "CANCELLED")))
;; Ensure font-lock is refreshed
(font-lock-flush)
(font-lock-ensure)))
;; Auto-update kanban boards on save
(add-hook 'before-save-hook
(lambda ()
(when (and (eq major-mode 'org-mode)
(save-excursion
(goto-char (point-min))
(re-search-forward "^#\\+BEGIN: kanban" nil t)))
(org-update-all-dblocks))))
(provide 'init-org)
;;; init-org.el ends here

View File

@@ -1,21 +1,120 @@
;;; init-project.el --- Project management configuration -*- lexical-binding: t -*- ;;; init-project.el --- Project management configuration -*- lexical-binding: t -*-
;;; Commentary: ;;; Commentary:
;;; Projectile and project management settings ;;; Built-in project.el configuration (replaces Projectile)
;;; Code: ;;; Code:
;;; Projectile - Project Management (require 'project)
(use-package projectile
:ensure t ;; Add additional project root markers
:init (setq project-vc-extra-root-markers
(projectile-mode +1) '(".projectile" ; Projectile marker
:bind-keymap ("C-c p" . projectile-command-map) ".project" ; Generic project marker
:bind (("C-c d" . dired-jump) "Makefile" ; Make projects
("C-c D" . projectile-dired)) "package.json" ; Node.js projects
:config "Cargo.toml" ; Rust projects
(setq projectile-completion-system 'default) ; Use default completion (works with Vertico) "go.mod" ; Go modules
(setq projectile-switch-project-action #'projectile-dired) "pom.xml" ; Maven projects
(setq projectile-enable-caching t)) "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 #'project-root))
;; 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) (provide 'init-project)
;;; init-project.el ends here ;;; init-project.el ends here

View File

@@ -9,7 +9,7 @@
:ensure t :ensure t
:defer t :defer t
:commands deadgrep :commands deadgrep
:bind (("C-c d g" . deadgrep))) :bind (("C-c G d" . deadgrep)))
;;; Wgrep - editable grep buffers ;;; Wgrep - editable grep buffers
(use-package wgrep (use-package wgrep
@@ -31,17 +31,23 @@
(defun search-project-for-symbol-at-point () (defun search-project-for-symbol-at-point ()
"Search project for symbol at point using consult-ripgrep." "Search project for symbol at point using consult-ripgrep."
(interactive) (interactive)
(require 'projectile) (require 'project)
(if (use-region-p) (let ((root (or (when-let ((proj (project-current)))
(consult-ripgrep (projectile-project-root) (project-root proj))
(buffer-substring-no-properties (region-beginning) (region-end))) default-directory)))
(consult-ripgrep (projectile-project-root) (thing-at-point 'symbol)))) (if (use-region-p)
(consult-ripgrep root
(buffer-substring-no-properties (region-beginning) (region-end)))
(consult-ripgrep root (thing-at-point 'symbol)))))
(defun search-project () (defun search-project ()
"Live search in project files using consult-ripgrep." "Live search in project files using consult-ripgrep."
(interactive) (interactive)
(require 'projectile) (require 'project)
(consult-ripgrep (projectile-project-root))) (let ((root (or (when-let ((proj (project-current)))
(project-root proj))
default-directory)))
(consult-ripgrep root)))
(defun search-current-directory () (defun search-current-directory ()
"Live search in current directory using consult-ripgrep." "Live search in current directory using consult-ripgrep."
@@ -69,18 +75,24 @@
(define-key search-map (kbd "p") (define-key search-map (kbd "p")
(lambda () (interactive) (lambda () (interactive)
(require 'consult) (require 'consult)
(require 'projectile) (require 'project)
(if (fboundp 'search-project) (let ((root (or (when-let ((proj (project-current)))
(call-interactively 'search-project) (project-root proj))
(consult-ripgrep (projectile-project-root))))) default-directory)))
(if (fboundp 'search-project)
(call-interactively 'search-project)
(consult-ripgrep root)))))
(define-key search-map (kbd "s") (define-key search-map (kbd "s")
(lambda () (interactive) (lambda () (interactive)
(require 'consult) (require 'consult)
(require 'projectile) (require 'project)
(if (fboundp 'search-project-for-symbol-at-point) (let ((root (or (when-let ((proj (project-current)))
(call-interactively 'search-project-for-symbol-at-point) (project-root proj))
(consult-ripgrep (projectile-project-root) (thing-at-point 'symbol))))) default-directory)))
(if (fboundp 'search-project-for-symbol-at-point)
(call-interactively 'search-project-for-symbol-at-point)
(consult-ripgrep root (thing-at-point 'symbol))))))
(define-key search-map (kbd "d") (define-key search-map (kbd "d")
(lambda () (interactive) (lambda () (interactive)
@@ -148,7 +160,9 @@
(interactive (interactive
(list (read-string "Search: " (thing-at-point 'symbol)) (list (read-string "Search: " (thing-at-point 'symbol))
(read-string "Replace: "))) (read-string "Replace: ")))
(let ((project-root (projectile-project-root))) (let ((project-root (or (when-let ((proj (project-current)))
(project-root proj))
default-directory)))
(rg search-string "*" project-root) (rg search-string "*" project-root)
(with-current-buffer "*rg*" (with-current-buffer "*rg*"
(wgrep-change-to-wgrep-mode) (wgrep-change-to-wgrep-mode)

View File

@@ -18,7 +18,7 @@
("C-c T s" . treemacs-search-file) ("C-c T s" . treemacs-search-file)
:map treemacs-mode-map :map treemacs-mode-map
("/" . treemacs-search-file) ("/" . treemacs-search-file)
("C-s" . projectile-find-file) ("C-s" . project-find-file)
("s" . consult-ripgrep)) ("s" . consult-ripgrep))
:config :config
(setq treemacs-collapse-dirs (if treemacs-python-executable 3 0) (setq treemacs-collapse-dirs (if treemacs-python-executable 3 0)
@@ -71,10 +71,8 @@
(treemacs-hide-gitignored-files-mode nil)) (treemacs-hide-gitignored-files-mode nil))
(use-package treemacs-projectile ;; treemacs-projectile is no longer needed with project.el
:ensure t ;; Treemacs has built-in support for project.el
:after (treemacs projectile)
:defer t)
(use-package treemacs-all-the-icons (use-package treemacs-all-the-icons
:ensure t :ensure t
@@ -96,8 +94,8 @@
(defun treemacs-search-file () (defun treemacs-search-file ()
"Search for a file in the current project using consult." "Search for a file in the current project using consult."
(interactive) (interactive)
(if (fboundp 'projectile-find-file) (if (fboundp 'project-find-file)
(projectile-find-file) (project-find-file)
(consult-find))) (consult-find)))
(defun treemacs-open-marked-files () (defun treemacs-open-marked-files ()

View File

@@ -18,22 +18,22 @@
(load-file (expand-file-name "init.el" user-emacs-directory)) (load-file (expand-file-name "init.el" user-emacs-directory))
;; Reload development config if it exists ;; Reload development config if it exists
(let ((dev-config (expand-file-name "emacs-dev-config.el" user-emacs-directory))) (let ((dev-config (expand-file-name "lisp/emacs-dev-config.el" user-emacs-directory)))
(when (file-exists-p dev-config) (when (file-exists-p dev-config)
(load-file dev-config))) (load-file dev-config)))
;; Reload SHR config if it exists ;; Reload SHR config if it exists
(let ((shr-config (expand-file-name "shr-config.el" user-emacs-directory))) (let ((shr-config (expand-file-name "lisp/shr-config.el" user-emacs-directory)))
(when (file-exists-p shr-config) (when (file-exists-p shr-config)
(load-file shr-config))) (load-file shr-config)))
;; Reload elfeed config if it exists ;; Reload elfeed config if it exists
(let ((elfeed-config (expand-file-name "elfeed-config.el" user-emacs-directory))) (let ((elfeed-config (expand-file-name "lisp/elfeed-config.el" user-emacs-directory)))
(when (file-exists-p elfeed-config) (when (file-exists-p elfeed-config)
(load-file elfeed-config))) (load-file elfeed-config)))
;; Reload mu4e config if it exists ;; Reload mu4e config if it exists
(let ((mu4e-config (expand-file-name "mu4e-config.el" user-emacs-directory))) (let ((mu4e-config (expand-file-name "lisp/mu4e-config.el" user-emacs-directory)))
(when (file-exists-p mu4e-config) (when (file-exists-p mu4e-config)
(condition-case err (condition-case err
(load-file mu4e-config) (load-file mu4e-config)
@@ -79,12 +79,16 @@
reload-emacs-config-files nil reload-emacs-config-files nil
reload-emacs-config-index 0)))) reload-emacs-config-index 0))))
(defun reload-emacs-config () (defun reload-emacs-config (&optional arg)
"Reload Emacs configuration non-blocking with incremental updates. "Reload Emacs configuration non-blocking with incremental updates.
This version loads configuration files one by one during idle time This version loads configuration files one by one during idle time
to prevent UI freezing." to prevent UI freezing. With prefix ARG, use blocking reload."
(interactive) (interactive "P")
;; Cancel any ongoing reload ;; If prefix arg given, use blocking reload
(if arg
(reload-emacs-config-blocking)
;; Otherwise, proceed with non-blocking reload
;; Cancel any ongoing reload
(when reload-emacs-config-timer (when reload-emacs-config-timer
(cancel-timer reload-emacs-config-timer) (cancel-timer reload-emacs-config-timer)
(setq reload-emacs-config-timer nil)) (setq reload-emacs-config-timer nil))
@@ -94,10 +98,10 @@ to prevent UI freezing."
(cl-remove-if-not (cl-remove-if-not
#'file-exists-p #'file-exists-p
(list (expand-file-name "init.el" user-emacs-directory) (list (expand-file-name "init.el" user-emacs-directory)
(expand-file-name "emacs-dev-config.el" user-emacs-directory) (expand-file-name "lisp/emacs-dev-config.el" user-emacs-directory)
(expand-file-name "shr-config.el" user-emacs-directory) (expand-file-name "lisp/shr-config.el" user-emacs-directory)
(expand-file-name "elfeed-config.el" user-emacs-directory) (expand-file-name "lisp/elfeed-config.el" user-emacs-directory)
(expand-file-name "mu4e-config.el" user-emacs-directory)))) (expand-file-name "lisp/mu4e-config.el" user-emacs-directory))))
(setq reload-emacs-config-index 0) (setq reload-emacs-config-index 0)
@@ -105,7 +109,7 @@ to prevent UI freezing."
(length reload-emacs-config-files)) (length reload-emacs-config-files))
;; Start the reload process ;; Start the reload process
(reload-emacs-config-process-next)) (reload-emacs-config-process-next)))
(defun reload-emacs-config-async () (defun reload-emacs-config-async ()
"Reload Emacs configuration asynchronously with progress feedback." "Reload Emacs configuration asynchronously with progress feedback."
@@ -125,10 +129,10 @@ to prevent UI freezing."
(cl-remove-if-not (cl-remove-if-not
#'file-exists-p #'file-exists-p
(list (list
(expand-file-name "emacs-dev-config.el" user-emacs-directory) (expand-file-name "lisp/emacs-dev-config.el" user-emacs-directory)
(expand-file-name "shr-config.el" user-emacs-directory) (expand-file-name "lisp/shr-config.el" user-emacs-directory)
(expand-file-name "elfeed-config.el" user-emacs-directory) (expand-file-name "lisp/elfeed-config.el" user-emacs-directory)
(expand-file-name "mu4e-config.el" user-emacs-directory))))) (expand-file-name "lisp/mu4e-config.el" user-emacs-directory)))))
(setq total-files (length config-files)) (setq total-files (length config-files))
(setq progress-reporter (setq progress-reporter
@@ -273,14 +277,14 @@ This is the fastest reload method but requires byte-compilation."
(defun enable-god-mode-config () (defun enable-god-mode-config ()
"Enable god-mode configuration." "Enable god-mode configuration."
(interactive) (interactive)
(let ((god-config (expand-file-name "god-mode-config.el" user-emacs-directory))) (let ((god-config (expand-file-name "lisp/god-mode-config.el" user-emacs-directory)))
(if (file-exists-p god-config) (if (file-exists-p god-config)
(condition-case err (condition-case err
(progn (progn
(load-file god-config) (load-file god-config)
(message "God-mode configuration loaded. Press ESC to toggle god-mode.")) (message "God-mode configuration loaded. Press ESC to toggle god-mode."))
(error (message "Failed to load god-mode config: %s" err))) (error (message "Failed to load god-mode config: %s" err)))
(message "God-mode config file not found at %s" god-config)))) (message "God-mode config file not found at %s" god-config)))))
(provide 'init-utils) (provide 'init-utils)
;;; init-utils.el ends here ;;; init-utils.el ends here

View File

@@ -53,10 +53,9 @@
(defun symbol-finder--get-root () (defun symbol-finder--get-root ()
"Get the root directory for symbol operations." "Get the root directory for symbol operations."
(or symbol-finder-root-directory (or symbol-finder-root-directory
(when (fboundp 'projectile-project-root)
(projectile-project-root))
(when (fboundp 'project-root) (when (fboundp 'project-root)
(car (project-roots (project-current)))) (and (project-current)
(project-root (project-current))))
default-directory)) default-directory))
(defun symbol-finder--get-cache-dir () (defun symbol-finder--get-cache-dir ()