From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: Eshel Yaron via "Bug reports for GNU Emacs,
 the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
Newsgroups: gmane.emacs.bugs
Subject: bug#68958: [PATCH] Support bookmarking Xref results buffers
Date: Thu, 15 Feb 2024 22:49:26 +0100
Message-ID: <m1r0hdtn2x.fsf@dazzs-mbp.home>
References: <m1h6ilgxee.fsf@dazzs-mbp.home> <86le7wzcjj.fsf@gnu.org>
 <0b3f4669-180e-466f-96f3-7eeae994581f@gutov.dev>
 <m1cyt35xrj.fsf@dazzs-mbp.home>
 <b521e786-377c-4834-be68-87a824ae6384@gutov.dev>
 <m14jee5341.fsf@dazzs-mbp.home>
 <1bea3fe4-51aa-418b-a55f-f09d0a4c558e@gutov.dev>
 <m1jzn9ewio.fsf@dazzs-mbp.home>
 <653af486-3b3b-4270-8385-ee3af6639eb5@gutov.dev>
 <m18r3ou9dx.fsf@dazzs-mbp.home>
 <622b208a-6e2a-4f47-b243-40846ec48df1@gutov.dev>
Reply-To: Eshel Yaron <me@eshelyaron.com>
Mime-Version: 1.0
Content-Type: text/plain
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="39773"; mail-complaints-to="usenet@ciao.gmane.io"
User-Agent: Gnus/5.13 (Gnus v5.13)
Cc: Eli Zaretskii <eliz@gnu.org>, 68958@debbugs.gnu.org
To: Dmitry Gutov <dmitry@gutov.dev>
Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Feb 15 22:50:05 2024
Return-path: <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>
Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.92)
	(envelope-from <bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org>)
	id 1rajcK-000A92-Ra
	for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 15 Feb 2024 22:50:05 +0100
Original-Received: from localhost ([::1] helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <bug-gnu-emacs-bounces@gnu.org>)
	id 1rajc1-0006pn-7C; Thu, 15 Feb 2024 16:49:45 -0500
Original-Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1rajbz-0006pJ-PH
 for bug-gnu-emacs@gnu.org; Thu, 15 Feb 2024 16:49:43 -0500
Original-Received: from debbugs.gnu.org ([2001:470:142:5::43])
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128)
 (Exim 4.90_1) (envelope-from <Debian-debbugs@debbugs.gnu.org>)
 id 1rajbz-0006DY-Ha
 for bug-gnu-emacs@gnu.org; Thu, 15 Feb 2024 16:49:43 -0500
Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2)
 (envelope-from <Debian-debbugs@debbugs.gnu.org>) id 1rajcI-0006tG-Bs
 for bug-gnu-emacs@gnu.org; Thu, 15 Feb 2024 16:50:02 -0500
X-Loop: help-debbugs@gnu.org
Resent-From: Eshel Yaron <me@eshelyaron.com>
Original-Sender: "Debbugs-submit" <debbugs-submit-bounces@debbugs.gnu.org>
Resent-CC: bug-gnu-emacs@gnu.org
Resent-Date: Thu, 15 Feb 2024 21:50:02 +0000
Resent-Message-ID: <handler.68958.B68958.170803379526469@debbugs.gnu.org>
Resent-Sender: help-debbugs@gnu.org
X-GNU-PR-Message: followup 68958
X-GNU-PR-Package: emacs
X-GNU-PR-Keywords: patch
Original-Received: via spool by 68958-submit@debbugs.gnu.org id=B68958.170803379526469
 (code B ref 68958); Thu, 15 Feb 2024 21:50:02 +0000
Original-Received: (at 68958) by debbugs.gnu.org; 15 Feb 2024 21:49:55 +0000
Original-Received: from localhost ([127.0.0.1]:57628 helo=debbugs.gnu.org)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <debbugs-submit-bounces@debbugs.gnu.org>)
 id 1rajc7-0006sl-Gq
 for submit@debbugs.gnu.org; Thu, 15 Feb 2024 16:49:54 -0500
Original-Received: from mail.eshelyaron.com ([107.175.124.16]:39484 helo=eshelyaron.com)
 by debbugs.gnu.org with esmtp (Exim 4.84_2)
 (envelope-from <me@eshelyaron.com>) id 1rajc5-0006se-QN
 for 68958@debbugs.gnu.org; Thu, 15 Feb 2024 16:49:50 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=eshelyaron.com;
 s=mail; t=1708033770;
 bh=2iQ9zhqKpZHePyMTS4H4samTPmPk3Fp/5aVL6ldq1+c=;
 h=From:To:Cc:Subject:In-Reply-To:References:Date:From;
 b=xIVtHmPgUFHoSyhoUbNqc4Y2SZ+rpX+1qSC5gPxyWBMBqDgAhIaeWCvMZDOZaVcbn
 GaQGQ5ECiXRbPmhTGT0xA3hqORuyIN98U841hx1sjCqV3SzHC8cPZo5e/EuZifCHFp
 zSeQti2V8c0NhpoH58gl2Av9PXGdWWi/FEK8qH/+DV5c4h5fJOKqGJjFGz5uY/VZgC
 IBHtEv7hPxDOxhAyxtaKEovdmhFy6zL47/LPUk6JOXv8Jx3XQ7bw2BzB5m13PDR6bo
 IvcY8D0rhYxu9C0Mn6+0pkZhBHs68vCsZaT+Vh2r6D/aGhI+aFdNvcCJQnItdqsb6/
 KKnWeXokXz7Og==
