Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix python indentation #3382

Merged
merged 7 commits into from
Oct 11, 2022
Merged

Conversation

Triton171
Copy link
Contributor

This introduces 2 new capture types for indent queries. With this, the python indent queries have been improved and re-enabled. It should fix most of the issues from #763. We still don't update the indentation retroactively, so there is still some room for improvements:

if condition:
    do_smth()
    else:

Here the else should ideally be outdented automatically, once one has finished typing it. This is tricky for 2 reasons:

  • We have to figure out when and for which lines to run indentation queries. For performance reasons, we don't want to do it too often and it also shouldn't "correct" the indentation after the user has manually changed it.
  • With python, the tree-sitter grammar doesn't even recognize the else statement since it is indented (see the discussion in Python file indentation is wrong #763). Either the tree-sitter grammar needs to improve here or we need a special case to recognize this and similar situations.

If you have ideas for this, please let me know. Also, if there's other languages than python that can be fixed with the new captures (i.e. languages where functions, classes, etc. end simply where the indentation level decreases), I'm happy to update them as well

Triton171 added 3 commits August 10, 2022 14:12
Improve and re-enable python indent queries.
Document @extend-indented and @stop-extend captures for indent queries.
@the-mikedavis the-mikedavis self-requested a review August 10, 2022 14:31
@AceofSpades5757
Copy link
Contributor

It's also causing an issue where it'll automatically update at the line before indentation, such as if you put your cursor at the beginning of if condition: in your example and press enter to move it down a line.

P.S. This may have also been in the current implementation. I don't usually code Python with Helix due to the really annoying indentation issues. And thanks for your work!

@Triton171
Copy link
Contributor Author

@AceofSpades5757 good find! The issue already existed in the old version but it's a somewhat rare edge case, so that's probably why it hasn't popped up before. The latest commit should fix it.

@AceofSpades5757
Copy link
Contributor

No problem. I've had this version installed while working with Python to test it out. Python is a real sore spot for Helix. It feels like I'm constantly fighting it.

Hopefully this PR will be able to change that 😄

@AceofSpades5757
Copy link
Contributor

This has been working pretty well, except for an issue where dedenting with < will be multiple indents rather than a single one. It sounds like some other people have this happen with other languages as well.

@Triton171
Copy link
Contributor Author

That's interesting, the code for dedenting is pretty simple and doesn't use the indentation heuristic. If you can reproduce this, it'd probably be best to create a new issue for this.

@AceofSpades5757
Copy link
Contributor

@Triton171 I haven't been able to reproduce it and I've been using it pretty extensively. I may have accidentally re-installed master as my default Helix. Everything has been going swimmingly recently but if something reproducible comes up, I'll comment here (or make a new issue).

@Dispersia
Copy link
Contributor

Dispersia commented Sep 5, 2022

Scala has the same issue, and this appears to work mostly correct for it too, though I am getting a strange behavior

When trying to add the indent functionality to scala's indents.scm, i'm currently adding

[
    (function_definition)
    (val_definition)
] @extend-indented

with just this, it seems to work correctly, however when trying to add stop-extend

[
    (identifier)
] @stop-extend

it seems to not work at all and was like its previous behavior. Even having an empty @stop-extend like [ ] @stop-extend does this, which I would expect does nothing

@Triton171
Copy link
Contributor Author

Triton171 commented Sep 5, 2022

Could you provide an example where the current indentation for Scala is incorrect? I'm not familiar with the language but from a quick look it seems like Scala uses blocks (delimited by curly braces) to define the range of functions. Because of this, I don't think we need @extend-indented here. Adding (function_definition) @extend-indented would cause indented lines that come after the function definition to be considered part of the function, which is incorrect in this case.

EDIT: I just saw that Scala 3 has multi-line methods without blocks. In this case, we do need the @extend-indented the way you used it. The issue with your @stop-extend query is that not every identifier marks the end of a function. I think we only need to add "}" @stop-extend, which should prevent any issues with the block syntax. We can't use stop-extend the same way I did for Python since Scala doesn't have a dedicated return statement.

I'm also not sure if the Tree-Sitter grammar actually supports multi-line methods: Judging from the syntax highlighting and the :tree-sitter-scopes command, there seems to be some weirdness going on there (the val keyword is parsed as an identifier). Maybe you could check that this actually works correctly. I have never used Scala so maybe I'm just misinterpreting something about the syntax.

@Dispersia
Copy link
Contributor

Dispersia commented Sep 5, 2022

No you're correct, that syntax for scala 3 is new and not supported by the current tree-sitter syntax, I will be working on that next, I'm just trying to get it to work for what is the current scala 2+ syntax. In scala, you will typically write a one line function as lamda's in C#, something like

val mappedUnit =
    ZIO.succeed(ZStream.fromStream(stream))

etc, where its identifier will go on a new line, not on its current, so it should always be indented. If the user chooses to wrap it in a block, e.g.

