Commit 62d5d465 authored by Dmitry Gutov's avatar Dmitry Gutov
Browse files

Add `project-ignores'

* lisp/progmodes/project.el (project-ignores): New generic
function, and an implementation for the	VC project type.

* lisp/progmodes/xref.el (xref--rgrep-command): Split, as a
variant of rgrep-default-command that handles a generic list of
ignores.
(xref-collect-matches): Use it, and pass through to it the value
of the newly added argument.
(xref-find-regexp): Handle ignored paths within the project.
Remove outdated comment.

* lisp/vc/vc.el (vc-default-ignore-completion-table):
Skip the comments and the empty lines.
parent 714f7313
...@@ -584,7 +584,6 @@ It can be quoted, or be inside a quoted form." ...@@ -584,7 +584,6 @@ It can be quoted, or be inside a quoted form."
(declare-function xref-make-bogus-location "xref" (message)) (declare-function xref-make-bogus-location "xref" (message))
(declare-function xref-make "xref" (description location)) (declare-function xref-make "xref" (description location))
(declare-function xref-collect-matches "xref" (symbol dir))
(declare-function xref-collect-references "xref" (symbol dir)) (declare-function xref-collect-references "xref" (symbol dir))
(defun elisp-xref-find (action id) (defun elisp-xref-find (action id)
......
...@@ -84,6 +84,19 @@ of any currently open related projects, if they're meant to be ...@@ -84,6 +84,19 @@ of any currently open related projects, if they're meant to be
edited together. The directory names should be absolute." edited together. The directory names should be absolute."
(list (project-root project))) (list (project-root project)))
(cl-defgeneric project-ignores (_project)
"Return the list of glob patterns that match ignored files.
To root an entry, start it with `./'. To match directories only,
end it with `/'."
(require 'grep)
(defvar grep-find-ignored-files)
(nconc
(mapcar
(lambda (dir)
(concat dir "/"))
vc-directory-exclusion-list)
grep-find-ignored-files))
(defun project-try-vc (dir) (defun project-try-vc (dir)
(let* ((backend (ignore-errors (vc-responsible-backend dir))) (let* ((backend (ignore-errors (vc-responsible-backend dir)))
(root (and backend (ignore-errors (root (and backend (ignore-errors
...@@ -93,6 +106,18 @@ edited together. The directory names should be absolute." ...@@ -93,6 +106,18 @@ edited together. The directory names should be absolute."
(cl-defmethod project-root ((project (head vc))) (cl-defmethod project-root ((project (head vc)))
(cdr project)) (cdr project))
(cl-defmethod project-ignores ((project (head vc)))
(nconc
(cl-call-next-method)
(let* ((dir (cdr project))
(backend (vc-responsible-backend dir)))
(mapcar
(lambda (entry)
(if (string-match "\\`/" entry)
(replace-match "./" t t entry)
entry))
(vc-call-backend backend 'ignore-completion-table dir)))))
(defun project-ask-user (dir) (defun project-ask-user (dir)
(cons 'user (read-directory-name "Project root: " dir nil t))) (cons 'user (read-directory-name "Project root: " dir nil t)))
......
...@@ -662,20 +662,19 @@ With prefix argument, prompt for the identifier." ...@@ -662,20 +662,19 @@ With prefix argument, prompt for the identifier."
"Find all matches for REGEXP. "Find all matches for REGEXP.
With \\[universal-argument] prefix, you can specify the directory With \\[universal-argument] prefix, you can specify the directory
to search in." to search in."
;; FIXME: Prompt for directory.
(interactive (list (xref--read-identifier "Find regexp: "))) (interactive (list (xref--read-identifier "Find regexp: ")))
(let* ((dirs (if current-prefix-arg (let* ((proj (project-current))
(dirs (if current-prefix-arg
(list (read-directory-name "In directory: ")) (list (read-directory-name "In directory: "))
(let ((proj (project-current)))
(project--prune-directories (project--prune-directories
(nconc (nconc
(project-directories proj) (project-directories proj)
(project-search-path proj)))))) (project-search-path proj)))))
(xref-find-function (xref-find-function
(lambda (_kind regexp) (lambda (_kind regexp)
(cl-mapcan (cl-mapcan
(lambda (dir) (lambda (dir)
(xref-collect-matches regexp dir)) (xref-collect-matches regexp dir (project-ignores proj)))
dirs)))) dirs))))
(xref--show-xrefs regexp 'matches regexp nil))) (xref--show-xrefs regexp 'matches regexp nil)))
...@@ -756,7 +755,7 @@ tools are used, and when." ...@@ -756,7 +755,7 @@ tools are used, and when."
(mapc #'kill-buffer (mapc #'kill-buffer
(cl-set-difference (buffer-list) orig-buffers))))) (cl-set-difference (buffer-list) orig-buffers)))))
(defun xref-collect-matches (regexp dir) (defun xref-collect-matches (regexp dir ignores)
"Collect matches for REGEXP inside DIR using rgrep." "Collect matches for REGEXP inside DIR using rgrep."
(cl-assert (directory-name-p dir)) (cl-assert (directory-name-p dir))
(require 'semantic/fw) (require 'semantic/fw)
...@@ -766,8 +765,8 @@ tools are used, and when." ...@@ -766,8 +765,8 @@ tools are used, and when."
(let* ((grep-find-template (replace-regexp-in-string "-e " "-E " (let* ((grep-find-template (replace-regexp-in-string "-e " "-E "
grep-find-template t t)) grep-find-template t t))
(grep-highlight-matches nil) (grep-highlight-matches nil)
(command (rgrep-default-command (xref--regexp-to-extended regexp) (command (xref--rgrep-command (xref--regexp-to-extended regexp)
"*.*" dir)) "*.*" 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))
...@@ -787,6 +786,40 @@ tools are used, and when." ...@@ -787,6 +786,40 @@ tools are used, and when."
(mapc #'kill-buffer (mapc #'kill-buffer
(cl-set-difference (buffer-list) orig-buffers))))) (cl-set-difference (buffer-list) orig-buffers)))))
(defun xref--rgrep-command (regexp files dir ignores)
(require 'find-dired) ; for `find-name-arg'
(defvar grep-find-template)
(defvar find-name-arg)
(grep-expand-template
grep-find-template
regexp
(concat (shell-quote-argument "(")
" " find-name-arg " "
(mapconcat
#'shell-quote-argument
(split-string files)
(concat " -o " find-name-arg " "))
" "
(shell-quote-argument ")"))
dir
(concat
(shell-quote-argument "(")
" -path "
(mapconcat
(lambda (ignore)
(when (string-match "\\(\\.\\)/" ignore)
(setq ignore (replace-match dir t t ignore 1)))
(when (string-match-p "/\\'" ignore)
(setq ignore (concat 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) (defun xref--regexp-to-extended (str)
(replace-regexp-in-string (replace-regexp-in-string
;; FIXME: Add tests. Move to subr.el, make a public function. ;; FIXME: Add tests. Move to subr.el, make a public function.
......
...@@ -1423,8 +1423,12 @@ Argument BACKEND is the backend you are using." ...@@ -1423,8 +1423,12 @@ Argument BACKEND is the backend you are using."
(defun vc-default-ignore-completion-table (backend file) (defun vc-default-ignore-completion-table (backend file)
"Return the list of ignored files under BACKEND." "Return the list of ignored files under BACKEND."
(cl-delete-if
(lambda (str)
;; Commented or empty lines.
(string-match-p "\\`\\(?:#\\|[ \t\r\n]*\\'\\)" str))
(vc--read-lines (vc--read-lines
(vc-call-backend backend 'find-ignore-file file))) (vc-call-backend backend 'find-ignore-file file))))
(defun vc--read-lines (file) (defun vc--read-lines (file)
"Return a list of lines of FILE." "Return a list of lines of FILE."
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment