diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 49b988640..6a5f3bb6e 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -1097,7 +1097,7 @@ thread_local! { #[derive(Debug)] pub struct Syntax { - layers: HopSlotMap, + pub layers: HopSlotMap, root: LayerId, loader: Arc>, } diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 05aa86e9f..eb61845f3 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5095,6 +5095,12 @@ type CommentTransactionFn = fn( block_tokens: Option<&[BlockCommentToken]>, doc: &Rope, selection: &Selection, + syntax: Option<&Syntax>, + injected_lang_tokens: fn( + range: Range, + syntax: Option<&Syntax>, + rope: RopeSlice, + ) -> (Option>, Option>), ) -> Transaction; fn toggle_comments_impl(cx: &mut Context, comment_transaction: CommentTransactionFn) { @@ -5109,8 +5115,41 @@ fn toggle_comments_impl(cx: &mut Context, comment_transaction: CommentTransactio .and_then(|lc| lc.block_comment_tokens.as_ref()) .map(|tc| &tc[..]); - let transaction = - comment_transaction(line_token, block_tokens, doc.text(), doc.selection(view.id)); + let transaction = comment_transaction( + line_token, + block_tokens, + doc.text(), + doc.selection(view.id), + doc.syntax(), + |range: Range, syntax: Option<&Syntax>, rope: RopeSlice| { + let mut best_fit = None; + let mut min_gap = usize::MAX; + + // TODO: improve performance of this + if let Some(syntax) = syntax { + for (layer_id, layer) in syntax.layers { + for ts_range in layer.ranges { + let (start, end) = range.into_byte_range(rope); + let is_encompassing = + ts_range.start_byte <= start && ts_range.end_byte >= end; + if is_encompassing { + let this_gap = ts_range.end_byte - ts_range.start_byte; + if this_gap < min_gap { + best_fit = Some(layer_id); + } + } + } + } + + if let Some(best_fit) = best_fit { + let config = syntax.layer_config(best_fit); + return (config.comment_tokens, config.block_comment_tokens); + } + } + + (None, None) + }, + ); doc.apply(&transaction, view.id); exit_select_mode(cx); @@ -5123,68 +5162,83 @@ fn toggle_comments_impl(cx: &mut Context, comment_transaction: CommentTransactio /// 4. all lines not commented and block tokens -> comment uncommented lines /// 5. no comment tokens and not block commented -> line comment fn toggle_comments(cx: &mut Context) { - toggle_comments_impl(cx, |line_token, block_tokens, doc, selection| { - let text = doc.slice(..); + toggle_comments_impl( + cx, + |line_token, block_tokens, doc, selection, syntax, lol_fn| { + let (injected_line_tokens, injected_block_tokens) = lol_fn() + let text = doc.slice(..); - // only have line comment tokens - if line_token.is_some() && block_tokens.is_none() { - return comment::toggle_line_comments(doc, selection, line_token); - } + // only have line comment tokens + if line_token.is_some() && block_tokens.is_none() { + return comment::toggle_line_comments(doc, selection, line_token); + } - let split_lines = comment::split_lines_of_selection(text, selection); + let split_lines = comment::split_lines_of_selection(text, selection); - let default_block_tokens = &[BlockCommentToken::default()]; - let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens); + let default_block_tokens = &[BlockCommentToken::default()]; + let block_comment_tokens = block_tokens.unwrap_or(default_block_tokens); - let (line_commented, line_comment_changes) = - comment::find_block_comments(block_comment_tokens, text, &split_lines); + let (line_commented, line_comment_changes) = + comment::find_block_comments(block_comment_tokens, text, &split_lines); - // block commented by line would also be block commented so check this first - if line_commented { - return comment::create_block_comment_transaction( - doc, - &split_lines, - line_commented, - line_comment_changes, - ) - .0; - } + // block commented by line would also be block commented so check this first + if line_commented { + return comment::create_block_comment_transaction( + doc, + &split_lines, + line_commented, + line_comment_changes, + ) + .0; + } - let (block_commented, comment_changes) = - comment::find_block_comments(block_comment_tokens, text, selection); + let (block_commented, comment_changes) = + comment::find_block_comments(block_comment_tokens, text, selection); - // check if selection has block comments - if block_commented { - return comment::create_block_comment_transaction( - doc, - selection, - block_commented, - comment_changes, - ) - .0; - } + // check if selection has block comments + if block_commented { + return comment::create_block_comment_transaction( + doc, + selection, + block_commented, + comment_changes, + ) + .0; + } - // not commented and only have block comment tokens - if line_token.is_none() && block_tokens.is_some() { - return comment::create_block_comment_transaction( - doc, - &split_lines, - line_commented, - line_comment_changes, - ) - .0; - } + // not commented and only have block comment tokens + if line_token.is_none() && block_tokens.is_some() { + return comment::create_block_comment_transaction( + doc, + &split_lines, + line_commented, + line_comment_changes, + ) + .0; + } - // not block commented at all and don't have any tokens - comment::toggle_line_comments(doc, selection, line_token) - }) + // not block commented at all and don't have any tokens + comment::toggle_line_comments(doc, selection, line_token) + }, + ) } fn testing1234(cx: &mut Context) { let doc = doc!(cx.editor); - let syntax = doc.syntax(); + let syntax = doc.syntax().unwrap(); - log::error!("{syntax:#?}"); + // let a = syntax.layers.keys().next().unwrap(); + let b = syntax + .layers + .values() + .map(|value| value.ranges.clone()) + .collect::>(); + + // b.depth + + // let config = syntax.layer_config(a); + + log::error!("{:#?}", b); } fn toggle_line_comments(cx: &mut Context) {