a smarter wrapper for `compile'
M-x package-install [RET] smarter-compile [RET]
This package provides `smarter-compile' function. It acts as a wrapper for `compile', providing a way to intelligently set the `compile-command' and then invoke `compile' as normal. It chooses a compile command, and suggests it by invoking `compile' interactively. It makes the choice according to the name of the current buffer, and the items - think of them as rules - in the `smart-compile-alist'. By default, it performs the selection logic just once per buffer. When you run `smarter-compile', it sets a buffer-local flag and does not walk the rules again. If you'd like to force to walk through the rules, use C-u M-x smarter-compile. The built-in rules are like this: - If there is a makefile in the current directory, ask if the user wants to run make, and if so, suggest make. - If there is a Msbuild project file in the current directory, suggest msbuild.exe . - if there is a comment in the header like compile: <...>, and the file has an extension that is a member of `smart-compile-compile-command-in-comments-extension-list', then use that string that as the compile command. - if editing a makefile, suggest make. - if the file extension is .cs, .vb, .c, .java, and so on... use a module-specific build command. To use this package, add this line to your .emacs file: (require 'smart-compile) To tweak it, set `smart-compile-alist'. This variable holds the rules for guessing the compile command. It is a list of cons cells, each one like (TEST . COMMAND). In the simplest case, the TEST is a regex that gets applied to the filename, and COMMAND is a string used for the `compile-command' when the TEST succeeds. You can either setq the list, which would replacing the built-in rules completely, or you can append items to the default list, thereby extending the built-in behavior of `smarter-compile.el'. Keep in mind that the order of evaluation of the rules is significant. The simplest kind of extension of the rules looks like this: (require 'smarter-compile) (add-to-list 'smart-compile-alist '("\\.css\\'" . "/bin/csslint.js --format=compiler %f")) More Details: That example uses a string for both the TEST and the COMMAND. But there are other options. TEST can be: - a string. In this case it is used as a regex, and test against the filename associated to the buffer. The TEST succeeds when the regex matches. - a symbol, representing the major-mode. In this case if the buffer uses that major mode, the TEST succeeds. - a symbol, representing any function with a name not ending in \"-mode\". In this case, the function is called and if it returns non-nil, the TEST succeeds. - a list of forms. In this case the forms are eval'd, and if the return value is non-nil, the TEST succeeds. COMMAND can be: - a string. This is used as a template to generate the actual shell command. `smarter-compile` will replace these opcodes in the string. %M make program ( nmake.exe or make ) %F absolute pathname ( /usr/home/dev/Module.c ) %f file name without directory ( Module.c ) %n file name without extension ( Module ) %e extension of file name ( c ) %t current time in 24-hr format ( 12:44:18 ) %d current date ( 2012-Mar-20 ) `smart-compile.el' sets `compile-command' to the string with all the replacements. With no opcodes, the COMMAND string is used directly as `compile-command'. - a symbol, representing a function. In this case the return value of the function should be a string. It is expanded as described above, and the expansion is then used as the `compile-command'. - a list of forms. In this case the list is eval'd, and the return value should be a string. It is expanded as described above, and the expansion is then used as the `compile-command'. Again, when extending, remember that the ordering of the rules is important. For example, the default ruleset in smarter-compile includes a test that returns true if a makefile is present in the current directory. There is also a rule that returns true if the file extension is .c. When both conditions are true, the order of these rules in the list determines which of the rules will apply. Rather than adding new rules, you may wish to replace existing rules in `smart-compile-alist'. There's a convenience function for this purpose. It inserts or replaces as appropriate: (require 'smarter-compile) (smart-compile-insert-simple-rule "\\.css\\'" "/bin/csslint.js --format=compiler %f") `smart-compile-insert-simple-rule' works best when the test is a string.