Skip to content
2639-unofficial edited this page Apr 3, 2024 · 5 revisions

Helix already has a default config in its languages.toml. But it's not perfect and sometimes fails e.g. cannot check which is the project root because it cannot recursively check if there is a Project.toml or Manifest.toml file. Some tips below you can follow 👇

Disclaimer: This part of the helix wiki is only for Unix/Linux systems. If you use Windows, you can probably follow some steps and modify to your liking. Please do add a Windows section if you have the time. 😄

Unix/Linux

You can edit the shipped languages.toml to your own liking. For example, if you want to setup with a compiled sysimage of the language server, you can run

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

Depending on your shell, adjust the command to your shell preference. Then edit the julia language configuration of your languages.toml file like so:

[[language]]
name = "julia"
scope = "source.julia"
injection-regex = "julia"
file-types = ["jl"]
roots = ["Project.toml", "Manifest.toml", "JuliaProject.toml"]
comment-token = "#"
language-servers = ["julia-lsp"]
indent = { tab-width = 4, unit = "    " }

[language-server.julia-lsp]
command = "julia"
timeout = 60
args = [
    "--project=@helix-lsp",
    "--startup-file=no",
    "--history-file=no",
    "--quiet",
    "-J/home/<yourusername>/.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", "nvim-lspconfig");
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)
"""]

Change <yourusername> to whatever name you use for your $HOME directory. Sadly, it needs to be hardcoded for now.

Alternative way

Write a script with any filename containing the following content:

#!julia --project=@helix-lsp --startup-file=no --history-file=no --quiet
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)

Make script executable by running chmod +x yourscript and make it available to PATH e.g. move it to /usr/local/bin

Have the following language server configuration in your languages.toml file:

[language-server.julia]
command = "julia-lsp-helix"
timeout = 60

Done

Clone this wiki locally