Helix + LanguageServer.jl + JuliaFormatter.jl

kousu
Sun, 09 Nov 2025 06:02:14 +0000
New to Julia

I’m trying to move from vscode to helix to save my RAM for Julia.

I’m on helix 25.07.01, julia 1.12.1. I haven’t configured anything except

$ cat ~/.config/helix/config.toml
theme = "autumn_night"

$ cat ~/.config/helix/languages.toml
[[language]]
name = "julia"
auto-format = true

If I open a julia file in helix I can see the language server is running

$ pgrep -laf julia
4072615 /usr/bin/julia --startup-file=no --history-file=no --quiet -e using LanguageServer; runserver()

and it’s doing its job: it knows about Julia keywords and types

But it’s unreliable around formatting.

It’s slow to format on the first save. It takes long enough that I can easily cancel it by changing the text. And it seems that if I am making lots of small changes and saving quickly, it never gets a chance to fully compile so it never formats my code.

The = button gives an error the first time I try to use it.

No configured language server supports range formatting

I have to wait, and then on the second time it works. This error is really confusing to me because it says “no support” but then a second later clearly there is support

If I press = multiple times in a row while it’s trying to figure itself out I’m able to lock the session up hard

Am I doing something wrong? neovim people, do you ever have these kinds of problems?

I’ve read the sysimage advice (repeated here and here). I tried

$ time julia --startup-file=no --project=@helix-lsp -e 'import Pkg; Pkg.add(["LanguageServer", "PackageCompiler", "JuliaFormatter"]); Pkg.update();using PackageCompiler; create_sysimage([:LanguageServer, :JuliaFormatter], sysimage_path=dirname(Pkg.Types.Context().env.project_file) * "/languageserver.so")'

I added this to language.toml:

[language-server.julia]
timeout = 60
command = "julia"
args = [
  "--project=@helix-lsp",
  "--startup-file=no",
  "--history-file=no",
  "--quiet",
  "-J/home/kousu/.julia/environments/helix-lsp/languageserver.so",
  "--sysimage-native-code=yes",
  "-e",
  """"
  import Pkg
project_path = let
    dirname(something(
        Base.load_path_expand((
            p = get(ENV, "JULIA_PROJECT", nothing);
            isnothing(p) ? nothing : isempty(p) ? nothing : p
        )),
        Base.current_project(pwd()),
        Pkg.Types.Context().env.project_file,
        Base.active_project(),
    ))
    end
ls_install_path = joinpath(get(DEPOT_PATH, 1, joinpath(homedir(), ".julia")), "environments", "helix-lsp");
pushfirst!(LOAD_PATH, ls_install_path);
using LanguageServer;
popfirst!(LOAD_PATH);
depot_path = get(ENV, "JULIA_DEPOT_PATH", "")
symbol_server_path = joinpath(homedir(), ".cache", "helix", "julia_lsp_symbol_server")
mkpath(symbol_server_path)
server = LanguageServer.LanguageServerIn`stance(stdin, stdout, project_path, depot_path, nothing, symbol_server_path, true)
server.runlinter = true
run(server)
"""
]

And I can see this is the version running now

$ pgrep -laf julia
23425 /usr/bin/julia --project=@helix-lsp --startup-file=no --history-file=no --quiet -J/home/kousu/.julia/environments/helix-lsp/languageserver.so --sysimage-native-code=yes -e "   import Pkg project_path = let     dirname(something(         Base.load_path_expand((             p = get(ENV, "JULIA_PROJECT", nothing);             isnothing(p) ? nothing : isempty(p) ? nothing : p         )),         Base.current_project(pwd()),         Pkg.Types.Context().env.project_file,         Base.active_project(),     ))     end ls_install_path = joinpath(get(DEPOT_PATH, 1, joinpath(homedir(), ".julia")), "environments", "helix-lsp"); pushfirst!(LOAD_PATH, ls_install_path); using LanguageServer; popfirst!(LOAD_PATH); depot_path = get(ENV, "JULIA_DEPOT_PATH", "") symbol_server_path = joinpath(homedir(), ".cache", "helix", "julia_lsp_symbol_server") mkpath(symbol_server_path) server = LanguageServer.LanguageServerInstance(stdin, stdout, project_path, depot_path, nothing, symbol_server_path, true) server.runlinter = true run(server)

But it’s still slow.

What am I doing wrong? How do I debug this (can I see a log of what the language server is loading?). How do I make it faster?

I just tried to see if vscode has the same first-load problem and it does. It won’t format my code until after it finished with this:

and then gives me this error about it crashing:

Once it gives that error, though, formatting is fast.

13 posts - 3 participants