mirror of https://github.com/helix-editor/helix
feat: block comment toggle and single line comment toggle
parent
544e460ac4
commit
371dec3774
|
@ -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("///")
|
||||||
// );
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue