Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

### New features

- [#2182](https://github.com/bbatsov/projectile/pull/2182): Add `projectile-todos-in-projects` and `projectile-multi-occur-in-projects`, so every sibling command now has a public generic taking any list of projects behind it and a command for a group of your own is a two-line wrapper for all five.
- [#2181](https://github.com/bbatsov/projectile/pull/2181): Sapling and Bazaar projects can now list their own ignored files, via the new `projectile-sapling-ignored-command` and `projectile-bzr-ignored-command`.
- [#2180](https://github.com/bbatsov/projectile/pull/2180): Every shell backend can now open in another window (`s-p x 4 <key>`), not just vterm, eat and ghostel: `shell`, `eshell`, `ielm`, `term` and the backend-dispatching `projectile-run` gained `-other-window` commands.
- [#2160](https://github.com/bbatsov/projectile/pull/2160): Add `projectile-find-file-in-sibling-projects` (`s-p n f`) and `projectile-search-in-sibling-projects` (`s-p n s`), which work across the family of related projects rather than just the one you're in.
Expand Down
13 changes: 7 additions & 6 deletions doc/modules/ROOT/pages/across_repositories.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,10 @@ reviewable replacement across all of them. See
xref:usage.adoc[the search and replace reviewers].

These all take a plain list of projects underneath -
`projectile-find-file-in-projects`, `projectile-search-in-projects` and
`projectile-switch-to-buffer-in-projects` - so a command for a group of
your own is a two-line wrapper:
`projectile-find-file-in-projects`, `projectile-search-in-projects`,
`projectile-switch-to-buffer-in-projects`,
`projectile-multi-occur-in-projects` and `projectile-todos-in-projects` -
so a command for a group of your own is a two-line wrapper:

[source,elisp]
----
Expand All @@ -260,9 +261,9 @@ your own is a two-line wrapper:
"Find file in infra: "))
----

`projectile-search-in-projects` and
`projectile-switch-to-buffer-in-projects` are the same shape for
searching and for buffers.
The others are the same shape: each takes the project list first, and the
sibling commands are nothing more than these with
`projectile-sibling-projects` filled in.

NOTE: A literal group search runs `rg` over each project in turn when
ripgrep is installed - one per project rather than one over the lot,
Expand Down
27 changes: 17 additions & 10 deletions projectile.el
Original file line number Diff line number Diff line change
Expand Up @@ -11541,9 +11541,10 @@ in the results buffer. The keyword does not have to sit in a comment.
With a prefix argument ARG, prompt for which keywords to search for
instead of using all of them."
(interactive "P")
(projectile--todos (list (projectile-acquire-root)) arg))
(projectile-todos-in-projects (list (projectile-acquire-root)) arg))

(defun projectile--todos (projects &optional arg)
;;;###autoload
(defun projectile-todos-in-projects (projects &optional arg)
"Collect the TODO-style annotations of PROJECTS into the search reviewer.
With ARG non-nil, prompt for which keywords to search for. PROJECTS is a
list of project roots, so one project and a whole group take the same
Expand Down Expand Up @@ -15290,25 +15291,31 @@ Related is what `projectile-switch-sibling-project' means by it."
(projectile--sibling-group) "Switch to sibling buffer: "))

;;;###autoload
(defun projectile-multi-occur-in-sibling-projects (&optional nlines)
"Do a `multi-occur' in the buffers of the current project and related ones.
Related is what `projectile-switch-sibling-project' means by it. With a
prefix argument, show NLINES of context.
(defun projectile-multi-occur-in-projects (projects &optional nlines)
"Do a `multi-occur' in the buffers of any of PROJECTS.
NLINES is the number of context lines `multi-occur' shows.

Note this searches the buffers you have open, not the projects on disk -
`projectile-search-in-sibling-projects' is the one that reads files."
(interactive "P")
(multi-occur (projectile-project-group-buffers (projectile--sibling-group))
`projectile-search-in-projects' is the one that reads files."
(multi-occur (projectile-project-group-buffers projects)
(car (occur-read-primary-args))
nlines))

;;;###autoload
(defun projectile-multi-occur-in-sibling-projects (&optional nlines)
"Do a `multi-occur' in the buffers of the current project and related ones.
Related is what `projectile-switch-sibling-project' means by it. With a
prefix argument, show NLINES of context."
(interactive "P")
(projectile-multi-occur-in-projects (projectile--sibling-group) nlines))

;;;###autoload
(defun projectile-todos-in-sibling-projects ()
"Collect TODO-style annotations across the current project and related ones.
Related is what `projectile-switch-sibling-project' means by it. See
`projectile-todos' for what counts as an annotation."
(interactive)
(projectile--todos (projectile--sibling-group)))
(projectile-todos-in-projects (projectile--sibling-group)))


;;; Project bookmarks
Expand Down
31 changes: 31 additions & 0 deletions test/projectile-project-group-test.el
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,37 @@ the two truename'd roots and `parent' to the directory holding them."
;; the prefix argument is passed through as the context line count
(expect (nth 2 args) :to-equal 3))))))

;; Every sibling command is a wrapper over a generic that takes any list of
;; projects, so a group of your own drives them the same way. `todos' and
;; `multi-occur' were the two that had no such generic to call.
(describe "the generic group commands"
(it "projectile-multi-occur-in-projects takes the projects it is given"
(projectile-group-test--with-projects
(let ((ba (find-file-noselect (expand-file-name "src/a.txt" alpha)))
(bb (find-file-noselect (expand-file-name "lib/b.txt" beta))))
(spy-on 'occur-read-primary-args :and-return-value '("needle"))
(spy-on 'multi-occur)
;; no sibling lookup involved
(spy-on 'projectile-sibling-projects :and-throw-error 'error)
(projectile-multi-occur-in-projects (list alpha beta) 2)
(let ((args (spy-calls-args-for 'multi-occur 0)))
(expect (nth 0 args) :to-contain ba)
(expect (nth 0 args) :to-contain bb)
(expect (nth 2 args) :to-equal 2)))))

(it "projectile-todos-in-projects takes the projects it is given"
(projectile-group-test--with-projects
(with-temp-file (expand-file-name "src/todo.txt" alpha)
(insert "TODO: alpha thing\n"))
(with-temp-file (expand-file-name "lib/todo.txt" beta)
(insert "FIXME: beta thing\n"))
(spy-on 'projectile-sibling-projects :and-throw-error 'error)
(cl-letf (((symbol-function 'pop-to-buffer) #'ignore))
(projectile-todos-in-projects (list alpha beta)))
(expect (projectile-test-match-files
(get-buffer projectile-search-buffer-name))
:to-equal '("alpha/src/todo.txt" "beta/lib/todo.txt")))))

;;; Ripgrep across a group

(defun projectile-group-test--seed-rg (buf root projects term)
Expand Down
Loading