flymake的临时文件可以在系统的临时目录中创建吗?

2024-06-01 10:15:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在使用以下代码在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文件时,会出现以下错误:

^{pr2}$

为什么flymake把一个看似错误的文件名传递给pyflakes?我希望它传递类似“/tmp/efe234234”的内容,但我没有修改任何tmp目录设置。在

我不记得emacs最近为Ubuntu更新过,我想不出是什么原因导致了它的混乱(.emacs文件是版本控制的)。在

我唯一能想到的问题是,这是一个高度嵌套的目录symlink到我的~/Dropbox目录中的一个目录,但是其他符号链接的方式没有类似的情况。在

我怎样才能解决这个问题?在

更新

我做了一些调试,现在我发现它没有传递正确的路径作为参数。它需要在路径中再插入一个父目录才能使它正常工作,这让我觉得它因为符号链接而变得一团糟。在

下面是一个示例shell会话来说明我的意思。我从正确的相对目录执行此操作:

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

在最后一部分,我不得不将参数从local-file改为list,因为local-file是我不想要的疯狂的相对路径。为什么这个片段的作者首先使用local-file?在

谢谢, 瑞安


Tags: or路径目录initlocalbuffercreatetemp
3条回答

我不能直接解决pyflakes的问题,但这里有一些类似的东西给你。在

我不喜欢在flymake中如何处理C,所以我修改了flymake-allowed-file-name-masks中的C条目,以引用不同的init和cleanup例程,代码如下:

(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例程应该返回用于语法检查运行的命令行。它被格式化为一个2元素列表,car是要运行的命令,而cadr本身就是一个参数列表。在我的示例中,返回值如下所示:

^{pr2}$

返回此命令行的init例程使用flymake的内置copy fn将现有缓冲区复制到临时文件中,然后使用临时文件的名称作为要检查的内容。如果缓冲区文件名是“来源.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))

我只在模式2中实现了不同的功能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-diruse-relative-source参数有关,我认为这是flymake-simple-make-init-impl。在

对于我来说,我通过修改用户脚本/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

函数make-temp-file使用变量temporary-file-directory,所以也许您可以尝试将temporary-file-directory设置为其他值来解决您的问题。在

相关问题 更多 >