↓ Skip to Content Start of content

Exploring my Emacs packages - Projectile

What is Projectile?

Project homepage : http://batsov.com/projectile/

Projectile is a project interaction library for Emacs. It's not a project management package, in that it doesn't handle task lists, gantt charts or things like that.

In practice, Projectile works as a way to limit functionality to files in whatever project is currently being worked on.

Projects are just a directory and its files which makes things simple. By default Projectile will treat any directory under source control as a project, but adding a .projectile file to a directory will also turn it into a project.

The file list can be filtered to ignore entries, either via .gitignore or in the .projectile file.

What can I use it for?

There's some tasks I perform quite often:

  • Navigating project files
  • Running tests and compilation commands
  • Switching between tests and source files
  • Switching between controllers and views
  • Running grep and occur

And some I do less often:

  • Running a shell in a project's directory
  • Renaming files within a project
  • Jumping to an included file

None of these are particularly time consuming, but I'd still like to streamline them if possible. Let's see if Projectile can help.

Navigating project files

Normally I would use C-x C-f (find-file) to open other files in a project. Projectile provides C-c p f (projectile-find-file), which is a very fast alternative.

Opening files with projectile

Ignored files are automatically filtered from the list and it integrates nicely with Helm.

C-c p d works in a similar way for directories and opens them in dired. C-c p b can be used to switch between project buffers.

Running tests and compilation commands

For most projects I'll have a terminal window open to run tests and compile code. Both of these things can be done using Projectile commands:

  • C-c p P – Runs a test command for the current project.
  • C-c p c – Runs a compilation command for the current project.

Each command will try to figure out the best function for the current project type. There are currently 30 different project types built-in, covering Rails, Symfony, Django and a bunch of other common platforms.

Project types are assigned by searching for specific files in the project root. For example, finding a Makefile file in the root will set the default compile command to make and the default test command to make test.

Projects can set their compile and test commands using Emacs .dir-locals.el.

  • projectile-project-compilation-cmd sets the compilation command
  • projectile-project-test-cmd sets the test command
  • projectile-project-run-cmd sets the run command
  • projectile-project-compilation-dir sets the directory to run compilation commands in.

These will override whatever type Projectile has assigned.

Example: .dir-locals.el for a Common Lisp project

((nil . ((projectile-project-test-cmd . "sbcl --script test.lisp"))))

The .dir-locals.el overrides make it possible to customize projects no matter what language or setup they're using.

Switching between tests and source files

Projectile's C-c p t command works most of the time, but a couple of my projects needed to be tweaked slightly to work properly due to the way test files are named and found.

To find the appropriate test file, Projectile strips the current filename of its path and extension, and then checks for a specific prefix or suffix.

For example:

"project/src/module/my_file.rb" will be stripped down to just "my_file". Ruby projects use "_test" as the suffix, meaning Projectile will attempt to open "my_file_test.rb" wherever it is located.

Some of my projects use the same name for source and test files, but stores them in different directories. It may be possible to extend this behaviour, but I'm still looking into that.

Switching between controllers and views

projectile-rails can be used to switch between models and views within rails projects.

For none-Rails projects, there are a couple of options, although neither are perfect:

  • C-c p a – Switches between files with the same name but a different extension.
  • C-c p g – Jumps to the file at the current point. This worked well for projects that explicitly named view templates.

Running grep and occur

Both of these options are supported and very quick:

  • C-c p s g – Runs grep on the entire project
  • C-c p o – Runs occur on all open project buffers

Running git

C-c p v opens version control for the current project. It automatically works out the best option based on what version control the project is under. For example, projects under git will open magit if installed.

Renaming files

There's no shortcut for renaming files, but being able to quickly open dired for project directories makes the whole process much easier.

Opening a terminal

C-c p ! runs a shell command in the project root. There's no shortcut to open a terminal .

More information

There's a full list of commands available on the Projectile project page: http://batsov.com/projectile/#interactive-commands

This post is part of the "Exploring my Emacs packages" series.

Exploring my Emacs packages

I've been using Emacs as my primary editor for around 5 years. Over that time I've installed plenty of packages and tweaked numerous settings. There are some packages that I use daily, but others have sat in the background, unused and unloved.

Over the next few weeks I'll be exploring some of those lesser-used packages and learning what they have to offer.

The packages are currently on my list to explore:

