As always, a big thank you to all of the contributors! This release saw changes from 125 contributors.
Breaking changes:
- `suffix` file-types in the `file-types` key in language configuration have been removed ([#8006](https://github.com/helix-editor/helix/pull/8006))
- The `file-types` key in language configuration no longer matches full filenames without a glob pattern ([#8006](https://github.com/helix-editor/helix/pull/8006))
Features:
- Open URLs with the `goto_file` command ([#5820](https://github.com/helix-editor/helix/pull/5820))
- Support drawing a border around popups and menus ([#4313](https://github.com/helix-editor/helix/pull/4313), [#9508](https://github.com/helix-editor/helix/pull/9508))
- Track long lived diagnostic sources like Clippy or `rustc` ([#6447](https://github.com/helix-editor/helix/pull/6447), [#9280](https://github.com/helix-editor/helix/pull/9280))
- This improves the handling of diagnostics from sources that only update the diagnostic positions on save.
- Add support for LSP `window/showDocument` requests ([#8865](https://github.com/helix-editor/helix/pull/8865))
- Refactor ad-hoc hooks to use a new generic event system ([#8021](https://github.com/helix-editor/helix/pull/8021), [#9668](https://github.com/helix-editor/helix/pull/9668), [#9660](https://github.com/helix-editor/helix/pull/9660))
- This improves the behavior of autocompletions. For example navigating in insert mode no longer automatically triggers completions.
- Allow using globs in the language configuration `file-types` key ([#8006](https://github.com/helix-editor/helix/pull/8006))
- Allow specifying required roots for situational LSP activation ([#8696](https://github.com/helix-editor/helix/pull/8696))
- Extend selections using mouse clicks in select mode ([#5436](https://github.com/helix-editor/helix/pull/5436))
- Support LSP diagnostic tags ([#9780](https://github.com/helix-editor/helix/pull/9780))
- Add a `file-absolute-path` statusline element ([#4535](https://github.com/helix-editor/helix/pull/4535))
- Cross injection layers in tree-sitter motions (`A-p`/`A-o`/`A-i`/`A-n`) ([#5176](https://github.com/helix-editor/helix/pull/5176))
- Add a Amp-editor-like jumping command ([#8875](https://github.com/helix-editor/helix/pull/8875))
Commands:
- `:move` - move buffers with LSP support ([#8584](https://github.com/helix-editor/helix/pull/8584))
- Also see [#8949](https://github.com/helix-editor/helix/pull/8949) which made path changes conform to the LSP spec and fixed the behavior of this command.
- `page_cursor_up`, `page_cursor_down`, `page_cursor_half_up`, `page_cursor_half_down` - commands for scrolling the cursor and page together ([#8015](https://github.com/helix-editor/helix/pull/8015))
- `:yank-diagnostic` - yank the diagnostic(s) under the primary cursor ([#9640](https://github.com/helix-editor/helix/pull/9640))
- `select_line_above` / `select_line_below` - extend or shrink a selection based on the direction and anchor ([#9080](https://github.com/helix-editor/helix/pull/9080))
Usability improvements:
- Make `roots` key of `[[language]]` entries in `languages.toml` configuration optional ([#8803](https://github.com/helix-editor/helix/pull/8803))
- Exit select mode in commands that modify the buffer ([#8689](https://github.com/helix-editor/helix/pull/8689))
- Use crossterm cursor when out of focus ([#6858](https://github.com/helix-editor/helix/pull/6858), [#8934](https://github.com/helix-editor/helix/pull/8934))
- Join empty lines with only one space in `join_selections` ([#8989](https://github.com/helix-editor/helix/pull/8989))
- Introduce a hybrid tree-sitter and contextual indentation heuristic ([#8307](https://github.com/helix-editor/helix/pull/8307))
- Allow configuring the indentation heuristic ([#8307](https://github.com/helix-editor/helix/pull/8307))
- Check for LSP rename support before showing rename prompt ([#9277](https://github.com/helix-editor/helix/pull/9277))
- Normalize `S-<lower-ascii>` keymaps to uppercase ascii ([#9213](https://github.com/helix-editor/helix/pull/9213))
- Add formatter status to `--health` output ([#7986](https://github.com/helix-editor/helix/pull/7986))
- Change path normalization strategy to not resolve symlinks ([#9330](https://github.com/helix-editor/helix/pull/9330))
- Select subtree within injections in `:tree-sitter-subtree` ([#9309](https://github.com/helix-editor/helix/pull/9309))
- Use tilde expansion and normalization for `$HELIX_RUNTIME` paths ([1bc7aac](https://github.com/helix-editor/helix/commit/1bc7aac))
- Improve failure message for LSP goto references ([#9382](https://github.com/helix-editor/helix/pull/9382))
- Use injection syntax trees for bracket matching ([5e0b3cc](https://github.com/helix-editor/helix/commit/5e0b3cc))
- Respect injections in `:tree-sitter-highlight-name` ([8b6565c](https://github.com/helix-editor/helix/commit/8b6565c))
- Respect injections in `move_parent_node_end` ([035b8ea](https://github.com/helix-editor/helix/commit/035b8ea))
- Use `gix` pipeline filter instead of manual CRLF implementation ([#9503](https://github.com/helix-editor/helix/pull/9503))
- Reload language configuration with `:reload`, SIGHUP ([#9415](https://github.com/helix-editor/helix/pull/9415))
- Allow numbers as bindings ([#8471](https://github.com/helix-editor/helix/pull/8471), [#9887](https://github.com/helix-editor/helix/pull/9887))
- Respect undercurl config when terminfo is not available ([#9897](https://github.com/helix-editor/helix/pull/9897))
- Ignore `.pijul`, `.hg`, `.jj` in addition to `.git` in file pickers configured to show hidden files ([#9935](https://github.com/helix-editor/helix/pull/9935))
- Add completion for registers to `:clear-register` and `:yank-diagnostic` ([#9936](https://github.com/helix-editor/helix/pull/9936))
- Repeat last motion for goto next/prev diagnostic ([#9966](https://github.com/helix-editor/helix/pull/9966))
- Allow configuring a character to use when rendering narrow no-breaking space ([#9604](https://github.com/helix-editor/helix/pull/9604))
- Switch to a streaming regex engine (regex-cursor crate) to significantly speed up regex-based commands and features ([#9422](https://github.com/helix-editor/helix/pull/9422), [#9756](https://github.com/helix-editor/helix/pull/9756), [#9891](https://github.com/helix-editor/helix/pull/9891))
Fixes:
- Swap `*` and `+` registers ([#8703](https://github.com/helix-editor/helix/pull/8703), [#8708](https://github.com/helix-editor/helix/pull/8708))
- Use terminfo to reset terminal cursor style ([#8591](https://github.com/helix-editor/helix/pull/8591))
- Fix precedence of `@align` captures in indentat computation ([#8659](https://github.com/helix-editor/helix/pull/8659))
- Only render the preview if a Picker has a preview function ([#8667](https://github.com/helix-editor/helix/pull/8667))
- Fix the precedence of `ui.virtual.whitespace` ([#8750](https://github.com/helix-editor/helix/pull/8750), [#8879](https://github.com/helix-editor/helix/pull/8879))
- Fix crash in `:indent-style` ([#9087](https://github.com/helix-editor/helix/pull/9087))
- Fix `didSave` text inclusion when sync capability is a kind variant ([#9101](https://github.com/helix-editor/helix/pull/9101))
- Update the history of newly focused views ([#9271](https://github.com/helix-editor/helix/pull/9271))
- Initialize diagnostics when opening a document ([#8873](https://github.com/helix-editor/helix/pull/8873))
- Sync views when applying edits to unfocused views ([#9173](https://github.com/helix-editor/helix/pull/9173))
- This fixes crashes that could occur from LSP workspace edits or `:write-all`.
- Treat non-numeric `+arg`s passed in the CLI args as filenames ([#9333](https://github.com/helix-editor/helix/pull/9333))
- Fix crash when using `mm` on an empty plaintext file ([2fb7e50](https://github.com/helix-editor/helix/commit/2fb7e50))
- Ignore empty tree-sitter nodes in match bracket ([445f7a2](https://github.com/helix-editor/helix/commit/445f7a2))
- Exit a language server if it sends a message with invalid JSON ([#9332](https://github.com/helix-editor/helix/pull/9332))
- Handle failures to enable bracketed paste ([#9353](https://github.com/helix-editor/helix/pull/9353))
- Gate all captures in a pattern behind `#is-not? local` predicates ([#9390](https://github.com/helix-editor/helix/pull/9390))
- Make path changes LSP spec conformant ([#8949](https://github.com/helix-editor/helix/pull/8949))
- Use range positions to determine `insert_newline` motion ([#9448](https://github.com/helix-editor/helix/pull/9448))
- Fix division by zero when prompt completion area is too small ([#9524](https://github.com/helix-editor/helix/pull/9524))
- Add changes to history in clipboard replacement typable commands ([#9625](https://github.com/helix-editor/helix/pull/9625))
- Fix a crash in DAP with an unspecified `line` in breakpoints ([#9632](https://github.com/helix-editor/helix/pull/9632))
- Fix space handling for filenames in bash completion ([#9702](https://github.com/helix-editor/helix/pull/9702), [#9708](https://github.com/helix-editor/helix/pull/9708))
- Key diagnostics off of paths instead of LSP URIs ([#7367](https://github.com/helix-editor/helix/pull/7367))
- Fix panic when using `join_selections_space` ([#9783](https://github.com/helix-editor/helix/pull/9783))
- Fix panic when using `surround_replace`, `surround_delete` ([#9796](https://github.com/helix-editor/helix/pull/9796))
- Fix panic in `surround_replace`, `surround_delete` with nested surrounds and multiple cursors ([#9815](https://github.com/helix-editor/helix/pull/9815))
- Fix panic in `select_textobject_around` ([#9832](https://github.com/helix-editor/helix/pull/9832))
- Don't stop reloading documents when reloading fails in `:reload-all` ([#9870](https://github.com/helix-editor/helix/pull/9870))
- Prevent `shell_keep_pipe` from stopping on nonzero exit status codes ([#9817](https://github.com/helix-editor/helix/pull/9817))
@ -68,6 +68,7 @@ Its settings will be merged with the configuration directory `config.toml` and t
| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
| `insert-final-newline` | Whether to automatically insert a trailing line-ending on write if missing | `true` |
| `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` |
| `popup-border` | Draw border around `popup`, `menu`, `all`, or `none` | `none` |
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
| `indent-heuristic` | How the indentation for a newly inserted line is computed: `simple` just copies the indentation level from the previous line, `tree-sitter` computes the indentation based on the syntax tree and `hybrid` combines both approaches. If the chosen heuristic is not available, a different one will be used as a fallback (the fallback order being `hybrid` -> `tree-sitter` -> `simple`). | `hybrid`
| `jump-label-alphabet` | The characters that are used to generate two character jump labels. Characters at the start of the alphabet are used first. | `"abcdefghijklmnopqrstuvwxyz"`
### `[editor.statusline]` Section
### `[editor.statusline]` Section
@ -75,7 +76,7 @@ Allows configuring the statusline at the bottom of the editor.
The configuration distinguishes between three areas of the status line:
The configuration distinguishes between three areas of the status line:
`[ ... ... LEFT ... ... | ... ... ... ... CENTER ... ... ... ... | ... ... RIGHT ... ... ]`
`[ ... ... LEFT ... ... | ... ... ... CENTER ... ... ... | ... ... RIGHT ... ... ]`
Statusline elements can be defined as follows:
Statusline elements can be defined as follows:
@ -178,7 +179,7 @@ All git related options are only enabled in a git repository.
|`max-depth` | Set with an integer value for maximum depth to recurse | Defaults to `None`.
|`max-depth` | Set with an integer value for maximum depth to recurse | Unset by default
Ignore files can be placed locally as `.ignore` or put in your home directory as `~/.ignore`. They support the usual ignore and negative ignore (unignore) rules used in `.gitignore` files.
Ignore files can be placed locally as `.ignore` or put in your home directory as `~/.ignore`. They support the usual ignore and negative ignore (unignore) rules used in `.gitignore` files.
@ -224,7 +225,7 @@ Additionally, this setting can be used in a language config. Unless
the editor setting is `false`, this will override the editor config in
the editor setting is `false`, this will override the editor config in
documents with this language.
documents with this language.
Example `languages.toml` that adds <> and removes ''
Example `languages.toml` that adds `<>` and removes `''`
```toml
```toml
[[language]]
[[language]]
@ -254,8 +255,8 @@ Options for rendering whitespace with visible characters. Use `:set whitespace.r
| Key | Description | Default |
| Key | Description | Default |
|-----|-------------|---------|
|-----|-------------|---------|
| `render` | Whether to render whitespace. May either be `"all"` or `"none"`, or a table with sub-keys `space`, `nbsp`, `tab`, and `newline` | `"none"` |
| `render` | Whether to render whitespace. May either be `all` or `none`, or a table with sub-keys `space`, `nbsp`, `nnbsp`, `tab`, and `newline` | `none` |
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `newline` or `tabpad` | See example below |
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `nnbsp`, `newline` or `tabpad` | See example below |
Example
Example
@ -266,11 +267,14 @@ render = "all"
[editor.whitespace.render]
[editor.whitespace.render]
space = "all"
space = "all"
tab = "all"
tab = "all"
nbsp = "none"
nnbsp = "none"
newline = "none"
newline = "none"
[editor.whitespace.characters]
[editor.whitespace.characters]
space = "·"
space = "·"
nbsp = "⍽"
nbsp = "⍽"
nnbsp = "␣"
tab = "→"
tab = "→"
newline = "⏎"
newline = "⏎"
tabpad = "·" # Tabs will look like "→···" (depending on tab width)
tabpad = "·" # Tabs will look like "→···" (depending on tab width)
> 💡 Mappings marked (**TS**) require a tree-sitter grammar for the file type.
> 💡 Mappings marked (**TS**) require a tree-sitter grammar for the file type.
> ⚠️ Some terminals' default key mappings conflict with Helix's. If any of the mappings described on this page do not work as expected, check your terminal's mappings to ensure they do not conflict. See the (wiki)[https://github.com/helix-editor/helix/wiki/Terminal-Support] for known conflicts.
## Normal mode
## Normal mode
Normal mode is the default mode when you launch helix. You can return to it from other modes by pressing the `Escape` key.
Normal mode is the default mode when you launch helix. You can return to it from other modes by pressing the `Escape` key.
@ -49,7 +51,7 @@ Normal mode is the default mode when you launch helix. You can return to it from
@ -150,6 +150,8 @@ They have to be defined in the `[language-server]` table as described in the pre
Different languages can use the same language server instance, e.g. `typescript-language-server` is used for javascript, jsx, tsx and typescript by default.
Different languages can use the same language server instance, e.g. `typescript-language-server` is used for javascript, jsx, tsx and typescript by default.
The definition order of language servers affects the order in the results list of code action menu.
In case multiple language servers are specified in the `language-servers` attribute of a `language`,
In case multiple language servers are specified in the `language-servers` attribute of a `language`,
it's often useful to only enable/disable certain language-server features for these language servers.
it's often useful to only enable/disable certain language-server features for these language servers.
/// If this method is called, all documents that have a reference to language servers used by the language config have to refresh their language servers,
/// If this method is called, all documents that have a reference to language servers used by the language config have to refresh their language servers,