From 1bfdf5225f5f945dae7a469e65be686a8dad9e44 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 10:26:57 +0100 Subject: [PATCH 01/12] Remove esh-autosuggest and try to fix xterm-color error --- .emacs.d/lisp/init-shell.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.emacs.d/lisp/init-shell.el b/.emacs.d/lisp/init-shell.el index f3eb3ed..a312d8c 100644 --- a/.emacs.d/lisp/init-shell.el +++ b/.emacs.d/lisp/init-shell.el @@ -16,15 +16,13 @@ :defer t :hook (eshell-mode . (lambda () (require 'eshell-z)))) -(use-package esh-autosuggest - :hook (eshell-mode . esh-autosuggest-mode)) - (use-package eshell-syntax-highlighting :after esh-mode :config (eshell-syntax-highlighting-global-mode +1)) (use-package xterm-color + :after esh-mode :hook (eshell-before-prompt . (lambda () (setq xterm-color-preserve-properties t))) From 85ed757c6240ccf4dc47eee1b705c995982b3f5c Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 10:28:23 +0100 Subject: [PATCH 02/12] Add consult-fd and fix binding --- .emacs.d/lisp/init-minibuffer.el | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index 3bdfc11..f31ed3d 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -189,15 +189,39 @@ (defun consult-line-symbol-at-point () (interactive) (consult-line (thing-at-point 'symbol))) + (defvar consult--fd-command nil) + (defun consult--fd-builder (input) + (unless consult--fd-command + (setq consult--fd-command + (if (eq 0 (call-process-shell-command "fdfind")) + "fdfind" + "fd"))) + (pcase-let* ((`(,arg . ,opts) (consult--command-split input)) + (`(,re . ,hl) (funcall consult--regexp-compiler + arg 'extended))) + (when re + (list :command (append + (list consult--fd-command + "--color=never" "--full-path" + (consult--join-regexps re 'extended)) + opts) + :highlight hl)))) + + (defun consult-fd (&optional dir initial) + (interactive "P") + (let* ((prompt-dir (consult--directory-prompt "Fd" dir)) + (default-directory (cdr prompt-dir))) + (find-file (consult--find (car prompt-dir) #'consult--fd-builder initial)))) ;; Add these here, as we have two bindings for search map (M-s and C-c s) - (define-key search-map "f" 'consult-find) - (define-key search-map "F" 'consult-locate) + (define-key search-map "f" 'consult-fd) + (define-key search-map "F" 'consult-find) + (define-key search-map (kbd "M-f") 'consult-locate) (define-key search-map "g" 'consult-grep) (define-key search-map "G" 'consult-git-grep) (define-key search-map "r" 'consult-ripgrep) (define-key search-map "R" 'consult-ripgrep-auto-preview) - (define-key search-map "M-r" 'consult-ripgrep-unrestricted) + (define-key search-map (kbd "M-r") 'consult-ripgrep-unrestricted) (define-key search-map "*" 'consult-ripgrep-symbol-at-point) (define-key search-map "z" 'consult-z-ripgrep) (define-key search-map "l" 'consult-line) From 61d2779ec3285df47ede87422a1d684ead8c88f0 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 10:29:59 +0100 Subject: [PATCH 03/12] Cleanup marginalia config --- .emacs.d/lisp/init-minibuffer.el | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index f31ed3d..051f285 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -296,18 +296,12 @@ ("C-x C-j" . consult-dir-jump-file))) (use-package marginalia - :bind (("M-A" . marginalia-cycle) - :map minibuffer-local-map - ("M-A" . marginalia-cycle)) :init (marginalia-mode) :config - ;; For Projectile - (add-to-list 'marginalia-prompt-categories '("Switch to project" . file)) - (add-to-list 'marginalia-prompt-categories '("Find file" . project-file)) - (add-to-list 'marginalia-prompt-categories '("Recently visited files" . project-file)) + ;; persp-switch-to-buffer / persp-switch-to-buffer* (add-to-list 'marginalia-prompt-categories '("Switch to buffer" . buffer)) - ;; For Crux + ;; crux-recentf-find-file (add-to-list 'marginalia-prompt-categories '("Choose recent file" . file))) (use-package embark From a58ad8889902dfb4d1d9262e619aefa96ab63837 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 10:34:46 +0100 Subject: [PATCH 04/12] Add embark preview to minibuffer --- .emacs.d/lisp/init-minibuffer.el | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index 051f285..e5c7ce6 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -312,11 +312,20 @@ ("C-." . embark-dwim) ("C-c C-o" . embark-export) ("C-h b" . embark-bindings) - ("C-h B" . describe-bindings)) + ("C-h B" . describe-bindings) + (:map minibuffer-local-map + ("M-." . embark-preview))) :init - ;; Optionally replace the key help with a completing-read interface (setq prefix-help-command #'embark-prefix-help-command) :config + ;; (define-key minibuffer-local-map (kbd "M-.") #'embark-preview) + (defun embark-preview () + (interactive) + (unless (bound-and-true-p consult--preview-function) ;; Disable preview for Consult commands + (save-selected-window + (let ((embark-quit-after-action)) + (embark-default-action))))) + ;; Hide the mode line of the Embark live/completions buffers (add-to-list 'display-buffer-alist '("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*" From 06842692d5b3f629092fe9104cff6ba62eb625d8 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 14:57:19 +0100 Subject: [PATCH 05/12] Remove most key-chords --- .emacs.d/lisp/init-clojure.el | 3 --- .emacs.d/lisp/init-crux.el | 3 --- .emacs.d/lisp/init-editor.el | 1 - .emacs.d/lisp/init-kill.el | 4 +--- .emacs.d/lisp/init-lsp.el | 5 ----- .emacs.d/lisp/init-minibuffer.el | 2 -- .emacs.d/lisp/init-navigation.el | 6 ------ .emacs.d/lisp/init-ui.el | 4 +--- 8 files changed, 2 insertions(+), 26 deletions(-) diff --git a/.emacs.d/lisp/init-clojure.el b/.emacs.d/lisp/init-clojure.el index 0f19c15..719f2ca 100644 --- a/.emacs.d/lisp/init-clojure.el +++ b/.emacs.d/lisp/init-clojure.el @@ -30,7 +30,6 @@ (use-package cider :diminish - :after key-chord :config (setq cider-repl-pop-to-buffer-on-connect 'display-only cider-repl-display-help-banner nil @@ -44,8 +43,6 @@ cider-repl-history-file "~/.emacs.d/cider-history" nrepl-log-messages t clojure-toplevel-inside-comment-form t) - (key-chord-define-global "??" 'cider-xref-fn-refs-select) - (key-chord-define-global "qq" 'cider-xref-fn-refs) (unbind-key "C-c C-l" cider-mode-map) :bind (:map cider-mode-map ("C-c M-l" . cider-load-file)) :hook diff --git a/.emacs.d/lisp/init-crux.el b/.emacs.d/lisp/init-crux.el index 93e5802..df4ade1 100644 --- a/.emacs.d/lisp/init-crux.el +++ b/.emacs.d/lisp/init-crux.el @@ -3,9 +3,6 @@ ;;; Code: (use-package crux - :after key-chord - :config - (key-chord-define-global "JJ" 'crux-switch-to-previous-buffer) :bind ("C-^" . crux-top-join-line) ("C-" . crux-kill-line-backwards) diff --git a/.emacs.d/lisp/init-editor.el b/.emacs.d/lisp/init-editor.el index d1d80cb..1946b46 100644 --- a/.emacs.d/lisp/init-editor.el +++ b/.emacs.d/lisp/init-editor.el @@ -150,7 +150,6 @@ and file 'filename' will be opened and cursor set on line 'linenumber'" (use-package undo-tree :diminish - :after key-chord :config (global-undo-tree-mode) :custom diff --git a/.emacs.d/lisp/init-kill.el b/.emacs.d/lisp/init-kill.el index ceada0d..2cc5ac7 100644 --- a/.emacs.d/lisp/init-kill.el +++ b/.emacs.d/lisp/init-kill.el @@ -4,10 +4,8 @@ ;;; Code: (use-package browse-kill-ring - :after key-chord :config - (browse-kill-ring-default-keybindings) - (key-chord-define-global "yy" 'browse-kill-ring)) + (browse-kill-ring-default-keybindings)) (use-package easy-kill :bind diff --git a/.emacs.d/lisp/init-lsp.el b/.emacs.d/lisp/init-lsp.el index 4b72759..ea4a850 100644 --- a/.emacs.d/lisp/init-lsp.el +++ b/.emacs.d/lisp/init-lsp.el @@ -8,7 +8,6 @@ (use-package lsp-mode :diminish - :after key-chord :hook (clojure-mode . lsp) :config (if (eq system-type 'darwin) @@ -34,10 +33,6 @@ ;; user cider for indendation and completion instead lsp-enable-indentation nil lsp-completion-enable nil) - (key-chord-define-global "QQ" 'lsp-find-references) - (key-chord-define-global "PP" 'lsp-peek-find-references) - (key-chord-define-global "GG" 'lsp-find-definition) - (key-chord-define-global "DD" 'lsp-peek-find-definitions) :bind (:map lsp-ui-mode-map ([remap xref-find-definitions] . lsp-ui-peek-find-definitions) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index e5c7ce6..f9d54e8 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -52,8 +52,6 @@ (select-window (minibuffer-selected-window)) (select-window (active-minibuffer-window)))) - (key-chord-define-global "XX" 'to-and-fro-minibuffer) - ;(key-chord-define-global ">>" 'preview-from-outside) :bind (("C-M-<" . up-from-outside) ("C-M->" . down-from-outside) ("C-M-+" . preview-from-outside) diff --git a/.emacs.d/lisp/init-navigation.el b/.emacs.d/lisp/init-navigation.el index e483637..082a64d 100644 --- a/.emacs.d/lisp/init-navigation.el +++ b/.emacs.d/lisp/init-navigation.el @@ -42,15 +42,9 @@ ;; TODO - which of these are useful? (use-package avy - :after key-chord :custom (avy-background t) (avy-style 'pre) - :config - (key-chord-define-global "LL" 'avy-goto-line) - (key-chord-define-global ",," 'avy-goto-char-in-line) - (key-chord-define-global "jj" 'avy-goto-word-1) - (key-chord-define-global "jk" 'avy-goto-char) :bind ("C-:" . avy-goto-char) ("C-'" . avy-goto-char-2) diff --git a/.emacs.d/lisp/init-ui.el b/.emacs.d/lisp/init-ui.el index f32e50b..c11bed4 100644 --- a/.emacs.d/lisp/init-ui.el +++ b/.emacs.d/lisp/init-ui.el @@ -92,11 +92,9 @@ :diminish :config (which-key-mode +1)) -;; Other key-chords defined with in the relevant use-package calls (use-package key-chord :config - (key-chord-mode +1) - (key-chord-define-global "xx" 'execute-extended-command)) + (key-chord-mode +1)) (use-package rainbow-delimiters :config From 56338465abfca9338c356b511bb66773977d1543 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 14:57:56 +0100 Subject: [PATCH 06/12] Turn on lsp lens and headerline breadcrumb --- .emacs.d/lisp/init-lsp.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.emacs.d/lisp/init-lsp.el b/.emacs.d/lisp/init-lsp.el index ea4a850..e66eb24 100644 --- a/.emacs.d/lisp/init-lsp.el +++ b/.emacs.d/lisp/init-lsp.el @@ -6,6 +6,8 @@ :config (require 'lsp-ui-imenu)) +(use-package lsp-treemacs) + (use-package lsp-mode :diminish :hook (clojure-mode . lsp) @@ -18,11 +20,12 @@ lsp-ui-peek-enable t lsp-ui-peek-always-show t lsp-ui-doc-delay 1 - lsp-lens-enable nil + lsp-lens-enable t lsp-ui-doc-enable t lsp-ui-doc-show-with-cursor t lsp-ui-doc-show-with-mouse t - lsp-headerline-breadcrumb-enable nil + lsp-headerline-breadcrumb-enable t + lsp-headerline-breadcrumb-enable-diagnostics nil lsp-enable-symbol-highlighting t lsp-ui-sideline-show-diagnostics t lsp-ui-sideline-show-code-actions nil @@ -38,7 +41,5 @@ ([remap xref-find-definitions] . lsp-ui-peek-find-definitions) ([remap xref-find-references] . lsp-ui-peek-find-references))) -(use-package lsp-treemacs) - (provide 'init-lsp) ;;; init-lsp.el ends here From 8b03b38ba6036ec069e99c46539edb9e14c4e2c9 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 14:58:43 +0100 Subject: [PATCH 07/12] Remove second embark-dwim binding for now --- .emacs.d/lisp/init-minibuffer.el | 2 -- 1 file changed, 2 deletions(-) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index f9d54e8..0e05026 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -305,8 +305,6 @@ (use-package embark :bind (("C-," . embark-act) - ;; CIDER will override M-. so have two bindings for this - ("M-." . embark-dwim) ("C-." . embark-dwim) ("C-c C-o" . embark-export) ("C-h b" . embark-bindings) From 46b8a3c0f84b796c94e323dbb5a1d8e292c4f662 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 14:59:57 +0100 Subject: [PATCH 08/12] Change isearch-yank-on-move to shift --- .emacs.d/lisp/init-search.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.emacs.d/lisp/init-search.el b/.emacs.d/lisp/init-search.el index c9a8305..be4de3c 100644 --- a/.emacs.d/lisp/init-search.el +++ b/.emacs.d/lisp/init-search.el @@ -8,9 +8,7 @@ (search-whitespace-regexp ".*\\b") (isearch-lax-whitespace t) (isearch-allow-scroll t) - ;; TODO - ;; (isearch-yank-on-move 'shift) - (isearch-yank-on-move t) + (isearch-yank-on-move 'shift) :bind-keymap ("C-c s" . search-map) ;; M-s clashes with paredit/smartparens bindings :bind ("C-*" . isearch-forward-symbol-at-point) From c8f0dadf53af99df0292398966a79c1600efe5d1 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 16:17:23 +0100 Subject: [PATCH 09/12] Remove unnecessary marginalia config --- .emacs.d/lisp/init-minibuffer.el | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index 0e05026..31a9268 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -289,18 +289,13 @@ (use-package consult-dir :ensure t :bind (("C-x C-d" . consult-dir) - :map vertico-map ;minibuffer-local-completion-map + :map vertico-map ("C-x C-d" . consult-dir) ("C-x C-j" . consult-dir-jump-file))) (use-package marginalia :init - (marginalia-mode) - :config - ;; persp-switch-to-buffer / persp-switch-to-buffer* - (add-to-list 'marginalia-prompt-categories '("Switch to buffer" . buffer)) - ;; crux-recentf-find-file - (add-to-list 'marginalia-prompt-categories '("Choose recent file" . file))) + (marginalia-mode)) (use-package embark :bind From afa8c2eab048db294dccec4ad6113ce8977d4bb2 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 16:23:45 +0100 Subject: [PATCH 10/12] Turn on isearch count display --- .emacs.d/lisp/init-search.el | 1 + 1 file changed, 1 insertion(+) diff --git a/.emacs.d/lisp/init-search.el b/.emacs.d/lisp/init-search.el index be4de3c..f9c8c31 100644 --- a/.emacs.d/lisp/init-search.el +++ b/.emacs.d/lisp/init-search.el @@ -9,6 +9,7 @@ (isearch-lax-whitespace t) (isearch-allow-scroll t) (isearch-yank-on-move 'shift) + (isearch-lazy-count t) :bind-keymap ("C-c s" . search-map) ;; M-s clashes with paredit/smartparens bindings :bind ("C-*" . isearch-forward-symbol-at-point) From 6d6aac358f7a5c2865824ff5317e6be7ccceeaa7 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 16:28:44 +0100 Subject: [PATCH 11/12] Switch from projectile to project.el --- .emacs.d/lisp/init-dashboard.el | 4 +- .emacs.d/lisp/init-minibuffer.el | 75 ++++++++++++++++++++++++++++---- .emacs.d/lisp/init-project.el | 60 +++++++++++++++++++++++++ .emacs.d/lisp/init-shell.el | 1 + 4 files changed, 129 insertions(+), 11 deletions(-) create mode 100644 .emacs.d/lisp/init-project.el diff --git a/.emacs.d/lisp/init-dashboard.el b/.emacs.d/lisp/init-dashboard.el index 30285a5..63cacc6 100644 --- a/.emacs.d/lisp/init-dashboard.el +++ b/.emacs.d/lisp/init-dashboard.el @@ -8,8 +8,8 @@ dashboard-startup-banner 'logo dashboard-set-footer nil dashboard-week-agenda t - dashboard-projects-backend 'projectile - dashboard-projects-switch-function 'projectile-persp-switch-project + dashboard-projects-backend 'project-el + dashboard-projects-switch-function 'switch-project dashboard-items '((recents . 15) (bookmarks . 5) (projects . 5) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index 31a9268..f1d81a4 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -64,7 +64,7 @@ :init (defvar switching-project nil) (defun vertico-directory-enter-or-switch-project () - "Wrapper around vertico-directory-enter that plays nicely with Projectile." + "Wrapper around vertico-directory-enter that plays nicely with adding projects." (interactive) (if switching-project (vertico-exit) @@ -72,7 +72,7 @@ (defun read-project (orig &rest args) (let ((switching-project t)) (apply orig args))) - (advice-add 'projectile-completing-read :around + (advice-add 'project-prompt-project-dir :around 'read-project) :config (defun vertico-directory-slash () @@ -104,7 +104,6 @@ :bind ("M-P" . vertico-repeat)) (use-package consult - :after projectile :bind (;; C-c bindings (mode-specific-map) ("C-c h" . consult-history) ("C-c m" . consult-mode-command) @@ -253,20 +252,78 @@ ;; You may want to use `embark-prefix-help-command' or which-key instead. ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) - (autoload 'projectile-project-root "projectile") - (setq consult-project-root-function #'projectile-project-root) + (setq consult-project-root-function + (lambda () + (when-let (project (project-current)) + (car (project-roots project))))) + + ;; Switch perspective when switching buffer if needed + (setq consult--display-buffer #'persp-switch-to-buffer) (defvar consult-initial-narrow-config - '((consult-buffer . ?p) - (consult-buffer-no-preview . ?p))) + '((consult-buffer . ?x) + (consult-buffer-no-preview . ?x))) ;; Add initial narrowing hook (defun consult-initial-narrow () (when-let (key (alist-get this-command consult-initial-narrow-config)) (setq unread-command-events (append unread-command-events (list key 32))))) (add-hook 'minibuffer-setup-hook #'consult-initial-narrow) - (when (and (eq system-type 'darwin) (string-match-p "^find" consult-find-command)) - (setq consult-find-command (concat "g" consult-find-command))) + (when (and (eq system-type 'darwin) (string-match-p "^find" consult-find-args)) + (setq consult-find-args (concat "g" consult-find-args))) + + ;; Use fd that that we aren't just getting recentf, but also respect .gitignore + (setq consult--source-project-file + (plist-put consult--source-project-file + :items '(lambda () + (let* ((root (consult--project-root)) + (len (length root)) + (inv-root (propertize root 'invisible t))) + (mapcar (lambda (x) + (concat inv-root (substring x len))) + (split-string + (shell-command-to-string + (format "fd --color never -t f -0 . %s" root)) + "\0" t)))))) + + (defvar consult--source-perspective-buffer + `(:name "Perspective Buffer" + :narrow (?x . "Perspective") + :hidden t + :category buffer + :face consult-buffer + :history buffer-name-history + :state ,#'consult--buffer-state + :enabled ,(lambda () persp-mode) + :items + ,(lambda () + (consult--buffer-query :sort 'visibility + :predicate #'persp-is-current-buffer + :as #'buffer-name))) + "Perspective buffer candidate source for `consult-buffer'.") + (add-to-list 'consult-buffer-sources 'consult--source-perspective-buffer t) + + ;; Copy of consult--source-project-file to use with perspective narrowing (identical except for narrowing key) + (defvar consult--source-perspective-files + (plist-put (copy-sequence consult--source-project-file) :narrow '(?x "Project Files"))) + (add-to-list 'consult-buffer-sources 'consult--source-perspective-files t) + + ;; Versions of consult--source-project-buffer and consult--source-project-file for use by consult-project-buffer + ;; They allow narrowing with b and f (instead of p) + (defvar consult--project-source-project-buffer + (plist-put (plist-put (copy-sequence consult--source-project-buffer) + :hidden nil) + :narrow '(?b . "Project Buffer"))) + (defvar consult--project-source-project-file + (plist-put (plist-put (copy-sequence consult--source-project-file) + :hidden nil) + :narrow '(?f . "Project File"))) + + (defun consult-project-buffer () + (interactive) + (let ((consult-buffer-sources '(consult--project-source-project-buffer + consult--project-source-project-file))) + (consult-buffer))) (defun consult--orderless-regexp-compiler (input type) (setq input (orderless-pattern-compiler input)) diff --git a/.emacs.d/lisp/init-project.el b/.emacs.d/lisp/init-project.el new file mode 100644 index 0000000..63aec7d --- /dev/null +++ b/.emacs.d/lisp/init-project.el @@ -0,0 +1,60 @@ +;;; init-project.el --- Project (and Perspective) Configuration File -*- lexical-binding: t -*- +;;; Commentary: +;;; Code: + +(use-package project + :ensure nil + :config + (defun project-recentf () + "Show a list of recently visited files in a project." + (interactive) + (if (boundp 'recentf-list) + (let* ((project-root (expand-file-name (project-root (project-current)))) + (project-recentf-files (mapcar + (lambda (f) (file-relative-name f project-root)) + (seq-filter (apply-partially 'string-prefix-p project-root) recentf-list)))) + (find-file (expand-file-name + (funcall project-read-file-name-function + "Find recent project files" + project-recentf-files nil 'file-name-history nil) + project-root))) + (message "recentf is not enabled"))) + + (add-to-list 'project-switch-commands '(?h "Recentf" project-recentf) t) + (add-to-list 'project-switch-commands '(?b "Consult Project Buffer" consult-project-buffer) t) + (add-to-list 'project-switch-commands '(?r "Consult Ripgrep" consult-ripgrep) t) + (add-to-list 'project-switch-commands '(?m "Magit" magit-status) t) + (add-to-list 'project-switch-commands '(?R "Replace Regexp" project-query-replace-regexp) t) + + ;; project-root and project-try-local copied/modified from https://github.com/karthink/project-x/blob/master/project-x.el + (cl-defmethod project-root ((project (head local))) + "Return root directory of current PROJECT." + (cdr project)) + (defun project-try-local (dir) + "Treat DIR as a project if it contains a .project file." + (if-let ((root (locate-dominating-file dir ".project"))) + (cons 'local root))) + ;; Add this hook last so so that vc takes precedence over local + (add-hook 'project-find-functions 'project-try-local 90) + :bind + ("C-x p P" . project-switch-project) + ("C-x f" . project-recentf)) + +(use-package perspective + :config (persp-mode) + (defun switch-project (proj) + "Switch to project or already open project perspective." + (interactive (list (project-prompt-project-dir))) + (let* ((persp-name (file-name-nondirectory (directory-file-name proj))) + (persp (gethash persp-name (perspectives-hash)))) + (unless (equal persp (persp-curr)) + ;; Create or switch to a perspective named after the project + (persp-switch persp-name) + ;; If the perspective did not exist, switch to the project + (when (not persp) + (project-switch-project proj))))) + :bind + ("C-x p p" . switch-project)) + +(provide 'init-project) +;;; init-project.el ends here diff --git a/.emacs.d/lisp/init-shell.el b/.emacs.d/lisp/init-shell.el index a312d8c..651ad61 100644 --- a/.emacs.d/lisp/init-shell.el +++ b/.emacs.d/lisp/init-shell.el @@ -33,6 +33,7 @@ (use-package multi-vterm :bind (("C-c t" . multi-vterm-next) + ("C-x p t" . multi-vterm-project) ("C-c C-M-t" . multi-vterm) (:map vterm-mode-map ("M-[" . multi-vterm-prev) From 1c9f64d02cc34312dfb0c27cbfdba4082cde9e25 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 1 Sep 2021 16:28:44 +0100 Subject: [PATCH 12/12] Switch from projectile to project.el --- .emacs.d/init.el | 2 +- .emacs.d/lisp/init-dashboard.el | 4 +- .emacs.d/lisp/init-minibuffer.el | 75 ++++++++++++++++++++++++++++---- .emacs.d/lisp/init-project.el | 60 +++++++++++++++++++++++++ .emacs.d/lisp/init-projectile.el | 61 -------------------------- .emacs.d/lisp/init-shell.el | 1 + 6 files changed, 130 insertions(+), 73 deletions(-) create mode 100644 .emacs.d/lisp/init-project.el delete mode 100644 .emacs.d/lisp/init-projectile.el diff --git a/.emacs.d/init.el b/.emacs.d/init.el index d8ec119..cb4aceb 100644 --- a/.emacs.d/init.el +++ b/.emacs.d/init.el @@ -26,7 +26,7 @@ (require 'init-search) (require 'init-navigation) (require 'init-windows) -(require 'init-projectile) +(require 'init-project) (require 'init-modeline) (require 'init-dashboard) (require 'init-completion) diff --git a/.emacs.d/lisp/init-dashboard.el b/.emacs.d/lisp/init-dashboard.el index 30285a5..63cacc6 100644 --- a/.emacs.d/lisp/init-dashboard.el +++ b/.emacs.d/lisp/init-dashboard.el @@ -8,8 +8,8 @@ dashboard-startup-banner 'logo dashboard-set-footer nil dashboard-week-agenda t - dashboard-projects-backend 'projectile - dashboard-projects-switch-function 'projectile-persp-switch-project + dashboard-projects-backend 'project-el + dashboard-projects-switch-function 'switch-project dashboard-items '((recents . 15) (bookmarks . 5) (projects . 5) diff --git a/.emacs.d/lisp/init-minibuffer.el b/.emacs.d/lisp/init-minibuffer.el index 31a9268..f1d81a4 100644 --- a/.emacs.d/lisp/init-minibuffer.el +++ b/.emacs.d/lisp/init-minibuffer.el @@ -64,7 +64,7 @@ :init (defvar switching-project nil) (defun vertico-directory-enter-or-switch-project () - "Wrapper around vertico-directory-enter that plays nicely with Projectile." + "Wrapper around vertico-directory-enter that plays nicely with adding projects." (interactive) (if switching-project (vertico-exit) @@ -72,7 +72,7 @@ (defun read-project (orig &rest args) (let ((switching-project t)) (apply orig args))) - (advice-add 'projectile-completing-read :around + (advice-add 'project-prompt-project-dir :around 'read-project) :config (defun vertico-directory-slash () @@ -104,7 +104,6 @@ :bind ("M-P" . vertico-repeat)) (use-package consult - :after projectile :bind (;; C-c bindings (mode-specific-map) ("C-c h" . consult-history) ("C-c m" . consult-mode-command) @@ -253,20 +252,78 @@ ;; You may want to use `embark-prefix-help-command' or which-key instead. ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) - (autoload 'projectile-project-root "projectile") - (setq consult-project-root-function #'projectile-project-root) + (setq consult-project-root-function + (lambda () + (when-let (project (project-current)) + (car (project-roots project))))) + + ;; Switch perspective when switching buffer if needed + (setq consult--display-buffer #'persp-switch-to-buffer) (defvar consult-initial-narrow-config - '((consult-buffer . ?p) - (consult-buffer-no-preview . ?p))) + '((consult-buffer . ?x) + (consult-buffer-no-preview . ?x))) ;; Add initial narrowing hook (defun consult-initial-narrow () (when-let (key (alist-get this-command consult-initial-narrow-config)) (setq unread-command-events (append unread-command-events (list key 32))))) (add-hook 'minibuffer-setup-hook #'consult-initial-narrow) - (when (and (eq system-type 'darwin) (string-match-p "^find" consult-find-command)) - (setq consult-find-command (concat "g" consult-find-command))) + (when (and (eq system-type 'darwin) (string-match-p "^find" consult-find-args)) + (setq consult-find-args (concat "g" consult-find-args))) + + ;; Use fd that that we aren't just getting recentf, but also respect .gitignore + (setq consult--source-project-file + (plist-put consult--source-project-file + :items '(lambda () + (let* ((root (consult--project-root)) + (len (length root)) + (inv-root (propertize root 'invisible t))) + (mapcar (lambda (x) + (concat inv-root (substring x len))) + (split-string + (shell-command-to-string + (format "fd --color never -t f -0 . %s" root)) + "\0" t)))))) + + (defvar consult--source-perspective-buffer + `(:name "Perspective Buffer" + :narrow (?x . "Perspective") + :hidden t + :category buffer + :face consult-buffer + :history buffer-name-history + :state ,#'consult--buffer-state + :enabled ,(lambda () persp-mode) + :items + ,(lambda () + (consult--buffer-query :sort 'visibility + :predicate #'persp-is-current-buffer + :as #'buffer-name))) + "Perspective buffer candidate source for `consult-buffer'.") + (add-to-list 'consult-buffer-sources 'consult--source-perspective-buffer t) + + ;; Copy of consult--source-project-file to use with perspective narrowing (identical except for narrowing key) + (defvar consult--source-perspective-files + (plist-put (copy-sequence consult--source-project-file) :narrow '(?x "Project Files"))) + (add-to-list 'consult-buffer-sources 'consult--source-perspective-files t) + + ;; Versions of consult--source-project-buffer and consult--source-project-file for use by consult-project-buffer + ;; They allow narrowing with b and f (instead of p) + (defvar consult--project-source-project-buffer + (plist-put (plist-put (copy-sequence consult--source-project-buffer) + :hidden nil) + :narrow '(?b . "Project Buffer"))) + (defvar consult--project-source-project-file + (plist-put (plist-put (copy-sequence consult--source-project-file) + :hidden nil) + :narrow '(?f . "Project File"))) + + (defun consult-project-buffer () + (interactive) + (let ((consult-buffer-sources '(consult--project-source-project-buffer + consult--project-source-project-file))) + (consult-buffer))) (defun consult--orderless-regexp-compiler (input type) (setq input (orderless-pattern-compiler input)) diff --git a/.emacs.d/lisp/init-project.el b/.emacs.d/lisp/init-project.el new file mode 100644 index 0000000..63aec7d --- /dev/null +++ b/.emacs.d/lisp/init-project.el @@ -0,0 +1,60 @@ +;;; init-project.el --- Project (and Perspective) Configuration File -*- lexical-binding: t -*- +;;; Commentary: +;;; Code: + +(use-package project + :ensure nil + :config + (defun project-recentf () + "Show a list of recently visited files in a project." + (interactive) + (if (boundp 'recentf-list) + (let* ((project-root (expand-file-name (project-root (project-current)))) + (project-recentf-files (mapcar + (lambda (f) (file-relative-name f project-root)) + (seq-filter (apply-partially 'string-prefix-p project-root) recentf-list)))) + (find-file (expand-file-name + (funcall project-read-file-name-function + "Find recent project files" + project-recentf-files nil 'file-name-history nil) + project-root))) + (message "recentf is not enabled"))) + + (add-to-list 'project-switch-commands '(?h "Recentf" project-recentf) t) + (add-to-list 'project-switch-commands '(?b "Consult Project Buffer" consult-project-buffer) t) + (add-to-list 'project-switch-commands '(?r "Consult Ripgrep" consult-ripgrep) t) + (add-to-list 'project-switch-commands '(?m "Magit" magit-status) t) + (add-to-list 'project-switch-commands '(?R "Replace Regexp" project-query-replace-regexp) t) + + ;; project-root and project-try-local copied/modified from https://github.com/karthink/project-x/blob/master/project-x.el + (cl-defmethod project-root ((project (head local))) + "Return root directory of current PROJECT." + (cdr project)) + (defun project-try-local (dir) + "Treat DIR as a project if it contains a .project file." + (if-let ((root (locate-dominating-file dir ".project"))) + (cons 'local root))) + ;; Add this hook last so so that vc takes precedence over local + (add-hook 'project-find-functions 'project-try-local 90) + :bind + ("C-x p P" . project-switch-project) + ("C-x f" . project-recentf)) + +(use-package perspective + :config (persp-mode) + (defun switch-project (proj) + "Switch to project or already open project perspective." + (interactive (list (project-prompt-project-dir))) + (let* ((persp-name (file-name-nondirectory (directory-file-name proj))) + (persp (gethash persp-name (perspectives-hash)))) + (unless (equal persp (persp-curr)) + ;; Create or switch to a perspective named after the project + (persp-switch persp-name) + ;; If the perspective did not exist, switch to the project + (when (not persp) + (project-switch-project proj))))) + :bind + ("C-x p p" . switch-project)) + +(provide 'init-project) +;;; init-project.el ends here diff --git a/.emacs.d/lisp/init-projectile.el b/.emacs.d/lisp/init-projectile.el deleted file mode 100644 index d314c8b..0000000 --- a/.emacs.d/lisp/init-projectile.el +++ /dev/null @@ -1,61 +0,0 @@ -;;; init-projectile.el --- Projectile Configuration File -*- lexical-binding: t -*- -;;; Commentary: -;;; Code: - -(defcustom projectile-default-dir "~/src" - "Starting directory when looking for new projects." - :group 'djm - :type 'directory) - -(defcustom projectile-switch-project-command 'projectile-persp-switch-project - "Projectile switch project command." - :group 'djm - :type 'function) - -(use-package projectile - :diminish - :after smartrep - :config - (projectile-mode t) - (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map) - (def-projectile-commander-method ?b - "consult-buffer" - (progn - (setq unread-command-events (listify-key-sequence "p ")) - (consult-buffer))) - (def-projectile-commander-method ?B - "Switch to project buffer" - (projectile-switch-to-buffer)) - (def-projectile-commander-method ?r - "consult-ripgrep" - (consult-ripgrep)) - (def-projectile-commander-method ?p - "DWIM" - (cond ((> (length (projectile-project-buffer-names)) 4) (projectile-switch-to-buffer)) - ((> (length (projectile-recentf-files)) 0) (projectile-recentf)) - (t (projectile-find-file)))) - (defun projectile-open-new-project (project-root) - (interactive (list (read-directory-name "Select project directory: " (file-name-as-directory projectile-default-dir)))) - (projectile-add-known-project project-root) - (funcall projectile-switch-project-command project-root)) - (smartrep-define-key projectile-mode-map - "C-c p" '(("C-p" . projectile-previous-project-buffer) - ("C-n" . projectile-next-project-buffer))) - :bind-keymap ("C-c p" . projectile-command-map) - :bind - (:map projectile-mode-map - ("C-c p n" . projectile-open-new-project) - ("C-x f" . projectile-recentf)) - :custom - (projectile-switch-project-action 'projectile-commander) - (projectile-cache-file (expand-file-name "projectile.cache" save-dir))) - -(use-package perspective - :init (persp-mode) - :bind ("C-x C-b" . persp-ibuffer) - :custom (persp-modestring-short t)) - -(use-package persp-projectile) - -(provide 'init-projectile) -;;; init-projectile.el ends here diff --git a/.emacs.d/lisp/init-shell.el b/.emacs.d/lisp/init-shell.el index a312d8c..651ad61 100644 --- a/.emacs.d/lisp/init-shell.el +++ b/.emacs.d/lisp/init-shell.el @@ -33,6 +33,7 @@ (use-package multi-vterm :bind (("C-c t" . multi-vterm-next) + ("C-x p t" . multi-vterm-project) ("C-c C-M-t" . multi-vterm) (:map vterm-mode-map ("M-[" . multi-vterm-prev)