Currently, my compilation command is as follow:

cd ~/somedir && ./somescript.sh

This prevents emacs from finding the file in which an error happens (and opening it).

Of course I can run M-x cd manually but is there a way to tell the buffer to change its current directory programmatically?

  • 1
    This is something I've been trying to do, too. Ideally, there'd be something you can put in .dir-locals.el in the base directory that would work (hacks I've seen to set default-directory there cause undesirable side effects, and setting it only for compilation-mode doesn't seem to work). Nov 26, 2014 at 17:55

4 Answers 4


Finally, I abandoned relying on the current directory as it was too intrusive and other things like ido where ending being affected...

Instead, I use added my build directory to compilation-search-path

(add-to-list 'compilation-search-path "/path/to/build")

Found on this question: How to adjust the path that Emacs' compile-goto-error gets from the compilation buffer?

The question also explains that the directory matcher can change the directory automatically if some particular strings are emitted:

Entering directory `...'
Leaving directory `...'

This is also customizable apparently.

  • This looks like a robust solution. If it works for you, feel free to accept it.
    – Malabarba
    Jun 1, 2015 at 21:20
  • Note that this may not work if you need the build system find some files in /path/to/build. Aug 20, 2019 at 14:53

You can simply make a Dired buffer of the directory where you want to invoke compile command, to serve as an anchor. When you want to compile, switch to the Dired buffer and run compile command. compile will run its command at this directory of the Dired buffer. The advantage of this is that you don't have to M-x cd or traverse directories when you want to compile.

If you use projectile, it has a command named projectile-compile that automatically runs compile command at project root recognized by projectile.


This alternate command should do the trick:

(defun compile-in-dir (dir command)
  (interactive "DCompile in directory: \nsCommand: ")
  (let ((default-directory dir))
    (compile command)))

Alternatively, after you have run the compilation using the regular compile command, you can eval (setq default-directory "~/somedir") in the *compilation* buffer. That should make the error navigation work, but it might stop recompile and friends from doing the right thing.


If you have a rule for creating the source search path, you can add it as advice to the function that compile uses for finding paths. For example, the default directory for building with bazel is ~/.cache/bazel. So I want to find all those and strip out that part of the file. I added an "advice" to the compilation-find-file function so that it will rename the file before calling the function. That elisp is:

;; Rewrite the names of bazel error filenames.
(defun rename-bazel (orig-fun marker filename &rest args)
  (let ((new-filename (or (and (string-match "^\\(.*\\)/.cache/bazel/.*/__main__/\\(.*\\)" filename)
                               (concat (match-string 1 filename) "/" (match-string 2 filename)))
    (apply orig-fun marker new-filename args)))

(advice-add 'compilation-find-file :around #'rename-bazel)

Now when I click on errors in the compilation buffer, it goes to the right place.

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.