Troubleshooting
In case you run into issues here are a few tips that can help you diagnose the problem.
Generally, it’s not a bad idea to configure Emacs to spit the backtrace on error
(instead of just logging the error in the *Messages* buffer). You can toggle
this behavior by using M-x toggle-debug-on-error.
Start with the doctor
Before you reach for the debugger, ask Projectile what it thinks is going on:
M-x projectile-doctor
(bound to s-p H, and available from the dispatch menu and the Projectile menu)
This opens a plain-text report in a *projectile-doctor* buffer describing
the project around default-directory:
-
Project - the project root and, crucially, which entry of
projectile-project-root-functionsfound it and off which marker file, the project name and where it came from, and whether the root is remote (TRAMP). -
Type - the detected project type and the marker that matched, or an explanation of what to do when nothing matched.
-
Indexing - the indexing method, whether async indexing is on, the actual command Projectile will shell out to (ignore rules and all), and which of
git,fdandrgare installed. -
Files - how many files are indexed and how long a fresh index took, plus the cache state (cached or not, how old, when it expires, whether the cache is persistent).
-
Ignores - the dirconfig and its parsed
+/-/!entries, the effective ignore patterns, and which entries in the project root those patterns are hiding. Handy when files you expect to see are missing. -
Findings - a short list of observations, each either
okor a concrete suggestion (fd not installed, caching off on a large project, a dirconfig using the deprecated prefix-less syntax, a remote project indexed synchronously, and so on).
Outside a project the report says so and lists the root functions that were tried, which is usually enough to figure out why a directory isn’t recognized.
The doctor is careful not to change what it measures: it never populates and never invalidates the file cache. When a project isn’t cached yet, the doctor indexes it with caching switched off and labels that as a fresh index, so running it can’t turn a cold project warm behind your back. On remote projects, indexing and program lookups are skipped rather than risking a hang, and the report marks them as skipped.
g regenerates the report, q buries it.
The report is plain, copy-pasteable text on purpose. When you file an
issue on the issue tracker,
pasting the output of projectile-doctor answers most of the questions we’d
otherwise have to ask you.
|
Debugging Projectile commands
Emacs features a super powerful built-in Emacs Lisp debugger and using it is the best way to diagnose problems of any kind.
| Here’s a great crash course on using the debugger. |
To debug some command you need to do the following:
-
Figure out the name of the command you want to debug (e.g. by using C-h k to see which command is associated with some keybinding)
-
Find the source of the command (e.g. by using M-x
find-functionRETfunction-name) -
Press C-u C-M-x while in the body of the function
-
Run the command again
At this point you’ll be dropped in the debugger and you can step forward until you find the problem.
Profiling Projectile commands
Emacs comes with a built-in profiler. Using it is pretty simple:
-
Start it with M-x
profiler-start. -
Invoke some commands.
-
Get the report with M-x
profiler-report.
| If you intend to share the profiling results with someone it’s a good idea to save the report buffer to a file with C-x C-w. |
Commonly encountered problems (and how to solve them)
Using some command causes Emacs to freeze for a while
Sometimes a Projectile command might hang for a while (e.g. due to a bug or a configuration issue). Such problems are super annoying, but are relatively easy to debug. Here are a few steps you can take in such situations:
-
Do M-x
toggle-debug-on-quit -
Reproduce the problem
-
Hit C-g around 10 seconds into the hang
This will bring up a backtrace with the entire function stack, including function arguments. So you should be able to figure out what’s going on (or at least what’s being required).
Projectile recognizes the wrong project
If Projectile does not think you are in a project, check how you
expect Projectile to recognize the project: it needs the presence of
an indicator file like .git or similar at the project root. If the
directory you want to be a project is not version-controlled, a file
named .projectile will do.
Note that Projectile caches the operation of checking which project
(if any) a file belongs to. If you have already opened a file, then
later added a marker file like .projectile, run M-x
projectile-invalidate-cache to reset the cache.
M-x projectile-doctor tells you exactly which of the
projectile-project-root-functions claimed the directory and off which marker
file, which usually settles the "why this root?" question on the spot.