projectile

概要

projectileはEmacs packageの1つ。 Gitリポジトリ単位でプロジェクトとし、その中でファイル検索してファイル切り替えをすばやく行える。

Repository

Memo

Tasks

TODO Don’t save nonexistent files in the Projectile cache · Issue #1551 · bbatsov/projectile

もう解決したのか、再現しない。 保存しなければキャッシュに保存されない。

Reference

Archives

DONE projectile issue#1709

projectile-project-buffer-p が誤検知してる。現在のバッファがプロジェクトでないのにプロジェクト判定し、それで消すときに含まれてしまう。

(defun projectile-project-buffer-p (buffer project-root)
"Check if BUFFER is under PROJECT-ROOT."
(with-current-buffer buffer
  (and (not (string-prefix-p " " (buffer-name buffer)))
       (not (projectile-ignored-buffer-p buffer))
       default-directory ;; これが怪しい。どこから取ってる?
       (string-equal (file-remote-p default-directory)
                     (file-remote-p project-root))
       (not (string-match-p "^http\\(s\\)?://" default-directory))
       (string-prefix-p project-root (file-truename default-directory) (eq system-type 'windows-nt)))))

default-directory が、switch先のdirectoryを指している。なのでtrueになる。 つまり消そうとしているdirectoryではないがtrueを返し誤って消される。

初回のループで変数 default-directory が引数のbufferと合っていない。現在開いているバッファが入り、現在開いているものまで消してしまう。 無理やり (cd ...) とすれば変更できるが、いかしてない。

default-directory を使わない方法でやるとこうなる。 ほかにも変更が必要そうだな。

(defun projectile-project-buffer-p (buffer project-root)
  "Check if BUFFER is under PROJECT-ROOT."
  (with-current-buffer buffer
    (and (not (string-prefix-p " " (buffer-name buffer)))
         (not (projectile-ignored-buffer-p buffer))
         (file-name-directory buffer-file-name)
         (string-equal (file-remote-p (file-name-directory buffer-file-name))
                       (file-remote-p project-root))
         (not (string-match-p "^http\\(s\\)?://" (file-name-directory buffer-file-name)))
         (string-prefix-p project-root (file-truename (file-name-directory buffer-file-name)) (eq system-type 'windows-nt)))))

取得できない理由。current buffer以外にセットされているから。 ループを進んだ後はなぜできてるのか。

Sometimes default-directory for the current buffer may be set to something other than the current directory of the file the buffer is currently visiting, in which case the solution above wouldn’t give what the asker was looking for.

In such cases, you can use the file-name-directory method, like so: (file-name-directory buffer-file-name)

初回以降の default-directory を変えている要素は何だ。何か変わっているはずだが、単なるループで他の条件は一切変わってないようだな…。

テストで再現できない。

project-root: /home/kijima/.emacs.d/ buffer: projectile.el default-directory: .emacs.d → これがおかしい。

projectile-switch-project → projectile-switch-project-by-name(名前で選択) → アクション選択 projectile-project-buffers → projectile-project-buffer-p

(it "ensures the buffer is switched immediately"
      (let ((projectile-switch-project-action
             (lambda () (switch-to-buffer (find-file-noselect "file" t)))))
        (projectile-test-with-sandbox
         (projectile-test-with-files
          ("project/"
           "project/file")
          (projectile-add-known-project (file-name-as-directory (expand-file-name "project")))
          (projectile-switch-project-by-name (file-name-as-directory (expand-file-name "project")))

          (expect (current-buffer) :to-be (get-file-buffer "project/file"))))))

テストでprojectバッファを開いてる状態にするにはどうしたらいいんだ。ディレクトリが間違っていた。 printデバッグで原因を把握する。

(projectile-acquire-root)が正しいディレクトリを取得していない。

(message (format "relevant: %s" (projectile-relevant-known-projects)))
(message (format "2: %s" (projectile-project-buffers)))
(message (format "%s" (projectile-acquire-root)))
(message (format "bbb  %s" (buffer-list)))

失敗するのは、scratchなどbuffer-file-nameを持たないとき(file-name-directory nil)となってエラーになるから。問題が起こるのは、実行されたディレクトリがプロジェクトディレクトリではないとき。

PR出したが、この方法だとshellなどで特殊bufferのときうまくいかない。修正してPR open。マージされた。 安易にcloseするのでなく、よく考えてからだな。焦って恥ずかしい、となるのだが耐える。