I'm trying to map F5 to compile from a parent directory of the current buffer.

Emacs compile-command find makefile in superior directory provides an excellent answer to achieve this:

(defun compile-project ()
  (let* ((make-directory (locate-dominating-file (buffer-file-name)
          (command (concat "make -k -C "
                           (shell-quote-argument make-directory))))
  (compile command)))

(global-set-key (kbd "<f5>") 'compile-project)

Besides, C/C++ Development Environment for Emacs describes a way such that F5 does not prompt for the compile command every time, but if a prefix argument C-u is provided, then compile prompts for a compile command:

(global-set-key (kbd "<f5>") (lambda ()
                               (setq-local compilation-read-command nil)
                               (call-interactively 'compile)))

Question: How can I modify the compile-project function, so that when a prefix command C-u is provided, it shows the compilation command in the mini-buffer, including a default command of make -k -C ... generated by the body of let*?


I think that you almost had it. I modified your original compile-project as follows:

(defun compile-project ()
  (let* ((mk-dir (locate-dominating-file (buffer-file-name) "Makefile"))
         (compile-command (concat "make -k -C " (shell-quote-argument mk-dir)))
         (compilation-read-command nil))
    (call-interactively 'compile)))

The only real difference is that the compile function reads from compilation-read-command to figure out how to read the compilation command and compile-command. If you set compilation-read-command to nil, compile will use the value of compile-command instead of prompting.

(Also, all of this is available in M-x describe-function compile if you need to look up something more.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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