aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Leake2016-01-29 17:43:26 -0600
committerStephen Leake2016-01-29 17:46:18 -0600
commit7deeab6ff05c392533e05c95ec5e7abb6e3ecfe7 (patch)
tree7ceca0dfc99f9e5a1699bb58443ac1ef41435876
parenta71560b0e3011c04dc86546b1da51b828cdf040a (diff)
downloademacs-7deeab6ff05c392533e05c95ec5e7abb6e3ecfe7.tar.gz
emacs-7deeab6ff05c392533e05c95ec5e7abb6e3ecfe7.zip
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.
-rw-r--r--lisp/progmodes/project.el78
-rw-r--r--lisp/progmodes/xref.el4
2 files changed, 51 insertions, 31 deletions
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 85f390746d9..d12f66233d4 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
154 vc-directory-exclusion-list) 154 vc-directory-exclusion-list)
155 grep-find-ignored-files)) 155 grep-find-ignored-files))
156 156
157(cl-defgeneric project-file-completion-table (_project _dirs)
158 "Return a completion table for files in directories DIRS in PROJECT.
159DIRS is a list of absolute directories; it should be some
160subset of the project roots and external roots.
161PROJECT is used to find the project ignores and other project meta-data."
162 )
163
157(defgroup project-vc nil 164(defgroup project-vc nil
158 "Project implementation using the VC package." 165 "Project implementation using the VC package."
159 :version "25.1" 166 :version "25.1"
@@ -313,51 +320,60 @@ pattern to search for."
313 320
314;;;###autoload 321;;;###autoload
315(defun project-find-file () 322(defun project-find-file ()
316 "Visit a file in the current project's roots. 323 "Visit a file (with completion) in the current project's roots.
317 324The completion default is the filename at point, if one is
318This is like `find-file', but it limits the file-name completion 325recognized."
319candidates to the files within the current project roots."
320 (interactive) 326 (interactive)
321 (let* ((pr (project-current t)) 327 (let* ((pr (project-current t))
322 (dirs (project-roots pr))) 328 (dirs (project-roots pr)))
323 (project--find-file-in dirs pr))) 329 (project-find-file-in (thing-at-point 'filename) dirs pr)))
324 330
325;;;###autoload 331;;;###autoload
326(defun project-or-external-find-file () 332(defun project-or-external-find-file ()
327 "Visit a file in the current project's roots or external roots. 333 "Visit a file (with completion) in the current project's roots or external roots.
328 334The completion default is the filename at point, if one is
329This is like `find-file', but it limits the file-name completion 335recognized."
330candidates to the files within the current project roots and external roots."
331 (interactive) 336 (interactive)
332 (let* ((pr (project-current t)) 337 (let* ((pr (project-current t))
333 (dirs (append 338 (dirs (append
334 (project-roots pr) 339 (project-roots pr)
335 (project-external-roots pr)))) 340 (project-external-roots pr))))
336 (project--find-file-in dirs pr))) 341 (project-find-file-in (thing-at-point 'filename) dirs pr)))
337 342
338;; FIXME: Uniquely abbreviate the roots? 343;; FIXME: Uniquely abbreviate the roots?
339(defun project--find-file-in (dirs project) 344(cl-defmethod project-file-completion-table (project dirs)
345 "Default implementation using `find-program'."
340 (require 'xref) 346 (require 'xref)
341 (let* ((all-files 347 (let ((all-files
342 (cl-mapcan 348 (cl-mapcan
343 (lambda (dir) 349 (lambda (dir)
344 (let ((command 350 (let ((command
345 (format "%s %s %s -type f -print0" 351 (format "%s %s %s -type f -print0"
346 find-program 352 find-program
347 dir 353 dir
348 (xref--find-ignores-arguments 354 (xref--find-ignores-arguments
349 (project-ignores project dir) 355 (project-ignores project dir)
350 (expand-file-name dir))))) 356 (expand-file-name dir)))))
351 (split-string (shell-command-to-string command) "\0" t))) 357 (split-string (shell-command-to-string command) "\0" t)))
352 dirs)) 358 dirs)))
353 (table (lambda (string pred action) 359 (lambda (string pred action)
354 (cond 360 (cond
355 ((eq action 'metadata) 361 ((eq action 'metadata)
356 '(metadata . ((category . project-file)))) 362 '(metadata . ((category . project-file))))
357 (t 363 (t
358 (complete-with-action action all-files string pred)))))) 364 (complete-with-action action all-files string pred))))
359 (find-file 365 ))
360 (completing-read "Find file: " table nil t)))) 366
367(defun project-find-file-in (filename dirs project)
368 "Complete FILENAME in DIRS in PROJECT, visit the file."
369 ;; FIXME: verify that filename is accepted by the completion table
370 (find-file
371 (completing-read
372 (if filename
373 (format "Find file (%s): " filename)
374 "Find file: ")
375 (project--file-completion-table project dirs)
376 nil t nil nil filename)))
361 377
362(provide 'project) 378(provide 'project)
363;;; project.el ends here 379;;; project.el ends here
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 267853d1642..2fd7297a2e8 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -854,6 +854,7 @@ and just use etags."
854(declare-function semantic-symref-find-references-by-name "semantic/symref") 854(declare-function semantic-symref-find-references-by-name "semantic/symref")
855(declare-function semantic-find-file-noselect "semantic/fw") 855(declare-function semantic-find-file-noselect "semantic/fw")
856(declare-function grep-expand-template "grep") 856(declare-function grep-expand-template "grep")
857(defvar ede-minor-mode) ;; ede.el
857 858
858(defun xref-collect-references (symbol dir) 859(defun xref-collect-references (symbol dir)
859 "Collect references to SYMBOL inside DIR. 860 "Collect references to SYMBOL inside DIR.
@@ -948,6 +949,9 @@ IGNORES is a list of glob patterns."
948 (xref--find-ignores-arguments ignores dir))) 949 (xref--find-ignores-arguments ignores dir)))
949 950
950(defun xref--find-ignores-arguments (ignores dir) 951(defun xref--find-ignores-arguments (ignores dir)
952 "Convert IGNORES and DIR to a list of arguments for 'find'.
953IGNORES is a list of glob patterns. DIR is an absolute
954directory, used as the root of the ignore globs."
951 ;; `shell-quote-argument' quotes the tilde as well. 955 ;; `shell-quote-argument' quotes the tilde as well.
952 (cl-assert (not (string-match-p "\\`~" dir))) 956 (cl-assert (not (string-match-p "\\`~" dir)))
953 (when ignores 957 (when ignores