December 5, 2013

Juggling Projects with Projectile

Filed under: blogging,emacs — jonEbird @ 9:56 am

When I’m introducing someone to Emacs, I will often talk about how a typical Emacsen will keep it running for long periods of time and will keep many files (buffers as we call them) open. I personally have over 100 buffers open as I write this. Part of the reason I have so many open is that I’m often jumping between different collections of files as I go about my work throughout the day. When I want to switch over to work on another project, I’ll switch to the desired buffer (C-x b) and while ido makes that easier, I still need to rely a good deal on mental memory to know which files make up which project. Worse yet is that some projects have commonly named files, so you may end up with buffers “Makefile”, “Makefile<2>”, etc. Which one was it?

The Projectile project aims to help solve this problem. It’s about context switching between projects and doing so deliberately. Projectile knows which files are a part of each project. The new workflow for switching to work on another project is: 1. Switch to Project (C-c p s) at which point you’re selecting (with ido again) against a list of projects only, then 2. picking a specific file from that project that you wanted to work on first. Mentally, it is “I want to work on file XX in project YY now. Take me there, Projectile!”. You can also easily switch between other buffers exclusively within the current project you’re working in (C-c p b) or open up a new file within your project (C-c p f). It’s about understanding which files and buffer make up your project and leveraging that to maximize your efficiency.

For example, earlier today I got an email asking for help on a minor issue. I wanted to consult a Python script but it’s been a while and I forgot the full path to the script. “Well, the project has ‘util’ in the name”, I thought to myself, so I switched projects (C-c p s) and typed “util” to narrow the choices of projects to the correct one and hit ENTER. I then typed “.py” to narrow the project files to only Python scripts I’m left with two choices. Nice! I didn’t have to remember the full path to the file and saved about 5-10s of searching which adds up with each project context switch.

The concept of managing the collection of files within a project is the core functionality of Projectile. I didn’t get that when I initially perused the few articles I’ve brought it to my attention. And yet Projectile does not stop there. Some of the other features that I’ve found useful in my 2 days of using it have been:

  • Launching an ack (C-c p a) or grep (C-c p g) to search through the files in your project.
    • This will replace my M-x rgrep habit.
  • Run a multi-occur on open buffers within your project.
    • I rarely used multi-occur because I found it a hassle to select which buffers. Happy addition.
  • Need to replace, ala query-replace (M-%), across all files in your project?
    • It can do that too. (C-c p r)
  • Handful of project testing integration (Listing these here but I honestly haven’t explored these features yet)
    • Support for switching between test file and your current buffer (C-c p t)
    • Find a test file (C-c p T)
    • Run your test suite (C-c p p)
  • And more

Now let’s make your experience with Projectile better:

  • Install guide-key and add “C-c p” (the default Projectile prefix key sequence) to your guide-key/guide-key-sequence. This makes learning a completely new system, like Projectile, nearly trivial since all of the actions use the same prefix. With guide-key, you type the beginning sequence “C-c p” and then be provided with a cheat-sheet.
  • Using IDO? Then install flx-ido and consider ido-vertical-mode
  • Install ack on your machine and then the corresponding Emacs ack-in-a-half module.
  • Make sure you have Exuberant Ctags installed for generating a proper TAGS file.

I will probably look to exploit the hooks available in Projectile. In particular, I think it would be nice to interact with my shell and switch to a different screen session or something. I’m excited to continue to use it.