unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: "Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Dmitry Gutov <dgutov@yandex.ru>
Cc: 49731@debbugs.gnu.org
Subject: bug#49731: 28.0.50; Filter xref results by filename
Date: Tue, 27 Jul 2021 19:08:00 +0200	[thread overview]
Message-ID: <m15ywv8z2n.fsf@yahoo.es> (raw)
In-Reply-To: <030dbe6c-130d-e578-f50d-54e90bfa7cfa@yandex.ru> (Dmitry Gutov's message of "Tue, 27 Jul 2021 02:28:58 +0300")

Dmitry Gutov <dgutov@yandex.ru> writes:

>
> We've discussed this sort of functionality before. Here are some
> approaches (not mutually exclusive):
>
> 1. Add the possibility to add filtering by file names, types, etc,
> before the search is done. This should fit 'project-find-regexp'
> well. I can point you to a previous discussion with some ideas. The
> main upside is you can speed up the search. And store such settings as
> a history.

I think that kind of search scoping in advance can be specially useful
when you are doing a grep-like search in the codebase, using either
grep, rgrep, project-find-regexp, or xref-find-apropos.

I see it less useful for example when you place the point in an
identifier and press M-?.  You'll want to see all the references first,
and then filter afterwards if they are too many.  But I think it's a
matter of personal preferences and different workflows.

>
> 2. Filter in the resulting Xref buffer. The best part is it can work
> with the output from any command that uses Xref. The "filtering" is 
> temporary. I'm assuming this is the direction you want to work in.
>

Yes, that's the direction that interests me the most, if it's actually a
worthy feature for Emacs users.

>
> I've never exactly considered the option 2., but I'd be happy to talk
> the details. WRT UI, maybe something along the lines of 
> package-menu-filter-* commands, bound inside a '/' prefix. One command
> could add "inclusion filter", another - "exclusion filter", and the 
> third one - reset all filters. '/ /' be bound to the last one.
>

I didn't have in mind implementing cumulative filters.  I don't know if
people would need such advanced filtering of results.  FTR, I've
researched how other tools and IDEs implement this feature, which is
less common than what I initially thought:

- Xcode: In the references panel there is a filter box on the bottom so
  that you type and filter the results to keep those that match the
  pattern.

- IntelliJ IDEA: I haven't seen a similar functionality.  There is a
  button to remove references from automatically generated code, but
  that's all.

- Sourcegraph: It doesn't seem to offer a similar functionality.

- Chromium Code Search: It offers a box to filter by file path.  It also
  offers an option to exclude tests and generated files.

>
> Another thing to keep an eye out for - is how the filtering will
> affect n/p navigation and the xref-query-replace-in-results command. I
> think they should respect the filtering as well.

Here's a first quick and dirty prototype based on Juri's code snippet:

diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index e2cd904a6c..27ff08f7ce 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -665,6 +665,36 @@ xref-goto-xref
       ;; Emacs < 27
       (setq next-error-last-buffer buffer))))
 
+(declare-function outline-show-entry "outline" ())
+(declare-function outline-hide-body "outline" ())
+
+(defun xref-filter-results-by-file (pattern)
+  "Filter xref results to only include those in files that match PATTERN."
+  (interactive (list (read-string
+                      "Filter results in files that match pattern (regexp): "
+                      nil nil)))
+  (require 'outline)
+  (setq-local outline-regexp
+              (if (eq xref-file-name-display 'abs) "/" "[^ 0-9]"))
+  (outline-minor-mode +1)
+  (outline-hide-body)
+  (save-excursion
+    (goto-char (point-min))
+    (let ((count 0))
+      (while (progn
+             (when (re-search-forward pattern (line-end-position) t)
+               (outline-show-entry)
+               (setq count (1+ count)))
+             (xref--search-property 'xref-group)))
+      (when (zerop count)
+        (message "No match")
+        (xref-exit-results-filter)))))
+
+(defun xref-exit-results-filter ()
+  "Remove any xref filter and show the full list of results."
+  (interactive)
+  (outline-minor-mode -1))
+
 (defun xref-quit-and-goto-xref ()
   "Quit *xref* buffer, then jump to xref on current line."
   (interactive)
@@ -824,6 +854,8 @@ xref--xref-buffer-mode-map
     (define-key map (kbd ",") #'xref-prev-line)
     (define-key map (kbd "g") #'xref-revert-buffer)
     (define-key map (kbd "M-,") #'xref-quit-and-pop-marker-stack)
+    (define-key map (kbd "f") #'xref-filter-results-by-file)
+    (define-key map (kbd "q") #'xref-exit-results-filter)
     map))
 
 (define-derived-mode xref--xref-buffer-mode special-mode "XREF"

I've bound the new command to "f".  For simplicity, each time you press
"f" you'll filter the entire list (filters are not cumulative).  As you
said, pressing "p" and "n" navigate results that are folded, which is
confusing.  Perhaps a new minor mode in xref could do the outline
folding and also make sure that "p" and "n" skip results that are
folded.





  reply	other threads:[~2021-07-27 17:08 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <m1pmv6iz4n.fsf.ref@yahoo.es>
2021-07-25  8:19 ` bug#49731: 28.0.50; Filter xref results by filename Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-07-25  8:32   ` Lars Ingebrigtsen
2021-07-25  8:33     ` Lars Ingebrigtsen
2021-07-26 23:16       ` Dmitry Gutov
2021-07-25  9:10   ` Eli Zaretskii
2021-07-25 14:58     ` Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-07-25 20:43   ` Juri Linkov
2021-07-26 11:49     ` Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-07-26 22:53       ` Juri Linkov
2022-01-16 18:52       ` Juri Linkov
2022-11-21  7:58         ` Juri Linkov
2022-11-23  8:39           ` Juri Linkov
2022-11-23 14:19             ` Dmitry Gutov
2022-11-23 17:50               ` Juri Linkov
2022-11-23 18:08                 ` Dmitry Gutov
2022-11-23 18:20                   ` Juri Linkov
2022-11-23 18:47                     ` Dmitry Gutov
2022-11-24  7:48                       ` Juri Linkov
2022-11-25  7:35                         ` Kévin Le Gouguec
2024-02-13 16:52               ` Juri Linkov
2024-02-14  9:25                 ` Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-15  7:23                   ` Juri Linkov
2021-07-26 23:28   ` Dmitry Gutov
2021-07-27 17:08     ` Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2021-07-27 20:51       ` Juri Linkov
2021-07-27 23:11         ` Dmitry Gutov
2021-07-28  0:08       ` Dmitry Gutov
2021-07-28 16:12         ` Juri Linkov
2021-07-29  2:02           ` Dmitry Gutov
2021-07-29 17:43             ` Juri Linkov
2021-08-02  2:09               ` Dmitry Gutov
2021-08-02 20:58                 ` Juri Linkov
2021-08-06  0:03                   ` Dmitry Gutov
2021-07-31 16:45         ` Daniel Martín via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-07-31 17:06           ` Eli Zaretskii
2022-11-23 18:48       ` Dmitry Gutov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m15ywv8z2n.fsf@yahoo.es \
    --to=bug-gnu-emacs@gnu.org \
    --cc=49731@debbugs.gnu.org \
    --cc=dgutov@yandex.ru \
    --cc=mardani29@yahoo.es \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).