GNU bug report logs - #56635
29.0.50; [PATCH] hide-show in python-mode supports ONLY function and class blocks

Previous Next

Package: emacs;

Reported by: Dima Kogan <dima <at> secretsauce.net>

Date: Mon, 18 Jul 2022 22:21:01 UTC

Severity: normal

Tags: patch

Found in version 29.0.50

Fixed in version 29.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

Bug is archived. No further changes may be made.

Full log


Message #20 received at 56635 <at> debbugs.gnu.org (full text, mbox):

From: kobarity <kobarity <at> gmail.com>
To: Dima Kogan <dima <at> secretsauce.net>
Cc: Lars Ingebrigtsen <larsi <at> gnus.org>, 56635 <at> debbugs.gnu.org
Subject: Re: bug#56635: 29.0.50; [PATCH] hide-show in python-mode supports
 ONLY function and class blocks
Date: Sun, 31 Jul 2022 19:18:26 +0900
[Message part 1 (text/plain, inline)]
I wrote:
> This code solves many problems of `hs-hide-block' mentioned in the
> first mail, but it breaks `hs-hide-level'.  It seems that current
> MDATA-SELECTOR support is limited and needs some fixes if we want to
> do something like above.  I will look into this a little bit more.

There are some problems in this approach.  The biggest one is the way
of processing in `hs-hide-level-recursive'.  It basically repeats:

1. hs-hide-block-at-point
2. forward-comment
3. re-search-forward hs-block-start-regexp

Let me explain with the following code:

#+begin_src python
class C:
    def a():
        pass

    def b():
        pass
#+end_src

Let's assume that point is at the beginning of the line "def a():".
The first step hides the method "a" and moves the point to the end of the
block.  The second step moves the point to the position "d" of "def b():",
not the beginning of the line.  Therefore, if hs-block-start-regexp
contains rx line-start, it fails to match "def b():".

Although this can be solved by adding a flag or a mode specific
forward-comment function to hs-special-modes-alist, I'm not sure if it
is the right approach.

So I think the following setting is best at this moment.

#+begin_src elisp
  (add-to-list
   'hs-special-modes-alist
   `(python-mode
     ,(python-rx (seq (* (syntax ?-)) block-start))
     ;; Use the empty string as end regexp so it doesn't default to
     ;; "\\s)".  This way parens at end of defun are properly hidden.
     ""
     "#"
     python-hideshow-forward-sexp-function
     nil))
#+end_src

(* (syntax ?-)) corresponds to "\\s-*" of the current regexp.  It
allows the point to be located before the block start symbols.

Another idea to improve the behavior of hiding a block is to provide a
wrapper function of `hs-hide-block' as follows and remap the key
bindings to this function like `python-mark-defun'.  With this
approach, C-c @ C-d and C-c @ C-h work as expected with the example
shown in the first mail.

#+begin_src elisp
(defun python-hideshow-hide-block (&optional end)
  "Python specific `hs-hide-block' function for `hs-minor-mode'.
Argument END is passed to `hs-hide-block'."
  (interactive "P")
  (python-nav-beginning-of-block)
  (hs-hide-block end))
#+end_src

Attached is a PoC level patch of this approach.  What do you think of
this approach?

Regards,
[56635-poc.patch (application/octet-stream, attachment)]

This bug report was last modified 2 years and 266 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.