In-Reply-To: <622b208a-6e2a-4f47-b243-40846ec48df1@gutov.dev> (Dmitry Gutov's
 message of "Thu, 15 Feb 2024 19:57:08 +0200")
X-BeenThere: debbugs-submit@debbugs.gnu.org
X-Mailman-Version: 2.1.18
Precedence: list
X-BeenThere: bug-gnu-emacs@gnu.org
List-Id: "Bug reports for GNU Emacs,
 the Swiss army knife of text editors" <bug-gnu-emacs.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/bug-gnu-emacs>
List-Post: <mailto:bug-gnu-emacs@gnu.org>
List-Help: <mailto:bug-gnu-emacs-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/bug-gnu-emacs>,
 <mailto:bug-gnu-emacs-request@gnu.org?subject=subscribe>
Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org
Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org
Xref: news.gmane.io gmane.emacs.bugs:280083
Archived-At: <http://permalink.gmane.org/gmane.emacs.bugs/280083>

Dmitry Gutov <dmitry@gutov.dev> writes:

> On 13/02/2024 09:10, Eshel Yaron wrote:
>> Dmitry Gutov <dmitry@gutov.dev> writes:
>>
>>> Otherwise, the requirements on the arguments are the same (fetcher --
>>> named function, args -- printability).
>> That might work, although it seems rather difficult to explain such
>> requirements, and it's difficult for callers to ensure or even check
>> whether they're kept (how do you know if your argument is too big
>> without printing it in advance?)
>
> You can usually track that on the level of user input. A good rule of
> thumb would be not to pass a generated list of files. And if some
> user's interactive input string is veeeeeery long, well, whatever disk
> space is wasted as a result is their own doing.

I agree, that's a good heuristic.

> What's the alternative, though? Writing a separate bookmark storage
> function for every sort of search? For project, lsp-mode/eglot (they
> both have additional commands doing extra searches), etc?

I think we should have an extensible interface that covers the Xref
commands by default, and allows other callers of `xref-show-xrefs` to
override the default to suite their needs.

> And the return value of xref-backend-context (from your proposal) must
> likewise be print-able and compact enough, right?

Yes, you're right.  By default, in my proposal, the return value of this
method is itself a bookmark record (pointing to the position where you
initiate the search), so we rely on the major mode of the original
buffer to define a reasonable `bookmark-make-record-function`.  If a
backend overrides the default method, it also needs to take into account
these limitations, indeed.

>> Furthermore, IIUC, what you get is an opaque function and argument list,
>> and the frontend cannot reason about these, it can only apply the
>> function to these arguments to get a list of xrefs.  In contrast,
>> xref-fetcher-alist provides clear (documented) semantics.
>
> Which will only work for Xref's own commands but not for any external
> callers of xref-show-xrefs. Right?

It doesn't work out of the box for external callers, but it isn't
strictly restricted to Xref commands either: it works for any caller of
`xref-show-xrefs` that defines a (possibly trivial) Xref backend, and
passes a fetcher function that sets `xref-fetcher-alist`.
`xref-make-fetcher` is supposed to make it easier to create the such a
fetcher function.

>> We use it for
>> bookmarking first and foremost, but the frontend can legitimately use it
>> for other stuff too, like showing some info in the mode line.
>>
>>> Also, I'm not sure how we're supposed to guarantee that
>>> xref--original-buffer is live.
>> In my patch, we don't guarantee that (see
>> xref-bookmark-make-record).
>> And that's fine, it's a best effort to give the backend all the context
>> it might need.  If there's no original buffer, we just don't save and
>> restore that bit of context.
>
> Okay, I see that. Basically, you bookmark the "original point" and
> then restore it from xref-backend-restore. So this would work, most of
> the time.
>
>> The backend can handle a nil CONTEXT
>> argument in xref-backend-restore however it sees fit.  By default, it
>> does nothing.
>
> I don't any LSP backend could handle nil, though. It would need
> additional data, like the origin file name, the value of point, etc.

Right.  For Eglot, we cannot restore a bookmark with nil context, and we
also need to make sure we're connected to the server.  Adding something
like the following in eglot.el seems to do the trick:

--8<---------------cut here---------------start------------->8---
(cl-defmethod xref-backend-restore ((_backend (eql eglot)) context)
  (unless context
    (error "No context available for restoring Xref search"))
  (bookmark-handle-bookmark context)
  (unless eglot--managed-mode
    (apply #'eglot--connect (eglot--guess-contact))))
--8<---------------cut here---------------end--------------->8---