I am in the way of automating my compilation process with, what is an unexplored but an omnipotent command compile. I expect it to decide upon the compiler using the filename extension & also, fill in the file name argument from the current buffer.

I made it half-way through for c & java modes,

(defun sk-compile-pre-hook ()
  (pcase major-mode
     (setq compile-command (concat "gcc " (buffer-file-name))))
     (setq compile-command (concat "javac " (buffer-file-name))))))
(add-hook 'c-mode-hook 'sk-compile-pre-hook)
(add-hook 'java-mode-hook 'sk-compile-pre-hook)

This works as long as I have one file of a type (java or c) open in the buffer. Life is not meant to be easy, though. The moment i open a second file of the same type, the mode hooks are not run again. Possibly, the mode configurations are not loaded the second time.

So, when i invoke compile command from the second file, it still refers to the first file as its argument.

Now, i explored the other way through advice as,

(advice-add 'compile :before
        (lambda (_)

Now, this puts me one step back, the compile-command is not modified and retains its original value as make -k.

Is there a work-around to set a new compile command, every time a file is loaded? Something that Vim's dispatch plugin provides like
autocmd FileType java let b:dispatch = 'javac %'

1 Answer 1


Directory variables may be used to solve the problem.

Contents of .dir-locals.el in the root of the project directory:

((c-mode . ((eval . 
                     (setq-local compile-command
                                 (concat "gcc " (buffer-file-name))))))
 (java-mode . ((eval . 
                     (setq-local compile-command
                                 (concat "javac " (buffer-file-name)))))))


Use of eval in directory or local variables is discussed at https://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html

There is a also short example there with compile-command.

  • this works like a charm. but, a more cleaner solution with one time configuration in .emacs, thus avoiding dir-specific confs is appreciated...
    – Saravana
    Commented Mar 7 at 0:03
  • Try your sk-compile-pre-hook exactly as above except instead of (setq compile-command ...) (setq-local compile-command). If you do C-h o compile-command there is an example making compile-command buffer local in a hook. Commented Mar 7 at 23:00

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.