diff --git a/.config/emacs/config.org b/.config/emacs/config.org index 7bf2372..da4e1aa 100644 --- a/.config/emacs/config.org +++ b/.config/emacs/config.org @@ -463,6 +463,31 @@ Functions that only use built-in Emacs functionality. (interactive) (org-babel-load-file (concat dot-emacs-dir "/config.org"))) +;; Reference: http://turingmachine.org/bl/2013-05-29-recursively-listing-directories-in-elisp.html +(defun dot/directory-files-recursively-depth (dir regexp include-directories maxdepth) + "Depth limited variant of the built-in `directory-files-recursively'." + (let ((result '()) + (current-directory-list (directory-files dir t))) + (dolist (path current-directory-list) + (cond + ((and (file-regular-p path) + (file-readable-p path) + (string-match regexp path)) + (setq result (cons path result))) + ((and (file-directory-p path) + (file-readable-p path) + (not (string-equal "/.." (substring path -3))) + (not (string-equal "/." (substring path -2)))) + (when (and include-directories + (string-match regexp path)) + (setq result (cons path result))) + (when (> maxdepth 1) + (setq result (append (nreverse (dot/directory-files-recursively-depth + path regexp include-directories (- maxdepth 1))) + result)))) + (t))) + (reverse result))) + (defun dot/dired-find-file () "In Dired, visit the file or directory named on this line." (interactive) @@ -1034,8 +1059,8 @@ General.el ~leader key binds. "n r r" '(org-roam-buffer-toggle :which-key "Toggle buffer") "n r s" '(org-roam-ui-mode :which-key "Toggle server") - ;; Projectile - "p" '(:keymap projectile-command-map :package projectile :which-key "projectile") + ;; Project + "p" '(:keymap project-prefix-map :which-key "project") ;; Quit "q" '(:ignore t :which-key "quit") @@ -1056,9 +1081,8 @@ General.el ~leader key binds. ;; Tabs / toggle "t" '(:ignore t :which-key "tabs/toggle") - "t b" '(centaur-tabs-group-buffer-groups :which-key "Group tabs by buffer") "t f" '(dot/toggle-fringe :which-key "Toggle fringe") - "t p" '(centaur-tabs-group-by-projectile-project :which-key "Group tabs by project") + "t g" '(centaur-tabs-switch-group :which-key "Switch tab group") "t h" '(centaur-tabs-backward-group :which-key "Tab backward group") "t j" '(centaur-tabs-select-end-tab :which-key "Tab select first") "t k" '(centaur-tabs-select-beg-tab :which-key "Tab select last") diff --git a/.config/emacs/config/development.org b/.config/emacs/config/development.org index 190e7d4..c04769d 100644 --- a/.config/emacs/config/development.org +++ b/.config/emacs/config/development.org @@ -5,7 +5,7 @@ ** Table of Contents :toc_4: - [[#company][Company]] - [[#git][Git]] - - [[#projectile][Projectile]] + - [[#project][Project]] - [[#languages][Languages]] - [[#language-server-support][Language Server Support]] - [[#debug-adapter-support][Debug Adapter Support]] @@ -107,28 +107,29 @@ GLSL integration with company requires the package: ~glslang~. (put 'magit-log-select-pick :advertised-binding [?\M-c]) (put 'magit-log-select-quit :advertised-binding [?\M-k])) #+END_SRC -** Projectile + +** Project Project manager. +[[https://michael.stapelberg.ch/posts/2021-04-02-emacs-project-override/][Adding to project.el project directory detection]]. + #+BEGIN_SRC emacs-lisp -(use-package projectile +(use-package project :defer t + :init (setq project-list-file (concat dot-cache-dir "/projects")) :config - (setq projectile-cache-file (concat dot-cache-dir "/projectile.cache")) - (setq projectile-completion-system 'default) - (setq projectile-enable-caching t) - (setq projectile-indexing-method 'hybrid) - (setq projectile-known-projects-file (concat dot-cache-dir "/projectile-bookmarks.eld")) - (setq projectile-project-search-path '("~")) - (setq projectile-sort-order 'recentf) + (defun dot/project-find (dir) + (let ((root (locate-dominating-file dir ".project"))) + (and root (cons 'vc root)))) + (add-hook 'project-find-functions #'dot/project-find) (defun dot/find-project-root () - "Return root of the project, determined by `.git/' and `.projectile', + "Return root of the project, determined by `.git/' and `.project', `default-directory' otherwise." - (let ((search-directory (projectile-project-root))) - (if search-directory - search-directory + (let ((project (project-current))) + (if project + (project-root project) default-directory))) (defun dot/find-file-in-project-root () @@ -137,7 +138,31 @@ Project manager. (let ((default-directory (dot/find-project-root))) (call-interactively 'find-file))) - (projectile-mode)) + (defun dot/project-remember-projects-under (dir maxdepth) + "Index all projects below directory DIR recursively, until MAXDEPTH." + (let ((files (mapcar 'file-name-directory + (dot/directory-files-recursively-depth + dir "\\.git$\\|\\.project$" t maxdepth)))) + (dolist (path files) + (project-remember-projects-under path)))) + + (unless (file-exists-p project-list-file) + (project-remember-projects-under "~/dotfiles") + (dot/project-remember-projects-under "~/code" 4)) + + (defun dot/project-project-name () + "Return project name." + (let ((project (project-current))) + (if project + (file-name-nondirectory (directory-file-name (project-root project))) + "-"))) + + (defun dot/project-save-project-buffers () + "Save all project buffers." + (interactive) + (let ((buffers (cl-remove-if (lambda (buffer) (not (buffer-file-name buffer))) + (project-buffers (project-current))))) + (save-some-buffers t (lambda () (member (current-buffer) buffers)))))) #+END_SRC ** Languages diff --git a/.config/emacs/config/org-mode.org b/.config/emacs/config/org-mode.org index 8fb452b..2da49a2 100644 --- a/.config/emacs/config/org-mode.org +++ b/.config/emacs/config/org-mode.org @@ -23,12 +23,12 @@ (setq tex-indent-basic 4))) :config - (with-eval-after-load 'projectile + (with-eval-after-load 'project (defun compile-latex () "Compile LaTeX project." (interactive) (let ((default-directory (dot/find-project-root))) - (projectile-save-project-buffers) + (dot/project-save-project-buffers) (shell-command "make"))))) #+END_SRC diff --git a/.config/emacs/config/selection.org b/.config/emacs/config/selection.org index 749eeea..585313e 100644 --- a/.config/emacs/config/selection.org +++ b/.config/emacs/config/selection.org @@ -40,7 +40,5 @@ (marginalia-mode)) (use-package consult - :after selectrum - :config - (setq consult-project-root-function #'dot/find-project-root)) + :after selectrum) #+END_SRC diff --git a/.config/emacs/config/ui.org b/.config/emacs/config/ui.org index 5e62232..a16e58d 100644 --- a/.config/emacs/config/ui.org +++ b/.config/emacs/config/ui.org @@ -53,17 +53,30 @@ Places buffers as tabs in a bar at the top of the frame. (setq centaur-tabs-set-modified-marker t) (setq centaur-tabs-style "slant") + (setq centaur-tabs-project-buffer-group-calc nil) (defun centaur-tabs-buffer-groups () "Organize tabs into groups by buffer." - (list - (cond - ((string-equal "*" (substring (buffer-name) 0 1)) "Emacs") - ((memq major-mode '(org-mode - emacs-lisp-mode)) "Org Mode") - ((derived-mode-p 'dired-mode) "Dired") - ((derived-mode-p 'prog-mode - 'text-mode) "Editing") - (t "User")))) + (unless centaur-tabs-project-buffer-group-calc + (set (make-local-variable 'centaur-tabs-project-buffer-group-calc) + (list + (cond + ((string-equal "*" (substring (buffer-name) 0 1)) "Emacs") + ((or (memq major-mode '(magit-process-mode + magit-status-mode + magit-diff-mode + magit-log-mode + magit-file-mode + magit-blob-mode + magit-blame-mode)) + (string= (buffer-name) "COMMIT_EDITMSG")) "Magit") + ((project-current) (dot/project-project-name)) + ((memq major-mode '(org-mode + emacs-lisp-mode)) "Org Mode") + ((derived-mode-p 'dired-mode) "Dired") + ((derived-mode-p 'prog-mode + 'text-mode) "Editing") + (t "Other"))))) + (symbol-value 'centaur-tabs-project-buffer-group-calc)) (defun centaur-tabs-hide-tab (buffer) "Hide from the tab bar by BUFFER name." @@ -137,6 +150,7 @@ Places buffers as tabs in a bar at the top of the frame. (setq dashboard-banner-logo-title "GNU Emacs master race!") (setq dashboard-center-content t) (setq dashboard-page-separator "\n\f\n") + (setq dashboard-projects-backend 'project-el) (setq dashboard-set-file-icons t) (setq dashboard-set-footer nil) (setq dashboard-set-heading-icons t) @@ -196,7 +210,7 @@ Provides Emacs with a file tree. :init ;; This needs to be in init to actually start loading the package - (with-eval-after-load 'projectile + (with-eval-after-load 'project (defun neotree-toggle-in-project-root () "Toggle Neotree in project root." (interactive) @@ -224,7 +238,7 @@ Emacs mode line replacement. (accent . (telephone-line-erc-modified-channels-segment telephone-line-process-segment telephone-line-buffer-segment)) - (nil . (telephone-line-projectile-segment)))) + (nil . (telephone-line-project-segment)))) (telephone-line-mode)) #+END_SRC