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'.
This commit is contained in:
parent
056da45d2c
commit
ed41d117a4
3 changed files with 71 additions and 23 deletions
|
@ -831,7 +831,8 @@ styles for specific categories, such as files, buffers, etc."
|
||||||
|
|
||||||
(defvar completion-category-defaults
|
(defvar completion-category-defaults
|
||||||
'((buffer (styles . (basic substring)))
|
'((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.
|
"Default settings for specific completion categories.
|
||||||
Each entry has the shape (CATEGORY . ALIST) where ALIST is
|
Each entry has the shape (CATEGORY . ALIST) where ALIST is
|
||||||
an association list that can specify properties such as:
|
an association list that can specify properties such as:
|
||||||
|
|
|
@ -45,10 +45,12 @@
|
||||||
|
|
||||||
;;; TODO:
|
;;; TODO:
|
||||||
|
|
||||||
;; * Commands `project-find-file' and `project-or-external-find-file'.
|
;; * Reliably cache the list of files in the project, probably using
|
||||||
;; Currently blocked on adding a new completion style that would let
|
;; filenotify.el (if supported) to invalidate. And avoiding caching
|
||||||
;; the user enter just the base file name (or a part of it), and get
|
;; if it's not available (manual cache invalidation is not nice).
|
||||||
;; it expanded to the absolute file name.
|
;;
|
||||||
|
;; * 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'
|
;; * Build tool related functionality. Start with a `project-build'
|
||||||
;; command, which should provide completions on tasks to run, and
|
;; 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-collect-matches "xref")
|
||||||
(declare-function xref--show-xrefs "xref")
|
(declare-function xref--show-xrefs "xref")
|
||||||
(declare-function xref-backend-identifier-at-point "xref")
|
(declare-function xref-backend-identifier-at-point "xref")
|
||||||
|
(declare-function xref--find-ignores-arguments "xref")
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun project-find-regexp (regexp)
|
(defun project-find-regexp (regexp)
|
||||||
|
@ -302,5 +305,42 @@ pattern to search for."
|
||||||
(user-error "No matches for: %s" regexp))
|
(user-error "No matches for: %s" regexp))
|
||||||
(xref--show-xrefs xrefs nil)))
|
(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)
|
(provide 'project)
|
||||||
;;; project.el ends here
|
;;; project.el ends here
|
||||||
|
|
|
@ -876,7 +876,9 @@ IGNORES is a list of glob patterns."
|
||||||
grep-find-template t t))
|
grep-find-template t t))
|
||||||
(grep-highlight-matches nil)
|
(grep-highlight-matches nil)
|
||||||
(command (xref--rgrep-command (xref--regexp-to-extended regexp)
|
(command (xref--rgrep-command (xref--regexp-to-extended regexp)
|
||||||
files dir ignores))
|
files
|
||||||
|
(expand-file-name dir)
|
||||||
|
ignores))
|
||||||
(orig-buffers (buffer-list))
|
(orig-buffers (buffer-list))
|
||||||
(buf (get-buffer-create " *xref-grep*"))
|
(buf (get-buffer-create " *xref-grep*"))
|
||||||
(grep-re (caar grep-regexp-alist))
|
(grep-re (caar grep-regexp-alist))
|
||||||
|
@ -912,23 +914,28 @@ IGNORES is a list of glob patterns."
|
||||||
" "
|
" "
|
||||||
(shell-quote-argument ")"))
|
(shell-quote-argument ")"))
|
||||||
dir
|
dir
|
||||||
(concat
|
(xref--find-ignores-arguments ignores dir)))
|
||||||
(shell-quote-argument "(")
|
|
||||||
" -path "
|
(defun xref--find-ignores-arguments (ignores dir)
|
||||||
(mapconcat
|
;; `shell-quote-argument' quotes the tilde as well.
|
||||||
(lambda (ignore)
|
(cl-assert (not (string-match-p "\\`~" dir)))
|
||||||
(when (string-match-p "/\\'" ignore)
|
(concat
|
||||||
(setq ignore (concat ignore "*")))
|
(shell-quote-argument "(")
|
||||||
(if (string-match "\\`\\./" ignore)
|
" -path "
|
||||||
(setq ignore (replace-match dir t t ignore))
|
(mapconcat
|
||||||
(unless (string-prefix-p "*" ignore)
|
(lambda (ignore)
|
||||||
(setq ignore (concat "*/" ignore))))
|
(when (string-match-p "/\\'" ignore)
|
||||||
(shell-quote-argument ignore))
|
(setq ignore (concat ignore "*")))
|
||||||
ignores
|
(if (string-match "\\`\\./" ignore)
|
||||||
" -o -path ")
|
(setq ignore (replace-match dir t t ignore))
|
||||||
" "
|
(unless (string-prefix-p "*" ignore)
|
||||||
(shell-quote-argument ")")
|
(setq ignore (concat "*/" ignore))))
|
||||||
" -prune -o ")))
|
(shell-quote-argument ignore))
|
||||||
|
ignores
|
||||||
|
" -o -path ")
|
||||||
|
" "
|
||||||
|
(shell-quote-argument ")")
|
||||||
|
" -prune -o "))
|
||||||
|
|
||||||
(defun xref--regexp-to-extended (str)
|
(defun xref--regexp-to-extended (str)
|
||||||
(replace-regexp-in-string
|
(replace-regexp-in-string
|
||||||
|
|
Loading…
Add table
Reference in a new issue