diff options
| author | Stephen Leake | 2016-01-29 17:43:26 -0600 |
|---|---|---|
| committer | Stephen Leake | 2016-01-29 17:46:18 -0600 |
| commit | 7deeab6ff05c392533e05c95ec5e7abb6e3ecfe7 (patch) | |
| tree | 7ceca0dfc99f9e5a1699bb58443ac1ef41435876 | |
| parent | a71560b0e3011c04dc86546b1da51b828cdf040a (diff) | |
| download | emacs-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.el | 78 | ||||
| -rw-r--r-- | 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 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. | ||
| 159 | DIRS is a list of absolute directories; it should be some | ||
| 160 | subset of the project roots and external roots. | ||
| 161 | PROJECT 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 | 324 | The completion default is the filename at point, if one is | |
| 318 | This is like `find-file', but it limits the file-name completion | 325 | recognized." |
| 319 | candidates 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 | 334 | The completion default is the filename at point, if one is | |
| 329 | This is like `find-file', but it limits the file-name completion | 335 | recognized." |
| 330 | candidates 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'. | ||
| 953 | IGNORES is a list of glob patterns. DIR is an absolute | ||
| 954 | directory, 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 |