Можно ли создать временный файл flymake во временном каталоге системы? - PullRequest
5 голосов
/ 26 апреля 2011

В настоящее время я использую следующий код для соединения flymake и Pyflakes в emacs:

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

Почему мухи пропускают то, что кажется неправильнымимя файла в pyflakes? Я ожидаю, что он передаст что-то вроде "/ tmp / efe234234", и я не изменил ни одного из параметров каталога tmp.

Я не помню, чтобы emacs обновлялся для Ubuntu недавно и может 'Я не думаю о чем-либо, что могло бы привести к путанице (файлы .emacs версионированы).

Единственная проблема, о которой я могу думать, это то, что это сильно вложенный каталог, связанный с каталогом в моем ~ / Dropboxкаталог, но это не происходит с другими символическими ссылками подобным образом.

Как я могу решить эту проблему?

ОБНОВЛЕНИЕ

Я имеюЯ выполнил некоторую отладку, и теперь я вижу, что он не передает правильный путь в качестве аргумента. Ему нужен еще один родительский каталог, вставленный в путь, чтобы заставить его работать, что заставляет меня думать, что он испорчен из-засимволические ссылки.

Вот пример сеанса оболочки, чтобы показать, что я имею в виду.Я делаю это из правильного относительного каталога:

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

Это команда, которую flymake пытается выполнить.Если я его поменяю:

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

Я не получаю вывод (как и ожидалось).Обратите внимание на дополнительные «..» на пути.

Как я могу заставить муху проходить абсолютный путь вместо этих безумных относительных путей?

ОБНОВЛЕНИЕ 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 ]

1 голос
/ 08 марта 2013

Для меня я решил изменить пользовательский скрипт / 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
0 голосов
/ 27 апреля 2011

Функция make-temp-file использует переменную temporary-file-directory, поэтому, возможно, вы можете попробовать установить temporary-file-directory на что-то другое, чтобы решить вашу проблему.

0 голосов
/ 15 сентября 2011

Это то, что я использую для PHP на Windows.Он использует предложение make-temp-file от Trey.Он также явно устанавливает функции init и cleanup для PHP в соответствии с тем, что я хочу.Вы можете использовать в основном то же самое для 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))))))
0 голосов
/ 26 апреля 2011

У меня нет прямого решения вопроса о пайфлкс, но вот что-то похожее для вас.

Мне не понравилось, как C # обрабатывался в flymake, поэтому я изменил запись 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))))

Документация вроде этого не совсем корректна, но код - это документация , и, как я могу сказать, подпрограмма init должна возвращать командную строку для запуска проверки синтаксиса. Он отформатирован как список из 2 элементов, команда - это команда для запуска, а 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.

В любом случае ... То, что вы видите, это то, что init fn создает временный файл, а затем возвращает аргументы. Вызов на flymake-get-syntax-check-program-args фактически сводится к вызову на get-cmdline-f, который в случае C # равен csharp-flymake-get-cmdline. Почему все это наслоение и косвенность? Я не знаю; Вот как мухи.

В специфичной для C # очистке fn я просто проверяю любые файлы "product" из проверки синтаксиса и удаляю их, а затем добавляю цепочку к flymake-simple-cleanup, чтобы удалить созданный временный файл * _flymake.cs.

Возможно, ваш вложенный путь к каталогу имеет какое-то отношение к аргументам use-relative-base-dir и use-relative-source, которые flymake использует в собственной процедуре инициализации по умолчанию, которую я считаю flymake-simple-make-init-impl.

...