# Using LanguageServer.jl with eglot in emacs

**URL:** <https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125>\
**Category:** Tooling\
**Tags:** editors, emacs\
**Created:** [April 14, 2019, 1:46am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125 "2019-04-14T01:46:19Z")\
**Posts on this page:** 15\
**Page:** 6

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [August 13, 2024, 12:43pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/101 "2024-08-13T12:43:16Z")

</div>

That sounds like the issue I’m having right now. The language server simply isn’t sending any function signatures or docstrings at all. Haven’t had time to dig into it.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [August 14, 2024, 9:41am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/102 "2024-08-14T09:41:23Z")

</div>

The functionality came back somehow, and it turns out that interpolation is necessary to get the bug. So I opened the issue below:

> <https://github.com/non-Jedi/eglot-jl/issues/50>
>
> With
> \`\`\`julia
> using DocStringExtensions
> 
> """
> $(SIGNATURES)
> 
> Docstring
> 
> …with
> 
> linebreaks
> """
> foo() = nothing
> \`\`\`
> 
> when the point is at \`foo(\` (before the \`(\`)), the following docstring displayes in the message buffer:
> 
> \`\`\`
> $(SIGNATURES)nnDocstringnnwithnnlinebreaksn"
> \`\`\`
> 
> (note the \`n\`s). If I remove \`$(SIGNATURES)\`, I just see the first line, ie \`Docstring\`.
> 
> Emacs 29.3, eglot-jl 20240318.1159 from MELPA.

No rush, I can live with this.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [August 14, 2024, 11:38am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/103 "2024-08-14T11:38:24Z")

</div>

Thanks! @pfitzseb can you confirm the vs-code plugin doesn’t have any similar issue with the added detail that it’s triggered when interpolating into a docstring?

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [August 14, 2024, 1:36pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/104 "2024-08-14T13:36:52Z")

</div>

Hm, interesting. I can repro this:  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/2/f225747d3e8806413acc0d15dc2218873ca2bea8.png)

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [August 14, 2024, 2:56pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/105 "2024-08-14T14:56:29Z")

</div>

On the emacs side, looking through the source code, it appears eglot is attempting to parse any dollar signs as the [start of a mathematical expression](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/writing-mathematical-expressions). The message being passed to the client from LanguageServer.jl with the docstring (response to a “textDocument/hover” request) is otherwise well-formed as far as I can tell. Maybe vs-code is doing the same? If so the solution is for LanguageServer.jl to start backslash-escaping any “$” in markdown strings it sends ([not a violation of the gfm spec](https://github.github.com/gfm/#backslash-escapes)–just unnecessary to escape “$” ordinarily).

This is all rather unfortunate from a spec perspective. The [language server protocol explicitly states](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#markupContent) that markdown follows the [github flavored markdown spec](https://github.github.com/gfm/) which doesn’t include dollar-sign-delimited math expressions. But Microsoft [chose to add support for math expressions](https://github.com/microsoft/language-server-protocol/issues/1538) to the markdown parser used on github without actually updating the gfm specification. Perhaps recently the vs-code markdown parser also added support for math expressions despite it being a violation of the lsp spec?

Should open an issue against LanguageServer.jl, but I wanted to make sure I had all the facts organized first.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [August 15, 2024, 3:30am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/106 "2024-08-15T03:30:30Z")

</div>

I have had the same trouble as @tom-plaa, namely that eglot seems to work with julia-mode but not julia-ts-mode (using emacs 29.4 w/ updated packages).  
I have a work-around: if I set the mode of the first-visited file in a project to julia-mode, then invoke eglot and wait for it to fully initialize, I find that the LS also works for files in that project later opened with julia-ts-mode.

FWIW, I observe that before eglot has processed all the caches, the first file (in julia-mode) temporarily shows the half-baked LS stuff that we see with invocation from julia-ts-mode. Perhaps t-s is not completing some handshake with the LS when it’s ready? Unfortunately not anything recorded in the eglot event buffer AFAICT.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [August 15, 2024, 11:53am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/107 "2024-08-15T11:53:18Z")

</div>

Hm. Could you or @tom-plaa try to replicate this issue with `emacs -Q` and then manually installing `eglot-jl` and `julia-ts-mode` so we can make sure it’s not something else in your config causing the issue? I’m not having any luck at all replicating your experience, but obviously something somewhere needs fixed if multiple people are having the same problem.

---

<div class="post-metadata">

**Author:** ![tom-plaa](https://avatars.discourse-cdn.com/v4/letter/t/d26b3c/32.png) [@tom-plaa](https://discourse.julialang.org/u/tom-plaa)\
**Post date:** [August 16, 2024, 10:08am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/108 "2024-08-16T10:08:17Z")

</div>

I haven’t had the chance to do it yet, but I plan on doing it when possible.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [August 19, 2024, 3:17am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/109 "2024-08-19T03:17:01Z")

</div>

I tried a new install of the various packages with no frills and got the same result. (Anyone else trying this should currently follow the advice [here](https://github.com/JuliaEditorSupport/julia-ts-mode/issues/21#issuecomment-2126885445) to get a compatible grammar; an update is in progress.) Then I did a bit of yak shaving, yielding the following observation.

The problem appears to be that the server object set up by `eglot-jl` gets the `languageId` parameter from the major-mode name, and at least for some of us the language server does not like “julia-ts” as a `languageId`. (Correspondingly, initializing the server from plain julia-mode this way works, as we saw.) This seems to be fixed by changing the major-mode spec in `eglot-jl-init` to the form with explicit `language-id` settings.

---

<div class="post-metadata">

**Author:** ![tom-plaa](https://avatars.discourse-cdn.com/v4/letter/t/d26b3c/32.png) [@tom-plaa](https://discourse.julialang.org/u/tom-plaa)\
**Post date:** [August 26, 2024, 10:54am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/110 "2024-08-26T10:54:19Z")

</div>

> [@Ralph\_Smith](#):
>
> This seems to be fixed by changing the major-mode spec in `eglot-jl-init` to the form with explicit `language-id` settings.

Ralph, could you show me how to do it? I’d also like to try it on my side later when I have time. Thanks

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [August 26, 2024, 1:14pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/111 "2024-08-26T13:14:58Z")

</div>

The change is in [this PR to eglot-jl](https://github.com/non-Jedi/eglot-jl/pull/51).

---

<div class="post-metadata">

**Author:** ![johannesnauta](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johannesnauta/32/47434_2.png) [@johannesnauta](https://discourse.julialang.org/u/johannesnauta)\
**Post date:** [September 19, 2024, 3:54pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/112 "2024-09-19T15:54:20Z")

</div>

By the way, perhaps I missed it, but is there already a solution or workaround for the `missing reference`-bug when using macros? Writing `ModelingToolkit` models and having all my parameters `@parameters a` get a red twiggle underneath them is quite jarring and distracting.

---

<div class="post-metadata">

**Author:** ![Nidish](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nidish/32/218326_2.png) [@Nidish](https://discourse.julialang.org/u/Nidish)\
**Post date:** [May 6, 2025, 10:33am UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/113 "2025-05-06T10:33:32Z")

</div>

I’m using eglot (with eglo-jl ) along with julia-snail on emacs. It’s quite nice in general but there’s one very annoying aspect.

Here’s my folder:

```bash
juliajim
├── dev
│ ├── a_hworld.jl
│ ├── b_contin.jl
│ ├── b_contin.jl~
│ ├── c_nlslv.jl
│ ├── d_epmc.jl
│ └── e_mdofgen.jl
├── Manifest.toml
├── Project.toml
├── src
│ ├── CONTINUATION.jl
│ ├── HARMONIC.jl
│ ├── juliajim.jl
│ └── MDOFGEN.jl
└── test
    └── a_afttests.jl

