(defun xref--add-log-current-defun ()
"Return the string used to group a set of locations.
This function is used as a value for `add-log-current-defun-function'."
- (xref--group-name-for-display
- (if-let (item (xref--item-at-point))
- (xref-location-group (xref-match-item-location item))
- (xref--imenu-extract-index-name))
- (xref--project-root (project-current))))
+ (let ((project-root (xref--project-root (project-current))))
+ (xref--group-name-for-display
+ (if-let (item (xref--item-at-point))
+ (xref-location-group (xref-match-item-location item))
+ (xref--imenu-extract-index-name))
+ project-root
+ (and
+ (string-prefix-p project-root default-directory)
+ (substring default-directory (length project-root))))))
(defun xref--next-error-function (n reset?)
(when reset?
(xref--apply-truncation)))
(run-hooks 'xref-after-update-hook))
-(defun xref--group-name-for-display (group project-root)
+(defun xref--group-name-for-display (group project-root dd-suffix)
"Return GROUP formatted in the preferred style.
The style is determined by the value of `xref-file-name-display'.
If GROUP looks like a file name, its value is formatted according
-to that style. Otherwise it is returned unchanged."
+to that style. Otherwise it is returned unchanged.
+
+PROJECT-ROOT is the root of the current project, if any. DD-SUFFIX is
+the relative name of `default-directory' relative to the project root."
;; XXX: The way we verify that it's indeed a file name and not some
;; other kind of string, e.g. Java package name or TITLE from
;; `tags-apropos-additional-actions', is pretty lax. But we don't
;; values themselves (e.g. by piping through some public function),
;; or adding a new accessor to locations, like GROUP-TYPE.
(cl-ecase xref-file-name-display
- (abs group)
+ (abs (if (file-name-absolute-p group) group (expand-file-name group)))
(nondirectory
- (if (file-name-absolute-p group)
- (file-name-nondirectory group)
- group))
+ (file-name-nondirectory group))
(project-relative
- (if (and project-root
- (string-prefix-p project-root group))
- (substring group (length project-root))
- group))))
+ (cond
+ ((not (file-name-absolute-p group))
+ (concat dd-suffix group))
+ ((and project-root
+ (string-prefix-p project-root group))
+ (substring group (length project-root)))
+ ;; Default to absolute when there's not project around.
+ (t
+ (expand-file-name group))))))
(defun xref--analyze (xrefs)
"Find common groups in XREFS and format group names.
(eq xref-file-name-display 'project-relative)
(project-current)))
(project-root (and project
- (expand-file-name (xref--project-root project)))))
+ (expand-file-name (xref--project-root project))))
+ (dd-suffix (and project-root
+ (string-prefix-p project-root default-directory)
+ (substring default-directory (length project-root)))))
(mapcar
(lambda (pair)
- (cons (xref--group-name-for-display (car pair) project-root)
+ (cons (xref--group-name-for-display (car pair) project-root dd-suffix)
(cdr pair)))
alist)))
(should (equal (sort (mapcar #'xref-item-summary matches) #'string<)
'("((nil . ((project-vc-ignores . (\"etc\")))))" "etc"))))))
+(ert-deftest project-find-regexp-with-prefix ()
+ "Check the happy path."
+ (skip-unless (executable-find find-program))
+ (skip-unless (executable-find "xargs"))
+ (skip-unless (executable-find "grep"))
+ (let* ((directory (ert-resource-directory))
+ (project-find-functions nil)
+ (project-list-file (expand-file-name "emacs-projects" temporary-file-directory))
+ (project (cons 'transient (expand-file-name "../elisp-mode-resources/" directory))))
+ (add-hook 'project-find-functions (lambda (_dir) project))
+ (should (eq (project-current) project))
+ (let* ((matches nil)
+ (xref-search-program 'grep)
+ (xref-show-xrefs-function
+ (lambda (fetcher _display)
+ (setq matches (funcall fetcher))))
+ (current-prefix-arg t))
+ (cl-letf (((symbol-function 'read-directory-name)
+ (lambda (_prompt _default _dirname _mm) directory))
+ ((symbol-function 'grep-read-files) (lambda (_re) "*")))
+ (project-find-regexp "etc"))
+ (should (equal (mapcar (lambda (item)
+ (file-name-base
+ (xref-location-group (xref-item-location item))))
+ matches)
+ '(".dir-locals" "etc")))
+ (should (equal (sort (mapcar #'xref-item-summary matches) #'string<)
+ '("((nil . ((project-vc-ignores . (\"etc\")))))" "etc"))))))
+
;;; project-tests.el ends here