diff --git a/helix-core/src/comment.rs b/helix-core/src/comment.rs index 599c441b3..6cf7fd873 100644 --- a/helix-core/src/comment.rs +++ b/helix-core/src/comment.rs @@ -303,9 +303,9 @@ pub fn create_block_comment_transaction( #[must_use] pub fn toggle_block_comments( doc: &Rope, - selection: &Selection, + ranges: &Vec, tokens: &[BlockCommentToken], -) -> Transaction { +) -> Vec { todo!() // let text = doc.slice(..); // let (commented, comment_changes) = find_block_comments(tokens, text, selection); @@ -390,7 +390,7 @@ mod test { range = range.map(transaction.changes()); 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] @@ -404,92 +404,95 @@ mod test { range = range.map(transaction.changes()); 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] - // fn uncomment_0_margin_comments_with_no_space() { - // let mut doc = Rope::from("#"); - // let mut selection = Selection::single(0, doc.len_chars() - 1); + #[test] + fn uncomment_0_margin_comments_with_no_space() { + let mut doc = Rope::from("#"); + let mut range = Range::new(0, doc.len_chars() - 1); - // let transaction = toggle_line_comments(&doc, &selection, None); - // transaction.apply(&mut doc); - // selection = selection.map(transaction.changes()); - // assert_eq!(doc, ""); - // assert!(selection.len() == 1); // to ignore the selection unused warning - // } - // } + let changes = toggle_line_comments(&doc, &range, None); + let transaction = Transaction::change(&doc, changes.into_iter()); + transaction.apply(&mut doc); + range = range.map(transaction.changes()); + assert_eq!(doc, ""); + assert_eq!(range, range); // to ignore the selection unused warning + } - // #[test] - // fn test_find_block_comments() { - // // three lines 5 characters. - // let mut doc = Rope::from("1\n2\n3"); - // // select whole document - // let selection = Selection::single(0, doc.len_chars()); + #[test] + fn test_find_block_comments() { + // three lines 5 characters. + let mut doc = Rope::from("1\n2\n3"); + // select whole document + 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!( - // res, - // ( - // false, - // vec![CommentChange::Uncommented { - // range: Range::new(0, 5), - // start_pos: 0, - // end_pos: 4, - // start_token: "/*".to_string(), - // end_token: "*/".to_string(), - // }] - // ) - // ); + assert_eq!( + res, + ( + false, + vec![CommentChange::Uncommented { + range: Range::new(0, 5), + start_pos: 0, + end_pos: 4, + start_token: "/*".to_string(), + end_token: "*/".to_string(), + }] + ) + ); - // // comment - // let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); - // transaction.apply(&mut doc); + // // comment + // let transaction = toggle_block_comments(&doc, &range, &[BlockCommentToken::default()]); + // transaction.apply(&mut doc); - // assert_eq!(doc, "/* 1\n2\n3 */"); + // assert_eq!(doc, "/* 1\n2\n3 */"); - // // uncomment - // let selection = Selection::single(0, doc.len_chars()); - // let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); - // transaction.apply(&mut doc); - // assert_eq!(doc, "1\n2\n3"); + // // uncomment + // let selection = Selection::single(0, doc.len_chars()); + // let transaction = + // toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); + // transaction.apply(&mut doc); + // assert_eq!(doc, "1\n2\n3"); - // // don't panic when there is just a space in comment - // doc = Rope::from("/* */"); - // let selection = Selection::single(0, doc.len_chars()); - // let transaction = toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); - // transaction.apply(&mut doc); - // assert_eq!(doc, ""); - // } + // // don't panic when there is just a space in comment + // doc = Rope::from("/* */"); + // let selection = Selection::single(0, doc.len_chars()); + // let transaction = + // toggle_block_comments(&doc, &selection, &[BlockCommentToken::default()]); + // transaction.apply(&mut doc); + // assert_eq!(doc, ""); + } - // /// Test, if `get_comment_tokens` works, even if the content of the file includes chars, whose - // /// byte size unequal the amount of chars - // #[test] - // fn test_get_comment_with_char_boundaries() { - // let rope = Rope::from("··"); - // let tokens = ["//", "///"]; + /// Test, if `get_comment_tokens` works, even if the content of the file includes chars, whose + /// byte size unequal the amount of chars + #[test] + fn test_get_comment_with_char_boundaries() { + let rope = Rope::from("··"); + let tokens = ["//", "///"]; - // assert_eq!( - // super::get_comment_token(rope.slice(..), tokens.as_slice(), 0), - // None - // ); - // } + assert_eq!( + super::get_comment_token(rope.slice(..), tokens.as_slice(), 0), + None + ); + } - // /// Test for `get_comment_token`. - // /// - // /// Assuming the comment tokens are stored as `["///", "//"]`, `get_comment_token` should still - // /// return `///` instead of `//` if the user is in a doc-comment section. - // #[test] - // fn test_use_longest_comment() { - // let text = Rope::from(" /// amogus"); - // let tokens = ["///", "//"]; + /// Test for `get_comment_token`. + /// + /// Assuming the comment tokens are stored as `["///", "//"]`, `get_comment_token` should still + /// return `///` instead of `//` if the user is in a doc-comment section. + #[test] + fn test_use_longest_comment() { + let text = Rope::from(" /// amogus ඞ"); + let tokens = ["///", "//"]; - // assert_eq!( - // super::get_comment_token(text.slice(..), tokens.as_slice(), 0), - // Some("///") - // ); + assert_eq!( + super::get_comment_token(text.slice(..), tokens.as_slice(), 0), + Some("///") + ); + } } } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index e984a290a..12860b897 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5174,7 +5174,7 @@ fn toggle_comments_impl<'a>( 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 /// 2. each line block commented -> uncomment all lines /// 3. whole selection block commented -> uncomment selection @@ -5184,11 +5184,11 @@ fn toggle_comments(cx: &mut Context) { toggle_comments_impl( cx, Box::new( - |doc_line_token, doc_block_tokens, doc, selection, mut get_comment_tokens| { - return Transaction::change( - doc, + |doc_line_token, doc_block_tokens, rope, selection, mut get_comment_tokens| { + Transaction::change( + rope, selection.iter().flat_map(|range| { - let text = doc.slice(..); + let text = rope.slice(..); let (injected_line_tokens, injected_block_tokens) = 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); - log::error!("{line_token:?}, {block_tokens:?}"); - // only have line tokens 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); @@ -5218,7 +5216,7 @@ fn toggle_comments(cx: &mut Context) { // block commented by line would also be block commented so check this first if line_commented { return comment::create_block_comment_transaction( - doc, + rope, &split_lines, line_commented, line_comment_changes, @@ -5232,7 +5230,7 @@ fn toggle_comments(cx: &mut Context) { // check if selection has block comments if block_commented { return comment::create_block_comment_transaction( - doc, + rope, &vec![*range], block_commented, comment_changes, @@ -5243,7 +5241,7 @@ fn toggle_comments(cx: &mut Context) { // not commented and only have block comment tokens if line_token.is_none() && block_tokens.is_some() { return comment::create_block_comment_transaction( - doc, + rope, &split_lines, line_commented, line_comment_changes, @@ -5252,9 +5250,9 @@ fn toggle_comments(cx: &mut Context) { } // 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) { toggle_comments_impl( cx, - Box::new(|a, b, doc, selection, comment_fn| { - todo!(); - // 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( - // doc, - // &comment::split_lines_of_selection(doc.slice(..), selection), - // block_comment_tokens, - // ) - // } else { - // comment::toggle_line_comments(doc, selection, line_token) - // } - }), + Box::new( + |doc_line_token, doc_block_tokens, rope, selection, mut get_comment_tokens| { + Transaction::change( + rope, + selection.iter().flat_map(|range| { + let (injected_line_tokens, injected_block_tokens) = + get_comment_tokens(range.from(), range.to()); + + 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_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) { toggle_comments_impl( cx, - Box::new(|a, b, doc, selection, comment_fn| { - todo!(); - // if line_token.is_some() && block_tokens.is_none() { - // comment::toggle_line_comments(doc, selection, line_token) - // } else { - // let default_block_tokens = &[BlockCommentToken::default()]; - // let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens); - // comment::toggle_block_comments(doc, selection, block_comment_tokens) - // } - }), + Box::new( + |doc_line_token, doc_block_tokens, rope, selection, mut get_comment_tokens| { + Transaction::change( + rope, + selection.iter().flat_map(|range| { + let (injected_line_tokens, injected_block_tokens) = + get_comment_tokens(range.from(), range.to()); + + 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, + ) + } + }), + ) + }, + ), ); }