From 29e0a00eb0bf3e798cb44b544cc79b0d839e09f8 Mon Sep 17 00:00:00 2001 From: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com> Date: Sat, 1 Feb 2025 18:49:30 +0000 Subject: [PATCH] feat: implement toggle comment for the simplest case --- helix-core/src/comment.rs | 76 ++++++++++++++++---------------------- helix-term/src/commands.rs | 56 ++++++++++++++++++---------- 2 files changed, 67 insertions(+), 65 deletions(-) diff --git a/helix-core/src/comment.rs b/helix-core/src/comment.rs index 01b2cdd73..22983e645 100644 --- a/helix-core/src/comment.rs +++ b/helix-core/src/comment.rs @@ -37,24 +37,19 @@ pub fn get_comment_token<'a, S: AsRef>( /// - Column of existing tokens, if the lines are commented; column to place tokens at otherwise. /// - The margin to the right of the comment tokens /// - Defaults to `1`. If any existing comment token is not followed by a space, changes to `0`. -fn find_line_comment<'a>( +fn find_line_comment( + token: &str, text: RopeSlice, - lines: impl IntoIterator< - Item = ( - // line number - usize, - // token for this line - &'a str, - ), - >, + lines: impl IntoIterator, ) -> (bool, Vec, usize, usize) { let mut commented = true; let mut to_change = Vec::new(); let mut min = usize::MAX; // minimum col for first_non_whitespace_char let mut margin = 1; + let token_len = token.chars().count(); - for (line, token) in lines { - let token_len = token.chars().count(); + for line in lines { + log::error!("{line}"); let line_slice = text.line(line); if let Some(pos) = line_slice.first_non_whitespace_char() { let len = line_slice.len_chars(); @@ -89,50 +84,41 @@ pub type GetCommentTokens<'a> = Box (Option>, Option>) + 'a>; #[must_use] -pub fn toggle_line_comments( - doc: &Rope, - selection: &Selection, - token: Option<&str>, - lol_fn: GetCommentTokens, -) -> Transaction { - todo!(); - // let text = doc.slice(..); +pub fn toggle_line_comments(doc: &Rope, range: &Range, token: Option<&str>) -> Vec { + let text = doc.slice(..); - // let token = token.unwrap_or(DEFAULT_COMMENT_TOKEN); - // let comment = Tendril::from(format!("{} ", token)); + let token = token.unwrap_or(DEFAULT_COMMENT_TOKEN); + let comment = Tendril::from(format!("{} ", token)); - // let mut lines: Vec<(usize, &str)> = Vec::with_capacity(selection.len()); + let start = text.char_to_line(range.from()); + let end = text.char_to_line(range.to()); - // let mut min_next_line = 0; - // for selection in selection { - // let (start, end) = selection.line_range(text); - // let start = start.clamp(min_next_line, text.len_lines()); - // let end = (end + 1).min(text.len_lines()); + let start = start.clamp(0, text.len_lines()); + let end = (end + 1).min(text.len_lines()); - // let start_byte = text.line_to_byte(start); - // let end_byte = text.line_to_byte(start); + // let start_byte = text.line_to_byte(start); + // let end_byte = text.line_to_byte(start); - // let tokens = lines.extend(start..end); - // min_next_line = end; - // } + let mut lines = vec![]; + lines.extend(start..end); - // let (commented, to_change, min, margin) = find_line_comment(token, text, lines); + let (commented, to_change, min, margin) = find_line_comment(token, text, lines); - // let mut changes: Vec = Vec::with_capacity(to_change.len()); + let mut changes: Vec = Vec::with_capacity(to_change.len()); - // for line in to_change { - // let pos = text.line_to_char(line) + min; + for line in to_change { + let pos = text.line_to_char(line) + min; - // if !commented { - // // comment line - // changes.push((pos, pos, Some(comment.clone()))); - // } else { - // // uncomment line - // changes.push((pos, pos + token.len() + margin, None)); - // } - // } + if !commented { + // comment line + changes.push((pos, pos, Some(comment.clone()))); + } else { + // uncomment line + changes.push((pos, pos + token.len() + margin, None)); + } + } - // Transaction::change(doc, changes.into_iter()) + changes } #[derive(Debug, PartialEq, Eq)] diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index af5876e16..5b89f895f 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -5145,7 +5145,10 @@ fn toggle_comments_impl<'a>( 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 { + if this_gap < min_gap + // ignore the "comment" language + && syntax.layer_config(layer_id).language_name != "comment" + { best_fit = Some(layer_id); min_gap = this_gap; } @@ -5181,32 +5184,45 @@ fn toggle_comments(cx: &mut Context) { cx, Box::new( |doc_line_token, doc_block_tokens, doc, selection, mut get_comment_tokens| { - let text = doc.slice(..); + return Transaction::change( + doc, + selection.iter().flat_map(|range| { + let (injected_line_tokens, injected_block_tokens) = + get_comment_tokens(range.from(), range.to()); - Transaction::change_by_selection(doc, selection, |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(|lt| lt.first()) + .map(|lt| lt.as_str()) + .or(doc_line_token); - let line_token = injected_line_tokens - .as_ref() - .and_then(|lt| lt.first()) - .map(|lt| lt.as_str()) - .unwrap_or(doc_line_token.unwrap_or(DEFAULT_COMMENT_TOKEN)); + let block_tokens = injected_block_tokens.as_deref().or(doc_block_tokens); - let default_block_tokens = &[BlockCommentToken::default()]; + log::error!("{line_token:?}, {block_tokens:?}"); - let block_tokens = injected_block_tokens - .as_deref() - .unwrap_or(doc_block_tokens.unwrap_or(default_block_tokens)); + // only have line tokens + if line_token.is_some() { + return comment::toggle_line_comments(doc, range, line_token); + } - log::error!("{line_token:?}, {block_tokens:?}"); + vec![] - todo!(); + // todo!(); + }), + ); - // if line_tokens.is_some() && block_tokens.is_none() { + // Transaction::change_by_selection(doc, selection, |range| { - // } - }); + // let default_block_tokens = &[BlockCommentToken::default()]; + + // let block_tokens = block_tokens.unwrap_or(default_block_tokens); + + // log::error!("{line_token:?}, {block_tokens:?}"); + + // if line_tokens.is_some() && block_tokens.is_none() { + + // } + // }); // // only have line comment tokens // if line_token.is_some() && block_tokens.is_none() { @@ -5218,7 +5234,7 @@ fn toggle_comments(cx: &mut Context) { // ); // } - todo!(); + // todo!(); // let split_lines = comment::split_lines_of_selection(text, selection);