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

Continue single comment #10996

Open
wants to merge 51 commits into
base: master
Choose a base branch
from

Conversation

TornaxO7
Copy link
Contributor

Closes #1730

Continues #8664

This is my attempt to apply the changes of #4718 to the PR.

@TornaxO7
Copy link
Contributor Author

TornaxO7 commented Jun 20, 2024

One thing which bothers me is how we want to "continue" the comment from block comments like for C of this style:

/*
 * | <-- let's say here's the cursor, how should we "recognize" this `*`? Adding another entry in `language.toml` per language which should indicate which "multiblock-continuity" there are?
 */

Should this be tackled in this PR or in another PR? Should this be tackled at all?

@kirawi kirawi added the A-core Area: Helix core improvements label Jun 21, 2024
@TornaxO7
Copy link
Contributor Author

TornaxO7 commented Aug 7, 2024

I don't see it as a must for this PR but definitly would be nice to have

I think, I'd like to create a followup PR for block comments after I'm done with this.

@TornaxO7 TornaxO7 marked this pull request as ready for review August 9, 2024 22:11
@TornaxO7 TornaxO7 marked this pull request as draft August 9, 2024 22:15
@TornaxO7 TornaxO7 marked this pull request as ready for review August 10, 2024 08:08
@TornaxO7 TornaxO7 marked this pull request as draft August 10, 2024 08:12
@TornaxO7 TornaxO7 marked this pull request as ready for review August 10, 2024 08:29
@the-mikedavis the-mikedavis added S-waiting-on-review Status: Awaiting review from a maintainer. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 11, 2024
/// Returns the matching comment token of the given line (if it exists).
pub fn get_comment_token<'a>(
text: &Rope,
tokens: Option<&'a Vec<String>>,
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should be trying to continue comments if a language doesn't configure comment token(s). Similarly I'm not sure we should be doing anything when using C-c on plaintext or a language that doesn't define comments. I think it's fine if this feature doesn't work on plaintext.

Copy link
Member

Choose a reason for hiding this comment

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

So instead this parameter can be &'a [String]


/// Returns the matching comment token of the given line (if it exists).
pub fn get_comment_token<'a>(
text: &Rope,
Copy link
Member

Choose a reason for hiding this comment

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

This can take a RopeSlice directly rather than a &Rope

.unwrap_or(DEFAULT_COMMENT_TOKEN);

for token in tokens {
let (is_commented, _, _, _) = find_line_comment(token, text, [line_num]);
Copy link
Member

Choose a reason for hiding this comment

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

find_line_comment does a fair amount of work that isn't necessary here (discarded with the _s). I think it's fine to not reuse that function and have the relevant parts of the implementation inline:

/// Returns the longest matching comment token of the given line (if it exists).
pub fn get_comment_token<'a>(
    text: RopeSlice,
    tokens: &'a [String],
    line_num: usize,
) -> Option<&'a str> {
    let mut result = None;
    let line = text.line(line_num);
    let start = line.char_to_byte(line.first_non_whitespace_char()?);
    for token in tokens {
        let end = std::cmp::min(start + token.len(), line.len_bytes());
        let fragment = Cow::from(line.byte_slice(start..end));
        if fragment == *token {
            result = Some(token.as_str());
        }
    }
    result
}

@@ -3391,16 +3391,17 @@ fn open(cx: &mut Context, open: Open) {
enter_insert_mode(cx);
let (view, doc) = current!(cx.editor);

let text = doc.text().slice(..);
let config = doc.config.load();
let doc_text = doc.text().slice(..);
Copy link
Member

Choose a reason for hiding this comment

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

The rename here isn't necessary, can be reset

@@ -342,6 +346,9 @@ pub struct Config {
deserialize_with = "deserialize_alphabet"
)]
pub jump_label_alphabet: Vec<char>,
/// Whether to prepend a comment token onto a new line that follows a commented line. (default: false)
#[serde(default = "default_continue_comments")]
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
#[serde(default = "default_continue_comments")]

