5

私は現在、次のコードを使用して、emacsでflymakeとPyflakesを接続しています。

(defun flymake-create-temp-in-system-tempdir (filename prefix)
  (make-temp-file (or prefix "flymake")))

次に、この関数をに渡しますflymake-init-create-temp-buffer-copy。(http://hustoknow.blogspot.com/2010/09/emacs-and-pyflakes-using-tmp-directory.htmlから取得)。

このコードは昨日まで正常に機能しました。特定のPythonファイルにアクセスすると、次のエラーが発生します。

switched OFF Flymake mode for buffer admin.py due to fatal status
CFGERR, warning Configuration error has occured while running    
(pyflakes ../../../../../../../tmp/flymake28459SVv)

flymakeが間違ったファイル名のように見えるものをpyflakesに渡すのはなぜですか?「/tmp/ efe234234」のようなものを渡すことを期待していますが、tmpディレクトリの設定は変更していません。

最近Ubuntu用に更新されたemacsを思い出せず、これが混乱する原因となった可能性のあるものは何も考えられません(.emacsファイルはバージョン管理されています)。

私が考えることができる唯一の問題は、これが私の〜/ Dropboxディレクトリ内のディレクトリにシンボリックリンクされた密にネストされたディレクトリであるということですが、これは同様の方法でシンボリックリンクされた他のディレクトリには発生しません。

この問題を解決するにはどうすればよいですか?

アップデート

デバッグを行ったところ、引数として正しいパスが渡されていないことがわかりました。パスを機能させるには、もう1つの親ディレクトリをパスに挿入する必要があります。これにより、シンボリックリンクが原因で混乱しているように見えます。

これが私が何を意味するかを示すためのシェルセッションの例です。私は正しい相対ディレクトリからこれを行っています:

$ pyflakes ../../../../../tmp/flymake13382xHi 
../../../../../tmp/flymake13382xHi: No such file or directory

これは、flymakeが実行しようとしているコマンドです。変更した場合:

$ pyflakes ../../../../../../tmp/flymake13382xHi

(期待どおりに)出力が得られません。パス内の余分な「..」に注意してください。

これらのクレイジーな相対パスの代わりに絶対パスをflymakeに渡すにはどうすればよいですか?

更新2

私はすべてが機能するようになりました。基本的にこの機能があります:

(defun flymake-pyflakes-init ()
     ; Make sure it's not a remote buffer or flymake would not work
     (when (not (subsetp (list (current-buffer)) (tramp-list-remote-buffers)))
      (let* ((temp-file (flymake-init-create-temp-buffer-copy
                    'flymake-create-temp-in-system-tempdir))
             (local-file (file-relative-name
                      temp-file
                      (file-name-directory buffer-file-name))))
    (list "pyflakes" (list temp-file)))))

最後の部分では、引数をlistからlocal-fileに変更する必要がありました。これは、私が望まなかったクレイジーな相対パスだったtemp-fileためです。そもそも、local-fileそのスニペットの作成者が使用したのはなぜですか?local-file

ありがとう、ライアン

4

4 に答える 4

1

私にとっては、ユーザー スクリプト /usr/local/bin/pyflakes を変更することで解決しました。ファイルが存在するかどうかをテストし、存在しない場合はスラッシュを追加します。

#!/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
于 2013-03-07T22:16:34.203 に答える
0

これは、私が Windows で PHP に使用するものです。make-temp-fileTrey からの提案を使用します。また、PHP の init 関数と cleanup 関数を、私が望むものに明示的に設定します。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))))))
于 2011-09-15T13:58:53.530 に答える
0

pyflakes の質問に対する直接的な解決策はありませんが、似たようなものがあります。

flymake での C# の処理方法が気に入らなかったので、次のflymake-allowed-file-name-masksコードで C# エントリを変更して、個別の init ルーチンとクリーンアップ ルーチンを参照するようにしました。

(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))))

この件に関するドキュメントはちょっとむらがありますが、コードはドキュメントであり、私が知る限り、init ルーチンは構文チェックの実行のためにコマンド ラインを返すことになっています。car は実行するコマンドで、cadr 自体は引数のリストです。私の例では、戻り値は次のようになります。

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

このコマンド ラインを返す init ルーチンは、flymake のビルトイン コピー fn を使用して既存のバッファを一時ファイルにコピーし、一時ファイルの名前をチェック対象として使用します。したがって、バッファ ファイル名が「source.cs」の場合、init fn から返される実際の値は次のようになります。

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

コードは次のようになります。

(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))

flymake.el で見たパターンに従うためだけに、2 つの異なる関数で実装しました。

とにかく...あなたが見ることができるのは、init fnが一時ファイルを作成してから引数を返すことです。への呼び出しは、flymake-get-syntax-check-program-args実際には への呼び出しに要約されますget-cmdline-f。これは、C# の場合は ですcsharp-flymake-get-cmdline。なぜこのすべての階層化と間接化が行われるのでしょうか? 知らない; それがフライメイクです。

C# 固有のクリーンアップ fn では、構文チェックから「製品」ファイルをチェックして削除し、さらに にチェーンしてflymake-simple-cleanup、作成された *_flymake.cs 一時ファイルを削除します。

おそらく、ネストされた dir パスは、 flymake が独自のデフォルトの init ルーチンで使用するuse-relative-base-dirおよび引数と関係があると思います。use-relative-sourceflymake-simple-make-init-impl

于 2011-04-26T17:53:00.880 に答える
0

関数make-temp-fileは変数を使用するため、おそらく問題を解決するために別のtemporary-file-directory設定を試すことができます。temporary-file-directory

于 2011-04-26T22:23:52.570 に答える