On this pageOverview
Editor and tools

Language servers

Every language server Tori knows, how to install each one, and how to add your own.

A language server gives the editor completion, hover, go to definition, rename, code actions and the compiler’s own diagnostics. Settings > LSP has a card for every one Tori has, in one list that Search filters. More, in the section’s title row, opens the catalog for the rest.

Each card has a status dot, a version, Install or Update where they apply, one trash button, and an on or off switch. For a pack from the catalog, the trash button removes the pack and the copy of the server Tori downloaded for it. For a server your own toolchain installs, it runs the uninstall command in a terminal first, then removes the pack.

Installing a server

Tori ships the TypeScript, JSON, YAML, CSS and HTML servers. Every other server is a pack in the catalog. Open a file no loaded server handles, and a banner over the file offers its pack: Get opens the install dialog, Not now asks again next session, Never for this language stops asking.

With the pack in place, the next file you open in that language gets a second banner when Tori can install the server itself: Install, Not now, or Never for this language. The card in Settings > LSP has the same Install button.

Tori installs a pinned version, either from npm or from a GitHub release whose checksum it checks before writing anything, into ~/.config/tori/servers/<id>/. A failed download leaves the previous install in place. When a Tori release pins a newer version, the card offers Update.

For a server your own toolchain installs, Install runs the command shown on the card in a terminal inside Settings, using your login shell’s PATH. Reopen Tori after installing one by hand outside of Settings so it is picked up.

If you already have a server on your PATH, Tori uses yours, even for one it could install itself.

Every server

Bundled

Language Server Notes
TypeScript, JavaScript typescript-language-server Bundled. Needs node on your PATH. Uses the project’s own TypeScript.
JSON vscode-json-languageserver Bundled. Validates against SchemaStore, so package.json, tsconfig.json and friends get checked.
YAML yaml-language-server Bundled. SchemaStore validation for GitHub workflows, compose files and the like.
CSS, SCSS, Less vscode-css-language-server Bundled.
HTML vscode-html-language-server Bundled.

ESLint, Biome, oxlint and Ruff also run as language servers; they are on the linters page.

Catalog packs Tori installs the server for

Language Server Source
Python pyright npm
Bash, sh bash-language-server npm
Svelte svelte-language-server npm
Astro @astrojs/language-server npm. Type checks with the project’s own TypeScript when it has one, else the copy Tori bundles.
PHP Intelephense npm
Vim script vim-language-server npm
Elm elm-language-server npm (needs elm installed)
Prisma @prisma/language-server npm
Perl Perl Navigator npm
GraphQL graphql-language-service-cli npm
Fish fish-lsp npm (needs fish installed)
C, C++, Objective-C clangd GitHub release. Xcode’s command line tools already ship one.
Lua lua-language-server GitHub release
Markdown marksman GitHub release
LaTeX texlab GitHub release
XML LemMinX GitHub release
Typst tinymist GitHub release
TOML tombi GitHub release
Clojure clojure-lsp GitHub release

Catalog packs you install the server for

Language Server Install
Rust rust-analyzer rustup component add rust-analyzer, so it always matches your toolchain
Go gopls go install golang.org/x/tools/gopls@latest
Ruby ruby-lsp gem install ruby-lsp
Java jdtls brew install jdtls
Kotlin kotlin-language-server brew install kotlin-language-server
Swift sourcekit-lsp Ships with Xcode and the Swift toolchain
C# csharp-ls dotnet tool install --global csharp-ls
Zig zls The release that matches your Zig
Haskell haskell-language-server ghcup install hls
OCaml ocaml-lsp-server opam install ocaml-lsp-server
Elixir elixir-ls brew install elixir-ls. Starts only under a mix.exs.
Dart, Flutter dart language-server Ships with the Dart and Flutter SDKs
Terraform terraform-ls brew install hashicorp/tap/terraform-ls
Scala Metals cs install metals
Nix nil nix profile install nixpkgs#nil

When a server does not start

  • The project is not trusted. Most servers run project code, so they wait until you trust the project. Tori offers it the first time; see trusted projects.
  • It is not on your PATH. The card says not found. If you installed it somewhere your login shell does not look, point Tori at it with your own TOML (below).
  • It is switched off. Check the card’s switch, and the project’s own .tori/settings.json.

A server starts per project root: the nearest folder above the file with a tsconfig.json, go.mod, Cargo.toml or whatever that language uses. In a monorepo, each package gets its own server.

Adding or replacing a server

Each server is a TOML file. Install one from its page in the catalog, or drop one into ~/.config/tori/packs/lsp/ and restart Tori. A file may not reuse a built in id, so to replace a built in server, give your file its own id and switch the built in one off on its card. This one runs Python through a pyright you installed yourself, in place of the built in python:

~/.config/tori/packs/lsp/python-pyright.toml
schema_version = 1
id = "python-pyright"
label = "Python (pyright)"
root_markers = ["pyproject.toml", "setup.py", "requirements.txt", ".git"]
[languages]
py = "python"
pyi = "python"
[launch]
kind = "path"
program = "pyright-langserver"
args = ["--stdio"]

Keep every top level key above the first [table]: in TOML a key written after a table header belongs to that table. A replacement is whole, so list every extension you still want served. A file that fails to load is listed under Needs fixing in Settings > LSP, and the server it would have replaced keeps running.

Missing a language?

Request a language server. Say which server, how you install it today, and paste your TOML if you already have one working.