13

I have some customizations for emacs that I'd like to use for a single project, but not affect emacs globally. Is there any way I can have emacs load a specific init file when launched from a certain directory or automatically load all init files in the directory its launched from?

3 Answers 3

19

You might want to take a look at Directory variables. Basically you will need to create a .dir-locals.el file in your project root with all the project specific setting in it. Now whenever you open a file in the directory or any of its subdirectories emacs will apply the settings in the .dir-locals.el file.

So for example suppose you want to use the make package install as compile command only in project A, you will need to create a file named .dir-locals.el in root directory of the project and add something like the following

((nil . ((compile-command . "make package install"))))

Henceforth whenever you run compile command from any file under the directory A, the default compile-command will be the one specified above, however the compile command for files outside the directory A will stay untouched.

4

A less-featured alternative to .dir-locals.el is the EditorConfig standard, which has an emacs-package. It doesn't support nearly as many options, however, it allows a team of people to standardize on some settings and use them across different editors.

It behaves much the same way, with a project-specific .editorconfig file at the top-level.

0

I know this is an old question, with an accepted answer. I found this entry, because I had the same question. I also agree that EditorConfig is attractive in team-contexts, but that is not relevant for me (anymore).

In fact, the accepted answer does not fully answer the question; Directory variables only let you set configuration variables. This does not allow all features that are possible in an emacs init file, such as defining new functions that are only relevant for the current project (or it only allows that via a rather tricky mechanism).

I found that the following a approach works better for me and is an more complete answer to the question. Perhaps it helps someone else who finds this question.

Add the following to your global emacs init file (~/.emacs , ~/.emacs.d/init.el or ~/.config/emacs/init.el):

(if (file-exists-p "./.emacs-local.el")
  (load-file "./.emacs-local.el"))

Now, suppose there exist such a file:

$ cat ~/my-super-project/.emacs-local.el

;; -*-Lisp-interaction-*-
;; Experimental local config
;; ONLY AS AN EXAMPLE IN THIS STACKEXCHANGE ANSWER 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Comment-out the current line, in mode-specific way.
(defun comment-current-line (arg)
  (interactive "p")
  (beginning-of-line)
  (let ((beg (point)))
    (forward-line 1)
    (comment-region beg (point)))
  (end-of-line))

;; Always hit the # key to comment-out current line.
(global-set-key "\#"       'comment-current-line)

Then this function and keybinding become available after cd'ing into that project directory before starting emacs.

$ cd ~/my-super-project
$ emacs . &

Of course, the two-liner load instruction could be improved by checking if the file is also readable, by carrying the filename in a variable, by checking a few file-name variants, etc., etc.. But that is left as an exercise to the reader.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.