```

In the test file (or any file in the dev folder), I’m unable to get completions for any functions I define in the module file `juliajim.jl` if I use `using juliajim` in the beginning of the script. Including the file explicitly by an `include` or `includet` call works, however.

For instance, if the following is my `juliajim.jl` module file:

```julia
module juliajim

export jimgreet;

jimgreet() = "Hello World!";

end

```

the following doesn’t trigger any completion if I typed jimgr :

```julia
using juliajim

jimgr 

```

but all the eglot features (completion, jump, etc.) work for the following:

```julia

includet("../src/juliajim.jl");
using .juliajim

jimgre

```

This is annoying since julia-snail is correctly able to include the module irrespective of which folder I’m on. I’ll appreciate any tips!

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [May 8, 2025, 12:56pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/114 "2025-05-08T12:56:48Z")

</div>

This is an unfortunate limitation of LanguageServer.jl. For the test directory specifically, see the same issue filed against the vscode extension:

> <https://github.com/julia-vscode/julia-vscode/issues/1740>
>
> Hello, I just created a dummy project with the following structure
> \`\`\`
> ├───src…
> │ vscode\_intellisense.jl
> │
> └───test
> runtests.jl
> \`\`\`
> I found that in \`runtests.jl\`, typing \`using \` and CTRL+SPACE does not show any module hint. Also the symbol in \`vscode\_intellisense\` are not sensed and suggested. Running the file directly does not give any error. Does \`julia-vscode\` support code completion for unit tests?

See my reply above for the more general issue with julia files outside the src directory and a link to some workarounds:

> [@Using LanguageServer.jl with eglot in emacs](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/88):
>
> I try to go through discourse every few months and see if there’s any eglot-jl-related questions I missed. Apologies for not replying here sooner. This is a [limitation of LanguageServer.jl](https://github.com/julia-vscode/LanguageServer.jl/issues/988) which is discussed along with possible workarounds here:

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [May 8, 2025, 1:00pm UTC](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125/115 "2025-05-08T13:00:07Z")

</div>

Looks like you already found what I’m linking to, but in case somebody else ends up here through search: here’s the upstream issue for the language server not being aware of variables defined by macros:

> <https://github.com/julia-vscode/StaticLint.jl/issues/381>
>
> (cut from LanguageServer as it seems that this is where this belongs)
> 
> In this… code:
> 
> \`\`\`\`julia
> using ModelingToolkit
> 
> @parameters param1,param2
> \`\`\`\`
> 
> \`param1\` and \`param2\` are undefined. In fact, at that line it returns a "Missing Reference".
> 
> I thought there could be a few options, first a better "macro walk" where macros should be evaluated by source, or a hard definition (mark \`@parameters\`...etc as "definers").

[Previous page](https://discourse.julialang.org/t/using-languageserver-jl-with-eglot-in-emacs/23125.md?page=5)
