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."
(declare-function xref-make-bogus-location "xref" (message))
(declare-function xref-make "xref" (description location))
(declare-function xref-collect-matches "xref" (symbol dir))
(declare-function xref-collect-references "xref" (symbol dir))
(defun elisp-xref-find (action id)
......
......@@ -84,6 +84,19 @@ of any currently open related projects, if they're meant to be
edited together. The directory names should be absolute."
(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)
(let* ((backend (ignore-errors (vc-responsible-backend dir)))
(root (and backend (ignore-errors
......@@ -93,6 +106,18 @@ edited together. The directory names should be absolute."
(cl-defmethod project-root ((project (head vc)))
(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)
(cons 'user (read-directory-name "Project root: " dir nil t)))
......
......@@ -662,20 +662,19 @@ With prefix argument, prompt for the identifier."
"Find all matches for REGEXP.
With \\[universal-argument] prefix, you can specify the directory
to search in."
;; FIXME: Prompt for directory.
(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: "))
(let ((proj (project-current)))
(project--prune-directories
(nconc
(project-directories proj)
(project-search-path proj))))))
(project--prune-directories
(nconc
(project-directories proj)
(project-search-path proj)))))
(xref-find-function
(lambda (_kind regexp)
(cl-mapcan
(lambda (dir)
(xref-collect-matches regexp dir))
(xref-collect-matches regexp dir (project-ignores proj)))
dirs))))
(xref--show-xrefs regexp 'matches regexp nil)))
......@@ -756,7 +755,7 @@ tools are used, and when."
(mapc #'kill-buffer
(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."
(cl-assert (directory-name-p dir))
(require 'semantic/fw)
......@@ -766,8 +765,8 @@ tools are used, and when."
(let* ((grep-find-template (replace-regexp-in-string "-e " "-E "
grep-find-template t t))
(grep-highlight-matches nil)
(command (rgrep-default-command (xref--regexp-to-extended regexp)
"*.*" dir))
(command (xref--rgrep-command (xref--regexp-to-extended regexp)
"*.*" dir ignores))
(orig-buffers (buffer-list))
(buf (get-buffer-create " *xref-grep*"))
(grep-re (caar grep-regexp-alist))
......@@ -787,6 +786,40 @@ tools are used, and when."
(mapc #'kill-buffer
(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)
(replace-regexp-in-string
;; FIXME: Add tests. Move to subr.el, make a public function.
......
......@@ -1423,8 +1423,12 @@ Argument BACKEND is the backend you are using."
(defun vc-default-ignore-completion-table (backend file)
"Return the list of ignored files under BACKEND."
(vc--read-lines
(vc-call-backend backend 'find-ignore-file file)))
(cl-delete-if
(lambda (str)
;; Commented or empty lines.
(string-match-p "\\`\\(?:#\\|[ \t\r\n]*\\'\\)" str))
(vc--read-lines
(vc-call-backend backend 'find-ignore-file file))))
(defun vc--read-lines (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