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:
1
init.el
1
init.el
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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)))
|
||||||
|
|||||||
@@ -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
81
lisp/init-org.el
Normal 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
|
||||||
@@ -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
|
||||||
@@ -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)
|
||||||
|
(let ((root (or (when-let ((proj (project-current)))
|
||||||
|
(project-root proj))
|
||||||
|
default-directory)))
|
||||||
(if (use-region-p)
|
(if (use-region-p)
|
||||||
(consult-ripgrep (projectile-project-root)
|
(consult-ripgrep root
|
||||||
(buffer-substring-no-properties (region-beginning) (region-end)))
|
(buffer-substring-no-properties (region-beginning) (region-end)))
|
||||||
(consult-ripgrep (projectile-project-root) (thing-at-point 'symbol))))
|
(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)
|
||||||
|
(let ((root (or (when-let ((proj (project-current)))
|
||||||
|
(project-root proj))
|
||||||
|
default-directory)))
|
||||||
(if (fboundp 'search-project)
|
(if (fboundp 'search-project)
|
||||||
(call-interactively 'search-project)
|
(call-interactively 'search-project)
|
||||||
(consult-ripgrep (projectile-project-root)))))
|
(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)
|
||||||
|
(let ((root (or (when-let ((proj (project-current)))
|
||||||
|
(project-root proj))
|
||||||
|
default-directory)))
|
||||||
(if (fboundp 'search-project-for-symbol-at-point)
|
(if (fboundp 'search-project-for-symbol-at-point)
|
||||||
(call-interactively 'search-project-for-symbol-at-point)
|
(call-interactively 'search-project-for-symbol-at-point)
|
||||||
(consult-ripgrep (projectile-project-root) (thing-at-point 'symbol)))))
|
(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)
|
||||||
|
|||||||
@@ -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 ()
|
||||||
|
|||||||
@@ -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,11 +79,15 @@
|
|||||||
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")
|
||||||
|
;; If prefix arg given, use blocking reload
|
||||||
|
(if arg
|
||||||
|
(reload-emacs-config-blocking)
|
||||||
|
;; Otherwise, proceed with non-blocking reload
|
||||||
;; Cancel any ongoing 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)
|
||||||
@@ -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
|
||||||
@@ -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 ()
|
||||||
|
|||||||
Reference in New Issue
Block a user