From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Daniel =?UTF-8?Q?Mart=C3=ADn?= via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#64283: 29.0.91; js-mode's mark-defun does not work correctly when functions have a comment on top Date: Sun, 25 Jun 2023 22:49:36 +0200 Message-ID: References: <83leg7y44c.fsf@gnu.org> Reply-To: Daniel =?UTF-8?Q?Mart=C3=ADn?= Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33607"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (darwin) Cc: Dmitry Gutov , Yuan Fu , 64283@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Jun 25 22:50:36 2023 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 1qDWgu-0008Z9-5z for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 25 Jun 2023 22:50:36 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qDWgQ-0007Nn-Dx; Sun, 25 Jun 2023 16:50:06 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qDWgM-0007N4-1W for bug-gnu-emacs@gnu.org; Sun, 25 Jun 2023 16:50:05 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qDWgL-0002Ab-PG for bug-gnu-emacs@gnu.org; Sun, 25 Jun 2023 16:50:01 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qDWgL-0003kd-KH for bug-gnu-emacs@gnu.org; Sun, 25 Jun 2023 16:50:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Daniel =?UTF-8?Q?Mart=C3=ADn?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 25 Jun 2023 20:50:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 64283 X-GNU-PR-Package: emacs Original-Received: via spool by 64283-submit@debbugs.gnu.org id=B64283.168772619214394 (code B ref 64283); Sun, 25 Jun 2023 20:50:01 +0000 Original-Received: (at 64283) by debbugs.gnu.org; 25 Jun 2023 20:49:52 +0000 Original-Received: from localhost ([127.0.0.1]:43735 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDWgC-0003k6-7t for submit@debbugs.gnu.org; Sun, 25 Jun 2023 16:49:52 -0400 Original-Received: from sonic307-54.consmr.mail.ir2.yahoo.com ([87.248.110.31]:37839) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qDWg7-0003jo-RS for 64283@debbugs.gnu.org; Sun, 25 Jun 2023 16:49:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.es; s=s2048; t=1687726182; bh=f8Eg/HC4/EksX38awvITzUVLoG9X2Kpayxz0IWIZtSg=; h=From:To:Cc:Subject:References:Date:In-Reply-To:From:Subject:Reply-To; b=l/2c5m8QTdnlFb0E2ArmyRF7Opp5buz0PxOZFnUp8pMpifMjzLxRtUwLTGIqnuYQUQU8wCPxa+Ao6ewK9xEUWU9DPD/ryawGQdQDfKWsncemm0BGUJ6n7MGVdprOBCLTwDqNJMTwUEXOk36fl10xklTO1RU7P62QMOwGN6RfN9pX7to+HiAbjGb7gawFhG7kOwZuF4bZmP1qCDOiTg/TNxLk8B1m1LavD+hnOdSqHdk3cA9m1RRhukYlY4FjuJBlDvS2J7Mz2qWi8cVX02GVkmNxCUQ0NLJveib7wgAo+m88+jr/J3W42cXPxYdI3/MJnzbCNQA9z5m419jDF0J29Q== X-SONIC-DKIM-SIGN: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s2048; t=1687726182; bh=b5kIMASm0cJTiS2JL0zAzfTuCp22d6zdVn/BQDmJyX+=; h=X-Sonic-MF:From:To:Subject:Date:From:Subject; b=pli9PFjd9veo+7m03A9O5XbHoZHO/RgUhZhpEZMzFhdoJj9TnZwKp1ZrAt3D5FuI35yPX8cAtMM+YF/ppkGlpZmHNdTpGoN8bmq0V3kVFhBIRdDA5buJX+bnbAMCp6Arhu8KJ08nxsfc/caHZysQ6MmbzX55xAbvYwuwQKq9PTG4AyTtjx1ppx3wIc4WuOnJYSuKPY+PmxBMroqgcqFdnyRJ7e/a3DbQr4GrZ1/qfWh81S4UukGlwM7IAA7G774Drpu9rXl7R8PF6M4mwLBDHtVBVDgqv+TH9Jc3/gpDvlWJ0AMK/qp4pAh8kEzWIlQV1dc38+WNdwSyarEZ+/fIwQ== X-YMail-OSG: FT9dAbQVM1kIS492OchNEkVdfBCm6t1INbM84wvBLLPrirW6qcnf8SFg7wxbRy3 zyd6Aw069SEs_B3WiIHKW2NcYxvrzo6qnMbi1HCZr4RFNzvrZWilAkXYhfUq1v1whqUPXyM7s9_6 Rhb3yHwe4mV7hZpRROBLEd3.JmvoYAdwOd3mJSDmZxlmwcsamsK3Zzy9.68RqTnVR12..aeFiDN8 PeieqSBC2RE22uc5qkGjbb2KbSwExrqTjKIYgRk92pcZVsbVjzqJyud61UtEE1n2Itfn8Lr_es4j IueNw4sKJkBK5S3e9ePBcGz1Y_9wCzal89W35.ewOwBCzbVHZkwjwCTohBqMf7zzOvt3oogxtBIr MZ8GZxHjpz8GgxmIJrZf6PQ_qtQfmPvZ5BwZDnpoNyvuGl6313nUh9NOiGpNJiaaAq5qHJOQzNCZ MyvqryuhHNPUgwlbIQVnPRs47FNScNMFB5G0ByV2FBMd36vv03hZ8fsQ7_7ZOlGrzHv5Rv4Zj6lE 4MF.Xjmwu2eD72NUc6FEjSPmL1QT6kdJW9HBT_ZP9EjgzmMwzmPoHgfEpxA9L7IjFIyU4KgzwYSI op8PFTZwn8Q1uEWDGK4vHv45wqJfqPFYOx.mXma7DutnDivFT2TC2.d5L4SmwwIpsFqSivJLas8D bkUyGCWxkq0TO5wPEzD_QrXUkY2yOZIoeyZCU0GQebqULnoQBNaJ_1eZ9H6Vf_qIhatAEqi0Vbq1 cFxvqzGahhttV88GMcjWW_XRnu8_dAC5YE3bxZY5DkY57m.Cuj4shoGZ74BZMb4pgjjCz_aV9OB9 ownMKZhG7mYe7NAa26qbRfQ7X4WvZBZZu_mIT_LI0J X-Sonic-MF: X-Sonic-ID: 111415a8-2878-4ee4-bb8e-320ea8569ae0 Original-Received: from sonic.gate.mail.ne1.yahoo.com by sonic307.consmr.mail.ir2.yahoo.com with HTTP; Sun, 25 Jun 2023 20:49:42 +0000 Original-Received: by hermes--production-ir2-7867f454fc-dskkf (Yahoo Inc. Hermes SMTP Server) with ESMTPA ID b485d3bb162144e24c307e6190194133; Sun, 25 Jun 2023 20:49:37 +0000 (UTC) In-Reply-To: <83leg7y44c.fsf@gnu.org> (Eli Zaretskii's message of "Sun, 25 Jun 2023 18:05:07 +0300") X-Mailer: WebService/1.1.21557 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo 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-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:264070 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Eli Zaretskii writes: >> Date: Sun, 25 Jun 2023 15:38:12 +0200 >> From: Daniel Mart=C3=ADn via "Bug reports for GNU Emacs, >> the Swiss army knife of text editors" >>=20 >> Daniel Mart=C3=ADn via "Bug reports for GNU Emacs, the Swiss army knife = of >> text editors" writes: >>=20 >> > This is a regression from Emacs 28.2. >> > >>=20 >> This is the first commit where this bug happens: >>=20 >> commit 4489450f37deafb013b1f0fc00c89f0973fda14a >> Author: Yuan Fu >> Date: Thu Nov 10 15:00:29 2022 -0800 >>=20 >> In end-of-defun, terminate early if no further defun exists >>=20=20=20=20=20 >> Before this change, end-of-defun calls end-of-defun-function even if >> point is not necessarily at the beginning of a defun (contrary to wh= at >> end-of-defun-function's docstring claims). Now it terminates early >> and doesn't call end-of-defun-function. >>=20=20=20=20=20 >> * lisp/emacs-lisp/lisp.el (beginning-of-defun-raw): Update docstring >> clarifying the return value. >> (end-of-defun): Terminate early if beginning-of-defun-raw returns ni= l. > > Yuan, could you please look into this? What I see is that, after 4489450f37deafb013b1f0fc00c89f0973fda14a, defun movement may be subtly broken if beginning-of-defun-function does not return non-nil when it found the beginning of a defun. One of the affected modes is js-mode, but who knows if there are more out there. We could either revert 4489450f37deafb013b1f0fc00c89f0973fda14a, because of the incompatibilities it may cause (Yuan, what is the bug it tries to fix?), or maybe adjust js-mode so that it follows the documentation of beginning-of-defun-function and returns non-nil when it found the beginning of a defun. I've attached a patch that follows this second approach, with some unit tests. It fixes the bug on my side. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Make-js-beginning-of-defun-return-non-nil-on-success.patch >From dbd0a48fba90b9a7f2fb291a3d279b6adf3117f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=ADn?= Date: Sun, 25 Jun 2023 22:17:14 +0200 Subject: [PATCH] Make js-beginning-of-defun return non-nil on success * lisp/progmodes/js.el (js-beginning-of-defun): The docstring of beginning-of-defun-function says that this function shall return non-nil when it found the beginning of a defun. This is specially important because the calling code decides when to move point depending on the return value. Make js-beginning-of-defun return non-nil when it found the beginning of a defun. (js--beginning-of-defun-flat): Same for this helper. * test/lisp/progmodes/js-tests.el (js-mode-end-of-defun): Add a unit test. --- lisp/progmodes/js.el | 61 ++++++++++++++++++--------------- test/lisp/progmodes/js-tests.el | 51 +++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 27 deletions(-) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 414b6eb2baf..a05bd758dbc 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -1024,38 +1024,45 @@ js--beginning-of-defun-flat "Helper function for `js-beginning-of-defun'." (let ((pstate (js--beginning-of-defun-raw))) (when pstate - (goto-char (js--pitem-h-begin (car pstate)))))) + (goto-char (js--pitem-h-begin (car pstate))) + t))) (defun js-beginning-of-defun (&optional arg) "Value of `beginning-of-defun-function' for `js-mode'." (setq arg (or arg 1)) - (while (and (not (eobp)) (< arg 0)) - (cl-incf arg) - (when (and (not js-flat-functions) - (or (eq (js-syntactic-context) 'function) - (js--function-prologue-beginning))) - (js-end-of-defun)) - - (if (js--re-search-forward - "\\_" nil t) - (goto-char (js--function-prologue-beginning)) - (goto-char (point-max)))) - - (while (> arg 0) - (cl-decf arg) - ;; If we're just past the end of a function, the user probably wants - ;; to go to the beginning of *that* function - (when (eq (char-before) ?}) - (backward-char)) - - (let ((prologue-begin (js--function-prologue-beginning))) - (cond ((and prologue-begin (< prologue-begin (point))) - (goto-char prologue-begin)) + (let ((found)) + (while (and (not (eobp)) (< arg 0)) + (cl-incf arg) + (when (and (not js-flat-functions) + (or (eq (js-syntactic-context) 'function) + (js--function-prologue-beginning))) + (js-end-of-defun)) + + (if (js--re-search-forward + "\\_" nil t) + (progn (goto-char (js--function-prologue-beginning)) + (setq found t)) + (goto-char (point-max)) + (setq found nil))) + + (while (> arg 0) + (cl-decf arg) + ;; If we're just past the end of a function, the user probably wants + ;; to go to the beginning of *that* function + (when (eq (char-before) ?}) + (backward-char)) - (js-flat-functions - (js--beginning-of-defun-flat)) - (t - (js--beginning-of-defun-nested)))))) + (let ((prologue-begin (js--function-prologue-beginning))) + (cond ((and prologue-begin (< prologue-begin (point))) + (goto-char prologue-begin) + (setq found t)) + + (js-flat-functions + (setq found (js--beginning-of-defun-flat))) + (t + (when (js--beginning-of-defun-nested) + (setq found t)))))) + found)) (defun js--flush-caches (&optional beg _ignored) "Flush the `js-mode' syntax cache after position BEG. diff --git a/test/lisp/progmodes/js-tests.el b/test/lisp/progmodes/js-tests.el index 00fa78e8891..5db92b08f8a 100644 --- a/test/lisp/progmodes/js-tests.el +++ b/test/lisp/progmodes/js-tests.el @@ -237,6 +237,57 @@ "jsx-unclosed-1.jsx" (js-deftest-indent "jsx-unclosed-2.jsx") (js-deftest-indent "jsx.jsx") +;;;; Navigation tests. + +(ert-deftest js-mode-beginning-of-defun () + (with-temp-buffer + (insert "function foo() { + var value = 1; +} + +/** A comment. */ +function bar() { + var value = 1; +} +") + (js-mode) + ;; Move point inside `foo'. + (goto-char 18) + (beginning-of-defun) + (should (bobp)) + ;; Move point between the two functions. + (goto-char 37) + (beginning-of-defun) + (should (bobp)) + ;; Move point inside `bar'. + (goto-char 73) + (beginning-of-defun) + ;; Point should move to the beginning of `bar'. + (should (equal (point) 56)))) + +(ert-deftest js-mode-end-of-defun () + (with-temp-buffer + (insert "function foo() { + var value = 1; +} + +/** A comment. */ +function bar() { + var value = 1; +} +") + (js-mode) + (goto-char (point-min)) + (end-of-defun) + ;; end-of-defun from the beginning of the buffer should go to the + ;; end of `foo'. + (should (equal (point) 37)) + ;; Move point to the beginning of /** A comment. */ + (goto-char 38) + (end-of-defun) + ;; end-of-defun should move point to eob. + (should (eobp)))) + (provide 'js-tests) ;;; js-tests.el ends here -- 2.40.1 --=-=-=--