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

Enter in insert mode should auto indent to scope #6939

Closed
tqwewe opened this issue May 2, 2023 · 10 comments
Closed

Enter in insert mode should auto indent to scope #6939

tqwewe opened this issue May 2, 2023 · 10 comments
Labels
A-indent Area: Indentation C-enhancement Category: Improvements

Comments

@tqwewe
Copy link

tqwewe commented May 2, 2023

When in insert mode, pressing enter to go to a new line places the cursor at the very start of the line, but it would be nice if the cursor automatically inserted indentations to match the scope.

Helix current behaviour

    // ...
    view! { cx,
|
^ cursor placed here
    }

VSCode behaviour

    // ...
    view! { cx,
        |
        ^ cursor placed here
    }

Additionally, when closing a scope in helix, the closing bracket is placed where the cursor is, but in VSCode it auto indents/dedents to put the closing bracket in the correct location.

Helix

} is inserted at the same location as the cursor.

simplescreenrecorder.mp4

VSCode

} is inserted at the correct indentation, despite the cursor position.

simplescreenrecorder-.2.mp4
@tqwewe tqwewe added the C-enhancement Category: Improvements label May 2, 2023
@kirawi
Copy link
Member

kirawi commented May 2, 2023

Partial duplicate of #6044

@kirawi kirawi marked this as a duplicate of #6044 May 2, 2023
@kirawi kirawi closed this as not planned Won't fix, can't repro, duplicate, stale May 2, 2023
@kirawi
Copy link
Member

kirawi commented May 2, 2023

Helix should automatically indent the line when inserting it, is your runtime setup correctly?
Run hx --health <LANG>

@tqwewe
Copy link
Author

tqwewe commented May 3, 2023

It's sad to see this closed. My helix health is all green for Rust.
I see the the second point of my issue is a duplicate, but isn't the first one still a valid issue?

Indentation almost works correctly when using o and O, but when already in insert mode and pressing enter, then it seems to go to the start of the line.

I say almost because when working with the view macro in rust, it jumps to the left most indentation of the macro with o, whereas VSCode places the curor directly next to the other html elements.

Helix

    view! { cx,
        <div>
            <hr />
    |
    ^ cursor placed here with `o`
        </div>
    }

VSCode

    view! { cx,
        <div>
            <hr />
            |
            ^ cursor placed here with `enter`
        </div>
    }

When working with longer nested html, it can be quite annoying having to press o and then tab many times to get back to the correct indentation.

@kirawi
Copy link
Member

kirawi commented May 3, 2023

Both the behavior of enter and o should be identical because they call the same underlying function. I'm actually not able to reproduce the behavior you're experiencing,

    view! { cx,
        <div>
            <hr />
        |
        ^ cursor here
        </div>
    }

I think the reason for this is that Helix will try to parse the macro as Rust and apply Rust indentation rules. @Triton171 what do you think might be happening here?

@gabydd
Copy link
Member

gabydd commented May 3, 2023

for the html indentation looking at this: tree-sitter/tree-sitter-rust#172 we probably would need an injection for html which makes sense.

Regarding your original issue that is weird cause I am also developing with leptos using helix and the first part of the view! macro indents properly, of course the rest does not cause as of now we don't have an injection for html in rust. The injection would have to be a bit complex cause not only would you need to inject html into the view macro you would also have to inject rust into the non html parts.

Though maybe there is a way to get the indent to be the same as the line before it, instead of the injection stuff.

@kirawi kirawi reopened this May 3, 2023
@tqwewe
Copy link
Author

tqwewe commented May 3, 2023

Hmm I'm very curious how VSCode is doing this... I just opened a new plaintext file with VScode, and the indentation behavior is still working nicely with the view macro.
I don't think VSCode uses the lsp for the indentation here, and simply follows the indentation of the line above.

@Triton171
Copy link
Contributor

I think there's 2 ways this could be improved:

  1. Of course the best solution would be an injection query for html as @gabydd mentioned. However, the indentation system currently doesn't support injections, so this would have to be added as well. In principle, it shouldn't be too difficult but it might require refactoring parts of the indent code.
  2. While injections can solve this specific use case, I think this is an example of a more general issue where our indentation system is sometimes not as robust as it could be. In VSCode, the indentation is computed is essentially computed by taking the indentation of the previous line and adding/subtracting 1 if specific patterns (such as {) are found. This means that even if these patterns are incorrect, the indentation will always roughly match the indentation of the previous line.
    In Helix, the indentation is computed just by looking at the syntax tree. This is in some sense more exact than only looking for specific regexes. However, if a node in the syntax tree that spans many lines is indented by 1 but Helix incorrectly thinks it shouldn't be (for example because it's an HTML macro in rust which it doesn't understand) this causes all lines contained in this node to be indented 1 less than they should be. Another example of this is C/C++ namespace incorrect indentation #6235.
    We could improve this by always computing the indentation for both the new line and the line above (using our current indent queries), taking the difference and adding it to the actual indentation of the line above. For the example of HTML macros in rust, this would give a new line inside such a macro the same indentation as the line above.

I'd like to implement the second solution, but since there's currently 2 open PRs changing the indent code (#6768 and #5355), I'd prefer to get those merged before making additional changes to the indent heuristic. Otherwise, we'll just get unnecessary merge conflicts.

@shahamran
Copy link

@Triton171, since #6768 and #5355 are merged, do you plan to implement the improvement you mentioned? Or are there more pressing issues?

I'm really glad to see this focus and discussion on indentation issues, as it's my main annoyance with Helix at the moment (which otherwise is really good).

And of course, thanks a lot for making such an amazing tool.

@Triton171
Copy link
Contributor

Yeah, this is the next issue I want to work on in Helix. I'll probably be busy in the next few weeks, but I'll start implementing it once I find some spare time. It's non-trivial though and there are still a few things to figure out:

I initially thought that we could just compare the indentation to the previous line. Having thought a bit more about it, this is probably not the best way to do it. For example, in the following C++ code we'd ideally use the start of the function call (i.e. the second line) as a baseline for indentation, since the following lines are aligned and provide no useful information on the indent level. In general, one could maybe choose the first predecessor or ancestor that starts at the beginning of a line but I'm not sure if this is always what we want (we should maybe also take into account @extend patterns).

int main() {
    some_fn_with_many_args(std::string arg1,
                           std::vector<int> arg2,
                           unsigned long long arg2); // Assume that we want to insert a newline after this
}

Also, comparing indents is not always feasible, especially when things like alignment are involved (as in the example above). If anyone has thoughts on these issues, please let me know, fresh ideas are always helpful.

@pascalkuthe
Copy link
Member

Addressed by #8307

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-indent Area: Indentation C-enhancement Category: Improvements
Projects
None yet
Development

No branches or pull requests

6 participants