Configuring languages
Most languages work with no setup. This page covers what you can change: per-language settings, which files belong to a language, which language servers run, and how code is formatted.
Settings go in your settings.json (~/.config/tyrn/settings.json) or in a project’s .tyrn/settings.json. Open them from the Tyrn > Settings menu.
Language-specific settings
Put overrides under languages, keyed by the language’s display name. Anything that is a top-level editor setting can be overridden this way.
{ "tab_size": 4, "languages": { "Python": { "tab_size": 4 }, "JavaScript": { "tab_size": 2, "format_on_save": "on" }, "Markdown": { "soft_wrap": "editor_width" } }}Common keys: tab_size, hard_tabs, soft_wrap, preferred_line_length, format_on_save, formatter, language_servers, code_actions_on_format, show_edit_predictions and debuggers. Language names include spaces and case as the language shows them, for example "C++", "TSX" and "Plain Text". The language button in the status bar (also cmd-k m) shows the name.
Tyrn also reads .editorconfig files.
File associations
Use file_types to map file names or globs to a language.
{ "file_types": { "JavaScript": ["notjs"], "TOML": ["Embargo.lock"], "C": ["h"] }}An entry is a file extension, a file name or a glob. To change the language for one buffer, use the language selector (cmd-k m).
Language servers
A language server is a program that provides completions, diagnostics, go to definition, rename and more. Tyrn starts the right one for each file and downloads built-in ones for you. See Languages.
The status bar has a Language Servers button. It lists the servers running for your project, and lets you restart or stop one, and open its logs. Language servers don’t run in a project you have not trusted. See Worktree trust.
Choose servers for a language
A language can have several servers. language_servers lists which to use. A name starts that server, a name with ! turns it off, and "..." stands for the remaining defaults.
{ "languages": { "Python": { // Use ty instead of basedpyright, and keep everything else as it is. "language_servers": ["ty", "!basedpyright", "..."] }, "TypeScript": { "language_servers": ["typescript-language-server", "!vtsls", "..."] } }}Turn off all language server features with "enable_language_server": false. It can be set per language.
Configure a server
Settings for one server go under lsp, keyed by the server’s name.
{ "lsp": { "rust-analyzer": { "initialization_options": { "check": { "command": "clippy" } }, "binary": { "path": "/opt/homebrew/bin/rust-analyzer", "arguments": [], "env": {} }, "fetch": { "pre_release": false } }, "basedpyright": { "settings": { "basedpyright": { "analysis": { "diagnosticMode": "workspace" } } } } }}| Key | Meaning |
|---|---|
initialization_options |
Sent once when the server starts. |
settings |
The server’s workspace configuration, sent at startup and when it changes. |
binary.path |
Use this program instead of the one Tyrn would download. Must be an absolute path. |
binary.arguments, binary.env |
Arguments and environment for the server |
binary.ignore_system_version |
Ignore a copy on your PATH and use the one Tyrn manages |
fetch.pre_release |
Download pre-release versions |
enable_lsp_tasks |
Allow tasks that the server provides. Default true. |
Each server documents which options it accepts. Check its own documentation. Settings merge on top of Tyrn’s defaults.
Global behavior is under global_lsp_settings: request_timeout (seconds, default 120), max_buffer_line_length (default 20000) and button (show the status bar button).
Node
Servers written in JavaScript need Node. Tyrn uses the node on your PATH if it is recent enough, and downloads its own otherwise.
{ "node": { "ignore_system_version": false, "path": null, "npm_path": null }}Changing node needs a restart.
Python toolchains
For Python, Tyrn detects virtual environments and uses the selected one for the language server and for running code. Run toolchain: select from the command palette to choose another, and use cmd-k cmd-m (toolchain: add toolchain) to add an environment by path.
Formatting and linting
Format on save
{ "format_on_save": "on", "languages": { "Rust": { "format_on_save": "on" }, "Markdown": { "format_on_save": "off" } }}format_on_save is "off" by default. It also accepts "modifications" to format only lines you changed. Format at any time with cmd-shift-i.
Choose the formatter
formatter decides what formats the buffer.
{ "languages": { "Python": { "formatter": { "language_server": { "name": "ruff" } } }, "JavaScript": { "formatter": { "external": { "command": "prettier", "arguments": ["--stdin-filepath", "{buffer_path}"] } } }, "TypeScript": { "formatter": [{ "code_action": "source.fixAll.eslint" }, "prettier"] } }}| Value | Meaning |
|---|---|
"auto" (default) |
Prettier if it applies to the language and is allowed, otherwise the language server |
"language_server" |
The current language server |
{ "language_server": { "name": "..." } } |
A specific server |
"prettier" |
Prettier |
{ "external": { "command": "...", "arguments": [...] } } |
A command that reads the file on standard input. {buffer_path} is the file path. |
{ "code_action": "..." } |
Run a code action |
| An array | Run each step in order |
Run code actions when formatting with code_actions_on_format, for example organize imports:
{ "languages": { "Go": { "code_actions_on_format": { "source.organizeImports": true } } }}Prettier
Prettier is used for web languages. It uses the version installed in your project. Without a project install it falls back to the options in the top-level prettier setting.
{ "languages": { "CSS": { "prettier": { "allowed": true } } }, "prettier": { "tabWidth": 2, "singleQuote": true }}Whitespace on save
remove_trailing_whitespace_on_save and ensure_final_newline_on_save are both true by default. line_ending is "detect" by default.
Linters
Linters run as language servers (such as ruff, eslint and shellcheck through bash-language-server). Their results show as diagnostics. Turn a linter off by adding its name with ! to language_servers.
Syntax highlighting
Tyrn highlights with Tree-sitter grammars. Some language servers also provide semantic tokens, which can refine colors. Use semantic_tokens:
"off"(default): Tree-sitter only."combined": semantic tokens on top of Tree-sitter."full": semantic tokens only.
Restart the language server after changing it. Change how colors map to token types with global_lsp_settings.semantic_token_rules, and change theme colors with Themes.
Other server features have settings of their own: inlay_hints.enabled, code_lens, document_folding_ranges, document_symbols and lsp_document_colors.