diff --git a/helix-core/src/comment.rs b/helix-core/src/comment.rs index 280b7c26dd58d..50a178a930b02 100644 --- a/helix-core/src/comment.rs +++ b/helix-core/src/comment.rs @@ -211,28 +211,33 @@ pub fn toggle_block_comments( Transaction::change(doc, changes.into_iter()) } +pub fn split_lines_of_selection(text: RopeSlice, selection: &Selection) -> Selection { + #[allow(clippy::trivial_regex)] + static REGEX: Lazy = + Lazy::new(|| Regex::new(r"\r\n|[\n\r\u{000B}\u{000C}\u{0085}\u{2028}\u{2029}]").unwrap()); + + selection::split_on_matches( + text, + &selection.clone().transform(|range| { + // extend each line + let (start_line, end_line) = range.line_range(text.slice(..)); + let start = text.line_to_char(start_line); + let end = text.line_to_char((end_line + 1).min(text.len_lines())); + + Range::new(start, end).with_direction(range.direction()) + }), + ®EX, + ) +} + pub fn toggle_block_comments_as_line_fallback( text: &Rope, selection: &Selection, tokens: Option<(&str, &str)>, ) -> Transaction { - #[allow(clippy::trivial_regex)] - static REGEX: Lazy = - Lazy::new(|| Regex::new(r"\r\n|[\n\r\u{000B}\u{000C}\u{0085}\u{2028}\u{2029}]").unwrap()); toggle_block_comments( text, - &selection::split_on_matches( - text.slice(..), - &selection.clone().transform(|range| { - // extend each line - let (start_line, end_line) = range.line_range(text.slice(..)); - let start = text.line_to_char(start_line); - let end = text.line_to_char((end_line + 1).min(text.len_lines())); - - Range::new(start, end).with_direction(range.direction()) - }), - ®EX, - ), + &split_lines_of_selection(text.slice(..), selection), tokens, ) } @@ -260,24 +265,25 @@ pub fn comment_type( lines.extend(start..end); min_next_line = end; } + let split_lines = split_lines_of_selection(text, selection); let (line_commented, block_commented) = match (token, tokens) { - (Some(token), Some(tokens)) => ( - find_line_comment(token, text, lines).0, + (Some(_), Some(tokens)) => ( + find_block_comments(tokens.0, tokens.1, text, &split_lines).0, find_block_comments(tokens.0, tokens.1, text, selection).0, ), (None, None) => ( - find_line_comment("//", text, lines).0, + find_block_comments("/*", "*/", text, &split_lines).0, find_block_comments("/*", "*/", text, selection).0, ), (Some(_), None) => return CommentType::Line, (None, Some(tokens)) => ( - false, + find_block_comments(tokens.0, tokens.1, text, &split_lines).0, find_block_comments(tokens.0, tokens.1, text, selection).0, ), }; if line_commented { - return CommentType::Line; + return CommentType::BlockAsLineFallback; } if block_commented { return CommentType::Block; diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 5cbc78bae8c00..8a13fda64bd55 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -4033,7 +4033,15 @@ pub fn completion(cx: &mut Context) { } // comments -fn toggle_comments(cx: &mut Context) { +fn toggle_comments_impl( + cx: &mut Context, + comment_type: fn( + token: Option<&str>, + tokens: Option<(&str, &str)>, + text: RopeSlice, + selection: &Selection, + ) -> comment::CommentType, +) { let (view, doc) = current!(cx.editor); let token: Option<&str> = doc .language_config() @@ -4044,8 +4052,7 @@ fn toggle_comments(cx: &mut Context) { .and_then(|lc| lc.block_comment_tokens.as_ref()) .map(|tc| (tc.0.as_ref(), tc.1.as_ref())); - let comment_type = - comment::comment_type(token, tokens, doc.text().slice(..), doc.selection(view.id)); + let comment_type = comment_type(token, tokens, doc.text().slice(..), doc.selection(view.id)); let transaction = match comment_type { comment::CommentType::Line => { comment::toggle_line_comments(doc.text(), doc.selection(view.id), token) @@ -4066,28 +4073,22 @@ fn toggle_comments(cx: &mut Context) { exit_select_mode(cx); } -fn toggle_line_comments(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let token = doc - .language_config() - .and_then(|lc| lc.comment_token.as_ref()) - .map(|tc| tc.as_ref()); - let transaction = comment::toggle_line_comments(doc.text(), doc.selection(view.id), token); +fn toggle_comments(cx: &mut Context) { + toggle_comments_impl(cx, comment::comment_type) +} - apply_transaction(&transaction, doc, view); - exit_select_mode(cx); +fn toggle_line_comments(cx: &mut Context) { + toggle_comments_impl(cx, |token, tokens, _, _| match (token, tokens) { + (None, Some(_)) => comment::CommentType::BlockAsLineFallback, + _ => comment::CommentType::Line, + }); } fn toggle_block_comments(cx: &mut Context) { - let (view, doc) = current!(cx.editor); - let tokens = doc - .language_config() - .and_then(|lc| lc.block_comment_tokens.as_ref()) - .map(|tc| (tc.0.as_ref(), tc.1.as_ref())); - let transaction = comment::toggle_block_comments(doc.text(), doc.selection(view.id), tokens); - - apply_transaction(&transaction, doc, view); - exit_select_mode(cx); + toggle_comments_impl(cx, |token, tokens, _, _| match (token, tokens) { + (Some(_), None) => comment::CommentType::Line, + _ => comment::CommentType::Block, + }); } fn rotate_selections(cx: &mut Context, direction: Direction) {