From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: kobarity Newsgroups: gmane.emacs.bugs Subject: bug#52092: 28.0.60; hs-toggle-hiding does not toggle once folded Date: Mon, 19 Sep 2022 15:31:56 +0900 Message-ID: References: <178345d38657e8ad3b7cb50b644b1c5c@sadiqpk.org> Mime-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") Content-Type: multipart/mixed; boundary="Multipart_Mon_Sep_19_15:31:56_2022-1" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="8878"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?UTF-8?Q?Goj=C5=8D?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/29.0.50 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) Cc: Stefan Monnier To: Eli Zaretskii , Mohammed Sadiq , 52092@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Sep 19 08:41:27 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oaAT9-00029o-AI for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 19 Sep 2022 08:41:27 +0200 Original-Received: from localhost ([::1]:55840 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oaAT8-0004Ge-3C for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 19 Sep 2022 02:41:26 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:38790) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oaAL1-0000zm-W5 for bug-gnu-emacs@gnu.org; Mon, 19 Sep 2022 02:33:05 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:52892) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1oaAL0-0000lg-Ez for bug-gnu-emacs@gnu.org; Mon, 19 Sep 2022 02:33:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1oaAKz-00035d-VA for bug-gnu-emacs@gnu.org; Mon, 19 Sep 2022 02:33:01 -0400 X-Loop: help-debbugs@gnu.org In-Reply-To: <178345d38657e8ad3b7cb50b644b1c5c@sadiqpk.org> Resent-From: kobarity Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 19 Sep 2022 06:33:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 52092 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: help Original-Received: via spool by 52092-submit@debbugs.gnu.org id=B52092.166356913211805 (code B ref 52092); Mon, 19 Sep 2022 06:33:01 +0000 Original-Received: (at 52092) by debbugs.gnu.org; 19 Sep 2022 06:32:12 +0000 Original-Received: from localhost ([127.0.0.1]:51970 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oaAKB-00034K-MW for submit@debbugs.gnu.org; Mon, 19 Sep 2022 02:32:12 -0400 Original-Received: from mail-pj1-f45.google.com ([209.85.216.45]:52750) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1oaAKA-000349-Q3 for 52092@debbugs.gnu.org; Mon, 19 Sep 2022 02:32:11 -0400 Original-Received: by mail-pj1-f45.google.com with SMTP id go6so22609692pjb.2 for <52092@debbugs.gnu.org>; Sun, 18 Sep 2022 23:32:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:user-agent:subject:cc:to:from:message-id:date:from:to :cc:subject:date; bh=RG6RUUo4q+I8vKvN5FscFLchVEPjqIeVcG58il/LH9s=; b=nL/F4NE4HNnFT0RdRtA9PZhNzEWHHNvdYS5u4b1OxmazVJ4JukfdcnMQbHeFzFitNI jV+RTxD8v4WFLODLe1JS58PKzanJl1DMBD1PLQsVSY5UcEZyJEiFcFelCIsbqNPsW1In 2lGNE6yj09DIOd3yJDCKVA5gq7JryUji8MNNlaeMqZJEcFYn7QyB3MC8HckyyxyQUMOl Ea0L5m+La1+ZNG37aWNeaBKUDUGYo/39Sz27zgifF8OMnwxGhstommgHqj/SnOvCdVGt 6g6uLw81uYuN6deHSWuIjSMKWu1kgslzftX3HYa3unTF7qs72mmEHNEboWcbEHaEOaFy mPvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=mime-version:user-agent:subject:cc:to:from:message-id:date :x-gm-message-state:from:to:cc:subject:date; bh=RG6RUUo4q+I8vKvN5FscFLchVEPjqIeVcG58il/LH9s=; b=NEO9n8kaYjq2HPU+bpCtl1zB+V59UmkxwPFzVOVmEWPO00rw8Y78abOX7/BWnH1f18 zZcejPuaQIGyN2V5RpWwmTIpbtCy+dv7pCwzXa+0HETzcIj1G4YSIg28H3rKV5QigHnz xU/nGbb95rXBhO/eVT0GTPFumGifn7KWE6W1gJYjhwYQyC4z20Oq9PCkMsUhDdb1YgYD erJWDbi/QdS5uGZBbV7RUOGlK/o3O+cuP6b1rbGERCIPc4uSlCZzooJny5c29lSaeuUu HoSM6HZU4s6Nsv4NgelIR7rvaWTWhiCcGnKabU6QEJGfLSAuSGIr6lisOopZvRiXNRM9 gA9w== X-Gm-Message-State: ACrzQf18RfRqFxaID8qVAoylnqKF4r3Hj2VO2Olh5ToVxO+ScWB7skXl Jncol9fm+jTaLZKeiA4KDWw= X-Google-Smtp-Source: AMsMyM5O1Bk4J07FIDQVGB5tNv/BVKV39ZRDb8w7v5H8ZZfALUDUm+motNQgM9ir1fS0IMr8KegunA== X-Received: by 2002:a17:90b:1d02:b0:203:2d73:8efb with SMTP id on2-20020a17090b1d0200b002032d738efbmr23323435pjb.214.1663569124955; Sun, 18 Sep 2022 23:32:04 -0700 (PDT) Original-Received: from localhost (58x12x133x161.ap58.ftth.ucom.ne.jp. [58.12.133.161]) by smtp.gmail.com with ESMTPSA id z7-20020a1709028f8700b001708c4ebbaesm19155182plo.309.2022.09.18.23.32.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 18 Sep 2022 23:32:04 -0700 (PDT) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:243030 Archived-At: --Multipart_Mon_Sep_19_15:31:56_2022-1 Content-Type: text/plain; charset=US-ASCII Mohammed Sadiq wrote: > With hs-minor-mode enabled, I could hide the visibility of a block with > hs-toggle-hiding, but using it again doesn't unfold the region. There is another problem related to this issue. `hs-toggle-hiding' is also bound to shift mouse-2, but it toggles the block where the current point is located instead of the block where mouse is clicked. The problem is described below: 1. emacs -Q 2. Open the following C mode file. #+begin_src C int main() { sub(); } int sub() { printf("sub\n"); } #+end_src 3. M-x hs-minor-mode 4. Move the point to the "printf" line in the "sub" function. 5. Shift mouse-2 in the function "main". The function body of "sub" is hidden instead of "main". This is not I expected. This behavior was introduced by the following commit. Is this intended behavior? commit d0e9113de9783094b4da7f6aeee131194653c325 Author: Stefan Monnier Date: Sun May 19 09:36:22 2019 -0400 * lisp/progmodes/hideshow.el: Simplify mouse binding; Use lexical-binding (hs-set-up-overlay, hs-adjust-block-beginning): Use non-nil default for function variables, so `add-function` can be used on them. (hs-toggle-hiding): Make it work for mouse bindings as well. (hs-minor-mode-map): Use it for the mouse binding. (hs-grok-mode-type): Use bound-and-true-p. (hs-life-goes-on): Use `declare` for the debug spec. (hs-mouse-toggle-hiding): Make it an obsolete alias. (posn-set-point (event-end e)) was added to `hs-toggle-hiding' by this commit. This is the main cause of bug#52092. When the point is inside the hidden block, (posn-set-point (event-end e)) moves the point to the first shown character (e.g. closing "}"), resulting in the failure to show the block. This is not needed for keyboard operations. Although this is necessary for mouse operations, current code does not handle mouse events because "e" is not specified in `interactive'. So I think `hs-mouse-toggle-hiding' should be revived to separate `posn-set-point' from `hs-toggle-hiding' if the above behavior is not intentional. As for the `hs-already-hidden-p', the current implementation returns nil when the point is at closing "}". Although this is not a big problem for keyboard operations, this is harmful for mouse to show the hidden block because `posn-set-point' sets the point at closing "}" as described above. Current implementation only checks if the end of the line is inside a block. I suggest to add a check if the beginning of the line is inside a block to be able detect a hidden block when the point is at the line of closing "}". Attached is a patch to fix bug#52092 and the above behavior. I'm not sure if it is okay to cancel `define-obsolete-function-alias'. Regards, --Multipart_Mon_Sep_19_15:31:56_2022-1 Content-Type: application/octet-stream; type=patch; name="0001-Fix-hs-toggle-hiding-behaviors.patch" Content-Disposition: attachment; filename="0001-Fix-hs-toggle-hiding-behaviors.patch" Content-Transfer-Encoding: 7bit >From 902fd35281c394173a9688c4b149f3b909f491c8 Mon Sep 17 00:00:00 2001 From: kobarity Date: Mon, 19 Sep 2022 13:43:33 +0900 Subject: [PATCH] Fix hs-toggle-hiding behaviors * lisp/progmodes/hideshow.el (hs-minor-mode-map): Change shift mouse-2 binding to `hs-mouse-toggle-hiding'. (hs-find-block-beginning-match): New function to be used in `hs-already-hidden-p'. (hs-already-hidden-p): Add check if beginning of line is inside a block. (hs-toggle-hiding): Move mouse specific processing to `hs-mouse-toggle-hiding'. (hs-mouse-toggle-hiding): Revived function for mouse binding. * test/lisp/progmodes/hideshow-tests.el (hideshow-tests-with-temp-buffer-selected): New helper macro. (hideshow-tests-make-event-at): New helper function. (hideshow-already-hidden-p-1): New test. (hideshow-toggle-hiding-1): New test. (hideshow-mouse-toggle-hiding-1): New test (bug#52092). --- lisp/progmodes/hideshow.el | 39 ++++++---- test/lisp/progmodes/hideshow-tests.el | 106 ++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 13 deletions(-) diff --git a/lisp/progmodes/hideshow.el b/lisp/progmodes/hideshow.el index c0796fc2ee..1cdb93138e 100644 --- a/lisp/progmodes/hideshow.el +++ b/lisp/progmodes/hideshow.el @@ -37,7 +37,7 @@ ;; hs-show-all C-c @ C-M-s ;; hs-hide-level C-c @ C-l ;; hs-toggle-hiding C-c @ C-c -;; hs-toggle-hiding [(shift mouse-2)] +;; hs-mouse-toggle-hiding [(shift mouse-2)] ;; hs-hide-initial-comment-block ;; ;; Blocks are defined per mode. In c-mode, c++-mode and java-mode, they @@ -361,7 +361,7 @@ hs-minor-mode-map (define-key map "\C-c@\C-t" 'hs-hide-all) (define-key map "\C-c@\C-d" 'hs-hide-block) (define-key map "\C-c@\C-e" 'hs-toggle-hiding) - (define-key map [(shift mouse-2)] 'hs-toggle-hiding) + (define-key map [(shift mouse-2)] 'hs-mouse-toggle-hiding) map) "Keymap for hideshow minor mode.") @@ -786,6 +786,14 @@ hs-life-goes-on (case-fold-search t)) ,@body))) +(defun hs-find-block-beginning-match () + "Reposition point at the end of match of the block-start regexp. +Return point, or nil if original point was not in a block." + (when (and (funcall hs-find-block-beginning-func) + (funcall hs-looking-at-block-start-p-func)) + ;; point is inside a block + (goto-char (match-end 0)))) + (defun hs-overlay-at (position) "Return hideshow overlay at POSITION, or nil if none to be found." (let ((overlays (overlays-at position)) @@ -802,12 +810,11 @@ hs-already-hidden-p (if (and c-reg (nth 0 c-reg)) ;; point is inside a comment, and that comment is hideable (goto-char (nth 0 c-reg)) - (end-of-line) - (when (and (not c-reg) - (funcall hs-find-block-beginning-func) - (funcall hs-looking-at-block-start-p-func)) - ;; point is inside a block - (goto-char (match-end 0))))) + (when (not c-reg) + (end-of-line) + (when (not (hs-find-block-beginning-match)) + (beginning-of-line) + (hs-find-block-beginning-match))))) (end-of-line) (hs-overlay-at (point)))) @@ -944,18 +951,24 @@ hs-hide-level (message "Hiding blocks ... done")) (run-hooks 'hs-hide-hook))) -(defun hs-toggle-hiding (&optional e) +(defun hs-toggle-hiding () "Toggle hiding/showing of a block. -See `hs-hide-block' and `hs-show-block'. -Argument E should be the event that triggered this action." +See `hs-hide-block' and `hs-show-block'." (interactive) (hs-life-goes-on - (posn-set-point (event-end e)) (if (hs-already-hidden-p) (hs-show-block) (hs-hide-block)))) -(define-obsolete-function-alias 'hs-mouse-toggle-hiding #'hs-toggle-hiding "27.1") +(defun hs-mouse-toggle-hiding (e) + "Toggle hiding/showing of a block. +This command should be bound to a mouse key. +Argument E is a mouse event used by `event-end'. +See `hs-hide-block' and `hs-show-block'." + (interactive "@e") + (hs-life-goes-on + (posn-set-point (event-end e)) + (hs-toggle-hiding))) (defun hs-hide-initial-comment-block () "Hide the first block of comments in a file. diff --git a/test/lisp/progmodes/hideshow-tests.el b/test/lisp/progmodes/hideshow-tests.el index ee2a0c7c4c..d4bcd3c164 100644 --- a/test/lisp/progmodes/hideshow-tests.el +++ b/test/lisp/progmodes/hideshow-tests.el @@ -41,6 +41,18 @@ hideshow-tests-with-temp-buffer (goto-char (point-min)) ,@body)) +(defmacro hideshow-tests-with-temp-buffer-selected (mode contents &rest body) + "Create and switch to a `hs-minor-mode' enabled MODE temp buffer with CONTENTS. +BODY is code to be executed within the temp buffer. Point is +always located at the beginning of buffer." + (declare (indent 1) (debug t)) + `(ert-with-test-buffer-selected () + (,mode) + (hs-minor-mode 1) + (insert ,contents) + (goto-char (point-min)) + ,@body)) + (defun hideshow-tests-look-at (string &optional num restore-point) "Move point at beginning of STRING in the current buffer. Optional argument NUM defaults to 1 and is an integer indicating @@ -96,6 +108,39 @@ hideshow-tests-visible-string (overlay-end overlay)))) (buffer-substring-no-properties (point-min) (point-max))))) +(defun hideshow-tests-make-event-at (string) + "Make dummy mouse event at beginning of STRING." + (save-excursion + (let ((pos (hideshow-tests-look-at string))) + (vector + `('S-mouse-2 + (,(get-buffer-window) ,pos (1 . 1) 0 nil ,pos (1 . 1) + nil (1 . 1) (1 . 1))))))) + +(ert-deftest hideshow-already-hidden-p-1 () + (let ((contents " +int +main() +{ + printf(\"Hello\\n\"); +} +")) + (hideshow-tests-with-temp-buffer + c-mode + contents + (hideshow-tests-look-at "printf") + (should (not (hs-already-hidden-p))) + (hs-hide-block) + (goto-char (point-min)) + (hideshow-tests-look-at "{") + (should (hs-already-hidden-p)) + (forward-line -1) + (should (not (hs-already-hidden-p))) + (hideshow-tests-look-at "}") + (should (hs-already-hidden-p)) + (forward-line) + (should (not (hs-already-hidden-p)))))) + (ert-deftest hideshow-hide-block-1 () "Should hide current block." (let ((contents " @@ -263,6 +308,67 @@ hideshow-hide-level-2 } ")))) +(ert-deftest hideshow-toggle-hiding-1 () + "Should toggle hiding/showing of a block." + (let ((contents " +int +main() +{ + printf(\"Hello\\n\"); +} +")) + (hideshow-tests-with-temp-buffer + c-mode + contents + (hideshow-tests-look-at "printf") + (hs-toggle-hiding) + (should (string= + (hideshow-tests-visible-string) + " +int +main() +{} +")) + (hs-toggle-hiding) + (should (string= (hideshow-tests-visible-string) contents))))) + +(ert-deftest hideshow-mouse-toggle-hiding-1 () + "Should toggle hiding/showing of a block by mouse events." + (let ((contents " +int +main() +{ + printf(\"Hello\\n\"); +} +") + (hidden " +int +main() +{} +")) + (hideshow-tests-with-temp-buffer-selected + c-mode + contents + ;; Should not hide the block when clicked outside of the block. + (call-interactively + #'hs-mouse-toggle-hiding nil (hideshow-tests-make-event-at "int")) + (should (string= (hideshow-tests-visible-string) contents)) + ;; Should hide the block when clicked inside of the block. + (goto-char (point-min)) + (call-interactively + #'hs-mouse-toggle-hiding nil (hideshow-tests-make-event-at "printf")) + (should (string= (hideshow-tests-visible-string) hidden)) + ;; Should not show the block when clicked outside of the block. + (goto-char (point-min)) + (call-interactively + #'hs-mouse-toggle-hiding nil (hideshow-tests-make-event-at "int")) + (should (string= (hideshow-tests-visible-string) hidden)) + ;; Should show the block when clicked inside of the block. + (goto-char (point-min)) + (call-interactively + #'hs-mouse-toggle-hiding nil (hideshow-tests-make-event-at "}")) + (should (string= (hideshow-tests-visible-string) contents))))) + (provide 'hideshow-tests) ;;; hideshow-tests.el ends here -- 2.34.1 --Multipart_Mon_Sep_19_15:31:56_2022-1--