diff --git a/ha-aux-apps.org b/ha-aux-apps.org index 03db5fc..033502d 100644 --- a/ha-aux-apps.org +++ b/ha-aux-apps.org @@ -178,9 +178,9 @@ What else? (use-package empv :straight (:host github :repo "isamert/empv.el") :general (ha-leader - "a P" '(projectile-command-map :wk "project") "a p" '(empv-map :wk "play music"))) #+end_src + * Technical Artifacts :noexport: Let's =provide= a name so we can =require= this file: diff --git a/ha-config.org b/ha-config.org index 9db894d..293e4d0 100644 --- a/ha-config.org +++ b/ha-config.org @@ -273,7 +273,7 @@ The [[https://github.com/minad/marginalia][marginalia]] package gives a preview :init (setq marginalia-annotators-heavy t) :config - (add-to-list 'marginalia-command-categories '(projectile-find-file . file)) + (add-to-list 'marginalia-command-categories '(project-find-file . file)) (marginalia-mode)) #+end_src * Key Bindings @@ -549,37 +549,32 @@ Magnar Sveen's [[https://github.com/magnars/expand-region.el][expand-region]] pr * Working Layout While editing any file on disk is easy enough, I like the mental context switch associated with a full-screen window frame showing all the buffers of a /project task/ (often a direct link to a repository project, but not always). ** Projects -While I don't /need/ all the features that [[https://github.com/bbatsov/projectile][projectile]] provides, it has all the features I do need, and is easy enough to install. I am referring to the fact that I /could/ use the built-in =project.el= system (see [[https://cestlaz.github.io/post/using-emacs-79-project/][this essay]] for details on what I mean as an alternative). +Since I wasn’t using all the features that [[https://github.com/bbatsov/projectile][projectile]] provides, I have switched to the built-in =project= functions. #+begin_src emacs-lisp - (use-package projectile - :custom - (projectile-sort-order 'recentf) - (projectile-project-root-functions '(projectile-root-bottom-up)) - + (use-package emacs :config (ha-leader "p" '(:ignore t :which-key "projects") "p W" '("initialize workspace" . ha-workspace-initialize) "p n" '("new project space" . ha-project-persp) - "p !" '("run cmd in project root" . projectile-run-shell-command-in-root) - "p &" '("async cmd in project root" . projectile-run-async-shell-command-in-root) - "p a" '("add new project" . projectile-add-known-project) - "p b" '("switch to project buffer" . projectile-switch-to-buffer) - "p C" '("compile in project" . projectile-compile-project) + + "p !" '("run cmd in project root" . project-shell-command) + "p &" '("run cmd async" . project-async-shell-command) + "p a" '("add new project" . project-remember-projects-under) + "p d" '("remove known project" . project-forget-project) + "p k" '("kill project buffers" . project-kill-buffers) + "p p" '("switch project" . project-switch-project) + + "p f" '("find file" . project-find-file) + "p F" '("find file o/win" . project-find-file-other-window) + "p b" '("switch to project buffer" . project-switch-to-buffer) + + "p C" '("compile in project" . compile-project) "p c" '("recompile" . recompile) - "p d" '("remove known project" . projectile-remove-known-project) - "p E" '("edit project .dir-locals" . projectile-edit-dir-locals) - "p f" '("find file in project" . projectile-find-file) - "p g" '("configure project" . projectile-configure-project) - "p i" '("invalidate project cache" . projectile-invalidate-cache) - "p k" '("kill project buffers" . projectile-kill-buffers) - "p o" '("find other file" . projectile-find-other-file) - "p p" '("switch project" . projectile-switch-project) - "p r" '("find recent project files" . projectile-recentf) - "p R" '("run project" . projectile-run-project) - "p S" '("save project files" . projectile-save-project-buffers) - "p T" '("test project" . projectile-test-project))) + + "p e" '("project shell" . project-eshell) + "p s" '("project shell" . project-shell))) #+end_src ** Workspaces A /workspace/ (at least to me) requires a quick jump to a collection of buffer windows organized around a project or task. For this, I'm basing my work on the [[https://github.com/nex3/perspective-el][perspective.el]] project. @@ -596,7 +591,8 @@ To do this, we need a way to generate a string of the perspectives in alphabetic (format " %d: %s%s" ; Shame that the following doesn't work: num ; (propertize (number-to-string num) :foreground "#00a0") (car names) ; Nor does surrounding the number with underbars. - (if (equal (car names) (projectile-project-name)) "*" "")) + + (if (equal (car names) (persp-name (persp-curr))) "*" "")) (ha--persp-label (1+ num) (cdr names))))) (defun ha-persp-labels () @@ -713,15 +709,17 @@ Given a list of information about project-workspaces, can we create them all? (ha-project-persp root name files)))) (persp-switch "main")) #+end_src -Often, but not always, I want a perspective based on an actual Git repository, e.g. a project. Projectile keeps state of a "project" based on the current file loaded, so we /combine/ the two projects by first choosing from a list of /known projects/ and then creating a perspective based on the name. To pin the perspective to a project, we load a file from it, e.g. Like a README or something. + +Often, but not always, I want a perspective based on an actual Git repository, e.g. a project. Emacs calls these transients. #+begin_src emacs-lisp (defun ha-project-persp (project &optional name files) - "Create a new perspective, and then switch to the PROJECT using projectile. + "Create a new perspective, and then switch to the PROJECT. If NAME is not given, then figure it out based on the name of the PROJECT. If FILES aren't specified, then see if there is a README. Otherwise, pull up Dired." - (interactive (list (projectile-completing-read "Project: " projectile-known-projects))) + (interactive (list (completing-read "Project: " + (project-known-project-roots)))) (when (f-directory-p project) (unless name (setq name (f-filename project))) @@ -729,12 +727,9 @@ Often, but not always, I want a perspective based on an actual Git repository, e ;; Unclear if the following is actually necessary. (ignore-errors - (projectile-add-known-project root) - (let ((projectile-switch-project-action nil)) - (projectile-switch-project-by-name root))) + (project-remember-project root) + (project-switch-project root)) - ;; To pin a project in projectile to the perspective, we need to load a file - ;; from that project. The README will do, or at least, the dired of it. (let ((recent-files (thread-last recentf-list (--filter (s-starts-with? project it)) (-take 3))) diff --git a/ha-dashboard.org b/ha-dashboard.org index 127c586..bcb9cd0 100644 --- a/ha-dashboard.org +++ b/ha-dashboard.org @@ -142,7 +142,7 @@ The [[https://github.com/emacs-dashboard/emacs-dashboard][emacs-dashboard]] proj dashboard-startup-banner "~/other/hamacs/support/levitating-gnu.png" dashboard-center-content t dashboard-set-init-info t - dashboard-projects-switch-function 'projectile-persp-switch-project + dashboard-projects-switch-function 'project-switch-project dashboard-items '(;; (projects . 5) ;; (agenda . 5) ;; (bookmarks . 5) diff --git a/ha-eshell.org b/ha-eshell.org index 76295cf..c4843db 100644 --- a/ha-eshell.org +++ b/ha-eshell.org @@ -1501,7 +1501,7 @@ And we can run a command in an opened Eshell buffer: See `eshell--buffer-from-dir'." (interactive "sCommand to Send: ") (unless dir - (setq dir (projectile-project-root))) + (setq dir (project-root (project-current)))) (save-window-excursion (eshell-there dir) (goto-char (point-max)) @@ -1524,19 +1524,6 @@ And let’s bind it: #+begin_src emacs-lisp (bind-key "C-!" 'eshell-here) #+end_src -** Shell for a Project -This version starts =eshell= in the project’s root, using [[help:projectile-project-root][projectile-project-root]]: -#+begin_src emacs-lisp - (defun eshell-project () - "Open a new shell in the project root directory, in a smaller window." - (interactive) - (eshell-there (projectile-project-root))) -#+end_src -And we can attach this function to the =projectile= menu: -#+begin_src emacs-lisp - (ha-leader "p e" '("eshell" . eshell-project)) -#+end_src - ** Shell Over There Would be nice to be able to run an eshell session and use Tramp to connect to the remote host in one fell swoop: #+begin_src emacs-lisp diff --git a/ha-general.org b/ha-general.org index 8a4c6e4..4ad7127 100644 --- a/ha-general.org +++ b/ha-general.org @@ -224,11 +224,12 @@ While =find-file= is still my bread and butter, I like getting information abou "Copy the file path of the buffer relative to the file's project. When given ROOT, this copies the filepath relative to that." (interactive) - (if-let (filename (buffer-file-name (buffer-base-buffer))) - (message "Copied path to clipboard: %s" - (kill-new - (f-relative filename (or root (projectile-project-root filename))))) - (error "Couldn't find filename in current buffer"))) + (if-let* ((filename (buffer-file-name (buffer-base-buffer))) + (relative (f-relative filename (or nil (project-root (project-current)))))) + (progn + (kill-new relative) + (message "Copied path to clipboard: %s" relative)) + (message "Couldn't find filename in current buffer"))) #+end_src This simple function allows me to load a project-specific file in a numbered window, based on winum: @@ -239,7 +240,7 @@ This simple function allows me to load a project-specific file in a numbered win (if (windowp win) (aw-switch-to-window win) (winum-select-window-by-number win)) - (consult-projectile-find-file)) + (project-find-file)) #+end_src With these helper functions in place, I can create a leader collection for file-related functions: @@ -248,7 +249,7 @@ With these helper functions in place, I can create a leader collection for file- "f" '(:ignore t :which-key "files") "f " '(keyboard-escape-quit :which-key t) "f a" '("load any" . find-file) - "f f" '("load" . consult-projectile-find-file) + "f f" '("load" . project-find-file) "f F" '("load new window" . find-file-other-window) "f l" '("locate" . locate) "f s" '("save" . save-buffer) @@ -315,9 +316,9 @@ And the collection of useful operations: (ha-leader "b" '(:ignore t :which-key "buffers") "b " '(keyboard-escape-quit :which-key t) - "b B" '("switch" . persp-switch-to-buffer) - "b o" '("switch" . switch-to-buffer-other-window) - "b O" '("other" . projectile-switch-buffer-to-other-window) + "b B" '("switch" . project-switch-to-buffer) + "b o" '("other" . project-switch-buffer-to-other-window) + "b O" '("switch" . switch-to-buffer-other-window) "b i" '("ibuffer" . ibuffer) "b I" '("ibuffer" . ibuffer-other-window) "b k" '("persp remove" . persp-remove-buffer) @@ -343,34 +344,19 @@ And the collection of useful operations: "b 9" '("load win-9" . (lambda () (interactive) (switch-buffer-in-window 9)))) #+end_src ** Bookmarks -I like the idea of dropping returnable bookmarks, however, the built-in behavior doesn’t honor either /projects/ or /perspectives/, but I can make a =projectile=-specific filter and use that to jump to only bookmarks in the current project. Likewise, if I want to jump to /any/ bookmark, I can switch to that buffer’s perspective. +I like the idea of dropping returnable bookmarks, however, the built-in behavior doesn’t honor either /projects/ or /perspectives/, but I use [[https://codeberg.org/ideasman42/emacs-bookmark-in-project][bookmark-in-project]] package to make a =project=-specific bookmarks and use that to jump to only bookmarks in the current project. #+begin_src emacs-lisp - (defun projectile-bookmark-jump (bmark) - "Jump to the bookmark, BMARK, showing a filtered list based on current project." - (interactive (list (completing-read "Jump to Bookmark: " (projectile-bookmarks)))) - (bookmark-jump bmark)) - - (defun projectile-bookmarks () - "Return a list of bookmarks associated with the current projectile project." - (let ((bmarks (bookmark-all-names))) - (cl-remove-if-not #'projectile-bookmark-p bmarks))) - - (defun projectile-bookmark-p (bmark) - "Use as a filter to compare bookmark, BMARK with current project." - (let ((bmark-path (expand-file-name (bookmark-location bmark)))) - (string-prefix-p (projectile-project-root) bmark-path))) - - (defun persp-bookmark-jump (bmark) - "Jump to bookmkar, BMARK, but switch to its perspective first." - (interactive (list (completing-read "Jump to Bookmark:" (bookmark-all-names)))) - (bookmark-jump bmark 'persp-switch-to-buffer)) - - (ha-leader - "b m" '("set bookmark" . bookmark-set) - "b g" '("goto proj bookmark" . projectile-bookmark-jump) - "b G" '("goto any bookmark" . persp-bookmark-jump) - "b M" '("delete mark" . bookmark-delete)) + (use-package bookmark-in-project + :config + (ha-leader + ;; Set or delete a bookmark associated with project: + "b m" '("set proj mark" . bookmark-in-project-toggle) + "b M" '("set global mark" . bookmark-set) + "b X" '("delete mark" . bookmark-delete) + "b g" '("goto proj mark" . bookmark-in-project-jump) + "b " '("next mark" . bookmark-in-project-jump-next) + "b " '("next mark" . bookmark-in-project-jump-previous))) #+end_src ** Toggle Switches The goal here is toggle switches and other miscellaneous settings. @@ -511,7 +497,7 @@ I’d like to have dirvish show in Window 0: (interactive) (if (seq-contains (winum--available-numbers) 0) (winum-select-window-0-or-10) - (dirvish-side (projectile-project-root)))) + (dirvish-side (project-root (project-current))))) #+end_src And let’s bind Command-0 to select the window that shows dirvish, or open drvish: @@ -607,9 +593,9 @@ And when creating new windows, why isn't the new window selected? Also, when I c (:below (split-window-vertically) (other-window 1))) (pcase file-or-buffer - (:file (call-interactively 'consult-projectile-find-file)) - (:buffer (call-interactively 'consult-projectile-switch-to-buffer)) - (:term (ha-shell (projectile-project-root))))) + (:file (call-interactively 'project-find-file)) + (:buffer (call-interactively 'project-switch-to-buffer)) + (:term (ha-shell (project-root (project-current)))))) #+end_src Shame that hydra doesn’t have an /ignore-case/ feature. @@ -675,7 +661,7 @@ Install the [[https://github.com/dajva/rg.el][rg]] package, which builds on the "s r" '("dwim" . rg-dwim) "s s" '("search" . rg) "s S" '("literal" . rg-literal) - "s p" '("project" . rg-project) ; or projectile-ripgrep + "s p" '("project" . rg-project) "s d" '("directory" . rg-dwim-project-dir) "s f" '("file only" . rg-dwim-current-file) "s j" '("next results" . ha-rg-go-next-results) @@ -825,21 +811,6 @@ The [[https://github.com/minad/consult][consult project]] aims to use libraries "gp" '("preview paste" . 'consult-yank-pop) "gs" '("go to line" . 'consult-line))) #+end_src -** Consult for Projects -One of the reasons that Consult hasn’t been too important to me, is that I often narrow my searching based on projectile. The [[https://gitlab.com/OlMon/consult-projectile][consult-projectile]] can help with this. -#+begin_src emacs-lisp - (use-package consult-projectile - :after (consult general projectile) - :straight (:host gitlab :repo "OlMon/consult-projectile" :branch "master") - :config - (ha-leader - "p ." '("switch to..." . consult-projectile) - "b b" '("switch buffer" . consult-projectile-switch-to-buffer) - "p p" '("switch project" . consult-projectile-switch-project) - "p f" '("find file" . consult-projectile-find-file) - "p r" '("find recent file" . consult-projectile-recentf))) -#+end_src -The advantage of [[help:persp-switch-to-buffer][persp-switch-to-buffer]] over =consult-projectile-switch-to-buffer= is that is shows non-file buffers. ** Embark The [[https://github.com/oantolin/embark/][embark]] project offers /actions/ on /targets/. I'm primarily thinking of acting on selected items in the minibuffer, but these commands act anywhere. I need an easy-to-use keybinding that doesn't conflict. Hey, that is what the Super key is for, right? #+begin_src emacs-lisp diff --git a/ha-org-clipboard.org b/ha-org-clipboard.org index 430cea3..7ca01f9 100644 --- a/ha-org-clipboard.org +++ b/ha-org-clipboard.org @@ -34,12 +34,12 @@ Sure, I try to keep my text editing world /inside/ the internal consistency and #+begin_src emacs-lisp (defun current-location (start-line) "Show the current location and put it into the kill ring. - Use the filename relative to the current projectile root directory. + Use the filename relative to the current project root directory. If called non-interactively, return the location as a string." (interactive "P") - (let* ((project-name (projectile-project-name)) - (file-name (when (and buffer-file-name (projectile-project-root)) - (file-relative-name buffer-file-name (projectile-project-root)))) + (let* ((project-name (project-name (project-current))) + (file-name (when (and buffer-file-name (project-root (project-current))) + (file-relative-name buffer-file-name (project-root (project-current))))) (line-number (if (and (called-interactively-p) start-line) (line-number-at-pos nil t) start-line)) diff --git a/ha-org.org b/ha-org.org index b241124..aa35f8e 100644 --- a/ha-org.org +++ b/ha-org.org @@ -370,7 +370,7 @@ Since [[https://github.com/BurntSushi/ripgrep][ripgrep]] is pretty fast, I’ll (when (string-match (rx "<<" (group (one-or-more any)) ">>") str) (setq str (match-string 1 str))) (ignore-errors - (let* ((default-directory (projectile-project-root)) + (let* ((default-directory (project-root (project-current))) (command (format "rg --ignore-case --json '#\\+name: +%s' *.org" str)) (results (thread-last command diff --git a/ha-programming-clojure.org b/ha-programming-clojure.org index 38ae773..bfd8333 100644 --- a/ha-programming-clojure.org +++ b/ha-programming-clojure.org @@ -155,7 +155,6 @@ Need the IDE features associated with [[https://github.com/clojure-emacs/cider][ "t p" '("run project" . cider-test-run-project-tests) "t f" '("run failed" . cider-test-rerun-failed-tests) "t R" '("show report" . cider-test-show-report) - "t T" '("toggle test/file" . projectile-toggle-between-implementation-and-test) "d" '(:ignore t :which-key "docs") "d d" '("documentation" . cider-doc) diff --git a/ha-programming-elisp.org b/ha-programming-elisp.org index b1799ea..59959a7 100644 --- a/ha-programming-elisp.org +++ b/ha-programming-elisp.org @@ -96,7 +96,7 @@ While I love packages that add functionality and I don’t have to learn anythin (when (string-match (rx (optional "#") (optional "'" ) (group (one-or-more any))) str) (setq str (match-string 1 str))) (ignore-errors - (let* ((default-directory (projectile-project-root)) + (let* ((default-directory (project-root (project-current))) (command (format "rg --json '\\(def[^ ]+ %s ' *.org" str)) (results (thread-last command shell-command-to-list diff --git a/ha-programming-python.org b/ha-programming-python.org index 1c1c852..097c43f 100644 --- a/ha-programming-python.org +++ b/ha-programming-python.org @@ -30,7 +30,7 @@ The critical part of Python integration with Emacs is running LSP in Python usin While Emacs supplies a Python editing environment, we’ll still use =use-package= to grab the latest: #+begin_src emacs-lisp (use-package python - :after projectile flycheck + :after flycheck :mode ("[./]flake8\\'" . conf-mode) :mode ("/Pipfile\\'" . conf-mode) :init @@ -41,11 +41,6 @@ While Emacs supplies a Python editing environment, we’ll still use =use-packag (string= python-shell-interpreter "python")) (setq python-shell-interpreter "python3")) - ;; While `setup.py' and `requirements.txt' are already added, I often - ;; create these files for my Python projects: - (add-to-list 'projectile-project-root-files "requirements-dev.txt") - (add-to-list 'projectile-project-root-files "requirements-test.txt") - (flycheck-add-next-checker 'python-pylint 'python-pycompile 'append)) #+end_src @@ -293,14 +288,7 @@ I work with a lot of projects with my team where I need to /configure/ the proje ;; (insert "python-lsp-black") ;; (insert "pyls-memestra") (insert "pylsp-rope\n")) - (shell-command "pip install -r requirements-dev.txt") - - (unless (f-exists? ".projectile") - (with-temp-file ".projectile")) - - (unless (f-exists? ".dir-locals.el") - (with-temp-file ".dir-locals.el" - (insert "((nil . ((projectile-enable-caching . t))))"))))) + (shell-command "pip install -r requirements-dev.txt"))) #+end_src * Technical Artifacts :noexport: Let's =provide= a name so we can =require= this file: diff --git a/ha-programming.org b/ha-programming.org index 0b718c0..de02a1d 100644 --- a/ha-programming.org +++ b/ha-programming.org @@ -844,7 +844,7 @@ What compile commands should I have on offer? Along with the values in =compile- #+begin_src emacs-lisp (defun ha--compile-command-list () "Return list of potential commands for a project." - (let ((default-directory (projectile-project-root))) + (let ((default-directory (project-root (project-current)))) ;; Make a list of ALL the things. ;; Note that `concat' returns an empty string if you give it null, ;; so we use `-concat' the dash library: @@ -863,7 +863,7 @@ My replacement to [[help:compile][compile]] uses my new =completing-read= functi (interactive (list (completing-read "Compile command: " (ha--compile-command-list) nil nil "" 'compile-history))) - (let ((default-directory (projectile-project-root))) + (let ((default-directory (project-root (project-current)))) (cond ((string-match rx-compile-to-vterm command) (ha-compile-vterm command)) ((string-match rx-compile-to-eshell command) (ha-compile-eshell command)) @@ -876,7 +876,7 @@ If I end a command with a =|v=, it sends the compile command to a vterm session (defun ha-compile-vterm (full-command &optional project-dir) (unless project-dir - (setq project-dir (projectile-project-name))) + (setq project-dir (project-name (project-current)))) ;; (add-to-list 'compile-history full-command) (let ((command (replace-regexp-in-string rx-compile-to-vterm "" full-command))) @@ -892,7 +892,7 @@ And what about sending the command to Eshell as well? If a terminal isn't running, it will be started, allowing follow-up commands." (unless project-dir - (setq project-dir (projectile-project-name))) + (setq project-dir (project-name (project-current)))) (let ((command (replace-regexp-in-string rx-compile-to-eshell "" full-command))) (ha-eshell-send command project-dir))) diff --git a/ha-remoting.org b/ha-remoting.org index dae346a..e1bd169 100644 --- a/ha-remoting.org +++ b/ha-remoting.org @@ -212,7 +212,7 @@ Simply calling =vterm= fails to load my full environment, so this allows me to s #+begin_src emacs-lisp (defun ha-shell (&optional directory name) "Creates and tidies up a =vterm= terminal shell in side window." - (interactive (list (read-directory-name "Starting Directory: " (projectile-project-root)))) + (interactive (list (read-directory-name "Starting Directory: " (project-root (project-current))))) (let* ((win-name (or name (ha-shell--name-from-dir directory))) (buf-name (format "*%s*" win-name)) (default-directory (or directory default-directory))) @@ -257,7 +257,7 @@ Since every project perspective may have a shell terminal, let’s see if I can The real work for this is done by `ha-ssh-send'. - If DIRECTORY is nil, use the project root from projectile." + If DIRECTORY is nil, use the project root from project." (let ((buf (ha-shell--buf-from-dir directory))) (unless buf (setq buf (ha-shell directory))) @@ -274,9 +274,9 @@ Since every project perspective may have a shell terminal, let’s see if I can (defun ha-shell--name-from-dir (&optional directory) "Return an appropriate title for a terminal based on DIRECTORY. - If DIRECTORY is nil, use the `projectile-project-name'." + If DIRECTORY is nil, use the `project-name'." (unless directory - (setq directory (projectile-project-name))) + (setq directory (project-name (project-current)))) (let ((name ;; Most of the time I just want the base project name, but in ;; my "work" directory, the projects are too similar, and I @@ -523,13 +523,13 @@ This file, so far, as been good-enough for a Vanilla Emacs installation, but to "a s o" '("overcloud" . ha-ssh-overcloud) "a s l" '("local shell" . ha-shell) "a s s" '("remote shell" . ha-ssh) - "a s p" '("project shell" . (lambda () (interactive) (ha-shell (projectile-project-root)))) + "a s p" '("project shell" . (lambda () (interactive) (ha-shell (project-root (project-current))))) "a s q" '("quit shell" . ha-ssh-exit) "a s f" '("find-file" . ha-ssh-find-file) "a s r" '("find-root" . ha-ssh-find-root) "a s b" '("send line" . ha-ssh-send-line) - "p t" '("project vterm" . (lambda () (interactive) (ha-shell (projectile-project-root))))) + "p t" '("project vterm" . (lambda () (interactive) (ha-shell (project-root (project-current)))))) #+end_src * Technical Artifacts :noexport: Provide a name so we can =require= the file: