Removed projectile for the built-in project

This commit is contained in:
Howard Abrams 2024-02-09 14:00:12 -08:00
parent 778bfd4685
commit 52046ffa91
12 changed files with 76 additions and 136 deletions

View file

@ -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:

View file

@ -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 wasnt 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)))

View file

@ -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)

View file

@ -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 lets bind it:
#+begin_src emacs-lisp
(bind-key "C-!" 'eshell-here)
#+end_src
** Shell for a Project
This version starts =eshell= in the projects 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

View file

@ -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 <escape>" '(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 <escape>" '(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 doesnt 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 buffers perspective.
I like the idea of dropping returnable bookmarks, however, the built-in behavior doesnt 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 <down>" '("next mark" . bookmark-in-project-jump-next)
"b <up>" '("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 @@ Id 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 lets 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 doesnt 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 hasnt 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

View file

@ -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))

View file

@ -370,7 +370,7 @@ Since [[https://github.com/BurntSushi/ripgrep][ripgrep]] is pretty fast, Ill
(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

View file

@ -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)

View file

@ -96,7 +96,7 @@ While I love packages that add functionality and I dont 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

View file

@ -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, well 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, well 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:

View file

@ -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)))

View file

@ -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, lets 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, lets 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: