Improve counsel-projectile-find-file performance
Current code will show significant lag for projects with large numbers of files. Tests with 400K files shows 15-20s lag for counsel-projectile-find-file. Profiling showed that this was due to the preprocessing of projectile-current-project-files to add 'ivy-virtual face to files not already in a buffer. To fix this, a display transformer was added for this command so that the face modification was applied only to at most ivy-height files. The preprocessed file list was also used by counsel-projectile code paths, so some additional modifications were made to ensure that that code path does not change behavior. Any similar issues in counsel-projectile performance was not addressed in this commit. Details: * move 'ivy-virtual face change to a display transformer function * use projectile-current-project-files instead of counsel-projectile--file-list for ivy-read. * reduce the scope of counsel-projectile--file-list, making it return only unvisited files, and renaming it accordingly. This is now only used indirectly by the counsel-projectile function. * change ivy-switch-buffer-transformer to propertize files at display time.
This commit is contained in:
parent
9e3db12005
commit
2a46d758f7
1 changed files with 21 additions and 13 deletions
|
|
@ -65,20 +65,16 @@
|
|||
|
||||
;;; counsel-projectile-find-file
|
||||
|
||||
(defun counsel-projectile--file-list (&optional no-buffer)
|
||||
"Return a list of files for the current project.
|
||||
(defun counsel-projectile--unvisited-file-list ()
|
||||
"Return a list of unvisited files for the current project.
|
||||
|
||||
Like `projectile-current-project-files', but fontifies
|
||||
non-visited file names with the `ivy-virtual' face. With optional
|
||||
argument NO-BUFFER, only list non-visited files."
|
||||
Like `projectile-current-project-files', but skips any files
|
||||
already being visited by a buffer."
|
||||
(let ((root (projectile-project-root)))
|
||||
(cl-loop
|
||||
for name in (projectile-current-project-files)
|
||||
for file = (expand-file-name name root)
|
||||
if (not (get-file-buffer file))
|
||||
collect (propertize name 'face 'ivy-virtual)
|
||||
else
|
||||
unless no-buffer
|
||||
collect name)))
|
||||
|
||||
(defun counsel-projectile--find-file-action (file &optional other-window)
|
||||
|
|
@ -94,6 +90,12 @@ argument NO-BUFFER, only list non-visited files."
|
|||
`projectile-find-file-hook'."
|
||||
(counsel-projectile--find-file-action file t))
|
||||
|
||||
(defun counsel-projectile--find-file-transformer (name)
|
||||
"Transform non-visited file names with `ivy-virtual' face."
|
||||
(if (not (get-file-buffer (expand-file-name name (projectile-project-root))))
|
||||
(propertize name 'face 'ivy-virtual)
|
||||
name))
|
||||
|
||||
;;;###autoload
|
||||
(defun counsel-projectile-find-file (&optional arg)
|
||||
"Jump to a project's file using completion.
|
||||
|
|
@ -103,7 +105,7 @@ invalidates the cache first."
|
|||
(interactive "P")
|
||||
(projectile-maybe-invalidate-cache arg)
|
||||
(ivy-read (projectile-prepend-project-name "Find file: ")
|
||||
(counsel-projectile--file-list)
|
||||
(projectile-current-project-files)
|
||||
:matcher #'counsel--find-file-matcher
|
||||
:require-match t
|
||||
:keymap counsel-projectile-map
|
||||
|
|
@ -115,6 +117,10 @@ invalidates the cache first."
|
|||
'(("j" counsel-projectile--find-file-other-window-action
|
||||
"other window")))
|
||||
|
||||
(ivy-set-display-transformer
|
||||
'counsel-projectile-find-file
|
||||
'counsel-projectile--find-file-transformer)
|
||||
|
||||
;;; counsel-projectile-find-dir
|
||||
|
||||
(defun counsel-projectile--dir-list ()
|
||||
|
|
@ -370,15 +376,17 @@ invokes `projectile-commander' instead of
|
|||
(counsel-projectile--buffer-list))
|
||||
(mapc (lambda (file)
|
||||
(add-text-properties 0 1 '(type file) file))
|
||||
(counsel-projectile--file-list t))))
|
||||
(counsel-projectile--unvisited-file-list))))
|
||||
|
||||
(defun counsel-projectile--transformer (str)
|
||||
"Fontifies modified, file-visiting buffers.
|
||||
|
||||
Relies on `ivy-switch-buffer-transformer'."
|
||||
(if (eq (get-text-property 0 'type str) 'buffer)
|
||||
(ivy-switch-buffer-transformer str)
|
||||
str))
|
||||
(let ((type (get-text-property 0 'type str)))
|
||||
(cond
|
||||
((eq type 'buffer) (ivy-switch-buffer-transformer str))
|
||||
((eq type 'file) (propertize str 'face 'ivy-virtual))
|
||||
(t str))))
|
||||
|
||||
(defun counsel-projectile--matcher (regexp candidates)
|
||||
"Return REGEXP-matching CANDIDATES.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue