1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
|
= Usage
NOTE: Everything in this section assumes you've enabled `projectile-mode`.
== Basic setup
In this section we'll cover the bare minimum of setup you might want to
do. Projectile works fine with no setup, but if you tweak the configuration a
bit you'll get more out of it.
Check out the xref:configuration.adoc["Configuration"] section of the manual
for a lot more information about configuring Projectile.
=== Automated Project Discovery
To add a project to Projectile's list of known projects, open a file
in the project. If you have a projects directory, you can tell
Projectile about all of the projects in it with the command `M-x
projectile-discover-projects-in-directory`.
You can go one step further and set a list of folders which Projectile
is automatically going to check for projects on startup.
Recursive discovery is configured by specifying the search depth in a cons cell:
[source,elisp]
----
(setq projectile-project-search-path '("~/projects/" "~/work/" ("~/github" . 1)))
----
You can suppress the auto-discovery of projects on startup by setting
`projectile-auto-discover` to `nil`. You can manually trigger the project
discovery using `M-x projectile-discover-projects-in-search-path`.
=== Minibuffer Completion
While Projectile works fine with Emacs's default minibuffer completion system you're highly encouraged to use some
powerful alternative like `ido`, `ivy`, `selectrum` or `vertico`.
TIP: If you're going to use the `ido` completion it's **highly** recommended that you install the optional
https://github.com/lewang/flx[flx-ido package], which provides a much more powerful
alternative to ``ido``'s built-in `flex` matching. Similarly, for `selectrum` it's
a good idea to enable `prescient` (a package similar to `flx`).
=== Installing External Tools
NOTE: Windows users can ignore this section unless they are using Emacs via WSL or `cygwin`.
Projectile will work without any external dependencies out of the box.
However, if you have various tools installed, they will be
automatically used when appropriate to improve performance.
Inside version control repositories, VC tools are used when installed
to list files more efficiently. The supported tools include git, hg,
fossil, bzr, darcs, pijul, and svn.
Outside version control repositories, file search tools are used when
installed for a faster search than pure Elisp. The supported tools
include https://github.com/sharkdp/fd[fd] and GNU/BSD find.
By default, if fd is installed, it is also used inside Git
repositories as an alternative to `git ls-files`, because `git
ls-files` has the limitation that it also lists deleted files until
the deletions are staged, which can be confusing. You can eliminate
the use of fd in this circumstance by setting `projectile-git-use-fd`
to nil.
To benefit from the `projectile-ag` and `projectile-ripgrep` commands
to perform file search, it's recommended to install
https://github.com/ggreer/the_silver_searcher[ag] (`the_silver_searcher`) and/or
https://github.com/BurntSushi/ripgrep[rg] (`ripgrep`)
TIP: You should also install the Emacs packages `ag`, `ripgrep` or `rg` if you want to make sure of Projectile's commands `projectile-ag` and `projectile-ripgrep`.
== Basic Usage
Just open some file in a version-controlled (e.g. `git`) or a project
(e.g. `maven`) directory that's recognized by Projectile and you're
ready for action. Projectile happens to recognize out of the box every common
VCS and many popular project types for various programming languages.
You can learn more about Projectile's notion of a project xref:projects.adoc[here].
NOTE: The extent of the support for every VCS differs and Git is the best supported
one. Projectile supports some advanced features like working with Git submodules
and using `git-grep` instead GNU grep.
You need to know only a handful of Projectile commands to start benefiting from it.
* Find file in current project (kbd:[s-p f])
* Switch project (kbd:[s-p p]) (you can also switch between open projects with kbd:[s-p q])
* Grep (search for text/regexp) in project (kbd:[s-p s g])
* Replace in project (kbd:[s-p r])
* Find references in project (kbd:[s-p ?] or kbd:[s-p s x])
* Invoke any Projectile command via the Projectile Commander (kbd:[s-p m])
* Toggle between implementation and test (kbd:[s-p t])
* Toggle between related files (e.g. `foo.h` <-> `foo.c` and `Gemfile` <-> `Gemfile.lock`) (kbd:[s-p a])
* Run a shell command in the root of the project (kbd:[s-p !] for a sync command and kbd:[s-p &] for an async command)
* Run various pre-defined project commands like:
** build/compile project (kbd:[s-p c])
** test project (kbd:[s-p T])
The next section lists many more commands, but the basics can get you pretty far.
== Interactive Commands
NOTE: Projectile doesn't have a default key prefix for its commands, but all the examples
in the manual assume you've opted for kbd:[s-p] (`super`-p).
Here's a list of the interactive Emacs Lisp functions, provided by Projectile:
|===
| Keybinding | Description
| kbd:[s-p f]
| Display a list of all files in the project. With a prefix argument it will clear the cache first.
| kbd:[s-p F]
| Display a list of all files in all known projects.
| kbd:[s-p g]
| Display a list of all files at point in the project. With a prefix argument it will clear the cache first.
| kbd:[s-p 4 f]
| Jump to a project's file using completion and show it in another window.
| kbd:[s-p 4 g]
| Jump to a project's file based on context at point and show it in another window.
| kbd:[s-p 5 f]
| Jump to a project's file using completion and show it in another frame.
| kbd:[s-p 5 g]
| Jump to a project's file based on context at point and show it in another frame.
| kbd:[s-p d]
| Display a list of all directories in the project. With a prefix argument it will clear the cache first.
| kbd:[s-p 4 d]
| Switch to a project directory and show it in another window.
| kbd:[s-p 5 d]
| Switch to a project directory and show it in another frame.
| kbd:[s-p T]
| Display a list of all test files(specs, features, etc) in the project.
| kbd:[s-p l]
| Display a list of all files in a directory (that's not necessarily a project)
| kbd:[s-p s g]
| Run grep on the files in the project.
| kbd:[M-- s-p s g]
| Run grep on `projectile-grep-default-files` in the project.
| kbd:[s-p s s]
| Runs `ag` (`the_silver_searcher`) on the project, performing a literal search. Requires the presence of `ag.el`. With a prefix argument it will perform a regex search.
| kbd:[s-p s r]
| Runs `rg` (`ripgrep`) on the project, performing a literal search. Requires the presence of `rg.el` or `ripgrep.el`. With a prefix argument it will perform a regex search.
| kbd:[s-p s x]
| Find references to the symbol at point within the project. Uses internally the `xref` library.
| kbd:[s-p v]
| Run `vc-dir` on the root directory of the project.
| kbd:[s-p V]
| Browse dirty version controlled projects.
| kbd:[s-p b]
| Display a list of all project buffers currently open.
| kbd:[s-p 4 b]
| Switch to a project buffer and show it in another window.
| kbd:[s-p 5 b]
| Switch to a project buffer and show it in another frame.
| kbd:[s-p 4 C-o]
| Display a project buffer in another window without selecting it.
| kbd:[s-p a]
| Switch between files with the same name but different extensions.
| kbd:[s-p 4 a]
| Switch between files with the same name but different extensions in other window.
| kbd:[s-p 5 a]
| Switch between files with the same name but different extensions in other frame.
| kbd:[s-p o]
| Runs `multi-occur` on all project buffers currently open.
| kbd:[s-p r]
| Runs interactive query-replace on all files in the projects.
| kbd:[s-p i]
| Invalidates the project cache (if existing).
| kbd:[s-p R]
| Regenerates the projects `TAGS` file.
| kbd:[s-p j]
| Find tag in project's `TAGS` file.
| kbd:[s-p k]
| Kills all project buffers.
| kbd:[s-p D]
| Opens the root of the project in `dired`.
| kbd:[s-p 4 D]
| Opens the root of the project in `dired` in another window.
| kbd:[s-p 5 D]
| Opens the root of the project in `dired` in another frame.
| kbd:[s-p e]
| Shows a list of recently visited project files.
| kbd:[s-p left]
| Switch to the previous project buffer.
| kbd:[s-p right]
| Switch to the next project buffer.
| kbd:[s-p E]
| Opens the root `dir-locals-file` of the project.
| kbd:[s-p !]
| Runs `shell-command` in the root directory of the project.
| kbd:[s-p &]
| Runs `async-shell-command` in the root directory of the project.
| kbd:[s-p C]
| Runs a standard configure command for your type of project.
| kbd:[s-p c]
| Runs a standard compilation command for your type of project.
| kbd:[s-p P]
| Runs a standard test command for your type of project.
| kbd:[s-p t]
| Toggle between an implementation file and its test file.
| kbd:[s-p 4 t]
| Jump to implementation or test file in other window.
| kbd:[s-p 5 t]
| Jump to implementation or test file in other frame.
| kbd:[s-p z]
| Adds the currently visited file to the cache.
| kbd:[s-p p]
| Display a list of known projects you can switch to.
| kbd:[s-p q]
| Display a list of open projects you can switch to.
| kbd:[s-p S]
| Save all project buffers.
| kbd:[s-p m]
| Run the commander (an interface to run commands with a single key).
| kbd:[s-p x e]
| Start or visit an `eshell` for the project.
| kbd:[s-p x i]
| Start or visit an `ielm` (Elisp REPL) for the project.
| kbd:[s-p x t]
| Start or visit an `ansi-term` for the project.
| kbd:[s-p x s]
| Start or visit a `shell` for the project.
| kbd:[s-p x g]
| Start or visit a `gdb` for the project.
| kbd:[s-p x v]
| Start or visit a `vterm` for the project.
| kbd:[s-p ESC]
| Switch to the most recently selected Projectile buffer.
|===
If you ever forget any of Projectile's keybindings just do a:
kbd:[s-p C-h]
== Customizing Projectile's Keybindings
It is possible to add additional commands to
`projectile-command-map` referenced by the prefix key in
`projectile-mode-map`. You can add multiple keymap prefix for all
commands. Here's an example that adds `super-,` as a command prefix:
[source,elisp]
----
(define-key projectile-mode-map (kbd "s-,") 'projectile-command-map)
----
You can also bind the `projectile-command-map` to any other map you'd
like (including the global keymap).
TIP: For some common commands you might want to take a little shortcut and
leverage the fairly unused `Super` key (by default `Command` on Mac
keyboards and `Windows` on Win keyboards).
Here's something you can
add to your Emacs config:
[source,elisp]
----
(define-key projectile-mode-map [?\s-d] 'projectile-find-dir)
(define-key projectile-mode-map [?\s-p] 'projectile-switch-project)
(define-key projectile-mode-map [?\s-f] 'projectile-find-file)
(define-key projectile-mode-map [?\s-g] 'projectile-grep)
----
NOTE: Note that the `Super` keybindings are not usable in Windows, as Windows
makes heavy use of such keybindings itself. Emacs Prelude already adds those
extra keybindings.
== Projectile Commander
Projectile's Commander (`projectile-commander`) is a nifty utility for those of you who are struggling to remember a lot of keybindings. It provides a simple
interface to most of Projectile's commands via 1-character shortcuts that you
need to press after invoking the commander (e.g. via kbd:[s-p m]).
The commander was created with the idea to provide a powerful project switching command (it will be triggered if you press kbd:[C-u s-p p]), but it's very useful on its own as well.
|===
| Keybinding | Description
| kbd:[?]
| Commander help buffer.
| kbd:[D]
| Open project root in dired.
| kbd:[R]
| Regenerate the project's etags/gtags.
| kbd:[T]
| Find test file in project.
| kbd:[V]
| Browse dirty projects
| kbd:[a]
| Run ag on project.
| kbd:[b]
| Switch to project buffer.
| kbd:[d]
| Find directory in project.
| kbd:[e]
| Find recently visited file in project.
| kbd:[f]
| Find file in project.
| kbd:[g]
| Run grep on project.
| kbd:[j]
| Find tag in project.
| kbd:[k]
| Kill all project buffers.
| kbd:[o]
| Run multi-occur on project buffers.
| kbd:[r]
| Replace a string in the project.
| kbd:[s]
| Switch project.
| kbd:[v]
| Open project root in vc-dir or magit.
|===
You can add additional commands to the commander like this:
[source,elisp]
----
(def-projectile-commander-method ?f
"Find file in project."
(projectile-find-file))
----
Place such snippets after ``projectile-mode``'s init code.
== Using Projectile with project.el
Starting with version 2.7 Projectile bundles some integration with
`project.el` that makes `project.el` use Projectile's
project lookup function (`projectile-project-root`) and project file
lookup function (`projectile-project-files`) whenever `projectile-mode`
is enabled. You can also enable the integration manually like this:
[source,elisp]
----
(add-hook 'project-find-functions #'project-projectile)
----
TIP: You can read more about the implementation details of the integration https://github.com/bbatsov/projectile/issues/1591[here].
That's useful as some packages (e.g. `eglot`) support natively only
``project.el``'s API for project discovery. Fortunately, `project.el`
makes it easy to install additional project lookup functions and that's
exactly what Projectile does.
The popular `xref` package also relies on `project.el` to infer the project for
helpful commands like `xref-find-references` (kbd:[M-?]), so it's useful to teach
it about Projectile's project discovery logic.
TIP: Projectile provides its own alternative to `xref-find-references` that's named
`projectile-find-references` (kbd:[s-p ?] or kbd:[s-p s-x]) and is using `xref` internally.
You can disable the `project.el` integration like this:
[source,elisp]
----
(remove-hook 'project-find-functions #'project-projectile)
----
|