all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Karl Fogel <kfogel@red-bean.com>
To: Drew Adams <drew.adams@oracle.com>
Cc: "emacs-devel@gnu.org" <emacs-devel@gnu.org>
Subject: Re: [PATCH] Let bookmark handlers do everything, including display the destination
Date: Thu, 18 Aug 2022 13:14:09 -0500	[thread overview]
Message-ID: <8735dt5si6.fsf@red-bean.com> (raw)
In-Reply-To: <SJ0PR10MB5488B76B824B691EC228B84BF3669@SJ0PR10MB5488.namprd10.prod.outlook.com> (Drew Adams's message of "Sat, 13 Aug 2022 20:59:20 +0000")

On 13 Aug 2022, Drew Adams wrote:
>tl;dr:
>
>Let's change the handling of a bookmark - including
>displaying the bookmark destination - to be the
>responsibility of its handler.

In general, +1 to this idea.

(My ability to be involved in actually making it happen may be 
limited right now, due to some family responsibilities.  I'll try 
to at least kibbitz constructively though.)

>Attached is a patch that does that.  It moves the displaying
>of a bookmark's "destination" from `bookmark-jump' to the
>bookmark itself - specifically, to its handler.
>
>Currently `bookmark-jump', rather than a bookmark's handler,
>displays the bookmark destination.  And the behavior's
>hard-coded: a bookmark always displays a destination, and
>that's always the last thing done before the after-jump
>hook.
>
>That's too rigid.  It means that a handler function can't do
>something more after the display, unless it finagles to put
>that after-display processing on `bookmark-after-jump-hook'
>(temporarily).  And it means that a handler can't choose its
>own display function - the DISPLAY-FUNCTION passed to
>`bookmark-jump' is always used.  And it means that a handler
>can't dispense with display altogether.
>
>By moving the responsibility for display to the handler, the
>patch gets rid of this rigidity.
>
>Specifically, instead of `bookmark--jump-via' systematically
>invoking its DISPLAY-FUNCTION argument, it saves the
>argument value in variable `bookmark-jump-display-function'.
>And then the default handler, `bookmark-default-handler'
>invokes that function.

*nod*

There's some parallelism-unsafety going on here, obviously.  I'd 
love a way to wrap all this in a clean closure, instead of setting 
a global variable which then retains that setting until the next 
time we happen to set it.

But I don't really see a way to do tihngs more cleanly than with 
the carry-out variable you propose.  If there's some creative 
solution for connecting `bookmark--jump-via' to the 
"corresponding" handler call that happens later, I don't see it, 
lexically or dynamically.  Maybe is just how Emacs usually handles 
these kinds of situations?

>Most bookmarks don't have their own handler; they use the
>default handler.  So their behavior doesn't change at all
>with this approach.  Most bookmarks use `bookmark-jump's
>DISPLAY FUNCTION as the last thing before running
>`bookmark-after-jump-hook' (and most should do that).
>
>The same applies to bookmarks that do have their own
>handler, if the handler invokes the default handler at the
>end.  For example, the Info bookmark handler,
>`Info-bookmark-jump' sets up what it needs, and ends by
>invoking the default handler:
>
>  (bookmark-default-handler
>   `("" (buffer . ,buf)
>     . ,(bookmark-get-bookmark-record bookmark)))
>
>What changes with the proposed approach is only what can
>happen for a bookmark that has its own handler, if that
>handler either (1) invokes the default handler at some point
>other than at the end - so it does something after
>displaying, or (2) it doesn't invoke the default handler.
>
>If a handler doesn't invoke the default handler, it can call
>whatever display function it likes, whenever it likes.  Or
>it can forego display altogether.
>
>This approach gives the handler more control - it can decide
>whether, when, and how to display the destination.  The
>entire behavior of a bookmark is then up to its handler.
>
>And this allows for more kinds of bookmarks, including
>bookmarks that don't display a destination.
>
>[...some example usages from Bookmark+...]

This is all very well-explained; thank you, Drew.

>[...]
>
>But really, the complications `pdf-view-bookmark-handler'
>goes through - creating a closure on the fly and adding it
>to the after-jump hook (and subsequently removing it) - are
>a workaround for the fact that vanilla `bookmark.el' doesn't
>let a handler display the destination when it wants to.
>
>PDF Tools wants to set up the buffer, display it, and then
>go to the right PDF page etc.  So it sets up the buffer,
>ends the handler, counts on `bookmark-jump' to display the
>buffer, and then has a (temporary) after-jump hook do the
>rest of the handling: go to the right page etc.  (The hook
>function captures some info from the bookmark, so it needs
>to be a closure.)  A clever workaround.
>
>With the approach provided by the patch, the handler can do
>all of that itself: set up the buffer, display it, then go
>to the page etc.  No after-jump-hook workaround.  The code
>is quite a bit simpler.

Yup; that makes sense to me.

>Between setting up the buffer and doing the additional stuff
>that was relegated to a temporary after-jump hook, the
>handler can either (1) just invoke the default handler or
>(2) just call a display function.  Code for each of those
>handler definitions is also attached, for comparison with
>the above code.
>
>Those solutions are examples #5 and #6, respectively, in
>attachment `pdf-tools-handler-fix.el'.
>
>I mention the PDF Tools handler as an example.  I'm not
>aware of other handlers that depend on `bookmark-jump'
>displaying some buffer and selecting its window, and then
>depend on the after-jump hook for additional handling in
>that buffer, but there may be some out there.
>
>This is a general problem for Bookmark+, even if it seems to
>be run into rarely because most handlers invoke the default
>handler (which in Bookmark+ displays the destination using
>the DISPLAY-FUNCTION passed to `bookmark-jump').
>
>But this is not just about getting rid of an incompatibility
>with Bookmark+'s bookmark handling.  It's also about
>improving vanilla `bookmark.el', by letting the handler
>handle a bookmark's behavior - all of it.  Give handlers the
>control over display, and have the default handler invoke
>the `bookmark-jump' DISPLAY-FUNCTION arg.

My main concern here is just that compatibility issue.  I have no 
idea how many bookmark-using packages will break if we install 
this patch.  You've explained very clearly how to fix them, and 
how in many cases their code is likely to get cleaner as a result, 
and I agree.

But still, compatibility-breaking changes are a serious thing. 
I'd like to know what others here think about this.  Your 
suggested guidelines below seem good *if* we decide to make this 
change:

>That makes possible bookmarks that don't necessarily display
>a destination - they perform some other action.  And it
>allows bookmarks to do any kind of displaying whatsoever
>(not just what the `bookmark-jump' DISPLAY-FUNCTION
>provides).
>
>Regardless of whether we adopt the proposed behavior, we
>might anyway want to post a guideline to let people who
>define custom bookmark handlers know that it's
>common/typical for a handler to invoke the default handler -
>that repositions the bookmark as needed etc.
>
>But with the new behavior we should also make clear that for
>a bookmark destination to be displayed, a custom handler
>needs to invoke either `bookmark-default-handler' or a
>display function.
>
>More generally, the thing to make clear is that a handler
>completely defines a bookmark's behavior.  And in
>particular, it decides whether, when, and how to display a
>bookmark destination.

Yup.

>I think the proposed approach (attached patch or similar)
>would affect very few people.  It would affect only library
>authors who define custom bookmark handlers (few do) that
>don't invoke the default handler (fewer still), AND whose
>code relegates some of the handling to the after-jump hook
>and depends on `bookmark-jump' invoking the DISPLAY-FUNCTION
>(very few, I expect).

I expect you are right.  I'm even inclined to risk the breakage 
and help callers fix it, just to get this long-term structural 
improvement.

But I'm not confident in this opinion, and would like to know what 
others here, especially the maintainers, think.

I reviewed the bookmark.el patch briefly, and overall it had the 
shape I expected.  I might have a few suggestions about doc 
strings and such; if we decide to go down this road, I'll do a 
real patch review.

Best regards,
-Karl










  reply	other threads:[~2022-08-18 18:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-13 20:59 [PATCH] Let bookmark handlers do everything, including display the destination Drew Adams
2022-08-18 18:14 ` Karl Fogel [this message]
2022-08-29 15:28   ` Stefan Monnier
2022-08-29 23:45     ` Karl Fogel
2022-09-06  0:07       ` [External] : " Drew Adams
2022-09-26 19:47         ` Karl Fogel

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

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

  git send-email \
    --in-reply-to=8735dt5si6.fsf@red-bean.com \
    --to=kfogel@red-bean.com \
    --cc=drew.adams@oracle.com \
    --cc=emacs-devel@gnu.org \
    /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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.