-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Continue comments when opening a new line #1937
Conversation
b6ea4db
to
3f0dbe1
Compare
helix-term/src/commands.rs
Outdated
let token = doc | ||
.language_config() | ||
.and_then(|lc| lc.comment_token.as_ref()) | ||
.map(|tc| tc.as_ref()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to move this to a new method since this code is duplicated 3 times. Where do you suggest we put it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest moving it to a new separate helper function residing in the same module. You could make it return an Option<()>
to get rid of all the and_then
and map
s.
3f0dbe1
to
99f66c6
Compare
helix-term/src/commands.rs
Outdated
let token = doc | ||
.language_config() | ||
.and_then(|lc| lc.comment_token.as_ref()) | ||
.map(|tc| tc.as_ref()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest moving it to a new separate helper function residing in the same module. You could make it return an Option<()>
to get rid of all the and_then
and map
s.
helix-core/src/comment.rs
Outdated
@@ -94,6 +96,24 @@ pub fn toggle_line_comments(doc: &Rope, selection: &Selection, token: Option<&st | |||
Transaction::change(doc, changes.into_iter()) | |||
} | |||
|
|||
/// Return token if the current line is commented. | |||
/// Otherwise, return None. | |||
pub fn continue_comment<'a>(doc: &Rope, line: usize, token: Option<&'a str>) -> Option<&'a str> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes more sense for this to return a bool since we already have the token in the calling code and continue_comment
doesn't change it in any way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would require to unwrap()
the token, though. Do you still want me to do this change?
helix-core/src/comment.rs
Outdated
.map(|pos| { | ||
let len = line_slice.len_chars(); | ||
// line can be shorter than pos + token len | ||
let fragment = Cow::from(line_slice.slice(pos..std::cmp::min(pos + token.len(), len))); | ||
fragment == token | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map(|pos| { | |
let len = line_slice.len_chars(); | |
// line can be shorter than pos + token len | |
let fragment = Cow::from(line_slice.slice(pos..std::cmp::min(pos + token.len(), len))); | |
fragment == token | |
}) | |
.map(|pos| Cow::from(line_slice.slice(pos..)).starts_with(token)) |
I converted to a draft because that doesn't support doc-comment. Any idea on how we want to do this? Do we want to add the doc-comment syntax in That would require a list as there can be |
We could extend Actually, an easier way would be: find a comment (
would produce Block commentsIt's okay to solve block comments later since none of the functions have support for this yet. Some bits and ideas: VSCode's config seems to have two separate blocks for line & block comments:
and here's the algorithms in codemirror: https://github.com/codemirror/comment/blob/269b9af21d68b1a71fa40bbf6c1e41c665e6e7d0/src/comment.ts#L48-L161= The initial implementation for line comments in helix was based on the functions in ^ |
I thought about this, but that wouldn't work: you could have a shebang in bash and you don't want to have Edit: for the shebang, vim does not continue the comment. Any way we could do the same? If I go with |
Yeah let's go with the simple approach for now and only resume exact matches?
You'll need to manually update the file, it's user-maintained. I'd also order the |
Since I have to edit the The problem I have is I don't know if there's a way to distinguish between a block-comment vs a line-comment. Do we have a way to know whether a cursor is within a block-comment? |
You could match this via tree-sitter queries, usually line comments vs block comments use different node types. For a more generic system we'd need to immitate https://github.com/codemirror/comment/blob/269b9af21d68b1a71fa40bbf6c1e41c665e6e7d0/src/comment.ts#L88-L120= then fallback to line comments |
I'm not familiar with tree-sitter. It seems to use strings to identify node: is this correct? My attempt at using |
Using tree-sitter node names might actually not work out very well since different grammars use different names for the comment nodes ( |
By that, do you mean that I should add a line like:
in Or should those captures already exist? |
I think something like that should work. It would be on a per-language basis though and I'm not sure how many languages have comment captures. I think it's ok if there's fallback behavior (even it the fallback behavior is just to not continue comments) for languages that don't have textobjects queries. |
99f66c6
to
a6d1db4
Compare
So, I started adding the missing tree-sitter objects and config for some languages and I wanted to have some feedback before I continue doing it for all the other languages. Also, I have an issue: it seems like tree-sitter doesn't consider the start of a comment to be a non-terminating comment, which means I cannot continue them completely. Thanks for your help! |
runtime/queries/rust/textobjects.scm
Outdated
@@ -33,3 +33,5 @@ | |||
(line_comment)+ @comment.around | |||
|
|||
(block_comment) @comment.around | |||
|
|||
(block_comment) @comment.block.around |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The textobject captures don't distinguish block vs line or other types of comments currently. Adding a .block. in the middle could be good, but existing code to handle textobject selection may need to be adjusted. @sudormrfbin what do you think?
Actually wondering if we add this to indents.scm instead, since it's kind of related functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second look at indents.scm, I don't think it'll work there easily. Textobjects is probably the best place unless we want a comments.scm specifically for this feature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but existing code to handle textobject selection may need to be adjusted
Why would it need to be adjusted? It continues using @comment.around
and that still works.
I'm not sure I understand everything this file does, but I was under the impression that I only added a new capture named @comment.block.around
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I missed the fact that you added a new capture instead of changing it, my bad! That is effectively adding a whole new capture, which is a good idea. I would maybe drop the 'around' and make up a new one like 'continue'. I'm wondering again in this light of this belongs in the indents.scm queries, since it would be a whole new capture name and wouldn't affect either existing implementations (indent or textobject).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this particular case that second block_comment
one overrides the first. You could have both captures like
(block_comment) @comment.around @comment.block.around
So, for the case of continuing start of comment, I had the following idea: |
I think it would be good to have an auto-pairs functionality for the block comment tokens, like HTML |
Do you suggest that it's OK that it's not reliable or would you prefer a workaround? |
It would probably be ok in most cases but it would be prone to edge-cases. I would prefer a workaround since I don't use auto-pairs myself but I don't have any good ideas for doing it efficiently. In any case, I think block comments should be handled in a separate PR as you say in the initial description. There are other block comment features like surrounding a selection with a block comment that might inform the design of continuing block comments. Line comment continuation would be a great increment on its own (although I'm biased because I mostly use languages that only have line comments). |
Are you suggesting we keep the block comment as is in this PR and I'll fix them in a later PR?
I disagree because we probably don't want a surrounding feature to add a |
I would prefer splitting the block comments entirely to another PR if possible since that implementation needs some design. |
Is this PR abandoned? |
No, I just haven't got the time to clean it up. I'll probably have time to do that in a couple months. |
I switched back to neovim, so I won't be updating this PR anymore. Feel free to take the changes and make another PR. |
Fix #1730.
We probably want to be able to configure whether we want this or not. If so, what option name do you propose?
This does not support continuing block comment, i.e. adding a
*
when a comment starts with/*
. I propose we do this in a future PR since this would require some more thought regarding the block comment token (i.e. do we want to add it tolanguages.toml
?).