]> code.delx.au - gnu-emacs-elpa/commitdiff
[#464] Optimisation and fixes in `company-files`
authorVitalie Spinu <spinuvit@gmail.com>
Sun, 31 Jan 2016 13:06:15 +0000 (14:06 +0100)
committerVitalie Spinu <spinuvit@gmail.com>
Mon, 1 Feb 2016 11:18:11 +0000 (12:18 +0100)
  - Don't rely on `directory-files`; it returns directories without
    trailing slash
  - Don't use `file-directory-p`; check for trailing / instead
  - Don't append children on remotes or remote children
  - Remove file-name-all-completions test from prefix check

company-files.el

index 53730c6e0691e90e3ebb0c8ad67d36c6d576db51..f90f3d02b233a7956a6821fa2047c356bb833f8c 100644 (file)
 
 (defun company-files--directory-files (dir prefix)
   (ignore-errors
 
 (defun company-files--directory-files (dir prefix)
   (ignore-errors
-    (if (equal prefix "")
-        (directory-files dir nil "\\`[^.]\\|\\`.[^.]")
-      (file-name-all-completions prefix dir))))
+    ;; Don't use directory-files. It produces directories without trailing /.
+    (let ((comp (file-name-all-completions prefix dir)))
+      (if (equal prefix "")
+          (delete "../" (delete "./" comp))
+        comp))))
 
 (defvar company-files--regexps
   (let* ((root (if (eq system-type 'windows-nt)
 
 (defvar company-files--regexps
   (let* ((root (if (eq system-type 'windows-nt)
          (setq dir (file-name-directory file))
          (not (string-match "//" dir))
          (file-exists-p dir)
          (setq dir (file-name-directory file))
          (not (string-match "//" dir))
          (file-exists-p dir)
-         (file-name-all-completions (file-name-nondirectory file) dir)
          file)))
 
 (defun company-files--connected-p (file)
   (or (not (file-remote-p file))
       (file-remote-p file nil t)))
 
          file)))
 
 (defun company-files--connected-p (file)
   (or (not (file-remote-p file))
       (file-remote-p file nil t)))
 
+(defun company-files--trailing-slash-p (file)
+  ;; `file-directory-p' is very expensive on remotes. We are relying on
+  ;; `file-name-all-completions' returning directories with trailing / instead.
+  (let ((len (length file)))
+    (and (> len 0) (eq (aref file (1- len)) ?/))))
+
 (defvar company-files--completion-cache nil)
 
 (defun company-files--complete (prefix)
   (let* ((dir (file-name-directory prefix))
 (defvar company-files--completion-cache nil)
 
 (defun company-files--complete (prefix)
   (let* ((dir (file-name-directory prefix))
-         (key (list (file-name-nondirectory prefix)
+         (file (file-name-nondirectory prefix))
+         (key (list file
                     (expand-file-name dir)
                     (nth 5 (file-attributes dir))))
                     (expand-file-name dir)
                     (nth 5 (file-attributes dir))))
-         (file (file-name-nondirectory prefix))
-         (completion-ignore-case read-file-name-completion-ignore-case)
-         candidates directories)
+         (completion-ignore-case read-file-name-completion-ignore-case))
     (unless (company-file--keys-match-p key (car company-files--completion-cache))
     (unless (company-file--keys-match-p key (car company-files--completion-cache))
-      (dolist (file (company-files--directory-files dir file))
-        (setq file (concat dir file))
-        (when (company-files--connected-p file)
-          (push file candidates)
-          (when (file-directory-p file)
-            (push file directories))))
-      (dolist (directory (reverse directories))
-        ;; Add one level of children.
-        (dolist (child (company-files--directory-files directory ""))
-          (push (concat directory
-                        (unless (eq (aref directory (1- (length directory))) ?/) "/")
-                        child) candidates)))
-      (setq company-files--completion-cache (cons key (nreverse candidates))))
+      (let* ((candidates (mapcar (lambda (f) (concat dir f))
+                                 (company-files--directory-files dir file)))
+             (directories (unless (file-remote-p dir)
+                            (cl-remove-if-not (lambda (f)
+                                                (and (company-files--trailing-slash-p f)
+                                                     (not (file-remote-p f))
+                                                     (company-files--connected-p f)))
+                                              candidates)))
+             (children (and directories
+                            (cl-mapcan (lambda (d)
+                                         (mapcar (lambda (c) (concat d c))
+                                                 (company-files--directory-files d "")))
+                                       directories))))
+        (setq company-files--completion-cache
+              (cons key (sort (append children candidates)
+                              #'string-lessp)))))
     (all-completions prefix
                      (cdr company-files--completion-cache))))
 
     (all-completions prefix
                      (cdr company-files--completion-cache))))