Rya*_*kel 5 python emacs flymake pyflakes
我目前正在使用以下代码在emacs中连接flymake和Pyflakes:
(defun flymake-create-temp-in-system-tempdir (filename prefix)
(make-temp-file (or prefix "flymake")))
Run Code Online (Sandbox Code Playgroud)
然后我将此功能传递给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)
Run Code Online (Sandbox Code Playgroud)
为什么flymake会将看似错误的文件名传递给pyflakes?我希望它传递类似"/ tmp/efe234234"的东西,我没有修改任何tmp目录设置.
我不记得最近为Ubuntu更新了emacs,也无法想到任何可能导致这个问题陷入困境的事情(.emacs文件版本化).
我能想到的唯一问题是,这是一个嵌套到目录中的嵌套目录,这个目录符号链接到〜/ Dropbox目录中的目录,但这种情况不会以类似的方式发生在其他符号链接中.
我该如何解决这个问题?
UPDATE
我做了一些调试,现在我发现它没有传递正确的路径作为参数.它需要在路径中插入一个更多的父目录才能使它工作,这让我觉得它因为符号链接而变得混乱.
这是一个示例shell会话,以显示我的意思.我是从正确的相对目录中这样做的:
$ pyflakes ../../../../../tmp/flymake13382xHi
../../../../../tmp/flymake13382xHi: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这就是flymake试图运行的命令.如果我改变它:
$ pyflakes ../../../../../../tmp/flymake13382xHi
Run Code Online (Sandbox Code Playgroud)
我没有输出(如预期的那样).注意路径中的额外"..".
我如何让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)))))
Run Code Online (Sandbox Code Playgroud)
在最后一部分,我不得不参数来改变list
从local-file
到temp-file
,因为local-file
是我不想疯狂的相对路径.为什么该片段的作者local-file
首先使用?
谢谢,瑞恩
我没有直接解决 pyflakes 问题的方法,但这里有一个类似的解决方案。
我不喜欢 Flymake 中处理 C# 的方式,因此我修改了 中的 C# 条目以flymake-allowed-file-name-masks
引用不同的初始化和清理例程,代码如下:
(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))))
Run Code Online (Sandbox Code Playgroud)
文档在这些东西上有点参差不齐,但代码就是文档,据我所知,init 例程应该返回命令行以进行语法检查运行。它的格式为 2 元素列表,car 是要运行的命令,cadr 本身是参数列表。在我的例子中,返回值是这样的:
("csc.exe" ("/t:module" "/nologo" "nameOfFileToCheck.cs"))
Run Code Online (Sandbox Code Playgroud)
返回此命令行的 init 例程使用 Flymake 的内置 copy fn 将现有缓冲区复制到临时文件中,然后使用临时文件的名称作为要检查的内容。因此,如果缓冲区文件名是“source.cs”,则从 init fn 返回的实际值是
("csc.exe" ("/t:module" "/nologo" "source_flymake.cs"))
Run Code Online (Sandbox Code Playgroud)
代码如下所示:
(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))
Run Code Online (Sandbox Code Playgroud)
我用两个不同的函数实现了它,只是为了遵循我在 Flymake.el 中看到的模式。
无论如何...您可以看到 init fn 创建临时文件然后返回参数。对 的调用flymake-get-syntax-check-program-args
实际上归结为对 的调用get-cmdline-f
,在 C# 的情况下是csharp-flymake-get-cmdline
. 为什么要采用这种分层和间接方式?我不知道; Flymake 就是这样。
在特定于 C# 的清理 fn 中,我只需从语法检查中检查任何“产品”文件并将其删除,然后还链接到flymake-simple-cleanup
, 以删除创建的 *_flymake.cs 临时文件。
也许您的嵌套 dir 路径与Flymake 在其自己的默认 init 例程中使用的use-relative-base-dir
和参数有关,我认为是.use-relative-source
flymake-simple-make-init-impl
归档时间: |
|
查看次数: |
1828 次 |
最近记录: |