val mappedUnit = {
    ZIO.succeed(ZStream.fromStream(stream))
}

it should still count as only one indentation, which is what currently happens correctly. However, when I add even an empty stop-extend, the original extend-indented stops working completely, if I put that line at all in the indents file the val mappedUnit =\n doesn't indent anymore (or if i put a random value, just incase it doesn't like being empty). I am trying to make it work like how current neovim does, which will end the indentation after the first line with a new identifier, effectively making the first statement "return" even if it isnt.

How I might try to achieve this in the long run is the last identifier for tree-sitter will be replaced with a wrapped return type, and then i could do that behavior in here, but im more worried about the common case (as multi line blocks for classes/objects/functions/vals aren't common yet)

@Triton171
Copy link
Contributor Author

The weird behavior with @stop-extend happens because you're writing an invalid indent query: Tree-Sitter doesn't allow empty alternations (for a description of the query syntax, see their documentation). Unfortunately, this currently fails silently and simply uses the fallback method of copying the indentation of the current line.

For getting the indentation right, you should definitely try to improve the Tree-Sitter grammar before tinkering with it in Helix. Once multiline functions are parsed correctly, you could also use something like (function_definition (identifier) @stop-extend), which would only match an identifier node nested directly inside a function. This prevents e.g. an identifier that's part of an assignment expression to be matched. Basically, you have to think about what exactly makes an expression a "return expression" after which the function ends. Tree-Sitter queries are surprisingly powerful, so once you have an idea of what exactly you want in your head, it often isn't too difficult to write a query for it.

If you manage to fix the grammar and need help with indent queries in Helix, feel free to ping me.

@kirawi kirawi added A-tree-sitter Area: Tree-sitter A-core Area: Helix core improvements S-waiting-on-review Status: Awaiting review from a maintainer. labels Sep 13, 2022
@the-mikedavis
Copy link
Member

Unfortunately, this currently fails silently and simply uses the fallback method of copying the indentation of the current line.

Recently we added an error log message for this. There isn't a visual indication as there is for syntax highlighting (i.e. no highlights) but you should be able to find out if your indent queries are invalid either by checking the log file or running cargo xtask query-check if you are building from source and the modified injections are under this repo's runtime/ dir

Comment on lines 516 to 541
// The query range should intersect with all nodes directly preceding
// the cursor in case one of them is extended.
// prev_child is the deepest such node.
let (query_range, prev_child) = {
// TODO Is there some way we can reuse this cursor?
let mut tree_cursor = node.walk();
let mut prev_child = None;
for child in node.children(&mut tree_cursor) {
if child.byte_range().end <= byte_pos {
prev_child = Some(child);
}
}
match prev_child {
Some(mut prev_child) => {
// Get the deepest directly preceding node
while prev_child.child_count() > 0 {
prev_child = prev_child.child(prev_child.child_count() - 1).unwrap();
}
(
prev_child.byte_range().end - 1..byte_pos + 1,
Some(prev_child),
)
}
None => (byte_pos..byte_pos + 1, None),
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this block can be simplified a bit - query_range can be calculated after prev_child is determined with a map+unwrap_or. So the whole let (query_range, prev_child) is not needed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I also noticed that the treesitter parser was borrowed unnecessarily early, so I fixed that too.

Comment on lines 49 to 60
- `@extend-indented`:
Extend the range of this node to the end of the line and to lines that
are indented more than the line that this node starts on. This is useful
for languages like Python, where for the purpose of indentation some nodes
(like functions or classes) should also contain indented lines that follow them.

- `@stop-extend`:
Prevents the first extension of an ancestor of this node. For example, in Python
a return expression always ends the block that it is in. Note that this only prevents
the next extension of one ancestor: If multiple ancestors can be extended (for example
multiple nested conditional blocks in python), only the extension of the innermost
ancestor is prevented.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the names could use some workshopping - I like "extend" but @stop-extend doesn't convey well that it only stops the extension once

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe @indent.extend and then @indent.extend.pause? Or @extend and @extend.pause-once? I also liked "after" from the discussion in the issue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@extend sounds good. In case we add more "extend" captures types, we can still rename it to something more specific later. Maybe @extend.prevent-once is a more accurate description of what the other capture does? Or @extend.end-once?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a question as a reader, why is it called @extend.prevent-once? More specifically, I'm not sure I understand how it is semantically "once". If I understand correctly, the capture type is supposed to convey that the extended range of the most immediate ancestor ends. Would @extend.end-immediate-ancestor be more apt albeit verbose?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the wording in the docs might be a bit confusing: It prevents the first extension of an ancestor, but this ancestor doesn't necessarily have to be immediate. Rather, this refers to the first ancestor that is captured by an @extend capture.

The last sentence in the docs ("All other ancestors are unaffected (regardless of whether the innermost ancestor would actually have been extended)") could probably be explained a bit better. What it means is that the first ancestor that is captured by an @extend may not actually cause any extension (for example because the lines after it are not indented enough). In this case, @extend.prevent-once "prevents" this extension, but since the extension wouldn't have happened anyways, it has no effect. In particular, if some more distant ancestor is actually extended, this extension is not prevented.

For python, these subtleties don't really make a difference but I still think it's important to document them, since for other languages they might be important. If you find a better name than @extend.prevent-once or a better wording for the docs, feel free to open a PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thank you for the explanation! So technically, we can say the most immediate ancestor captured by @extend capture.

Would it be easier to simply think of @extend and @extend.prevent-once as opposite operations, like opening and closing parentheses? We could then rename them into @extend.begin-once and @extend.end-once, or @extend.open and @extend.close to emphasize this; something with symmetry in the naming. Is this a correct characterization?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@extend and @extend.prevent-once are sort of opposites but it's not completely symmetric. With parentheses, there's usually exactly one closing parenthesis for each opening parenthesis. Here, this is not the case: There can be multiple @extend captures without any @extend.prevent-once (in which case the innermost one takes precedence) and there might be multiple @extend.prevent-once captures without any @extend (although they have no effect in this situation). Also, the @extend.prevent-once doesn't appear after the @extend but rather as a descendant of it, in other words, it is contained in it.

I'm not sure if there is a better name for this, but the documentation could definitely be improved. Maybe a link to the python indent queries could also be helpful as an example for how to use the captures in practice.


// Check for extend captures (starting with the deepest
// candidate node and then going up the syntax tree).
if let Some(mut prev_child) = prev_child {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block is a bit long and seems to be somewhat well-contained. It may clean this function up a bit to split this into its own function. This function is already quite large and hard to follow

Comment on lines +50 to +51
Extend the range of this node to the end of the line and to lines that
are indented more than the line that this node starts on. This is useful
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious if we can fork tree-sitter-python and have the function_definition and other rules that end in : consume the newline. That way the cursor would belong to the indented node and I think we might not need the extend system. I'll try it out

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the behavior would need to be a bit more complicated: It doesn't just have to consume the newline but also any following indented lines. Additionally, this should not happen when the function ends with for example a return expression.

If all this was implemented in the grammar, it would make this PR redundant but I'm not sure if it's worth the effort of forking the tree-sitter grammars for all languages that are affected by this.

Split extend logic into a separate file.
This improves the behavior in case of multiple nested extensions.
@Triton171
Copy link
Contributor Author

I've found an additional issue when there are multiple nested @extend-indented nodes:

def func():
    if condition:
        return
    | # <--- Cursor

In this situation, pressing enter would result in a line that's not indented at all. This happens since we're not inside the if_statement, so the extension prevented by the return_statement is the extension of the function. The latest commit slightly changes the behavior of the @stop-extend capture to fix this.

@archseer archseer mentioned this pull request Sep 18, 2022
// the cursor in case one of them is extended.
let mut deepest_preceding = None; // The deepest node preceding the cursor
let mut tree_cursor = node.walk();
for child in node.children(&mut tree_cursor) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this is probably just due to unfamiliarity, but I'm not understanding how you can have the cursor on a node with children that happen before the cursor. Could you please give an example of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my comments are somewhat misleading: By "cursor" I mean the position of the indent query (not the tree-sitter cursor). Usually, this will just be the position of the text cursor when starting a new line. I'll change the comments to clarify that.

An example then looks like this:

def func(): # <-- The function_definition node ends here
    
    # <--- The indent is queried for this position

The function_definition node ends before the position of the indent query (but since it directly precedes the query position, it is considered for extension).

Clarify comments in indent code.
Copy link
Member

@archseer archseer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this! There's been a few testers that are using this branch already so I think this is fine to merge 🎉

@archseer archseer merged commit 0813276 into helix-editor:master Oct 11, 2022
netbsd-srcmastr pushed a commit to NetBSD/pkgsrc that referenced this pull request Dec 7, 2022
Rework the pkgsrc infrastructure to simplify tree-sitter-depends.mk, rewrite
the awk script to simplify things and support regular awk, and put it in the
usual place.  Also add support for Darwin (where this was tested).

# 22.12 (2022-12-06)

This is a great big release filled with changes from a 99 contributors. A big _thank you_ to you all!

As usual, the following is a summary of each of the changes since the last release.
For the full log, check out the [git log](https://github.com/helix-editor/helix/compare/22.08.1..22.12).

Breaking changes:

- Remove readline-like navigation bindings from the default insert mode keymap ([e12690e](helix-editor/helix@e12690e), [#3811](helix-editor/helix#3811), [#3827](helix-editor/helix#3827), [#3915](helix-editor/helix#3915), [#4088](helix-editor/helix#4088))
- Rename `append_to_line` as `insert_at_line_end` and `prepend_to_line` as `insert_at_line_start` ([#3753](helix-editor/helix#3753))
- Swap diagnostic picker and debug mode bindings in the space keymap ([#4229](helix-editor/helix#4229))
- Select newly inserted text on paste or from shell commands ([#4458](helix-editor/helix#4458), [#4608](helix-editor/helix#4608), [#4619](helix-editor/helix#4619), [#4824](helix-editor/helix#4824))
- Select newly inserted surrounding characters on `ms<char>` ([#4752](helix-editor/helix#4752))
- Exit select-mode after executing `replace_*` commands ([#4554](helix-editor/helix#4554))
- Exit select-mode after executing surround commands ([#4858](helix-editor/helix#4858))
- Change tree-sitter text-object keys ([#3782](helix-editor/helix#3782))
- Rename `fleetish` theme to `fleet_dark` ([#4997](helix-editor/helix#4997))

Features:

- Bufferline ([#2759](helix-editor/helix#2759))
- Support underline styles and colors ([#4061](helix-editor/helix#4061), [98c121c](helix-editor/helix@98c121c))
- Inheritance for themes ([#3067](helix-editor/helix#3067), [#4096](helix-editor/helix#4096))
- Cursorcolumn ([#4084](helix-editor/helix#4084))
- Overhauled system for writing files and quiting ([#2267](helix-editor/helix#2267), [#4397](helix-editor/helix#4397))
- Autosave when terminal loses focus ([#3178](helix-editor/helix#3178))
- Use OSC52 as a fallback for the system clipboard ([#3220](helix-editor/helix#3220))
- Show git diffs in the gutter ([#3890](helix-editor/helix#3890), [#5012](helix-editor/helix#5012), [#4995](helix-editor/helix#4995))
- Add a logo ([dc1ec56](helix-editor/helix@dc1ec56))
- Multi-cursor completion ([#4496](helix-editor/helix#4496))

Commands:

- `file_picker_in_current_directory` (`<space>F`) ([#3701](helix-editor/helix#3701))
- `:lsp-restart` to restart the current document's language server ([#3435](helix-editor/helix#3435), [#3972](helix-editor/helix#3972))
- `join_selections_space` (`A-j`) which joins selections and selects the joining whitespace ([#3549](helix-editor/helix#3549))
- `:update` to write the current file if it is modified ([#4426](helix-editor/helix#4426))
- `:lsp-workspace-command` for picking LSP commands to execute ([#3140](helix-editor/helix#3140))
- `extend_prev_word_end` - the extend variant for `move_prev_word_end` ([7468fa2](helix-editor/helix@7468fa2))
- `make_search_word_bounded` which adds regex word boundaries to the current search register value ([#4322](helix-editor/helix#4322))
- `:reload-all` - `:reload` for all open buffers ([#4663](helix-editor/helix#4663), [#4901](helix-editor/helix#4901))
- `goto_next_change` (`]g`), `goto_prev_change` (`[g`), `goto_first_change` (`[G`), `goto_last_change` (`]G`) textobjects for jumping between VCS changes ([#4650](helix-editor/helix#4650))

Usability improvements and fixes:

- Don't log 'LSP not defined' errors in the logfile ([1caba2d](helix-editor/helix@1caba2d))
- Look for the external formatter program before invoking it ([#3670](helix-editor/helix#3670))
- Don't send LSP didOpen events for documents without URLs ([44b4479](helix-editor/helix@44b4479))
- Fix off-by-one in `extend_line_above` command ([#3689](helix-editor/helix#3689))
- Use the original scroll offset when opening a split ([1acdfaa](helix-editor/helix@1acdfaa))
- Handle auto-formatting failures and save the file anyway ([#3684](helix-editor/helix#3684))
- Ensure the cursor is in view after `:reflow` ([#3733](helix-editor/helix#3733))
- Add default rulers and reflow config for git commit messages ([#3738](helix-editor/helix#3738))
- Improve grammar fetching and building output ([#3773](helix-editor/helix#3773))
- Add a `text` language to language completion ([cc47d3f](helix-editor/helix@cc47d3f))
- Improve error handling for `:set-language` ([e8add6f](helix-editor/helix@e8add6f))
- Improve error handling for `:config-reload` ([#3668](helix-editor/helix#3668))
- Improve error handling when passing improper ranges to syntax highlighting ([#3826](helix-editor/helix#3826))
- Render `<code>` tags as raw markup in markdown ([#3425](helix-editor/helix#3425))
- Remove border around the LSP code-actions popup ([#3444](helix-editor/helix#3444))
- Canonicalize the path to the runtime directory ([#3794](helix-editor/helix#3794))
- Add a `themelint` xtask for linting themes ([#3234](helix-editor/helix#3234))
- Re-sort LSP diagnostics after applying transactions ([#3895](helix-editor/helix#3895), [#4319](helix-editor/helix#4319))
- Add a command-line flag to specify the log file ([#3807](helix-editor/helix#3807))
- Track source and tag information in LSP diagnostics ([#3898](helix-editor/helix#3898), [1df32c9](helix-editor/helix@1df32c9))
- Fix theme returning to normal when exiting the `:theme` completion ([#3644](helix-editor/helix#3644))
- Improve error messages for invalid commands in the keymap ([#3931](helix-editor/helix#3931))
- Deduplicate regexs in `search_selection` command ([#3941](helix-editor/helix#3941))
- Split the finding of LSP root and config roots ([#3929](helix-editor/helix#3929))
- Ensure that the cursor is within view after auto-formatting ([#4047](helix-editor/helix#4047))
- Add pseudo-pending to commands with on-next-key callbacks ([#4062](helix-editor/helix#4062), [#4077](helix-editor/helix#4077))
- Add live preview to `:goto` ([#2982](helix-editor/helix#2982))
- Show regex compilation failure in a popup ([#3049](helix-editor/helix#3049))
- Add 'cycled to end' and 'no more matches' for search ([#3176](helix-editor/helix#3176), [#4101](helix-editor/helix#4101))
- Add extending behavior to tree-sitter textobjects ([#3266](helix-editor/helix#3266))
- Add `ui.gutter.selected` option for themes ([#3303](helix-editor/helix#3303))
- Make statusline mode names configurable ([#3311](helix-editor/helix#3311))
- Add a statusline element for total line count ([#3960](helix-editor/helix#3960))
- Add extending behavior to `goto_window_*` commands ([#3985](helix-editor/helix#3985))
- Fix a panic in signature help when the preview is too large ([#4030](helix-editor/helix#4030))
- Add command names to the command palette ([#4071](helix-editor/helix#4071), [#4223](helix-editor/helix#4223), [#4495](helix-editor/helix#4495))
- Find the LSP workspace root from the current document's path ([#3553](helix-editor/helix#3553))
- Add an option to skip indent-guide levels ([#3819](helix-editor/helix#3819), [2c36e33](helix-editor/helix@2c36e33))
- Change focus to modified docs on quit ([#3872](helix-editor/helix#3872))
- Respond to `USR1` signal by reloading config ([#3952](helix-editor/helix#3952))
- Exit gracefully when the close operation fails ([#4081](helix-editor/helix#4081))
- Fix goto/view center mismatch ([#4135](helix-editor/helix#4135))
- Highlight the current file picker document on idle-timeout ([#3172](helix-editor/helix#3172), [a85e386](helix-editor/helix@a85e386))
- Apply transactions to jumplist selections ([#4186](helix-editor/helix#4186), [#4227](helix-editor/helix#4227), [#4733](helix-editor/helix#4733), [#4865](helix-editor/helix#4865), [#4912](helix-editor/helix#4912), [#4965](helix-editor/helix#4965), [#4981](helix-editor/helix#4981))
- Use space as a separator for fuzzy matcher ([#3969](helix-editor/helix#3969))
- Overlay all diagnostics with highest severity on top ([#4113](helix-editor/helix#4113))
- Avoid re-parsing unmodified tree-sitter injections ([#4146](helix-editor/helix#4146))
- Add extending captures for indentation, re-enable python indentation ([#3382](helix-editor/helix#3382), [3e84434](helix-editor/helix@3e84434))
- Only allow either `--vsplit` or `--hsplit` CLI flags at once ([#4202](helix-editor/helix#4202))
- Fix append cursor location when selection anchor is at the end of the document ([#4147](helix-editor/helix#4147))
- Improve selection yanking message ([#4275](helix-editor/helix#4275))
- Log failures to load tree-sitter grammars as errors ([#4315](helix-editor/helix#4315))
- Fix rendering of lines longer than 65,536 columns ([#4172](helix-editor/helix#4172))
- Skip searching `.git` in `global_search` ([#4334](helix-editor/helix#4334))
- Display tree-sitter scopes in a popup ([#4337](helix-editor/helix#4337))
- Fix deleting a word from the end of the buffer ([#4328](helix-editor/helix#4328))
- Pretty print the syntax tree in `:tree-sitter-subtree` ([#4295](helix-editor/helix#4295), [#4606](helix-editor/helix#4606))
- Allow specifying suffixes for file-type detection ([#2455](helix-editor/helix#2455), [#4414](helix-editor/helix#4414))
- Fix multi-byte auto-pairs ([#4024](helix-editor/helix#4024))
- Improve sort scoring for LSP code-actions and completions ([#4134](helix-editor/helix#4134))
- Fix the handling of quotes within shellwords ([#4098](helix-editor/helix#4098))
- Fix `delete_word_backward` and `delete_word_forward` on newlines ([#4392](helix-editor/helix#4392))
- Fix 'no entry found for key' crash on `:write-all` ([#4384](helix-editor/helix#4384))
- Remove lowercase requirement for tree-sitter grammars ([#4346](helix-editor/helix#4346))
- Resolve LSP completion items on idle-timeout ([#4406](helix-editor/helix#4406), [#4797](helix-editor/helix#4797))
- Render diagnostics in the file picker preview ([#4324](helix-editor/helix#4324))
- Fix terminal freezing on `shell_insert_output` ([#4156](helix-editor/helix#4156))
- Allow use of the count in the repeat operator (`.`) ([#4450](helix-editor/helix#4450))
- Show the current theme name on `:theme` with no arguments ([#3740](helix-editor/helix#3740))
- Fix rendering in very large terminals ([#4318](helix-editor/helix#4318))
- Sort LSP preselected items to the top of the completion menu ([#4480](helix-editor/helix#4480))
- Trim braces and quotes from paths in goto-file ([#4370](helix-editor/helix#4370))
- Prevent automatic signature help outside of insert mode ([#4456](helix-editor/helix#4456))
- Fix freezes with external programs that process stdin and stdout concurrently ([#4180](helix-editor/helix#4180))
- Make `scroll` aware of tabs and wide characters ([#4519](helix-editor/helix#4519))
- Correctly handle escaping in `command_mode` completion ([#4316](helix-editor/helix#4316), [#4587](helix-editor/helix#4587), [#4632](helix-editor/helix#4632))
- Fix `delete_char_backward` for paired characters ([#4558](helix-editor/helix#4558))
- Fix crash from two windows editing the same document ([#4570](helix-editor/helix#4570))
- Fix pasting from the blackhole register ([#4497](helix-editor/helix#4497))
- Support LSP insertReplace completion items ([1312682](helix-editor/helix@1312682))
- Dynamically resize the line number gutter width ([#3469](helix-editor/helix#3469))
- Fix crash for unknown completion item kinds ([#4658](helix-editor/helix#4658))
- Re-enable `format_selections` for single selection ranges ([d4f5cab](helix-editor/helix@d4f5cab))
- Limit the number of in-progress tree-sitter query matches ([#4707](helix-editor/helix#4707), [#4830](helix-editor/helix#4830))
- Use the special `#` register with `increment`/`decrement` to change by range number ([#4418](helix-editor/helix#4418))
- Add a statusline element to show number of selected chars ([#4682](helix-editor/helix#4682))
- Add a statusline element showing global LSP diagnostic warning and error counts ([#4569](helix-editor/helix#4569))
- Add a scrollbar to popups ([#4449](helix-editor/helix#4449))
- Prefer shorter matches in fuzzy matcher scoring ([#4698](helix-editor/helix#4698))
- Use key-sequence format for command palette keybinds ([#4712](helix-editor/helix#4712))
- Remove prefix filtering from autocompletion menu ([#4578](helix-editor/helix#4578))
- Focus on the parent buffer when closing a split ([#4766](helix-editor/helix#4766))
- Handle language server termination ([#4797](helix-editor/helix#4797), [#4852](helix-editor/helix#4852))
- Allow `r`/`t`/`f` to work on tab characters ([#4817](helix-editor/helix#4817))
- Show a preview for scratch buffers in the buffer picker ([#3454](helix-editor/helix#3454))
- Set a limit of entries in the jumplist ([#4750](helix-editor/helix#4750))
- Re-use shell outputs when inserting or appending shell output ([#3465](helix-editor/helix#3465))
- Check LSP server provider capabilities ([#3554](helix-editor/helix#3554))
- Improve tree-sitter parsing performance on files with many language layers ([#4716](helix-editor/helix#4716))
- Move indentation to the next line when using `<ret>` on a line with only whitespace ([#4854](helix-editor/helix#4854))
- Remove selections for closed views from all documents ([#4888](helix-editor/helix#4888))
- Improve performance of the `:reload` command ([#4457](helix-editor/helix#4457))
- Properly handle media keys ([#4887](helix-editor/helix#4887))
- Support LSP diagnostic data field ([#4935](helix-editor/helix#4935))
- Handle C-i keycode as tab ([#4961](helix-editor/helix#4961))
- Fix view alignment for jumplist picker jumps ([#3743](helix-editor/helix#3743))
- Use OSC52 for tmux clipboard provider ([#5027](helix-editor/helix#5027))

Themes:

- Add `varua` ([#3610](helix-editor/helix#3610), [#4964](helix-editor/helix#4964))
- Update `boo_berry` ([#3653](helix-editor/helix#3653))
- Add `rasmus` ([#3728](helix-editor/helix#3728))
- Add `papercolor_dark` ([#3742](helix-editor/helix#3742))
- Update `monokai_pro_spectrum` ([#3814](helix-editor/helix#3814))
- Update `nord` ([#3792](helix-editor/helix#3792))
- Update `fleetish` ([#3844](helix-editor/helix#3844), [#4487](helix-editor/helix#4487), [#4813](helix-editor/helix#4813))
- Update `flatwhite` ([#3843](helix-editor/helix#3843))
- Add `darcula` ([#3739](helix-editor/helix#3739))
- Update `papercolor` ([#3938](helix-editor/helix#3938), [#4317](helix-editor/helix#4317))
- Add bufferline colors to multiple themes ([#3881](helix-editor/helix#3881))
- Add `gruvbox_dark_hard` ([#3948](helix-editor/helix#3948))
- Add `onedarker` ([#3980](helix-editor/helix#3980), [#4060](helix-editor/helix#4060))
- Add `dark_high_contrast` ([#3312](helix-editor/helix#3312))
- Update `bogster` ([#4121](helix-editor/helix#4121), [#4264](helix-editor/helix#4264))
- Update `sonokai` ([#4089](helix-editor/helix#4089))
- Update `ayu_*` themes ([#4140](helix-editor/helix#4140), [#4109](helix-editor/helix#4109), [#4662](helix-editor/helix#4662), [#4764](helix-editor/helix#4764))
- Update `everforest` ([#3998](helix-editor/helix#3998))
- Update `monokai_pro_octagon` ([#4247](helix-editor/helix#4247))
- Add `heisenberg` ([#4209](helix-editor/helix#4209))
- Add `bogster_light` ([#4265](helix-editor/helix#4265))
- Update `pop-dark` ([#4323](helix-editor/helix#4323))
- Update `rose_pine` ([#4221](helix-editor/helix#4221))
- Add `kanagawa` ([#4300](helix-editor/helix#4300))
- Add `hex_steel`, `hex_toxic` and `hex_lavendar` ([#4367](helix-editor/helix#4367), [#4990](helix-editor/helix#4990))
- Update `tokyonight` and `tokyonight_storm` ([#4415](helix-editor/helix#4415))
- Update `gruvbox` ([#4626](helix-editor/helix#4626))
- Update `dark_plus` ([#4661](helix-editor/helix#4661), [#4678](helix-editor/helix#4678))
- Add `zenburn` ([#4613](helix-editor/helix#4613), [#4977](helix-editor/helix#4977))
- Update `monokai_pro` ([#4789](helix-editor/helix#4789))
- Add `mellow` ([#4770](helix-editor/helix#4770))
- Add `nightfox` ([#4769](helix-editor/helix#4769), [#4966](helix-editor/helix#4966))
- Update `doom_acario_dark` ([#4979](helix-editor/helix#4979))
- Update `autumn` ([#4996](helix-editor/helix#4996))
- Update `acme` ([#4999](helix-editor/helix#4999))
- Update `nord_light` ([#4999](helix-editor/helix#4999))
- Update `serika_*` ([#5015](helix-editor/helix#5015))

LSP configurations:

- Switch to `openscad-lsp` for OpenScad ([#3750](helix-editor/helix#3750))
- Support Jsonnet ([#3748](helix-editor/helix#3748))
- Support Markdown ([#3499](helix-editor/helix#3499))
- Support Bass ([#3771](helix-editor/helix#3771))
- Set roots configuration for Elixir and HEEx ([#3917](helix-editor/helix#3917), [#3959](helix-editor/helix#3959))
- Support Purescript ([#4242](helix-editor/helix#4242))
- Set roots configuration for Julia ([#4361](helix-editor/helix#4361))
- Support D ([#4372](helix-editor/helix#4372))
- Increase default language server timeout for Julia ([#4575](helix-editor/helix#4575))
- Use ElixirLS for HEEx ([#4679](helix-editor/helix#4679))
- Support Bicep ([#4403](helix-editor/helix#4403))
- Switch to `nil` for Nix ([433ccef](helix-editor/helix@433ccef))
- Support QML ([#4842](helix-editor/helix#4842))
- Enable auto-format for CSS ([#4987](helix-editor/helix#4987))
- Support CommonLisp ([4176769](helix-editor/helix@4176769))

New languages:

- SML ([#3692](helix-editor/helix#3692))
- Jsonnet ([#3714](helix-editor/helix#3714))
- Godot resource ([#3759](helix-editor/helix#3759))
- Astro ([#3829](helix-editor/helix#3829))
- SSH config ([#2455](helix-editor/helix#2455), [#4538](helix-editor/helix#4538))
- Bass ([#3771](helix-editor/helix#3771))
- WAT (WebAssembly text format) ([#4040](helix-editor/helix#4040), [#4542](helix-editor/helix#4542))
- Purescript ([#4242](helix-editor/helix#4242))
- D ([#4372](helix-editor/helix#4372), [#4562](helix-editor/helix#4562))
- VHS ([#4486](helix-editor/helix#4486))
- KDL ([#4481](helix-editor/helix#4481))
- XML ([#4518](helix-editor/helix#4518))
- WIT ([#4525](helix-editor/helix#4525))
- ENV ([#4536](helix-editor/helix#4536))
- INI ([#4538](helix-editor/helix#4538))
- Bicep ([#4403](helix-editor/helix#4403), [#4751](helix-editor/helix#4751))
- QML ([#4842](helix-editor/helix#4842))
- CommonLisp ([4176769](helix-editor/helix@4176769))

Updated languages and queries:

- Zig ([#3621](helix-editor/helix#3621), [#4745](helix-editor/helix#4745))
- Rust ([#3647](helix-editor/helix#3647), [#3729](helix-editor/helix#3729), [#3927](helix-editor/helix#3927), [#4073](helix-editor/helix#4073), [#4510](helix-editor/helix#4510), [#4659](helix-editor/helix#4659), [#4717](helix-editor/helix#4717))
- Solidity ([20ed8c2](helix-editor/helix@20ed8c2))
- Fish ([#3704](helix-editor/helix#3704))
- Elixir ([#3645](helix-editor/helix#3645), [#4333](helix-editor/helix#4333), [#4821](helix-editor/helix#4821))
- Diff ([#3708](helix-editor/helix#3708))
- Nix ([665e27f](helix-editor/helix@665e27f), [1fe3273](helix-editor/helix@1fe3273))
- Markdown ([#3749](helix-editor/helix#3749), [#4078](helix-editor/helix#4078), [#4483](helix-editor/helix#4483), [#4478](helix-editor/helix#4478))
- GDScript ([#3760](helix-editor/helix#3760))
- JSX and TSX ([#3853](helix-editor/helix#3853), [#3973](helix-editor/helix#3973))
- Ruby ([#3976](helix-editor/helix#3976), [#4601](helix-editor/helix#4601))
- R ([#4031](helix-editor/helix#4031))
- WGSL ([#3996](helix-editor/helix#3996), [#4079](helix-editor/helix#4079))
- C# ([#4118](helix-editor/helix#4118), [#4281](helix-editor/helix#4281), [#4213](helix-editor/helix#4213))
- Twig ([#4176](helix-editor/helix#4176))
- Lua ([#3552](helix-editor/helix#3552))
- C/C++ ([#4079](helix-editor/helix#4079), [#4278](helix-editor/helix#4278), [#4282](helix-editor/helix#4282))
- Cairo ([17488f1](helix-editor/helix@17488f1), [431f9c1](helix-editor/helix@431f9c1), [09a6df1](helix-editor/helix@09a6df1))
- Rescript ([#4356](helix-editor/helix#4356))
- Zig ([#4409](helix-editor/helix#4409))
- Scala ([#4353](helix-editor/helix#4353), [#4697](helix-editor/helix#4697), [#4701](helix-editor/helix#4701))
- LaTeX ([#4528](helix-editor/helix#4528), [#4922](helix-editor/helix#4922))
- SQL ([#4529](helix-editor/helix#4529))
- Python ([#4560](helix-editor/helix#4560))
- Bash/Zsh ([#4582](helix-editor/helix#4582))
- Nu ([#4583](helix-editor/helix#4583))
- Julia ([#4588](helix-editor/helix#4588))
- Typescript ([#4703](helix-editor/helix#4703))
- Meson ([#4572](helix-editor/helix#4572))
- Haskell ([#4800](helix-editor/helix#4800))
- CMake ([#4809](helix-editor/helix#4809))
- HTML ([#4829](helix-editor/helix#4829), [#4881](helix-editor/helix#4881))
- Java ([#4886](helix-editor/helix#4886))
- Go ([#4906](helix-editor/helix#4906), [#4969](helix-editor/helix#4969), [#5010](helix-editor/helix#5010))
- CSS ([#4882](helix-editor/helix#4882))
- Racket ([#4915](helix-editor/helix#4915))
- SCSS ([#5003](helix-editor/helix#5003))

Packaging:

- Filter relevant source files in the Nix flake ([#3657](helix-editor/helix#3657))
- Build a binary for `aarch64-linux` in the release CI ([038a91d](helix-editor/helix@038a91d))
- Build an AppImage for `aarch64-linux` in the release CI ([b738031](helix-editor/helix@b738031))
- Enable CI builds for `riscv64-linux` ([#3685](helix-editor/helix#3685))
- Support preview releases in CI ([0090a2d](helix-editor/helix@0090a2d))
- Strip binaries built in CI ([#3780](helix-editor/helix#3780))
- Fix the development shell for the Nix Flake on `aarch64-darwin` ([#3810](helix-editor/helix#3810))
- Raise the MSRV and create an MSRV policy ([#3896](helix-editor/helix#3896), [#3913](helix-editor/helix#3913), [#3961](helix-editor/helix#3961))
- Fix Fish completions for `--config` and `--log` flags ([#3912](helix-editor/helix#3912))
- Use builtin filenames option in Bash completion ([#4648](helix-editor/helix#4648))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-core Area: Helix core improvements A-tree-sitter Area: Tree-sitter S-waiting-on-review Status: Awaiting review from a maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants