aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2015-12-08 03:40:37 +0200
committerDmitry Gutov2015-12-08 03:40:37 +0200
commit5edb06e1e6aa09e0a997fff73dd914bc3f723630 (patch)
tree667e99d2e02257bc158fe3cf8a7d4f23c50eaec1
parent87f5f31ee43bcf773da5ea765ecdf1a499fd8920 (diff)
downloademacs-scratch/project-directories-with-shallow.tar.gz
emacs-scratch/project-directories-with-shallow.zip
Add method project-directory-shallow-pscratch/project-directories-with-shallow
-rw-r--r--lisp/progmodes/project.el33
-rw-r--r--lisp/progmodes/xref.el22
2 files changed, 40 insertions, 15 deletions
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 5394e8afadd..a1b9374dae5 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -100,6 +100,13 @@ end it with `/'. DIR must be one of `project-directories' or
100 vc-directory-exclusion-list) 100 vc-directory-exclusion-list)
101 grep-find-ignored-files)) 101 grep-find-ignored-files))
102 102
103(cl-defgeneric project-directory-shallow-p (_project _dir)
104 "Return non-nil if DIR's subdirectories should be skipped.
105
106If this method returns nil, a consumer should traverse DIR's
107contents recursively when listing or searching through files."
108 nil)
109
103(defgroup project-vc nil 110(defgroup project-vc nil
104 "Project implementation using the VC package." 111 "Project implementation using the VC package."
105 :group 'tools) 112 :group 'tools)
@@ -174,16 +181,22 @@ implementation of `project-library-roots'.")
174 181
175(defun project-directories-in-categories (project &rest categories) 182(defun project-directories-in-categories (project &rest categories)
176 (project-combine-directories 183 (project-combine-directories
184 project
177 (cl-delete-if 185 (cl-delete-if
178 (lambda (dir) 186 (lambda (dir)
179 (cl-set-difference categories (project-directory-categories project dir))) 187 (cl-set-difference categories (project-directory-categories project dir)))
180 (project-directories project)))) 188 (project-directories project))))
181 189
182(defun project-combine-directories (dirs) 190(defun project-combine-directories (project dirs)
183 "Return a sorted and culled list of directory names in PROJECT. 191 "Return a sorted and culled list of directory names in PROJECT.
184It takes DIRS, removes non-existing directories, as well as 192It takes DIRS, removes non-existing directories, as well as
185directories a parent of whose is already in the list." 193directories a parent of whose is already in the list (if the
186 (let* ((dirs (sort 194parent is not shallow)."
195 (let* ((deep-dirs (cl-delete-if
196 (lambda (dir)
197 (project-directory-shallow-p project dir))
198 dirs))
199 (dirs (sort
187 (mapcar 200 (mapcar
188 (lambda (dir) 201 (lambda (dir)
189 (file-name-as-directory (expand-file-name dir))) 202 (file-name-as-directory (expand-file-name dir)))
@@ -192,16 +205,21 @@ directories a parent of whose is already in the list."
192 (ref dirs)) 205 (ref dirs))
193 ;; Delete subdirectories from the list. 206 ;; Delete subdirectories from the list.
194 (while (cdr ref) 207 (while (cdr ref)
195 (if (string-prefix-p (car ref) (cadr ref)) 208 (if (and (string-prefix-p (car ref) (cadr ref))
209 (member (car ref) deep-dirs))
196 (setcdr ref (cddr ref)) 210 (setcdr ref (cddr ref))
197 (setq ref (cdr ref)))) 211 (setq ref (cdr ref))))
198 (cl-delete-if-not #'file-exists-p dirs))) 212 (cl-delete-if-not #'file-exists-p dirs)))
199 213
200(defun project-subtract-directories (files dirs) 214(defun project-subtract-directories (project files dirs)
201 "Return a list of elements from FILES that are outside of DIRS. 215 "Return a list of elements from FILES that are outside of DIRS.
202DIRS must contain directory names." 216DIRS must contain directory names."
203 ;; Sidestep the issue of expanded/abbreviated file names here. 217 ;; Sidestep the issue of expanded/abbreviated file names here.
204 (cl-set-difference files dirs :test #'file-in-directory-p)) 218 (cl-set-difference files dirs
219 :test
220 (lambda (file dir)
221 (and (file-in-directory-p file dir)
222 (not (project-directory-shallow-p project dir))))))
205 223
206(defun project--value-in-dir (var dir) 224(defun project--value-in-dir (var dir)
207 (with-temp-buffer 225 (with-temp-buffer
@@ -249,7 +267,8 @@ pattern to search for."
249 (xrefs (cl-mapcan 267 (xrefs (cl-mapcan
250 (lambda (dir) 268 (lambda (dir)
251 (xref-collect-matches regexp files dir 269 (xref-collect-matches regexp files dir
252 (project-ignores project dir))) 270 (project-ignores project dir)
271 (project-directory-shallow-p project dir)))
253 dirs))) 272 dirs)))
254 (unless xrefs 273 (unless xrefs
255 (user-error "No matches for: %s" regexp)) 274 (user-error "No matches for: %s" regexp))
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index b86074f99c0..bc6303b6ee6 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -240,10 +240,12 @@ be found, return nil.
240The default implementation uses `semantic-symref-tool-alist' to 240The default implementation uses `semantic-symref-tool-alist' to
241find a search tool; by default, this uses \"find | grep\" in the 241find a search tool; by default, this uses \"find | grep\" in the
242`project-current' roots." 242`project-current' roots."
243 (cl-mapcan 243 (let ((project (project-current t)))
244 (lambda (dir) 244 (cl-mapcan
245 (xref-collect-references identifier dir)) 245 (lambda (dir)
246 (project-directories-in-categories (project-current t)))) 246 (xref-collect-references identifier dir
247 (project-directory-shallow-p project dir)))
248 (project-directories-in-categories project))))
247 249
248(cl-defgeneric xref-backend-apropos (backend pattern) 250(cl-defgeneric xref-backend-apropos (backend pattern)
249 "Find all symbols that match PATTERN. 251 "Find all symbols that match PATTERN.
@@ -833,11 +835,13 @@ and just use etags."
833(declare-function semantic-find-file-noselect "semantic/fw") 835(declare-function semantic-find-file-noselect "semantic/fw")
834(declare-function grep-expand-template "grep") 836(declare-function grep-expand-template "grep")
835 837
836(defun xref-collect-references (symbol dir) 838(defun xref-collect-references (symbol dir &optional shallow)
837 "Collect references to SYMBOL inside DIR. 839 "Collect references to SYMBOL inside DIR.
838This function uses the Semantic Symbol Reference API, see 840This function uses the Semantic Symbol Reference API, see
839`semantic-symref-find-references-by-name' for details on which 841`semantic-symref-find-references-by-name' for details on which
840tools are used, and when." 842tools are used, and when."
843 ;; FIXME: Apparently we'll have to support SHALLOW inside
844 ;; semantic-symref tools now.
841 (cl-assert (directory-name-p dir)) 845 (cl-assert (directory-name-p dir))
842 (require 'semantic/symref) 846 (require 'semantic/symref)
843 (defvar semantic-symref-tool) 847 (defvar semantic-symref-tool)
@@ -855,7 +859,7 @@ tools are used, and when."
855 (mapc #'kill-buffer 859 (mapc #'kill-buffer
856 (cl-set-difference (buffer-list) orig-buffers))))) 860 (cl-set-difference (buffer-list) orig-buffers)))))
857 861
858(defun xref-collect-matches (regexp files dir ignores) 862(defun xref-collect-matches (regexp files dir ignores &optional shallow)
859 "Collect matches for REGEXP inside FILES in DIR. 863 "Collect matches for REGEXP inside FILES in DIR.
860FILES is a string with glob patterns separated by spaces. 864FILES is a string with glob patterns separated by spaces.
861IGNORES is a list of glob patterns." 865IGNORES is a list of glob patterns."
@@ -868,7 +872,7 @@ IGNORES is a list of glob patterns."
868 grep-find-template t t)) 872 grep-find-template t t))
869 (grep-highlight-matches nil) 873 (grep-highlight-matches nil)
870 (command (xref--rgrep-command (xref--regexp-to-extended regexp) 874 (command (xref--rgrep-command (xref--regexp-to-extended regexp)
871 files dir ignores)) 875 files dir ignores shallow))
872 (orig-buffers (buffer-list)) 876 (orig-buffers (buffer-list))
873 (buf (get-buffer-create " *xref-grep*")) 877 (buf (get-buffer-create " *xref-grep*"))
874 (grep-re (caar grep-regexp-alist)) 878 (grep-re (caar grep-regexp-alist))
@@ -888,7 +892,7 @@ IGNORES is a list of glob patterns."
888 (mapc #'kill-buffer 892 (mapc #'kill-buffer
889 (cl-set-difference (buffer-list) orig-buffers))))) 893 (cl-set-difference (buffer-list) orig-buffers)))))
890 894
891(defun xref--rgrep-command (regexp files dir ignores) 895(defun xref--rgrep-command (regexp files dir ignores shallow)
892 (require 'find-dired) ; for `find-name-arg' 896 (require 'find-dired) ; for `find-name-arg'
893 (defvar grep-find-template) 897 (defvar grep-find-template)
894 (defvar find-name-arg) 898 (defvar find-name-arg)
@@ -905,6 +909,8 @@ IGNORES is a list of glob patterns."
905 (shell-quote-argument ")")) 909 (shell-quote-argument ")"))
906 dir 910 dir
907 (concat 911 (concat
912 (when shallow
913 " -maxdepth 1 ")
908 (shell-quote-argument "(") 914 (shell-quote-argument "(")
909 " -path " 915 " -path "
910 (mapconcat 916 (mapconcat