ProjectSettings are settings for Emacs that apply to all files in a directory (“project”) and are distributed along with said directory. This is a very useful feature for working in a team of people who have to agree on coding standards for source code, character coding systems for text documents (see SelectingTheRightCodingSystem), and so on.

Similar functionality has been integrated into current Emacs.
See DirectoryVariables.

This makes solutions like ProjectLocalVariables and DirVarsPackage obsolete.

Project Settings in Lisp

KimStorm suggested to store the stuff in a function.

(setq c-style-variables-are-local-p t)

(defun my-c-mode-hooks ()
  (let ((bname (buffer-file-name)))
     ((string-match "tools_src/" bname) (c-set-style "gnu"))
     ((string-match "uClinux/" bname) (c-set-style "linux"))
     ((string-match "pump/" bname) (c-set-style "gnu"))
     ((string-match "dhcp-" bname) (c-set-style "gnu"))
     ((string-match "ipconfd/" bname) (c-set-style "gnu"))
     ((string-match "gnu/emacs/" bname) (gnu-tabs))
     ((string-match "nn-tk/" bname) (tab8))
     ((string-match "gnu" bname) t)
     ((string-match "\\.[ch]$" bname) (c-set-style "gnu"))

(add-hook 'c-mode-hook 'my-c-mode-hooks)

Note how the function executes everytime C mode runs.

Helper code based on existing files and subdirectories: project-root.el

Updated version with new features (link works but no .el file): project-root.el (Updated version on BitBucket: project-root.el)

Project-root is a very simple module that allows you to define projects like this:

  (setq project-roots
        '(("Blog" :root-contains-files ("index.muse" "images" "content"))
          ("Generic Perl Project" :root-contains-files ("t" "lib"))))

With this configuration, anytime you are in a project with t and lib at the root level you will have access to the project-root functions. This will allow you to write project-specific code.

When ever you are in a project you will have access to ‘project-details’ that will look like this:

("Generic Perl Project" . "/home/phil/projects/something")

and you get a handy macro called ‘with-project-root’ that lets you do stuff like this:

(with-project-root (call-interactively 'grep))

Which will run grep as if it had been called from the root directory.

There are several helpers already defined in the module and the option to use the provided anything.el integration should one wish.

Open a shell at current root

(global-set-key (kbd "C-c p s")
                (lambda ()
                       (getenv "SHELL")
                       (concat (car project-details) "-shell")))

Start a vc interface at root

(global-set-key (Kbd "C-c p v")
                (lambda ()
                      (let ((root (cdr project-details)))
                          ((file-exists-p ".svn")
                           (svn-status root))
                          ((file-exists-p ".git")
                           (magit-status root))
                           (vc-directory root nil)))))))

Get hook and minor mode based on relevant files: eproject.el

Download: eproject.el

eproject is similar to project-root.el, but less invasive and more customizable. The docs in the file are pretty descriptive, as is this blog post (archive org version) (see original source code for that blog post).

Basically, you can declare project types like:

(define-project-type perl (generic)
  (or (look-for "Makefile.PL") (look-for "Build.PL"))
  :relevant-files ("\\.pm$" "\\.t$" "\\.pl$" "\\.PL$"))

then you get a hook and minor mode that you can customize further.

Project management using EDE

The EDE tool EricLudlam wrote tries to do project management. It has a concept of project local variables which it will set for you in your source files when you edit them. This innocuous feature comes along with a lot of baggage, however, in that EDE has a big project configuration file, tracks all related source files, and will also try to build Makefiles for you, and nifty stuff like that.

A simple package: pgrok

pgrok is a simple package for loading project setting files (both generic and mode specific) and containing a couple of functions for operating on projects (wrappers for find-dired and rgrep at the moment.)

Using an existing package: desktop

You can also create a little project-management tool out of DeskTop. Provided that you’ve got a directory with a subdirectory for every single project you work on (it doesn’t have to contain the project’s source code), you can switch between desktops (“workspaces” or “projects” in other IDEs’ terminology). DeskTop will remember paths of open files and values of variables (you can customize which variables you want).

A unified interface to the project manager libraries using projany

The purpose of projany is to provide a unified interface to the half a dozen emacs project manager libraries out there. It is intended to give libraries a way of knowing about projects without committing to any particular project manager.

This is alpha software. Right now all it provides is ‘projany-pick’, which picks a file of some given type from a project.

Some slight support for EDE with projany is at:


Projectile “provides easy project management and navigation.” A project is a folder containing a special file. Currently git, mercurial and bazaar repositories are considered projects by default. You can also manually designate a folder as a project.

CategoryDotEmacs CategoryProgrammerUtils