This has been bugging me for awhile. Recent versions of Emacs save _flymake files “inplace”, meaning in the same directory as the source file. Problem is, Flymake has a tendency to crash, leaving behind the corpses of various _flymake files, which in turn cause version control annoyances, automated build issues, unusual problems with caching in web frameworks, etc.
There’s an obscure FlymakeRuby entry on the EmacsWiki with a suggested fix, repeated here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
(defun flymake-create-temp-intemp (file-name prefix) "Return file name in temporary directory for checking FILE-NAME. This is a replacement for `flymake-create-temp-inplace'. The difference is that it gives a file name in `temporary-file-directory' instead of the same directory as FILE-NAME. For the use of PREFIX see that function. Note that not making the temporary file in another directory \(like here) will not if the file you are checking depends on relative paths to other files \(for the type of checks flymake makes)." (unless (stringp file-name) (error "Invalid file-name")) (or prefix (setq prefix "flymake")) (let* ((name (concat (file-name-nondirectory (file-name-sans-extension file-name)) "_" prefix)) (ext (concat "." (file-name-extension file-name))) (temp-name (make-temp-file name nil ext)) ) (flymake-log 3 "create-temp-intemp: file=%s temp=%s" file-name temp-name) temp-name)) |
Add this to lisp/progmodes/flymake.el in your Emacs distro, and then call it from the init method corresponding to your target language. PHP, for example:
1 2 3 4 5 6 7 8 |
;;;; php-specific init-cleanup routines (defun flymake-php-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-intemp)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "php" (list "-f" local-file "-l")))) |
Note that 'flymake-create-temp-inplace
has been replaced with 'flymake-create-temp-intemp
. Be sure to remove or recompile the corresponding flymake.elc file.
Now _flymake junk will be saved to where you have defined temporary-file-directory in .emacs. In my case:
(setq temporary-file-directory "~/.emacs.d/tmp/")
Yay. Much less annoying.
I got some errors that i thought were because of the relative nature of the paths returned by your function, wrapping the definition of “temp-name” in the let* expression with (file-truemane) [the “make-into-an-absolute-path” function] fixed it for me.
The line I changed:
from: (temp-name (make-temp-file name nil ext)))
to: (temp-name (file-truename (make-temp-file name nil ext))))
And the new full function-def, for copy-and-pasting:
(defun flymake-create-temp-intemp (file-name prefix)
“Return file name in temporary directory for checking FILE-NAME.
This is a replacement for
flymake-create-temp-inplace'. The
temporary-file-directory’ instead of the same directory asdifference is that it gives a file name in
FILE-NAME.
For the use of PREFIX see that function.
Note that not making the temporary file in another directory
\(like here) will not if the file you are checking depends on
relative paths to other files \(for the type of checks flymake
makes).”
(unless (stringp file-name)
(error “Invalid file-name”))
(or prefix
(setq prefix “flymake”))
(let* ((name (concat
(file-name-nondirectory
(file-name-sans-extension file-name))
“_” prefix))
(ext (concat “.” (file-name-extension file-name)))
(temp-name (file-truename (make-temp-file name nil ext))))
(flymake-log 3 “create-temp-intemp: file=%s temp=%s” file-name temp-name)
temp-name))
Thanks. That really helped.
One drawback on the cutting and pasting part, though:
The quotation marks are not plain ascii, thus the code above is invalid. You will have to replace “ and ” and the like with their respective ascii versions.
And there is a typo in the docstring. I believe
“Note that not making the temporary file in another directory
will not if the file…”
shoud read
“… will not work if …”