Subject: Re: [PATCH] Fix two bugs in removing bookmark fringe marks (bug#70019)

From: Karl Fogel <[email-masked]>
Date: Sun, 21 Apr 2024 22:51:43 -0500

On 20 Apr 2024, Dani Moncayo wrote:
>On Sat, Apr 20, 2024 at 2:54 AM Karl Fogel <[email-masked]> 
>wrote:
>> Nope, you didn't make any mistake.  I see the problem; please
>> try this revised version, and thank you for testing.
>
>OK.  With this second patch, I don't see the first problem [1]
>anymore, but I keep seeing the second one [2].

Ah, I'm sorry, I meant to discuss that second problem here.  For 
reference, here's your description of it:

> 1. Open some *info* manual and set a named bookmark there.
> E.g. [C-h r C-x r m f o o RET].
> 2. Kill the *info* buffer and open it again: [C-x k RET C-h r].
> 
> When I do that, I don't see the bookmark icon in the fringe 
> (wrong).
>
> But I _do_ see the icon if I _jump_ to the bookmark: [C-x r b f 
> o o RET]

This is the expected behavior, I think.

Let me explain why I believe that.  If you or someone can point 
out why this reasoning is wrong, I'd appreciate it.

In general, there's no mechanism for a bookmark fringe mark to be 
shown when one goes to a bookmarked location by some means *other* 
than through a bookmark function.

For example,

1. Find a file "SomeFile" in your home directory.

2. Create new bookmark "foo" on the first line.

   (Now you see a fringe mark.)

3. Kill the buffer entirely. 

4. Use [C-x C-f] to find "SomeFile" into a buffer again.

   (Now you don't see a fringe mark.)

5. Kill the buffer again.

6. Use [C-x r b] (`bookmark-jump') to visit bookmark "foo"

   (Now you see the fringe mark again.)

The reason the fringe mark appears in Step 6 is because the 
bookmark code had a chance to get involved (i.e., 
`bookmark--set-fringe-mark' got called somewhere along the way 
from `bookmark-jump').

In general, if you set a bookmark in a buffer, and you merely 
*leave* the buffer but don't kill the buffer (e.g., you do 
`bury-buffer' or something), then that fringe mark will still be 
there when you come back.  The fringe mark will also be placed if 
you get to the location via `bookmark-jump', and if you set a 
bookmark there with `bookmark-set'.

Also, if you retarget bookmark "foo" to point to a new location, 
then if there's some buffer currently displaying the old target of 
"foo", that old buffer's corresponding fringe mark for "foo" will 
get removed (bug #1 that I just fixed was about a special case of 
this behavior).

Now let's look at how this all works with Info nodes:

Often, two Info nodes are actually in the same file.  This was the 
case with the two that you used in your reproduction recipe: the 
"Distrib" node and the "Intro" node in the Emacs manual -- both 
are in emacs.info.gz, which is located at 
/usr/local/share/info/emacs.info.gz for me (but might be somewhere 
else for you).

When two Info nodes X and Y are in the same underlying file, then 
if you put a bookmark in node X, the fringe mark will stay there 
even if you go visit node Y and then come back to X (assuming you 
didn't do anything to kill the "*info*" buffer along the way). 
This is because the buffer has never been killed and the 
underlying file that it's visiting has not actually changed.

But imagine that your two nodes X and Y were in two different Info 
files.  If you set a bookmark in X and then go visit Y, and then 
come back to X (but not by using `bookmark-jump'), the fringe mark 
will be gone from from X.

So in your reproduction recipe quoted above, when you kill the 
"*info*" buffer, you're killing the buffer that's visiting that 
particular Info file.  When you visit that same Info node again 
via a non-bookmark route, there's no code that magically knows 
that there is a bookmark located here, and so no fringe mark is 
displayed.  On the other hand, when you use `bookmark-jump' to 
jump to the bookmark, then of course the bookmark code has a 
chance to put the fringe mark back.

By the way, I am not claiming that this behavior is ideal.  It 
would be wonderful if all of Emacs *did* magically have a way to 
know when a line associated with some bookmark is being displayed, 
so we could show a fringe mark there.

But I can't think of any reasonable way to implement that.  By 
"reasonable", I mean worth the complexity involved (I'm also not 
sure how to do it without an unacceptable performance penalty, but 
I haven't thought hard about it, because I'm pretty sure that if 
one *were* able to do it without a big performance hit, then the 
solution would be far more complex than a fringe mark is worth).

Best regards,
-Karl