This doesn't need a default directive for serde since Default for Config is implemented manually.

Also the doc here is outdated that the default is false. This should also be added to the book

I wonder if this needs to be configurable at all? I'm not sure it's configurable in Kakoune for example

Comment on lines +3428 to +3435
let comment_token = {
let tokens = doc
.language_config()
.and_then(|config| config.comment_tokens.as_ref());

get_comment_token(doc.text(), tokens, cursor_line)
};
let new_line_will_be_comment = config.continue_comments && comment_token.is_some();
Copy link
Member

Choose a reason for hiding this comment

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

We can clean this up a bit to both signal that we will be continuing the comment and carry the comment token:

let continue_comment_token = if config.continue_comments {
    doc.language_config()
        .and_then(|config| config.comment_tokens.as_ref())
        .and_then(|tokens| comment::get_comment_token(text, tokens, cursor_line))
} else {
    None
};

then in the match below we check if continue_comment_token.is_some() instead

Comment on lines +3437 to +3438
let indent = {
let line = doc_text.line(cursor_line);
Copy link
Member

Choose a reason for hiding this comment

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

style nit: we try to avoid using blocks for bindings like this. It's fine for line to escape into the outer scope

@@ -3459,6 +3483,9 @@ fn open(cx: &mut Context, open: Open) {
transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));

doc.apply(&transaction, view.id);

// Since we might have added a comment token, move to the end of the line.
goto_line_end_newline(cx);
Copy link
Member

Choose a reason for hiding this comment

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

Rather than jumping to the end of the line we should update the selection ranges based on how much we're inserting in the block above with the "calculate new selection ranges" comment. I think the final formula there should be pos + (i * (1 + indent_len + comment_len)) + indent_len + comment_len where comment_len is

let comment_len = continue_comment_token.map(|token| token.len() + 1).unwrap_or_default();

(+ 1 for the extra space added).

@@ -3886,6 +3914,14 @@ pub mod insert {

let mut new_text = String::new();

let comment_token = {
Copy link
Member

Choose a reason for hiding this comment

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

Similar here

let continue_comment_token = if config.continue_comments {
    doc.language_config()
        .and_then(|config| config.comment_tokens.as_ref())
        .and_then(|tokens| comment::get_comment_token(text, tokens, current_line))
} else {
    None
};

@@ -3916,18 +3958,30 @@ pub mod insert {
.map_or(false, |pair| pair.open == prev && pair.close == curr);

let local_offs = if on_auto_pair {
Copy link
Member

Choose a reason for hiding this comment

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

We can add an extra block to special case comment continuing here:

let local_offs = if let Some(token) = continue_comment_token {
    // insert the line ending, then indent then token then ' '
} else if on_auto_pair() {
    // unchanged
} else {
    // unchanged
}

and switch on_auto_pair to be a closure that takes no arguments - that way we avoid computing it if we're continuing a comment

@the-mikedavis the-mikedavis added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from a maintainer. labels Oct 3, 2024
@the-mikedavis
Copy link
Member

I'm not sure how much extra work it would be (maybe belongs in a follow-up PR) but it would be nice to have a way to not continue a comment. You might want to add an uncommented line after a commented line and with this change you need to go to the next line and use O rather than using o on the commented line. I think it would be handy if the first Enter (or o) continued the comment and then a second Enter removed the comment token and trailing ' '.

@pascalkuthe
Copy link
Member

I'm not sure how much extra work it would be (maybe belongs in a follow-up PR) but it would be nice to have a way to not continue a comment. You might want to add an uncommented line after a commented line and with this change you need to go to the next line and use O rather than using o on the commented line. I think it would be handy if the first Enter (or o) continued the comment and then a second Enter removed the comment token and trailing ' '.

Maybe a dedicated command/jeybinding (kaklune tends to use alt based bindings like a-o for stuff like this) you work.

This requires either adding state or doing this for every commented line which would be surprising. Also I often have empty lines in doc comments (like writing code inside markdown doc comments) so that would get annoying there

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 S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Continue comments
5 participants