Subject: bug#75387: 29.4; hideshow: hs-hide-level hides multiple top-level blocks as one

From: kobarity <[email-masked]>
Date: Mon, 13 Jan 2025 09:46:09 +0900

Christoph Groth wrote:
> 
> Eli Zaretskii wrote:
> > Hm... the doc string of hs-hide-level says:
> >
> >   Hide all blocks ARG levels below this block.
> >
> > So what is "this block" when point is at position 1 in this buffer?
> 
> In my understanding position 1 corresponds to “outermost level”.  Hiding
> all blocks below this level should give the same result as calling
> hs-hide-all.  And indeed this is what I observe after the initial hiccup
> (e.g. after having invoked hs-hide-all and then hs-show-all).
> 
> > If I move point to here:
> >
> >   @total_ordering
> >   class SiteFamily(metaclass=abc.ABCMeta):
> >
> > and invoke hs-hide-level, then all the "def" blocks inside this one
> > are hidden, as expected.  And note that the command only hides blocks
> > that are inside the current block, not those inside other blocks of
> > the same level.
> 
> Did you try this immediately after opening the file with find-file?  The
> problem I observe only manifests itself until (at most) a full cycle of
> hide-all then show-all.
> 
> If (after freshly loading the file - should there be a buffer visiting
> the file, I first kill it) I move point to the “@” before
> total_ordering, and invoke hs-hide-level, then I see the following (only
> showing the lower part of the buffer where something is hidden):
> 
> ----------------------------------------------------------------
> ################ Sites and site families
> 
> class Site(tuple):...
> 
> 
> @total_ordering
> class SiteFamily(metaclass=abc.ABCMeta):...
> --------------- end of buffer ----------------------------------
> 
> But if I do this after invoking hs-hide-all and then hs-show-all, all
> top-level blocks are visible but hidden (as expected).
> 
> If, after freshly loading the file, I position point on the “c” of
> “class SiteFamily”, and then invoke hs-hide-level, the methods of that
> class are hidden, but also top-level blocks that follow it (for example
> the function validate_hopping).
> 
> On the other hand, when I invoke hs-hide-level at the same place but
> after “cycling” at least once (=hs-hide-all followed by hs-show-all),
> only the methods of the class are hidden, and following top level blocks
> remain unhidden (as I would expect).
> 
> > So this could be a documentation issue, whereby the doc string doesn't
> > explain clearly enough what the command does.
> 
> The behavior I observe depends on whether the file has been freshly
> opened or already “cycled”.  But any correct behavior should not differ
> between a fresh buffer and one where blocks were hidden and then
> completely unhidden.  Therefore I think that there is a problem
> somewhere, at least in Emacs 29.4 that I use.  I have no idea whether
> this is in hideshow.all or in some other component like python.el.

I confirmed the same behavior.  This is not a problem in hideshow.el.
Only immediately after the file is read, `python-nav-end-of-block'
behaves unexpectedly.

1. emacs -Q
2. Find file builder.py
3. Search "class SiteFamily" and go there
4. M-x python-nav-end-of-block  
5. Search "class Symmetry" and go there
6. M-x python-nav-end-of-block

The point moves to the end of the buffer, which is not an expected
behavior.  However, repeating the steps 5 and 6 does not produce this
issue.

This is the direct cause of the problem of `hs-hide-level'.

This problem does not occur when I run `font-lock-debug-fontify' after
reading the file, so it might be related to font-lock code in
python.el, but it seems that disabling font-lock does not solve this
issue.  I will continue to look into this, but it may take some time.