Subject: Re: bug#41649: 27.0.91; beginning-of-defun doesn't work inside React markup in js-jsx-mode

From: Alan Mackenzie <[email-masked]>
Date: 2 Jun 2020 17:12:21 -0000

Hello Brian.

In article <[email-masked]> you wrote:
> [-- text/plain, encoding 7bit, charset: UTF-8, 44 lines --]

> With a file App.js that looks like:

> import * as React from "react";
> import { render } from "react-dom";

> const App = () => {
>   return (
>     <div>
>       <h1 id="abc">hello</h1>
>       <SearchParams />
>     </div>
>   );
> };

> render(<App />, document.getElementById("root"));

> If you open the file in JS mode (Emacs 27), and move point inside of
> "abc", calling

> M-: (c-beginning-of-defun)

That looks like a strange thing to do.  JS mode has its own
js-beginning-of-defun.

But wait - beginning-of-defun-function is set to c-beginning-of-defun,
which is probably why you reported the bug the way you did.

c-beginning-of-defun won't work, because a suitable member or derivative
of CC Mode hasn't been fully initialised.

> gives the following error:

> Debugger entered--Lisp error: (wrong-type-argument hash-table-p nil)
>   copy-hash-table(nil)
>   c-forward-<>-arglist(nil)
>   c-backward-<>-arglist(nil nil)
>   c-looking-at-decl-block(99 nil)
>   c-most-enclosing-decl-block((117 99 88 (40 . 50)))
>   c-widen-to-enclosing-decl-scope((117 99 88 (40 . 50)) 1 234)
>   c-beginning-of-defun()
>   eval((c-beginning-of-defun) t)
>   eval-expression((c-beginning-of-defun) nil nil 127)
>   funcall-interactively(eval-expression (c-beginning-of-defun) nil nil 127)
>   call-interactively(eval-expression nil nil)
>   command-execute(eval-expression)

> Manually invoking C-M-a inside the double quotes should end the same way.

It does.

The problem seems to stem from the top-level function #'js-mode.  Early
on, it invokes

    (c-init-language-vars js-mode)

, which initialises the CC Mode language variables to (mostly) their
Java Mode values.  js-mode continues by overwriting the local value of
quite a few of these variables, including beginning-of-defun-function.

js-mode then invokes

    (c-init-language-vars js-mode)

a second time, which initialises the language variables again, in
particular, those variables which just got a local value, including
beginning-of-defun-function.

Daniel, what is going on, here?  Is this just a simple coding error,
where the second c-init-language-vars should have been removed at some
stage?

> In GNU Emacs 27.0.91 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.24.20)
> Windowing system distributor 'The X.Org Foundation', version 11.0.12008000
> System Description: NixOS 20.09 (Nightingale)

-- 
Alan Mackenzie (Nuremberg, Germany).