[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] emacs-25 ed41d11: Add project-find-file and project-or-ext
From: |
Dmitry Gutov |
Subject: |
[Emacs-diffs] emacs-25 ed41d11: Add project-find-file and project-or-external-find-file |
Date: |
Thu, 07 Jan 2016 17:57:09 +0000 |
branch: emacs-25
commit ed41d117a434abd28df4585663c2311c87160d1c
Author: Dmitry Gutov <address@hidden>
Commit: Dmitry Gutov <address@hidden>
Add project-find-file and project-or-external-find-file
* lisp/minibuffer.el (completion-category-defaults):
Add `project-file' category.
* lisp/progmodes/project.el (project-find-file)
(project-or-external-find-file): New commands.
(project--find-file-in): New private function.
* lisp/progmodes/xref.el (xref-collect-matches): Use
`expand-file-name' on DIR, to expand the tildes.
(xref--find-ignores-arguments): Extract from
`xref--rgrep-command'.
---
lisp/minibuffer.el | 3 +-
lisp/progmodes/project.el | 48 +++++++++++++++++++++++++++++++++++++++++---
lisp/progmodes/xref.el | 43 +++++++++++++++++++++++----------------
3 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 1251a4e..ecac0ae 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -831,7 +831,8 @@ styles for specific categories, such as files, buffers,
etc."
(defvar completion-category-defaults
'((buffer (styles . (basic substring)))
- (unicode-name (styles . (basic substring))))
+ (unicode-name (styles . (basic substring)))
+ (project-file (styles . (basic substring))))
"Default settings for specific completion categories.
Each entry has the shape (CATEGORY . ALIST) where ALIST is
an association list that can specify properties such as:
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index d771587..2e3222f 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -45,10 +45,12 @@
;;; TODO:
-;; * Commands `project-find-file' and `project-or-external-find-file'.
-;; Currently blocked on adding a new completion style that would let
-;; the user enter just the base file name (or a part of it), and get
-;; it expanded to the absolute file name.
+;; * Reliably cache the list of files in the project, probably using
+;; filenotify.el (if supported) to invalidate. And avoiding caching
+;; if it's not available (manual cache invalidation is not nice).
+;;
+;; * Allow the backend to override the file-listing logic? Maybe also
+;; to delegate file name completion to an external tool.
;;
;; * Build tool related functionality. Start with a `project-build'
;; command, which should provide completions on tasks to run, and
@@ -258,6 +260,7 @@ DIRS must contain directory names."
(declare-function xref-collect-matches "xref")
(declare-function xref--show-xrefs "xref")
(declare-function xref-backend-identifier-at-point "xref")
+(declare-function xref--find-ignores-arguments "xref")
;;;###autoload
(defun project-find-regexp (regexp)
@@ -302,5 +305,42 @@ pattern to search for."
(user-error "No matches for: %s" regexp))
(xref--show-xrefs xrefs nil)))
+(defun project-find-file ()
+ (interactive)
+ (let* ((pr (project-current t))
+ (dirs (project-roots pr)))
+ (project--find-file-in dirs pr)))
+
+(defun project-or-external-find-file ()
+ (interactive)
+ (let* ((pr (project-current t))
+ (dirs (append
+ (project-roots pr)
+ (project-external-roots pr))))
+ (project--find-file-in dirs pr)))
+
+;; FIXME: Uniquely abbreviate the roots?
+(defun project--find-file-in (dirs project)
+ (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))))
+
(provide 'project)
;;; project.el ends here
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index ae5ec61..5970011 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -876,7 +876,9 @@ IGNORES is a list of glob patterns."
grep-find-template t t))
(grep-highlight-matches nil)
(command (xref--rgrep-command (xref--regexp-to-extended regexp)
- files dir ignores))
+ files
+ (expand-file-name dir)
+ ignores))
(orig-buffers (buffer-list))
(buf (get-buffer-create " *xref-grep*"))
(grep-re (caar grep-regexp-alist))
@@ -912,23 +914,28 @@ IGNORES is a list of glob patterns."
" "
(shell-quote-argument ")"))
dir
- (concat
- (shell-quote-argument "(")
- " -path "
- (mapconcat
- (lambda (ignore)
- (when (string-match-p "/\\'" ignore)
- (setq ignore (concat ignore "*")))
- (if (string-match "\\`\\./" ignore)
- (setq ignore (replace-match dir t t ignore))
- (unless (string-prefix-p "*" ignore)
- (setq ignore (concat "*/" ignore))))
- (shell-quote-argument ignore))
- ignores
- " -o -path ")
- " "
- (shell-quote-argument ")")
- " -prune -o ")))
+ (xref--find-ignores-arguments ignores dir)))
+
+(defun xref--find-ignores-arguments (ignores dir)
+ ;; `shell-quote-argument' quotes the tilde as well.
+ (cl-assert (not (string-match-p "\\`~" dir)))
+ (concat
+ (shell-quote-argument "(")
+ " -path "
+ (mapconcat
+ (lambda (ignore)
+ (when (string-match-p "/\\'" ignore)
+ (setq ignore (concat ignore "*")))
+ (if (string-match "\\`\\./" ignore)
+ (setq ignore (replace-match dir t t ignore))
+ (unless (string-prefix-p "*" ignore)
+ (setq ignore (concat "*/" ignore))))
+ (shell-quote-argument ignore))
+ ignores
+ " -o -path ")
+ " "
+ (shell-quote-argument ")")
+ " -prune -o "))
(defun xref--regexp-to-extended (str)
(replace-regexp-in-string
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] emacs-25 ed41d11: Add project-find-file and project-or-external-find-file,
Dmitry Gutov <=