unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: kobarity <kobarity@gmail.com>
To: Dima Kogan <dima@secretsauce.net>
Cc: Lars Ingebrigtsen <larsi@gnus.org>, 56635@debbugs.gnu.org
Subject: 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	[thread overview]
Message-ID: <CAMQkrSqbuU5Y=eQ55P-TFAY5CdanCn8o-zQVANmedH8enygqPw@mail.gmail.com> (raw)
In-Reply-To: <CAMQkrSriwQiQ-seoYMTP=kYrwi8fkfpZfzgaCUMy0N4p-ONK5w@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2336 bytes --]

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,

[-- Attachment #2: 56635-poc.patch --]
[-- Type: application/octet-stream, Size: 2082 bytes --]

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index b8fc7d4c54..ca8bff9a6e 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -303,6 +303,8 @@ python-mode-map
     (define-key map "\C-c\C-v" #'python-check)
     (define-key map "\C-c\C-f" #'python-eldoc-at-point)
     (define-key map "\C-c\C-d" #'python-describe-at-point)
+    ;; Hideshow
+    (define-key map [remap hs-hide-block] #'python-hideshow-hide-block)
     ;; Utilities
     (substitute-key-definition #'complete-symbol #'completion-at-point
                                map global-map)
@@ -4825,9 +4827,16 @@ python-describe-at-point
 (defun python-hideshow-forward-sexp-function (_arg)
   "Python specific `forward-sexp' function for `hs-minor-mode'.
 Argument ARG is ignored."
-  (python-nav-end-of-defun)
-  (unless (python-info-current-line-empty-p)
-    (backward-char)))
+  (python-nav-end-of-block))
+
+(declare-function hs-hide-block "hideshow")
+
+(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))
 
 \f
 ;;; Imenu
@@ -5773,8 +5782,8 @@ python-mode
 
   (add-to-list
    'hs-special-modes-alist
-   '(python-mode
-     "\\s-*\\_<\\(?:def\\|class\\)\\_>"
+   `(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.
      ""
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 6f2ad87f81..bc56abaa2a 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -5857,8 +5857,11 @@ python-hideshow-hide-levels-1
 class SomeClass:
 
     def __init__(self, arg, kwarg=1):
+
     def filter(self, nums):
-    def __str__(self):"))))
+
+    def __str__(self):
+"))))
       (or enabled (hs-minor-mode -1)))))
 
 (ert-deftest python-hideshow-hide-levels-2 ()

  reply	other threads:[~2022-07-31 10:18 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-18 22:20 bug#56635: 29.0.50; [PATCH] hide-show in python-mode supports ONLY function and class blocks Dima Kogan
2022-07-23  7:58 ` Lars Ingebrigtsen
2022-07-23 15:51   ` kobarity
2022-07-23 20:41     ` Dima Kogan
2022-07-24  0:57       ` kobarity
2022-07-31 10:18         ` kobarity [this message]
2022-07-31 19:04           ` Dima Kogan
2022-08-07 14:37             ` kobarity
2022-08-08 15:16               ` Augusto Stoffel
2022-08-13 12:36                 ` kobarity
2022-08-15 15:00                   ` kobarity
2022-08-15 17:16                     ` Dima Kogan
2022-08-16  2:28                       ` kobarity
2022-08-17 10:45                     ` Lars Ingebrigtsen
2022-08-17 11:11                       ` Lars Ingebrigtsen
2022-08-17 11:32                         ` kobarity
2022-08-24  0:39                           ` Dima Kogan
2022-08-24 10:27                             ` Lars Ingebrigtsen
2022-08-24 14:15                               ` kobarity
2022-08-25 12:31                                 ` Lars Ingebrigtsen
2022-08-25 13:39                                   ` kobarity

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

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to='CAMQkrSqbuU5Y=eQ55P-TFAY5CdanCn8o-zQVANmedH8enygqPw@mail.gmail.com' \
    --to=kobarity@gmail.com \
    --cc=56635@debbugs.gnu.org \
    --cc=dima@secretsauce.net \
    --cc=larsi@gnus.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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).