branch: elpa/projectile
commit 898b4f7c0bca298792fff4df947e27cf2a607c2c
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
Cache file-truename calls in projectile-project-buffer-p
When checking which buffers belong to a project, file-truename was
called for every buffer's directory. Many buffers share the same
directory, so memoize the results in a hash table passed from
projectile-project-buffers. This reduces redundant symlink resolution,
which is especially costly over TRAMP.
---
projectile.el | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/projectile.el b/projectile.el
index 5323db0a0a..d1ef7b2ada 100644
--- a/projectile.el
+++ b/projectile.el
@@ -1783,9 +1783,10 @@ this case unignored files will be absent from FILES."
"Get a list of a project's buffers.
If PROJECT is not specified the command acts on the current project."
(let* ((project-root (or project (projectile-acquire-root)))
+ (truename-cache (make-hash-table :test 'equal))
(all-buffers (seq-filter
(lambda (buffer)
- (projectile-project-buffer-p buffer project-root))
+ (projectile-project-buffer-p buffer project-root
truename-cache))
(buffer-list))))
(if projectile-buffers-filter-function
(funcall projectile-buffers-filter-function all-buffers)
@@ -1817,8 +1818,10 @@ If PROJECT is not specified the command acts on the
current project."
(projectile-buffers-with-file
(projectile-project-buffers project)))))
-(defun projectile-project-buffer-p (buffer project-root)
- "Check if BUFFER is under PROJECT-ROOT."
+(defun projectile-project-buffer-p (buffer project-root &optional
truename-cache)
+ "Check if BUFFER is under PROJECT-ROOT.
+Optional TRUENAME-CACHE is a hash table used to memoize `file-truename'
+calls when checking multiple buffers against the same project root."
(with-current-buffer buffer
(let ((directory (if buffer-file-name
(file-name-directory buffer-file-name)
@@ -1829,7 +1832,11 @@ If PROJECT is not specified the command acts on the
current project."
(string-equal (file-remote-p directory)
(file-remote-p project-root))
(not (string-match-p "^http\\(s\\)?://" directory))
- (string-prefix-p project-root (file-truename directory) (eq
system-type 'windows-nt))))))
+ (let ((true-dir (if truename-cache
+ (or (gethash directory truename-cache)
+ (puthash directory (file-truename
directory) truename-cache))
+ (file-truename directory))))
+ (string-prefix-p project-root true-dir (eq system-type
'windows-nt)))))))
(defun projectile-ignored-buffer-p (buffer)
"Check if BUFFER should be ignored."