feat: block comment toggle and single line comment toggle

pull/12759/head
Nikita Revenco 2025-02-01 20:53:07 +00:00 committed by Nik Revenco
parent 544e460ac4
commit 371dec3774
2 changed files with 151 additions and 112 deletions

View File

@ -303,9 +303,9 @@ pub fn create_block_comment_transaction(
#[must_use] #[must_use]
pub fn toggle_block_comments( pub fn toggle_block_comments(
doc: &Rope, doc: &Rope,
selection: &Selection, ranges: &Vec<Range>,
tokens: &[BlockCommentToken], tokens: &[BlockCommentToken],
) -> Transaction { ) -> Vec<Change> {
todo!() todo!()
// let text = doc.slice(..); // let text = doc.slice(..);
// let (commented, comment_changes) = find_block_comments(tokens, text, selection); // let (commented, comment_changes) = find_block_comments(tokens, text, selection);
@ -390,7 +390,7 @@ mod test {
range = range.map(transaction.changes()); range = range.map(transaction.changes());
assert_eq!(doc, " 1\n\n 2\n 3"); assert_eq!(doc, " 1\n\n 2\n 3");
assert!(range.len() == 1); // to ignore the selection unused warning assert_eq!(range, range); // to ignore the selection unused warning
} }
#[test] #[test]
@ -404,92 +404,95 @@ mod test {
range = range.map(transaction.changes()); range = range.map(transaction.changes());
assert_eq!(doc, " 1\n\n 2\n 3"); assert_eq!(doc, " 1\n\n 2\n 3");
assert!(range.len() == 1); // to ignore the selection unused warning assert_eq!(range, range); // to ignore the selection unused warning
} }
// #[test] #[test]
// fn uncomment_0_margin_comments_with_no_space() { fn uncomment_0_margin_comments_with_no_space() {
// let mut doc = Rope::from("#"); let mut doc = Rope::from("#");
// let mut selection = Selection::single(0, doc.len_chars() - 1); let mut range = Range::new(0, doc.len_chars() - 1);
// let transaction = toggle_line_comments(&doc, &selection, None); let changes = toggle_line_comments(&doc, &range, None);
// transaction.apply(&mut doc); let transaction = Transaction::change(&doc, changes.into_iter());
// selection = selection.map(transaction.changes()); transaction.apply(&mut doc);
// assert_eq!(doc, ""); range = range.map(transaction.changes());
// assert!(selection.len() == 1); // to ignore the selection unused warning assert_eq!(doc, "");
// } assert_eq!(range, range); // to ignore the selection unused warning
// } }
// #[test] #[test]
// fn test_find_block_comments() { fn test_find_block_comments() {
// // three lines 5 characters. // three lines 5 characters.
// let mut doc = Rope::from("1\n2\n3"); let mut doc = Rope::from("1\n2\n3");
// // select whole document // select whole document
// let selection = Selection::single(0, doc.len_chars()); let range = Range::new(0, doc.len_chars());
// let text = doc.slice(..); let text = doc.slice(..);
// let res = find_block_comments(&[BlockCommentToken::default()], text, &selection); let res = find_block_comments(&[BlockCommentToken::default()], text, &vec![range]);
// assert_eq!( assert_eq!(
// res, res,
// ( (
// false, false,
// vec![CommentChange::Uncommented { vec![CommentChange::Uncommented {
// range: Range::new(0, 5), range: Range::new(0, 5),
// start_pos: 0, start_pos: 0,
// end_pos: 4, end_pos: 4,
// start_token: "/*".to_string(), start_token: "/*".to_string(),
// end_token: "*/".to_string(), end_token: "*/".to_string(),
// }] }]
// ) )
// ); );
// // comment // // comment
// let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); // let transaction = toggle_block_comments(&doc, &range, &[BlockCommentToken::default()]);
// transaction.apply(&mut doc); // transaction.apply(&mut doc);
// assert_eq!(doc, "/* 1\n2\n3 */"); // assert_eq!(doc, "/* 1\n2\n3 */");
// // uncomment // // uncomment
// let selection = Selection::single(0, doc.len_chars()); // let selection = Selection::single(0, doc.len_chars());
// let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); // let transaction =
// transaction.apply(&mut doc); // toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]);
// assert_eq!(doc, "1\n2\n3"); // transaction.apply(&mut doc);
// assert_eq!(doc, "1\n2\n3");
// // don't panic when there is just a space in comment // // don't panic when there is just a space in comment
// doc = Rope::from("/* */"); // doc = Rope::from("/* */");
// let selection = Selection::single(0, doc.len_chars()); // let selection = Selection::single(0, doc.len_chars());
// let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); // let transaction =
// transaction.apply(&mut doc); // toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]);
// assert_eq!(doc, ""); // transaction.apply(&mut doc);
// } // assert_eq!(doc, "");
}
// /// Test, if `get_comment_tokens` works, even if the content of the file includes chars, whose /// Test, if `get_comment_tokens` works, even if the content of the file includes chars, whose
// /// byte size unequal the amount of chars /// byte size unequal the amount of chars
// #[test] #[test]
// fn test_get_comment_with_char_boundaries() { fn test_get_comment_with_char_boundaries() {
// let rope = Rope::from("··"); let rope = Rope::from("··");
// let tokens = ["//", "///"]; let tokens = ["//", "///"];
// assert_eq!( assert_eq!(
// super::get_comment_token(rope.slice(..), tokens.as_slice(), 0), super::get_comment_token(rope.slice(..), tokens.as_slice(), 0),
// None None
// ); );
// } }
// /// Test for `get_comment_token`. /// Test for `get_comment_token`.
// /// ///
// /// Assuming the comment tokens are stored as `["///", "//"]`, `get_comment_token` should still /// Assuming the comment tokens are stored as `["///", "//"]`, `get_comment_token` should still
// /// return `///` instead of `//` if the user is in a doc-comment section. /// return `///` instead of `//` if the user is in a doc-comment section.
// #[test] #[test]
// fn test_use_longest_comment() { fn test_use_longest_comment() {
// let text = Rope::from(" /// amogus"); let text = Rope::from(" /// amogus ඞ");
// let tokens = ["///", "//"]; let tokens = ["///", "//"];
// assert_eq!( assert_eq!(
// super::get_comment_token(text.slice(..), tokens.as_slice(), 0), super::get_comment_token(text.slice(..), tokens.as_slice(), 0),
// Some("///") Some("///")
// ); );
}
} }
} }

