Subject: bug#67463: 30.0.50; Eglot may manage js-json-mode buffers with wrong server

From: João Távora <[email-masked]>
Date: Sun, 3 Dec 2023 18:14:30 +0000

On Sat, Dec 2, 2023 at 12:51 PM Eli Zaretskii <[email-masked]> wrote:
>
> > From: Pengji Zhang <[email-masked]>
> > Date: Sun, 26 Nov 2023 16:15:54 -0500
> >
> > It seems that buffers in `js-json-mode', the default mode for JSON
> > files, could be wrongly managed by JavaScript language servers of Eglot,
> > perhaps because:
> >
> >   - `js-json-mode' is derived from `js-mode';
> >   - Eglot uses `provided-mode-derived-p' to determine whether a buffer
> >     should be managed by a server.
> >
> > Here is a recipe to reproduce the problem I encountered:
> >
> >   1. Install Node.js[0] and NPM[1]. (Sorry, but I could not find an
> >      easier way to set up the environment. They may be installable with
> >      your system's package manager.)
> >   2. mkdir /tmp/repro && cd /tmp/repro
> >   3. npm install typescript typescript-language-server (This will install
> >      the language server locally in the directory.)
> >   4. emacs -Q
> >   5. C-x C-f main.js RET
> >   6. C-u M-x eglot; enter "npx typescript-language-server --stdio"
> >   7. C-x C-f package.json RET (This file is automatically created by
> >      `npm install'.)
> >
> > I expect that the 'package.json' buffer is not managed by Eglot, but it
> > is actually managed by typescript-language-server, which does not really
> > understand JSON and is reporting some invalid errors.
> >
> > Thanks!
> >
> > [0] https://nodejs.org/en
> > [1] https://docs.npmjs.com/downloading-and-installing-node-js-and-npm
>
> João, any suggestions?

Thanks Eli.  Yes, some notes:

1. JSON is technically Javascript (but only really technically, in actual
   programming practice  it's not much use editing JSON as Javascript)

2. For the above reason the derivation of `json-json-mode` from `js-mode`
   is technically correct.  When looking at a JSON file you are technically
   looking at some minimalistic Javascript code.

3. It wouldn't be a bad idea for Emacs to do whatever behaviour-reuse it
   is doing for 'js-json-mode' with inheritance from 'js-mode' with some
   other mechanism like composition.  This would immediately solve Pengji's
   problem.  But it is not trivial to do so.

4. It follows from 1 and 2 that this problem can be viewed as a bug in
   typescript-language-server.  It's complaining we're not giving it
   a Javascript file, but it has no reason to complain: we are!  Not sure
   if it's worth arguing with the server devs like so.  Maybe.

5. A more promising change that can be tried today is to make use
   of Eglot's :language-id feature, which is already in place for this
   family of modes.  The current one looks like this:

  (((js-mode :language-id "javascript")
    (js-ts-mode :language-id "javascript")
    (tsx-ts-mode :language-id "typescriptreact")
    (typescript-ts-mode :language-id "typescript")
    (typescript-mode :language-id "typescript"))
  . ("typescript-language-server" "--stdio"))

Which means that any Javascript file is reported as javascript.
Maybe just adding

     (js-json-mode :language-id "json")

there would work.  In other words, this patch:

--- ./lisp/progmodes/eglot.el
+++ #<buffer eglot.el>
@@ -222,6 +222,7 @@

("vscode-json-languageserver" "--stdio")

("json-languageserver" "--stdio"))))
                                 (((js-mode :language-id "javascript")
+                                  (js-json-mode :language-id "json")
                                   (js-ts-mode :language-id "javascript")
                                   (tsx-ts-mode :language-id "typescriptreact")
                                   (typescript-ts-mode :language-id
"typescript")