Project interaction library. Lots of functionality for moving around projects.
Live web development for Emacs. It can update web pages without reloading them and also features a JavaScript REPL.
Adds auto-complete functionality.
Snippet expansion library.
Major mode for editing HTML. Can handle plenty of template languages.

I'll be updating this list with links to each post.

Groundhog Day Resolutions - October 2016

I skipped a couple of months, but here we are in October.

July's Goals

1. Redesign philnewton.net

It took a while to settle on a look and feel I liked. The design is still not completely finished, but it's a start. The build process was also simplified, which considerably decreased the build time.

2. Build another game

Failed. Kind of.

I did spend some time working on game-related code. The majority was entity system related, but there was some game scripting in there as well. I've been working on both of those for a long time and I'd like to write more about them (as seen in #3).

3. Blog more

I'll say this one is a success. I didn't write as much as I wanted, but I setup a new site to hold some of the more code-oriented things I write.

Other things

As well as my written goals, I worked on a couple of other things:

  • Set up sodaware.sdf.org – This is a tiny site for me to fill with code notes and more in-depth software development articles.
  • Worked on dogecoind-api – A Common Lisp library for interacting with Dogecoin.
  • Worked on cl-dogechain-api – Another common lisp library - this one for working with the dogechain.info api.

I also did some experimenting with Common Lisp web frameworks and ORM libraries. I built a couple of tiny site prototypes, but I'd like to polish them up into something releasable.

Goals for this month

1. Finish some Common Lisp projects

There's a couple of libraries I'm working on that I want to finish and release. If possible, I'd also like to release a web project that uses CL.

2. Build a game

#1GAM hasn't been as motivating as last year, but I'd still like to get at least one or two games built by the end of the year. There are plenty of game jams to enter, and short bursts of activity seem to work better for me.

3. Blog more

This is working well so far. I have plenty of ideas, I just need to make the time to actually write them out.

Groundhog Day Resolutions - July 2016

February's goals went pretty well - I achieved everything I wanted and finally crossed off some items that have been on my list for far too long.

February's Goals

1. Rebuild sodaware.net

Not very exciting, but I finally got around to rebuilding my game site at sodaware.net. The site is all static, using a mix of middleman and Jekyll, and also runs under SSL.

It took a while to get all the various parts working together, but I'm definitely happy with how the site looks and works now. There's still some work to be done (mostly polishing and removing dead content) but it's a good first step that I should have taken years ago.

2. Release a game

My second success was releasing my first game in over two years. And boy, was it terrible! You can read more about it here: "February's #1GAM Entry - Trip into the Future". It wasn't particularly complex to build, and it isn't much fun to play, but it was a good step to getting back into the groove.

3. Blog more

I'm still in the habit of leaving things to the last minute, but it's getting there.

The last few months have been a complete bust. But there's no point dwelling on the past. On to July!

Goals for this month

1. Redesign this site

This is another one of those "nice but not urgent" tasks that I've had in the works for years. Rebuilding the site to Jekyll was probably the hardest part, so the redesign should go smoother than the Sodaware one.

2. Build another game

I have plenty of ideas, it's just a matter of finding the most realistic ones to develop. I have a tendency to over-complicate them which doesn't help when there's only a few weeks to create them.

3. Blog more

A permanent goal that I frequently miss.

Groundhog Day Resolutions 2016

Last year I decided to start the year right by organizing all of my goals and ideas onto a Trello board. It seemed like a productive thing to do at the time.

However, when December rolled around there was still much that hadn't been touched. It wasn't that I didn't want to do things, they just got lost amongst everything else.

The lesson for me here: it's not much use having things written down if you don't look at them.

This year I'm trying something different: Dave Seah's Groundhog Day resolutions. Instead of a large list of resolutions at the start of the year, it's a smaller list made every month.

Here's February's (very short) list:

Release a game for #1GAM 2016

I wrote 4 games for #1GAM back in 2014 and had a great time. 2015 was not so good, but I want to get back on the game development wagon this year.

Finish the rebuild of Sodaware

This is something I've wanted to get done for a while but just kept pushing it back. Sodaware was my first "real" website, but sadly it's been left to gather dust over the last few years.

My original plan was to use Jekyll (which is what powers this site), but I've since decided to go with Middleman. I still like Jekyll, but Middleman felt like a better fit for a none-blog site.

Write one blog post a week

Every year I tell myself I'm going to start writing more. Why should 2016 be any different?

More to come next month (March 3rd).