ModeCompile provides a smart command for compiling files according to major-mode.

Compile commands are defined for CcMode, CPlusPlusMode, MakefileMode, DiredMode, AdaMode, EmacsLispMode, LispInteractionMode, ShMode, csh-mode, fundamental-mode, TextMode, indented-text-mode, CompilationMode, FortranMode, CPerlMode, zsh-mode, JavaMode, TclMode, PythonMode.

For other modes a default behaviour is provided.

A live github version is here:

You used to be able to get the latest version here, but this link is dead as of May 2020:

Put something like this in your .emacs:

    (autoload 'mode-compile "mode-compile"
      "Command to compile current buffer file based on the major mode" t)
    (global-set-key "\C-cc" 'mode-compile)
    (autoload 'mode-compile-kill "mode-compile"
      "Command to kill a compilation launched by `mode-compile'" t)
    (global-set-key "\C-ck" 'mode-compile-kill)

See Also : DwimCompile, SmartCompile, CompileCommand

mode-compile and SQL

I’ve been using this for running SQL scripts, , patch is at ModeCompileSql --TimAnderson

Automatically close the compilation buffer after a successful compilation

Assume you run M-x compile and the compilation succeeds without an error. Then the *compilation* window is usually not of much interest. Put the following code into your .emacs file to close this window. The *compilation* buffer itself will be kept, but buried, so that C-x b doesn’t go directly to it.

  ;; Helper for compilation. Close the compilation window if
  ;; there was no error at all.
  (defun compilation-exit-autoclose (status code msg)
    ;; If M-x compile exists with a 0
    (when (and (eq status 'exit) (zerop code))
      ;; then bury the *compilation* buffer, so that C-x b doesn't go there
      ;; and delete the *compilation* window
      (delete-window (get-buffer-window (get-buffer "*compilation*"))))
    ;; Always return the anticipated result of compilation-exit-message-function
    (cons msg code))
  ;; Specify my function (maybe I should have done a lambda function)
  (setq compilation-exit-message-function 'compilation-exit-autoclose)


This has the side-effect of making your rgrep output vanish upon success.

– Tero

Here is a variation on the above that is more convenient if you like working with two windows open. It will switch back to whatever buffer was in your other window if compilation is successful. Ideally, there would be a way to restore the window state to whatever it was before compilation started.

  ;; Close the compilation window if there was no error at all.
  (setq compilation-exit-message-function
        (lambda (status code msg)
          ;; If M-x compile exists with a 0
          (when (and (eq status 'exit) (zerop code))
            ;; then bury the *compilation* buffer, so that C-x b doesn't go there
  	  (bury-buffer "*compilation*")
  	  ;; and return to whatever were looking at before
  	  (replace-buffer-in-windows "*compilation*"))
          ;; Always return the anticipated result of compilation-exit-message-function
  	(cons msg code)))


Holger’s code looks promising, but doesn’t work in xemacs; it can be adapted, by using compilation-finish-function instead of compilation-exit-message-function (and, I believe, that’s a semantically more appropriate variable even for emacs). Unfortunately, the interface is quite a bit more opaque, which makes me think I need to test it some more before releasing the adaptation.


A first pass at compilation-finish-functions. We don’t get an exit code like Holger’s function above, but the cons cell doesn’t get inserted into whatever bufffer is current at the moment.

 (setq compilation-finish-functions 'compile-autoclose)
 (defun compile-autoclose (buffer string)
   (cond ((string-match "finished" string)
          (message "Build maybe successful: closing window.")
          (run-with-timer 10 nil                      
                          (get-buffer-window buffer t)))
          (message "Compilation exited abnormally: %s" string))))

You also can use winner-undo from WinnerMode to get back to whatever window configuration you had before compile:

  (setq compilation-finish-functions 'compile-autoclose)
  (defun compile-autoclose (buffer string)
     (cond ((string-match "finished" string)
	  (bury-buffer "*compilation*")
          (message "Build successful."))
          (message "Compilation exited abnormally: %s" string))))



The winner-mode version is excellent but does not work when ECB is activated. Any hint?

LaTeX support for mode-compile

To compile LaTeX with mode-compile does not work out-of-the-box as AUCTeX makes the variable compile-command (see CompileCommand) buffer-local and thus mode-compile never looks up entries in mode-compile-modes-alist. But it works like follows:

  (add-hook 'LaTeX-mode-hook 'mysite-latex-mode-hook)
  (defun mysite-latex-mode-hook () 
    (kill-local-variable 'compile-command)  
  (setq mode-compile-modes-alist
       (append '((latex-mode . (tex-compile kill-compilation)))


mode-compile is unmaintained

Ok, so I am not an expert, but this mode is unmaintained many other mode seem to need it, at least to use them to their full potential lile CPerl-Mode for example

is this an issue? (maybe it isnt, maybe it doesnt need any updated, i dont know, but someone more knowlegeable about it use should day so)

is there a replacement? is mode-compile replaced by a new framework for compilation? i dont know, things seem unclear, and googling doesnt help much --SysTems

My guess is that most people just use ‘M-x compile’ and are happy enough with the defaults. See CompileCommand. – AlexSchroeder

I dont think M-x compile is a replacement to M-x mode-compile, I needed mode-compile for CPerlMode, to be able to execute Perl script inside emacs, and get the output in an emacs buffer M-x compile seem to call Make --SysTems