Release 24.03 Highlights
The Helix 24.03 release has arrived! First, a very big thank you to everyone who made this release possible. This release saw changes from 125 contributors.
New to Helix? Helix is a modal text editor with built-in support for multiple selections, Language Server Protocol (LSP), tree-sitter, and experimental support for Debug Adapter Protocol (DAP).
Let's check out this release's highlights.
Amp-like jumping
Jumping features are popular in the (Neo)Vim plugin space and there are even
plugins to add the same functionality to other tools like browsers. They allow
you to move your selection efficiently across even large parts of the view,
like you could by clicking with a mouse, but by entering "labels" instead.
24.03 introduces jumping commands inspired by the Amp editor's jump mode.
Press gw
to add the jump labels and then enter one of the labels to jump to
the word under that label. Using gw
in select mode (v
) extends the
selection.
Block comments
In the past, Helix has only been able to toggle line comments like //
and #
and languages like OCaml have been left with workarounds like a "line" comment
token of (*
. In 24.03 Helix can now toggle block comments as well. Use C-c
or <space>c
to smartly add or remove line or block comments around the current
selection based on the language's comment token configuration, <space>c
to
toggle block comments around the current selection, or <space><A-c>
to toggle
only line comments on the current line.
Improvements to tree-sitter injections
Helix uses tree-sitter
incremental parsing for syntax highlighting,
textobjects, indentation and some motions and commands. 24.03 improves how we
handle injections - a powerful tree-sitter feature for parsing documents
with multiple languages. For example you might have JavaScript, CSS or other
languages within a <script>
or <style>
tag in HTML. The HTML parser doesn't
need to know how to parse all of these languages. Instead it can inject
JavaScript or CSS parsers to handle the <script>
or <style>
tag contents.
One of these improvements is to the :tree-sitter-subtree
command that
displays an S-expression of the syntax tree under the cursor. 24.03 shows the
injection layer under the selection instead of only the root layer. For example
in this asciicast we now show the syntax tree for the JavaScript parts of the
document while in the past we only showed the HTML part of the tree.
The other big improvement is to the tree-sitter motions. A-o
(alt + o)
expands the selection to the parent node of the syntax tree node covered by the
current selection. A-i
shrinks to the child node and A-n
and A-p
go to
the next and previous nodes, respectively. Previously these
commands only worked on the root layer (for example HTML in the asciicast) but
they now find the injection layer that contains the selection and move along
that layer's syntax tree. Internally we organize injection layers into a
tree-like structure so that these motions can switch layers when needed.
Stay tuned for future changes that improve injections, like finding textobjects within injected content.
Internal improvements
24.03 also saw major internal improvements. The first comes from a new "event system" - a system built around Tokio channels and tasks that allows different parts of the Helix codebase to communicate with one another. The event system also adds generic ways to debounce and run tasks in background threads so we can prevent locking up the UI. Some parts of the code base have already been migrated to the event system like LSP completion and signature-help. In 24.03 you'll notice that LSP completion doesn't automatically pop up after just navigating around in insert mode, for example with arrow keys. It's now hooked into document changes instead, so it can smartly pop up when you start changing a document rather than every time the editor goes idle.
The other major improvement to be excited for is the general replacement of the
regex
crate with regex-cursor
, a streaming regex implementation
compatible with ropey
, the rope crate we use to represent all documents.
regex-cursor
is capable of running on discontiguous strings - input that
may not be collocated in memory. In a rope, different parts of the document
might be stored separately internally. To use the regex
API we needed to
convert slices of the document to a regular Rust String
, duplicating the
memory footprint of that slice of the document. regex-cursor
operates on the
chunks of the rope instead, which greatly improves efficiency.
Wrapping up
As always, this is just the highlights from the 24.03 release. Check out the full changelog for the details.
Come chat about usage and development questions in the Matrix space and follow along with Helix's development in the GitHub repository.