One of my most commonly used commands with projectile is helm-projectile. This
lets me locate any file in my project by pressing
C-c p h. Using the
narrowing abilities of helm, I can quickly filter the list of options to
exactly the one I want.
Because I work on some projects that are extremely large in size, I have
enabled projectiles caching mechanism. This tells projectile to maintain a
local cache of all the files within a project for faster searching. You can
enable this with
(setq projectile-enable-caching t)
Projectile helps maintain the current state of this cache by adding a hook to
find-file. Whenever a new file is found or created, projectile will
automatically add that new file to the cache. This saves me from having to
manually invalidate the cache with
C-c p i every time a create a new file.
However, if I delete a file, projectile does not automatically remove it from the cache. The next time I search for a similarly named file, the deleted file will still show up in the helm list of candidates. While not a deal breaker, it is certainly a source of annoyance for me. Since emacs is all about tweaking your environment to eliminate those little headaches, I knew I had to fix it.
At first, I thought adding a hook to delete-file would be the easy, straightforward fix. I couldn't find any documentation for a delete-file-hook. Having tried to check out the source code, I realized that while find-file is implemented in lisp, delete-file is actually implemented in C.
Having been unable to find a hook associated with this function, what was I do to?
This is where defadvice comes in. I won't go into detail about how defadvice works, but the short version is that defadvice allows you to suggest behavior to emacs before, after, or around an invocation of a particular function. You can read more about defadvice in the manual.
The below snippet adds advice before the delete-file function is called. It checks to see if the file is part of a projectile project; if the file is cached by projectile, it removes it from the cache.
NOTE This defadvice function is no longer necessary. This functionality has now been incorporated into projectile.
That's it. With just a few short lines, projectile will now invalidate the cache as soon as I delete a file, just as I would like. Isn't emacs great?