unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Eshel Yaron via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Juri Linkov <juri@linkov.net>
Cc: Dmitry Gutov <dmitry@gutov.dev>, Eli Zaretskii <eliz@gnu.org>,
	68958@debbugs.gnu.org
Subject: bug#68958: [PATCH] Support bookmarking Xref results buffers
Date: Thu, 15 Feb 2024 10:28:02 +0100	[thread overview]
Message-ID: <m1frxum5zx.fsf@sp-byods-145-109-12-61.wireless.uva.nl> (raw)
In-Reply-To: <86il2qxg5c.fsf@mail.linkov.net> (Juri Linkov's message of "Thu,  15 Feb 2024 09:58:19 +0200")

[-- Attachment #1: Type: text/plain, Size: 1351 bytes --]

Hi Juri,

Juri Linkov <juri@linkov.net> writes:

>> Also, we'd probably want to limit the size of the printed representation
>> (FETCHER created by project-find-regexp currently closes over the full list
>> of files, that's too much to save; it will probably be a good idea to
>> rewrite it to fetch the list of files anew).
>
> Indeed, I confirm the problem: reverting an xref buffer with 'g'
> can't find matches in a new file added after the first run.
>
> Doesn't this hint that both a bookmark and a revert function
> should store more high-level arguments?  For example, for
> 'project-find-regexp' it should be sufficient to store
> its argument 'regexp' together with 'default-directory'
> to reconstruct the previous xref buffer contents.
> Then it could store these arguments in a buffer-local variable
> that could be used to create a bookmark.

Yes, that's almost exactly what I did in my bookmarking implementation.
Only difference is I kept the whole project object instead of just
'default-directory', since different project types can use different
information.  I'm attaching below the patch I applied in my local
branch, as a reference.

> PS: With C-u 'project-find-regexp' reads more arguments
> in the body, but such reading should be moved to the
> interactive form anyway like 'rgrep' does.

Agreed.  This patch does that too:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Support-bookmarking-project-find-regexp-results-buff.patch --]
[-- Type: text/x-patch, Size: 7648 bytes --]

From 5de2bfd3e2d672d0f955b916a200edc16dca6b07 Mon Sep 17 00:00:00 2001
From: Eshel Yaron <me@eshelyaron.com>
Date: Mon, 12 Feb 2024 18:38:36 +0100
Subject: [PATCH] Support bookmarking 'project-find-regexp' results buffer

* lisp/progmodes/project.el (xref-backend-apropos)
(xref-backend-context, xref-backend-restore): New methods.
(project-find-regexp, project-or-external-find-regexp): Use
'xref-make-fetcher' instead of a bespoke fetcher function to
facilitate bookmarking the results buffer.

* lisp/progmodes/xref.el (xref-bookmark-make-record): Use
strings for 'format-spec' specifications.
(xref-bookmark-jump): Autoload it.
(xref-show-xrefs): Make DISPLAY-ACTION argument optional.
(xref-make-fetcher): Autoload, and make BUFFER and POINT
arguments optional, default to the current buffer and point.
---
 lisp/progmodes/project.el | 69 ++++++++++++++++++++-------------------
 lisp/progmodes/xref.el    | 14 +++++---
 2 files changed, 45 insertions(+), 38 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 916a031ec60..6b0b4e86851 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -947,32 +947,44 @@ project-other-tab-command
 (declare-function grep-read-files "grep")
 (declare-function xref--find-ignores-arguments "xref")
 
+(cl-defmethod xref-backend-context ((_backend (head project)) _id _kind))
+(cl-defmethod xref-backend-restore ((_backend (head project)) _context))
+(cl-defmethod xref-backend-apropos ((backend (head project)) pattern)
+  (project--find-regexp-in-files pattern (project-files (cdr backend))))
+
+(cl-defmethod xref-backend-context ((_backend (head project-dir)) _id _kind))
+(cl-defmethod xref-backend-restore ((_backend (head project-dir)) _context))
+(cl-defmethod xref-backend-apropos ((backend (head project-dir)) pattern)
+  (project--find-regexp-in-files
+   pattern (project--files-in-directory (nth 1 backend) nil (nth 2 backend))))
+
+(cl-defmethod xref-backend-context ((_backend (head project-ext)) _id _kind))
+(cl-defmethod xref-backend-restore ((_backend (head project-ext)) _context))
+(cl-defmethod xref-backend-apropos ((backend (head project-ext)) pattern)
+  (let ((pr (cdr backend)))
+    (project--find-regexp-in-files
+     pattern (project-files pr (cons (project-root pr)
+                                     (project-external-roots pr))))))
+
 ;;;###autoload
-(defun project-find-regexp (regexp)
+(defun project-find-regexp (regexp &optional dir pattern)
   "Find all matches for REGEXP in the current project's roots.
-With \\[universal-argument] prefix, you can specify the directory
-to search in, and the file name pattern to search for.  The
+With \\[universal-argument] prefix, you can specify the DIR
+to search in, and the file name PATTERN to search for.  The
 pattern may use abbreviations defined in `grep-files-aliases',
 e.g. entering `ch' is equivalent to `*.[ch]'.  As whitespace
 triggers completion when entering a pattern, including it
 requires quoting, e.g. `\\[quoted-insert]<space>'."
-  (interactive (list (project--read-regexp)))
-  (require 'xref)
-  (require 'grep)
-  (let* ((caller-dir default-directory)
-         (pr (project-current t))
-         (default-directory (project-root pr))
-         (files
-          (if (not current-prefix-arg)
-              (project-files pr)
-            (let ((dir (read-directory-name "Base directory: "
-                                            caller-dir nil t)))
-              (project--files-in-directory dir
-                                           nil
-                                           (grep-read-files regexp))))))
-    (xref-show-xrefs
-     (apply-partially #'project--find-regexp-in-files regexp files)
-     nil)))
+  (interactive (let* ((regexp (project--read-regexp))
+                      (dir-pat (when current-prefix-arg
+                                 (cons (read-directory-name "Base directory: ")
+                                       (grep-read-files regexp)))))
+                 (list regexp (car dir-pat) (cdr dir-pat))))
+  (xref-show-xrefs (xref-make-fetcher
+                    (if dir
+                        (list 'project-dir dir pattern)
+                      (cons 'project (project-current t)))
+                    regexp 'apropos regexp)))
 
 (defun project--dir-ignores (project dir)
   (let ((root (project-root project)))
@@ -987,20 +999,11 @@ project--dir-ignores
 
 ;;;###autoload
 (defun project-or-external-find-regexp (regexp)
-  "Find all matches for REGEXP in the project roots or external roots.
-With \\[universal-argument] prefix, you can specify the file name
-pattern to search for."
+  "Find all matches for REGEXP in the project roots or external roots."
   (interactive (list (project--read-regexp)))
-  (require 'xref)
-  (let* ((pr (project-current t))
-         (default-directory (project-root pr))
-         (files
-          (project-files pr (cons
-                             (project-root pr)
-                             (project-external-roots pr)))))
-    (xref-show-xrefs
-     (apply-partially #'project--find-regexp-in-files regexp files)
-     nil)))
+  (xref-show-xrefs (xref-make-fetcher
+                    (cons 'project-ext (project-current t))
+                    regexp 'apropos regexp)))
 
 (defun project--find-regexp-in-files (regexp files)
   (unless files
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 6841f93a9c2..2742cc56ea1 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -1049,8 +1049,8 @@ xref-bookmark-make-record
     (user-error "Cannot bookmark due to unknown Xref backend"))
   `(,(format-spec xref-default-bookmark-name-format
                   `((?i . ,xref--identifier)
-                    (?k . ,xref--kind)
-                    (?b . ,xref--backend)))
+                    (?k . ,(symbol-name xref--kind))
+                    (?b . ,(prin1-to-string xref--backend))))
     ,@(bookmark-make-record-default t)
     (backend . ,xref--backend)
     (context . ,(when (buffer-live-p xref--original-buffer)
@@ -1064,6 +1064,7 @@ xref-bookmark-make-record
     (kind . ,xref--kind)
     (handler . xref-bookmark-jump)))
 
+;;;###autoload
 (defun xref-bookmark-jump (bookmark)
   "Jump to Xref buffer bookmark BOOKMARK."
   (let* ((backend (bookmark-prop-get bookmark 'backend))
@@ -1587,7 +1588,7 @@ xref--read-identifier-history
 (defvar xref--read-pattern-history nil)
 
 ;;;###autoload
-(defun xref-show-xrefs (fetcher display-action)
+(defun xref-show-xrefs (fetcher &optional display-action)
   "Display some Xref values produced by FETCHER using DISPLAY-ACTION.
 The meanings of both arguments are the same as documented in
 `xref-show-xrefs-function'."
@@ -1680,7 +1681,8 @@ xref--find-definitions
    (xref--create-fetcher id 'definitions id)
    display-action))
 
-(defun xref-make-fetcher (backend input kind identifier buffer point)
+;;;###autoload
+(defun xref-make-fetcher (backend input kind identifier &optional buffer point)
   "Return fetcher function for xrefs of kind KIND for IDENTIFIER using BACKEND.
 
 INPUT is the user input for the Xref operation, usually it is the same
@@ -1690,7 +1692,9 @@ xref-make-fetcher
 
 The fetcher function returns a list of xrefs, and sets
 `xref-fetcher-alist', which see."
-  (let ((method (intern (format "xref-backend-%s" kind))))
+  (let ((method (intern (format "xref-backend-%s" kind)))
+        (buffer (or buffer (current-buffer)))
+        (point (or point (point))))
     (lambda ()
       (setq xref-fetcher-alist (list (cons 'original-buffer buffer)
                                      (cons 'original-point point)
-- 
2.42.0


  reply	other threads:[~2024-02-15  9:28 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-06 20:17 bug#68958: [PATCH] Support bookmarking Xref results buffers Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-07 12:25 ` Eli Zaretskii
2024-02-07 17:04   ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-11  3:27   ` Dmitry Gutov
2024-02-11  6:18     ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-11 11:13       ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-11 15:34       ` Dmitry Gutov
2024-02-11 17:21         ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-11 23:01           ` Dmitry Gutov
2024-02-12 11:45             ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-13  3:18               ` Dmitry Gutov
2024-02-13  7:10                 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-14  7:14                   ` Juri Linkov
2024-02-15 17:57                   ` Dmitry Gutov
2024-02-15 21:49                     ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-15  7:58             ` Juri Linkov
2024-02-15  9:28               ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-02-07 17:25 ` Juri Linkov
2024-02-11  3:21   ` Dmitry Gutov
2024-02-11 17:37     ` Juri Linkov
2024-02-11 22:45       ` Dmitry Gutov
2024-02-12 18:31         ` Juri Linkov
2024-02-12 18:40           ` 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=m1frxum5zx.fsf@sp-byods-145-109-12-61.wireless.uva.nl \
    --to=bug-gnu-emacs@gnu.org \
    --cc=68958@debbugs.gnu.org \
    --cc=dmitry@gutov.dev \
    --cc=eliz@gnu.org \
    --cc=juri@linkov.net \
    --cc=me@eshelyaron.com \
    /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).