Hints for using the new JETLS.jl language server

I reached a point where JETLS.JL is good enough for me and has no serious issues anymore.

I needed some special configuration, though, and I want to share it with you:

I find it much better than the old language server because it also works in tests and examples of a project and gives warnings that otherwise do not appear, such as warnings about abstract types.

14 Likes

LanguageServer.jl not working on tests is one of my greatest pain points with it. That and the lack of support for package extensions.

Do you know if JETLS.jl work well with code in a Package extension module?

Not at all: Broken with pkgextensions? · Issue #521 · aviatesk/JETLS.jl · GitHub

1 Like

I have also had a positive experience with JETLS. I am using it in emacs. For anyone who might be trying it out in emacs 29 with eglot, it might help to know that this issue is solved in recent versions of eglot. So you might want to upgrade to eglot 1.21. It took me too long to figure that out.

I really like JETLS.jl as well. As of right now I cannot use it due to a weird race condition that prevents the process from exiting. This is primarily in Neovim. But up until the introduction of that bug it was a joy to use and I’m looking forward to using it again. :folded_hands:t2::blush:

Very cool stuff.

Is there some reason you can’t go back to whatever release was working for you? I was assuming that there might be bumps along the road in development and I might have to do that at some point. (Although that hasn’t happened for me so far.)

No reason at all. I just don’t remember which version was working. So I’m guessing is faster to try the next could of versions instead given how fast the development is going. :blush:

This was due to an issue with Neovim’s abnormal server process lifecycle handling (i.e. Neovim actually doesn’t comply with LSP by not sending exit notification before killing server process), but it has been fixed on the latest JETLS version 2026-03-13 by making JETLS’s abnormal server shutdown handling more robust. Thanks for @abap34 for this.

6 Likes

Yes and it works like a charm. I’ll try and see if I can get an issue up and running for neovim as this seems to be a rather serious bug. It only happens with jetls though. I use around 5 different language servers and they all works as one would expect. Weird.

Thanks for all the great work on JETLS! :tada:

1 Like

Would a kind soul please explain WHERE the configuration files mentioned in the man page are meant to be saved?

In the root directory of your package or project. See: GitHub - OpenSourceAWE/KiteModels.jl: Kite and tether models for the simulation of kite power systems · GitHub

I have a .JETLSConfig.toml.default file in Git, my install script copies it to .JETLSConfig.toml . By doing this, every developer can have different settings that are not in Git, while still getting a reasonable default as a starting point.

If you run jetls from the command line you can specify the root directory like this:

jetls check --root=. src/

The root directory is the directory that also contains the Project.toml file.

Thanks, I had one file with that name, that I found i your opening post but not in the JETLS manual (Diagnostic section), but it makes no effect to me. I still see hundreds of false positives may be used before it is defined. The contents of my .toml file are:

[[diagnostic.patterns]]
pattern = "lowering/(unused-argument|unused-local)"
match_by = "code"
match_type = "regex"
severity = "off"

[[diagnostic.patterns]]
pattern = "lowering/undef-local-var"
match_by = "code"
match_type = "regex"
severity = "off"

Can you share the project that produces these warnings?

Without seeing your code, it is hard to answer the question of why there are these warnings.

Possible reasons:

  • you are not using Julia 1.12
  • instantiating your project fails (try: julia --project=. 'using Pkg; Pkg.instantiate'. Does that work?)

When I started using jetls I started with a very small project first, to get a feeling for how it works and which coding patterns to avoid.

I have it in the root folder of the GMT.jl. I don’t use projects. But the question is not on why the warnings are produced. They are mostly false positives but that has time … to improve with time. The question is why they are not suppressed.

You should use --project. If you are not doing it, which environment shall JETLS assume? JETLS has two modes: package mode and script mode. If you analyze the files of a package in script mode, you will get a lot of wrong warnings.
See: Working with Julia projects | Julia programming notes

Did you run this command in the terminal:

jetls check --root=. src/

If you do that, then we know the problem is not the VSCode integration.

If I look at my way to suppress messages, I see one difference:

[[diagnostic.patterns]]
pattern = "copy!.*Random.TaskLocalRNG.*Nothing"
match_by = "message"
match_type = "regex"
severity = "off"

I use match_by ="message"

I don’t need projects so I don’t use them.
By moving the setting to VSC’s .vscode/settings.json I’m starting to see the suppressions I want.
Thanks for your help.

I saw the match_by = "code" in JETLS’s docs and that is also what I put in the settings.json and it worked. Maybe they both do.

1 Like

Didn’t you say you are working on GMT.jl? This is a package, and a package is always also a Julia project. This is not true the other way round.

OK, I meant the I don’t use --project=???

BTW, anyone know how to suppress the messages:
Indexing with indices obtained from length, sizeetc is discouraged. Useeachindexoraxes instead.

Tried with the "pattern": "IndexFromLength", that is shown together with warning but it didn’t work

IMO, this messages should not be shown by default. It is my choice to use
for k = 1:length(v)
and not be censured.

I can’t help with JETLS but please note that there can be a tangible difference between

for k in 1:length(v)

And

for k in eachindex(v)

Even when you don’t consider exotic indices. In the latter, Julia knows that all indices are inbounds and is very likely to ellide boundchecks - so effectively you get a free and 100% safe @inbounds for using the “correct” pattern. So this is a bit more than a stylistic choice.

2 Likes