View File

@ -5174,7 +5174,7 @@ fn toggle_comments_impl<'a>(
exit_select_mode(cx); exit_select_mode(cx);
} }
/// commenting behavior, for each line in selection: /// commenting behavior, for each range in selection:
/// 1. only line comment tokens -> line comment /// 1. only line comment tokens -> line comment
/// 2. each line block commented -> uncomment all lines /// 2. each line block commented -> uncomment all lines
/// 3. whole selection block commented -> uncomment selection /// 3. whole selection block commented -> uncomment selection
@ -5184,11 +5184,11 @@ fn toggle_comments(cx: &mut Context) {
toggle_comments_impl( toggle_comments_impl(
cx, cx,
Box::new( Box::new(
|doc_line_token, doc_block_tokens, doc, selection, mut get_comment_tokens| { |doc_line_token, doc_block_tokens, rope, selection, mut get_comment_tokens| {
return Transaction::change( Transaction::change(
doc, rope,
selection.iter().flat_map(|range| { selection.iter().flat_map(|range| {
let text = doc.slice(..); let text = rope.slice(..);
let (injected_line_tokens, injected_block_tokens) = let (injected_line_tokens, injected_block_tokens) =
get_comment_tokens(range.from(), range.to()); get_comment_tokens(range.from(), range.to());
@ -5200,11 +5200,9 @@ fn toggle_comments(cx: &mut Context) {
let block_tokens = injected_block_tokens.as_deref().or(doc_block_tokens); let block_tokens = injected_block_tokens.as_deref().or(doc_block_tokens);
log::error!("{line_token:?}, {block_tokens:?}");
// only have line tokens // only have line tokens
if line_token.is_some() && block_tokens.is_none() { if line_token.is_some() && block_tokens.is_none() {
return comment::toggle_line_comments(doc, range, line_token); return comment::toggle_line_comments(rope, range, line_token);
} }
let split_lines = comment::split_lines_of_range(text, range); let split_lines = comment::split_lines_of_range(text, range);
@ -5218,7 +5216,7 @@ fn toggle_comments(cx: &mut Context) {
// block commented by line would also be block commented so check this first // block commented by line would also be block commented so check this first
if line_commented { if line_commented {
return comment::create_block_comment_transaction( return comment::create_block_comment_transaction(
doc, rope,
&split_lines, &split_lines,
line_commented, line_commented,
line_comment_changes, line_comment_changes,
@ -5232,7 +5230,7 @@ fn toggle_comments(cx: &mut Context) {
// check if selection has block comments // check if selection has block comments
if block_commented { if block_commented {
return comment::create_block_comment_transaction( return comment::create_block_comment_transaction(
doc, rope,
&vec![*range], &vec![*range],
block_commented, block_commented,
comment_changes, comment_changes,
@ -5243,7 +5241,7 @@ fn toggle_comments(cx: &mut Context) {
// not commented and only have block comment tokens // not commented and only have block comment tokens
if line_token.is_none() && block_tokens.is_some() { if line_token.is_none() && block_tokens.is_some() {
return comment::create_block_comment_transaction( return comment::create_block_comment_transaction(
doc, rope,
&split_lines, &split_lines,
line_commented, line_commented,
line_comment_changes, line_comment_changes,
@ -5252,9 +5250,9 @@ fn toggle_comments(cx: &mut Context) {
} }
// not block commented at all and don't have any tokens // not block commented at all and don't have any tokens
comment::toggle_line_comments(doc, range, line_token) comment::toggle_line_comments(rope, range, line_token)
}), }),
); )
}, },
), ),
) )
@ -5263,36 +5261,74 @@ fn toggle_comments(cx: &mut Context) {
fn toggle_line_comments(cx: &mut Context) { fn toggle_line_comments(cx: &mut Context) {
toggle_comments_impl( toggle_comments_impl(
cx, cx,
Box::new(|a, b, doc, selection, comment_fn| { Box::new(
todo!(); |doc_line_token, doc_block_tokens, rope, selection, mut get_comment_tokens| {
// if line_token.is_none() && block_tokens.is_some() { Transaction::change(
// let default_block_tokens = &[BlockCommentToken::default()]; rope,
// let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens); selection.iter().flat_map(|range| {
// comment::toggle_block_comments( let (injected_line_tokens, injected_block_tokens) =
// doc, get_comment_tokens(range.from(), range.to());
// &comment::split_lines_of_selection(doc.slice(..), selection),
// block_comment_tokens, let line_token = injected_line_tokens
// ) .as_ref()
// } else { .and_then(|token| token.first())
// comment::toggle_line_comments(doc, selection, line_token) .map(|token| token.as_str())
// } .or(doc_line_token);
}),
let block_tokens = injected_block_tokens.as_deref().or(doc_block_tokens);
if line_token.is_none() && block_tokens.is_some() {
let default_block_tokens = &[BlockCommentToken::default()];
let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens);
comment::toggle_block_comments(
rope,
&comment::split_lines_of_range(rope.slice(..), range),
block_comment_tokens,
)
} else {
comment::toggle_line_comments(rope, range, line_token)
}
}),
)
},
),
); );
} }
fn toggle_block_comments(cx: &mut Context) { fn toggle_block_comments(cx: &mut Context) {
toggle_comments_impl( toggle_comments_impl(
cx, cx,
Box::new(|a, b, doc, selection, comment_fn| { Box::new(
todo!(); |doc_line_token, doc_block_tokens, rope, selection, mut get_comment_tokens| {
// if line_token.is_some() && block_tokens.is_none() { Transaction::change(
// comment::toggle_line_comments(doc, selection, line_token) rope,
// } else { selection.iter().flat_map(|range| {
// let default_block_tokens = &[BlockCommentToken::default()]; let (injected_line_tokens, injected_block_tokens) =
// let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens); get_comment_tokens(range.from(), range.to());
// comment::toggle_block_comments(doc, selection, block_comment_tokens)
// } let line_token = injected_line_tokens
}), .as_ref()
.and_then(|token| token.first())
.map(|token| token.as_str())
.or(doc_line_token);
let block_tokens = injected_block_tokens.as_deref().or(doc_block_tokens);
if line_token.is_some() && block_tokens.is_none() {
comment::toggle_line_comments(rope, range, line_token)
} else {
let default_block_tokens = &[BlockCommentToken::default()];
let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens);
comment::toggle_block_comments(
rope,
&vec![*range],
block_comment_tokens,
)
}
}),
)
},
),
); );
} }