emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-25 7deeab6 2/3: Improve project-find-file


From: Stephen Leake
Subject: [Emacs-diffs] emacs-25 7deeab6 2/3: Improve project-find-file
Date: Fri, 29 Jan 2016 23:54:00 +0000

branch: emacs-25
commit 7deeab6ff05c392533e05c95ec5e7abb6e3ecfe7
Author: Stephen Leake <address@hidden>
Commit: Stephen Leake <address@hidden>

    Improve project-find-file
    
    * lisp/progmodes/project.el (project-file-completion-table): New.
    (project-find-file, project-or-external-find-file): Default to filename
    at point.
    (project-file-completion-table): New, split out from
    project--find-file-in.
    (project-find-file-in): Renamed from project--find-file-in, use
    project-file-completion-table.
    
    * lisp/progmodes/xref.el (ede-minor-mode): New declaration.
    (xref--find-ignores-arguments): Add doc string.
---
 lisp/progmodes/project.el |   78 +++++++++++++++++++++++++++------------------
 lisp/progmodes/xref.el    |    4 ++
 2 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 85f3907..d12f662 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -154,6 +154,13 @@ end it with `/'.  DIR must be one of `project-roots' or
     vc-directory-exclusion-list)
    grep-find-ignored-files))
 
+(cl-defgeneric project-file-completion-table (_project _dirs)
+  "Return a completion table for files in directories DIRS in PROJECT.
+DIRS is a list of absolute directories; it should be some
+subset of the project roots and external roots.
+PROJECT is used to find the project ignores and other project meta-data."
+  )
+
 (defgroup project-vc nil
   "Project implementation using the VC package."
   :version "25.1"
@@ -313,51 +320,60 @@ pattern to search for."
 
 ;;;###autoload
 (defun project-find-file ()
-  "Visit a file in the current project's roots.
-
-This is like `find-file', but it limits the file-name completion
-candidates to the files within the current project roots."
+  "Visit a file (with completion) in the current project's roots.
+The completion default is the filename at point, if one is
+recognized."
   (interactive)
   (let* ((pr (project-current t))
          (dirs (project-roots pr)))
-    (project--find-file-in dirs pr)))
+    (project-find-file-in (thing-at-point 'filename) dirs pr)))
 
 ;;;###autoload
 (defun project-or-external-find-file ()
-  "Visit a file in the current project's roots or external roots.
-
-This is like `find-file', but it limits the file-name completion
-candidates to the files within the current project roots and external roots."
+  "Visit a file (with completion) in the current project's roots or external 
roots.
+The completion default is the filename at point, if one is
+recognized."
   (interactive)
   (let* ((pr (project-current t))
          (dirs (append
                 (project-roots pr)
                 (project-external-roots pr))))
-    (project--find-file-in dirs pr)))
+    (project-find-file-in (thing-at-point 'filename) dirs pr)))
 
 ;; FIXME: Uniquely abbreviate the roots?
-(defun project--find-file-in (dirs project)
+(cl-defmethod project-file-completion-table (project dirs)
+  "Default implementation using `find-program'."
   (require 'xref)
-  (let* ((all-files
-          (cl-mapcan
-           (lambda (dir)
-             (let ((command
-                    (format "%s %s %s -type f -print0"
-                            find-program
-                            dir
-                            (xref--find-ignores-arguments
-                             (project-ignores project dir)
-                             (expand-file-name dir)))))
-               (split-string (shell-command-to-string command) "\0" t)))
-           dirs))
-         (table (lambda (string pred action)
-                  (cond
-                   ((eq action 'metadata)
-                    '(metadata . ((category . project-file))))
-                   (t
-                    (complete-with-action action all-files string pred))))))
-    (find-file
-     (completing-read "Find file: " table nil t))))
+  (let ((all-files
+        (cl-mapcan
+         (lambda (dir)
+           (let ((command
+                  (format "%s %s %s -type f -print0"
+                          find-program
+                          dir
+                          (xref--find-ignores-arguments
+                           (project-ignores project dir)
+                           (expand-file-name dir)))))
+             (split-string (shell-command-to-string command) "\0" t)))
+         dirs)))
+    (lambda (string pred action)
+      (cond
+       ((eq action 'metadata)
+       '(metadata . ((category . project-file))))
+       (t
+       (complete-with-action action all-files string pred))))
+    ))
+
+(defun project-find-file-in (filename dirs project)
+  "Complete FILENAME in DIRS in PROJECT, visit the file."
+  ;; FIXME: verify that filename is accepted by the completion table
+  (find-file
+   (completing-read
+    (if filename
+        (format "Find file (%s): " filename)
+      "Find file: ")
+    (project--file-completion-table project dirs)
+    nil t nil nil filename)))
 
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 267853d..2fd7297 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -854,6 +854,7 @@ and just use etags."
 (declare-function semantic-symref-find-references-by-name "semantic/symref")
 (declare-function semantic-find-file-noselect "semantic/fw")
 (declare-function grep-expand-template "grep")
+(defvar ede-minor-mode) ;; ede.el
 
 (defun xref-collect-references (symbol dir)
   "Collect references to SYMBOL inside DIR.
@@ -948,6 +949,9 @@ IGNORES is a list of glob patterns."
    (xref--find-ignores-arguments ignores dir)))
 
 (defun xref--find-ignores-arguments (ignores dir)
+  "Convert IGNORES and DIR to a list of arguments for 'find'.
+IGNORES is a list of glob patterns.  DIR is an absolute
+directory, used as the root of the ignore globs."
   ;; `shell-quote-argument' quotes the tilde as well.
   (cl-assert (not (string-match-p "\\`~" dir)))
   (when ignores



reply via email to

[Prev in Thread] Current Thread [Next in Thread]