Can flymake's temporary file be created in the system's temporary directory?

点点圈 提交于 2019-12-03 16:03:01

For me, i have resolved by modify user script /usr/local/bin/pyflakes, i test if file exist, if no, i add a slash.

#!/bin/bash

FILE=$1

# Test if folder exist
if [ ! -e "$FILE" ]; then
FILE="/$1"
fi

epylint "$FILE" 2>/dev/null
pep8 --ignore=E221,E701,E202 --repeat "$FILE"
true

I don't have a direct solution to the pyflakes question, but here's something similar for you.

I didn't like how C# was handled in flymake, so I modified the C# entry in the flymake-allowed-file-name-masks to refer to distinct init and cleanup routines, with this code:

(let ((csharpentry (assoc "\\.cs\\'" flymake-allowed-file-name-masks)))
  (if csharpentry
      (setcdr csharpentry '(csharp-flymake-init csharp-flymake-cleanup))
    (add-to-list
     'flymake-allowed-file-name-masks
     (list key 'csharp-flymake-init 'csharp-flymake-cleanup))))

The documentation is sort of spotty on this stuff, but the code is the documentation, and from what I could tell, the init routine is supposed to return the command line for a syntax check run. It is formatted as a 2-element list, the car is the command to run, and the cadr is itself a list of the arguments. In my example the return value is like this:

("csc.exe" ("/t:module" "/nologo" "nameOfFileToCheck.cs"))  

The init routine that returns this command line copies the existing buffer into a temporary file, using flymake's builtin copy fn, and then uses the name of the temp file as the thing to check. So if the buffer filename is "source.cs", the actual value returned from the init fn is

("csc.exe" ("/t:module" "/nologo" "source_flymake.cs"))  

The code looks like this:

(defun csharp-flymake-init ()
  (csharp-flymake-init-impl
   'flymake-create-temp-inplace t t 'csharp-flymake-get-cmdline))

(defun csharp-flymake-init-impl (create-temp-f use-relative-base-dir use-relative-source get-cmdline-f)
  "Create syntax check command line for a directly checked source file.
Use CREATE-TEMP-F for creating temp copy."
  (let* ((args nil)
        (temp-source-file-name  (flymake-init-create-temp-buffer-copy create-temp-f)))
    (setq args (flymake-get-syntax-check-program-args
                temp-source-file-name "."
                use-relative-base-dir use-relative-source
                get-cmdline-f))
    args))

I implemented it in 2 distinct functions, only to follow the pattern I saw in flymake.el.

Anyway...What you can see is that the init fn creates the temp file then returns the arguments. The call to flymake-get-syntax-check-program-args actually boils down to a call into get-cmdline-f, which in the case of C# is csharp-flymake-get-cmdline. Why all this layering and indirection? I don't know; that's how flymake is.

In the C#-specific cleanup fn, I just check for any "product" files from the syntax check and delete them, and then also chain to flymake-simple-cleanup, to delete the *_flymake.cs temp file that was created.

Maybe your nested dir path has something to do with the use-relative-base-dir and use-relative-source arguments that flymake uses in its own default init routine, which I think is flymake-simple-make-init-impl.

The function make-temp-file uses the variable temporary-file-directory, so perhaps you could try setting temporary-file-directory to something else to fix your problem.

This is what I use for PHP on Windows. It uses the make-temp-file suggestion from Trey. It also explicitly sets the init and cleanup functions for PHP, to the things I want. You could use basically the same thing, for python.

(defun cheeso-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.

This won't always work; it will fail if the source module
refers to relative paths.
"
  (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))


(defun cheeso-php-flymake-get-cmdline  (source base-dir)
  "Gets the cmd line for running a flymake session in a PHP buffer.
This gets called by flymake itself."

        (list "c:\\Progra~2\\PHP\\v5.3\\php.exe"
              (list "-f" source  "-l")))


(defun cheeso-php-flymake-init ()
  "initialize flymake for php"
  (let ((create-temp-f 'cheeso-flymake-create-temp-intemp)
        ;;(create-temp-f 'flymake-create-temp-inplace)
        (use-relative-base-dir t)
        (use-relative-source t)
        (get-cmdline-f 'cheeso-php-flymake-get-cmdline)
        args
        temp-source-file-name)

    (setq temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f)

          args (flymake-get-syntax-check-program-args
                temp-source-file-name "."
                use-relative-base-dir use-relative-source
                get-cmdline-f))
    args))


(defun cheeso-php-flymake-cleanup ()
  )

(eval-after-load "flymake"
  '(progn

  ;; 1. add a PHP entry to the flymake-allowed-file-name-masks
  (let* ((key "\\.php\\'")
         (phpentry (assoc key flymake-allowed-file-name-masks)))
    (if phpentry
        (setcdr phpentry '(cheeso-php-flymake-init cheeso-php-flymake-cleanup))
      (add-to-list
       'flymake-allowed-file-name-masks
       (list key 'cheeso-php-flymake-init 'cheeso-php-flymake-cleanup))))))
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!