- Change a built-in language for yourself: put a file with the same
idin thelanguagesfolder of the configuration directory. It replaces the built-in definition as a whole (fields are not merged), so start from a copy of the built-in file. - Add a language for yourself: put a new file with a new
idin the same folder. - Ship a language to others: add it to a plugin (see Contributing a language from a plugin), or to the repository’s
languages/folder.
The folder is read once at startup, so restart the IDE after changing a file. A file that does not parse is skipped and the reason is written to the log.
Example
A complete definition for a language with a tree-sitter grammar, a language server and a debugger:languages/zig.toml
id and name are required; a definition with nothing else still gives the files a name in the UI.
Language fields
Bundled tree-sitter grammars:
bash, c, cmake, cpp, csharp, css, dart, elixir, gdscript, go, graphql, haskell, hcl, html, java, javascript, json, kotlin, lua, make, markdown, nix, ocaml, ocaml_interface, php, proto, python, ruby, rust, scala, swift, toml, tsx, typescript, xml, yaml, zig. A new grammar has to be compiled into the IDE; a plugin can provide highlighting and structure for a language without a grammar instead (see Language features).
[[framework-ui-modes]]
The first entry whose marker is found wins. HTML uses this for Angular templates:
[[language-servers]]
Each entry starts one LSP server. Servers are listed in order; all regular servers run side by side, and a fallback server runs only while every server listed before it is missing.
Users can override most of these per server in Settings › Languages & Frameworks › Language Servers (executable, arguments, environment, initialization options, workspace configuration), without editing the definition.
TCP servers
Some servers only listen on a TCP port, such as the one inside the Godot editor. Withconnect, the IDE connects to that address when something listens there. Otherwise it starts command (when installed) and connects once it accepts connections: to 127.0.0.1:${port} when the arguments contain ${port} (the IDE picks a free port), else to the connect address. ${root} in the arguments is the workspace root. A server the IDE reached without starting it is never shut down by the IDE.
[debugger]
A language with a
[debugger] lets you set breakpoints in its files.
formatter
An external formatter, used when no language server can format the file, or when selected in settings:
Contributing a language from a plugin
A plugin ships the same file and declares it in its manifest:plugin.toml
language-servers.command, debugger.command) needs a process:<program> capability; a server whose program is not granted is left out, while the language itself still works. Built-in and user definitions win: a plugin cannot reuse their ids, extensions or file names. See Language features for the plugin side, and the Solidity example in plugins/official/solidity.
Adding a built-in language
To add a language to OpenIDEA itself, addlanguages/<id>.toml and register it in the BUILTIN table in crates/ide-language/src/registry.rs, where the files are embedded at build time. One-click installation of its server needs an entry in crates/ide-tools/src/registry.rs under the same name.