GNU bug report logs - #72343
[PATCH] Fix eglot-server-programs for TeX modes

Previous Next

Package: emacs;

Reported by: Augusto Stoffel <arstoffel <at> gmail.com>

Date: Sun, 28 Jul 2024 18:09:01 UTC

Severity: normal

Tags: patch

Full log


Message #47 received at 72343 <at> debbugs.gnu.org (full text, mbox):

From: João Távora <joaotavora <at> gmail.com>
To: Augusto Stoffel <arstoffel <at> gmail.com>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 72343 <at> debbugs.gnu.org
Subject: Re: bug#72343: [PATCH] Fix eglot-server-programs for TeX modes
Date: Tue, 6 Aug 2024 19:08:45 +0100
On Tue, Aug 6, 2024 at 5:38 PM Augusto Stoffel <arstoffel <at> gmail.com> wrote:

> > So there's no "single pick" in general.
> You don't need to explain that to me ;-).

It is you who alluded to a single pick, so I thought I had to.  Also
earlier you proposed multiple entries in eglot-server-programs, which
would impede this multi-language-per-session feature.  So I figured you
wouldn't be familiar with it.

> What I want to achieve (or, if I may, what Eglot should do) in case it
> wasn't clear yet, is: file x.tex is sent language id "latex" and file
> y.tex is sent language id "plain-tex".

Indeed it wasn't clear, so I'm very glad I asked.  I don't see
"plain-tex" in the list over at

  https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/

I just see "tex" and "latex" and "bibtex".

Now, if you want "latex" to be sent for x.tex (in latex-mode) and "tex"
to be sent for x.tex (in plain-tex-mode), there is this possibility.

diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 5845aff39b7..2695aa93ffe 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -292,7 +292,7 @@ eglot-server-programs
     (scala-mode . ,(eglot-alternatives
                     '("metals" "metals-emacs")))
     (racket-mode . ("racket" "-l" "racket-langserver"))
-    ((tex-mode context-mode texinfo-mode bibtex-mode)
+    ((latex-mode tex-mode context-mode texinfo-mode bibtex-mode)
      . ,(eglot-alternatives '("digestif" "texlab")))
     (erlang-mode . ("erlang_ls" "--transport" "stdio"))
     ((yaml-ts-mode yaml-mode) . ("yaml-language-server" "--stdio"))

No need to mention plain-tex-mode at all. The "guess" logic will work
(though I still recommend :language-id cookie).

You might notice this will only work for a particular sequence of
invocations (specifically starting the server with the latex-mode file
open, then opening other files in plain-tex-mode).

But it won't for many other cases.  The fact that Emacs models
latex-mode as a descendent of tex-mode is something Eglot can't do
anything about.  It means that Emacs thinks that that every LaTex
program is a TeX program at least at some syntactic level (is this true?
no idea).  So as soon as you have the two files open, M-x
eglot-reconnect will send "tex" for _both_.  Which, according to Emacs's
view of the world, isn't wrong.

This has happened before with the js/json mode and has been fixed in the
mode relations.  I think bug#67463.  The same idea thatfixed it there
could be applied here.

Anyway, if plain-tex-mode is an attempt to fix this, by making a core
mode that is not directly related to latex-mode, then I think it should
appear in the list, but then :language-id set to to "tex".

But I see plain-tex-mode also inherits from tex-mode, so the fundamental
problem remains. Unless you remove tex-mode from the list (which is what
you did).  But then outside descendents of tex-mode would be cut off,
which is what I warned about.

I do think that's the lesser of two evils though.  So anyway this is my
suggestion:

@@ -292,7 +292,7 @@ eglot-server-programs
     (scala-mode . ,(eglot-alternatives
                     '("metals" "metals-emacs")))
     (racket-mode . ("racket" "-l" "racket-langserver"))
-    ((tex-mode context-mode texinfo-mode bibtex-mode)
+    ((latex-mode (plain-tex-mode :language-id "tex") context-mode
texinfo-mode bibtex-mode)
      . ,(eglot-alternatives '("digestif" "texlab")))
     (erlang-mode . ("erlang_ls" "--transport" "stdio"))
     ((yaml-ts-mode yaml-mode) . ("yaml-language-server" "--stdio"))

In theory, this could also be fixed by keeping tex-mode in there, and
then adjusting Eglot's heuristic, by ranking the potential ancestors and
selecting the closest one, in 'eglot--languageId'.  Could be tricky or
could be easy, feel free to give it a shot.

Yet another idea is to not reorder modes at all in 'eglot--lookup-mode'
and use an explicit order to express this ranking.  I admit I don't
remember what the reordering idea (main-mode-sym is the local var name)
is for.  it couldprecede the multiple-language-ids feature.  Or it could
be essential for some other thing: testing would be needed.

> This doesn't matter, as it's an Eglot issue.  Any TeX server will do.

This is not established, at least not yet.  You are requesting for a
"plain-tex" LSP languageId property to be sent and that is outside the
spec as far as I can tell from reading the spec.  Maybe your digestif
server supports and likes it, though.  But it might break "texlab" for
all I know.  Even the fact that "tex" is all that's being sent at the
moment may or may not be a bug -- only LaTex/Tex specialists can say
that.  And certainly a capable enough language server, which is tasked
with analysing a file syntactically, can do much the same as our own
tex-mode.el and figure out the correct language from the contents.
Might do it better than Emacs.

That said, if you really want to send "plain-tex", then there are two
options.  You can change your user value of eglot-server-programs,
obviously.  Or you can confirm with "texlab" that they don't mind, in
which case -- but only in that case -- your latest patch is acceptable.




This bug report was last modified 361 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.