Flymake is a emacs package for on-the-fly syntax checking. IDEs such as emacs will highlight syntax errors in red without needing to compile the program, allowing you to fix errors as you are typing; Flymake implements this for emacs. Flymake works by using an external tool(usually a compiler) and checking the output of it for errors to highlight. Flymake also provides tooltips over these errors to explain what went wrong.
Flymake’s customization is a huge pain and fairly incomprehensible. There’s a TODO item in Emacs for someone to fix it, if you’re interested in cleaning it up at all. Having looked at it, I’d actually rather just reimplement it than attempt to fix it so that the configuration isn’t as bad. One of the main problems with Flymake is that it relies on functions defined within itself in order to actually run the syntax check; to change how you want syntax checking to be performed, you have to load flymake and override these functions in your initialization.
For C++/Java, there were two functions that I needed to override. One was understandable; the flymake-get-make-cmdline returns the command to call ‘Make’ with. The default version of this function adds arguments to make that tended to fail, so I replaced it with a much simpler version:
(require 'flymake) (defun flymake-get-make-cmdline (source base-dir) (list (car (flymake-split-string compile-command " ")) (cdr (flymake-split-string compile-command " "))))
This version just uses the buffer-specific compile-command in order to determine how to syntax check the buffer. If I was to fix flymake, this would be one of the key changes; it would respect compile-command instead of providing it’s own defaults for compiling different types of buffers. There would be an option to change it, but in all cases it would default to using compile-command.
The other function I had to override I was not entirely sure why was failing. It is the function called after syntax-checking is complete, and can turn off flymake-mode if any errors are encountered in the actual command used. It was reporting that the ‘make’ command was returning error code ‘2′ in some cases when there was no output, and so I modified it slightly to pass on that exit-status as well.
(defun flymake-post-syntax-check (exit-status command) (setq flymake-err-info flymake-new-err-info) (setq flymake-new-err-info nil) (setq flymake-err-info (flymake-fix-line-numbers flymake-err-info 1 (flymake-count-lines))) (flymake-delete-own-overlays) (flymake-highlight-err-lines flymake-err-info) (let (err-count warn-count) (setq err-count (flymake-get-err-count flymake-err-info "e")) (setq warn-count (flymake-get-err-count flymake-err-info "w")) (flymake-log 2 "%s: %d error(s), %d warning(s) in %.2f second(s)" (buffer-name) err-count warn-count (- (flymake-float-time) flymake-check-start-time)) (setq flymake-check-start-time nil) (if (and (equal 0 err-count) (equal 0 warn-count)) (if (or (equal 0 exit-status) (equal 2 exit-status)) (flymake-report-status "" "") ; PASSED (if (not flymake-check-was-interrupted) (flymake-report-fatal-status "CFGERR" (format "Configuration error has occured while running %s" command)) (flymake-report-status nil ""))) ; "STOPPED" (flymake-report-status (format "%d/%d" err-count warn-count) ""))))
I had one other issue with flymake; tooltips for overlays are not displayed in the echo area when point is over them. js2-mode has this functionality, and it is very useful to not have to use the mouse or compile yourself to see the exact error message for each line. I looked at how js2-mode implemented it, which turned out to be with text properties. Strings in emacs *can* have a function called when point enters them: it is only overlays that do not. js2-mode created both an overlay and modified the text properties at that location in the buffer, which is a somewhat inelegant solution. Asking on emacs-devel clued me into the help-at-pt package, which if enabled will display any tooltips for location at point in the echo area. To enable this, put the following in your initialization file:
(setq help-at-pt-timer-delay 0) (help-at-pt-set-timer)
Help-at-pt uses the idle-timer in order to determine when to display tooltips; after help-at-pt-timer-delay seconds, it will display the tooltip at point in the echo area. A value of 0 will have the tooltip display immediatly. This isn’t as elegant as giving overlays the ability to run functions when entered, but it works and is part of emacs-core.
Another problem I have with flymake/java is that it can only highlight an entire line instead of just the section of the line that is causing the trouble.