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

Command to hard-wrap selected text. #625

Closed
cessen opened this issue Aug 19, 2021 · 10 comments · Fixed by #2128
Closed

Command to hard-wrap selected text. #625

cessen opened this issue Aug 19, 2021 · 10 comments · Fixed by #2128
Labels
A-tree-sitter Area: Tree-sitter C-enhancement Category: Improvements

Comments

@cessen
Copy link
Contributor

cessen commented Aug 19, 2021

Often when writing code you want to hard-wrap your text to a maximum line-width. A command to re-wrap selected text would be great for that purpose.

Personally, I find myself mostly wanting to do this in code comments, more than in the code itself (which is often better handled by auto-formatters). So I would suggest supporting re-wrapping of code comments as a first-class aspect of this feature.

@cessen cessen added the C-enhancement Category: Improvements label Aug 19, 2021
@sudormrfbin
Copy link
Member

So I would suggest supporting re-wrapping of code comments as a first-class aspect of this feature.

A tree sitter based text object for comments would help here, and I was thinking of adding other objects too (functions, classes, etc).

@cessen
Copy link
Contributor Author

cessen commented Aug 20, 2021

Is that necessary? If we can keep the code relatively self-contained without bringing in too many other APIs, I think that would be preferable. Scanning for blocks of commented lines isn't much work, and we'll need to do scanning anyway to detect e.g. indentation level, paragraph breaks denoted by blank commented lines, etc.

I can see possibly wanting to use tree sitter for multi-line comments (e.g. /* like this */), except in general they don't need special handling: they can be re-wrapped like normal text.

I guess if someone has something like this:

/*
 * A multi-line comment where
 * leading asterisks are used
 * to make things prettier.
 */

It might be helpful just for identifying the commented area, but then re-wrapping that as the user probably intends is a whole 'nother can of worms anyway, and I don't know if we want the feature to get that deep in the weeds, with heuristics for all the fancy ways people might format their comments.

@sudormrfbin
Copy link
Member

I was talking about a generic text object for comments that will simply select it and then you can copy, delete, change, etc. I was imagining the hard wrapping command to work on selections, so selecting the comment and then re-wrapping it was the workflow I was comparing it to. But since we have the comment character for each language it should be easy to rewrap all the comments in the file for consecutive single line comments, which is what I think you meant ?

@archseer
Copy link
Member

The flow I had in vim was to make a selection then press Q (should be a different key here since we'll use that for macros) to wrap all the lines in the selection. It's comment aware so that if lines begin with the comment token it'll properly wrap them (prefix new lines with comment tokens).

Should be fairly easy to do with the existing commenting functions (there's one that can detect line comments)

Text objects: I do want to have these for functions, comments etc (mf, mc). We'll need to add a new objects.scm query file that can mark nodes with types (@function, @module, @comment). They aren't necessary for this feature to work, but they compose well together.

@cessen
Copy link
Contributor Author

cessen commented Aug 21, 2021

I was talking about a generic text object for comments that will simply select it and then you can copy, delete, change, etc.

Ah, got it. I thought you were talking about how we would implement this feature, but you're talking about an additional separate-but-complementary feature, right? For conveniently selecting comment blocks?

But since we have the comment character for each language it should be easy to rewrap all the comments in the file for consecutive single line comments, which is what I think you meant?

What I meant was the following: if you have a comment that looks something like this:

    // A comment that has uneven and
    // too-long lines in it.  Now I'm just typing text to make it longer, because there's nothing further useful to say
    // in this comment.

And you select all three lines and run the proposed command from this issue, then you get this:

    // A comment that has uneven and too-long
    // lines in it.  Now I'm just typing text
    // to make it longer, because there's
    // nothing further useful to say in this
    // comment.

In other words, if you've selected consecutive lines of comments, it smartly re-wraps them as a single comment. That's all.

@sudormrfbin
Copy link
Member

Ah, got it. I thought you were talking about how we would implement this feature, but you're talking about an additional separate-but-complementary feature, right? For conveniently selecting comment blocks?

That's exactly what I meant :)

In other words, if you've selected consecutive lines of comments, it smartly re-wraps them as a single comment. That's all.

In that case having a comment text object will make it even easier to do this. I was investigating treesitter text objects before the sticky key PR; I'll see what I can come up with.

@pickfire
Copy link
Contributor

pickfire commented Aug 23, 2021

Kakoune did badly in this. We should take into account with support for multiple types of line comments. Like rust, //, //!, ///, //!!, ////, kakoune can only use external tool and external tools like fmt do not take multiple types of comments into account. Block comment as well but I don't know how to solve /** vs /* issue. Does treesitter have wrapping functions?

@cessen
Copy link
Contributor Author

cessen commented Aug 23, 2021

@pickfire
Definitely agree this should properly account for the different kinds of line comments. Probably it makes sense for each language to have a list of line-comment tokens (e.g. //, ///, //! etc.), and we always try to match the longest ones first when determining what the starting token is. Maybe there are some corner-cases that approach won't 100% handle (I'm not sure), but if there are I suspect they would be weird situations where people should probably fix their formatting anyway.

Block comments (e.g. /* comment */ and similar) probably don't need special handling at all, as mentioned up-thread. We can just re-wrap them as normal text. Although we will want to still preserve indentation, I suspect. But I think that also goes for non-comment text anyway.

@kirawi kirawi added the A-tree-sitter Area: Tree-sitter label Nov 6, 2021
@the-mikedavis the-mikedavis linked a pull request Apr 17, 2022 that will close this issue
@Ablu
Copy link

Ablu commented Apr 25, 2022

Another use case: git commit messages. vim seems to do it by default for those. So I can simply type without needing to remember manually wrapping at the column restriction.

@vlmutolo
Copy link
Contributor

vlmutolo commented Apr 26, 2022

Another use case: git commit messages

This commit doesn't exactly get us on par with vim, since this requires a command to reflow and Helix won't be doing it as you type. That said, both soft wrap and "live-reflowing" are features I'd like to work on. Editing Markdown is kind of terrible without at least one of the two.

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

Successfully merging a pull request may close this issue.

7 participants