From a0ee29a80619df3512ca08f259a3d8446ab27158 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Apr 2024 14:22:47 -0700 Subject: [PATCH] Use first line comment prefix when toggling comments (#10335) This fixed an issue introduced in https://github.com/zed-industries/zed/pull/10126, where, when toggling comments in a language with multiple line comment prefixes (e.g. Gleam, Erlang) Zed would insert the *last* prefix instead of the first. Release Notes: - Fixed an issue where the `toggle comments` command inserted the wrong line comment prefix in some languages (preview only). Co-authored-by: Marshall --- crates/editor/src/editor.rs | 58 +++++++++++---------------- crates/editor/src/editor_tests.rs | 21 +++++++++- crates/languages/src/rust/config.toml | 2 +- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 3aee72778c..d603bfd155 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -7098,22 +7098,13 @@ impl Editor { .line_comment_prefixes() .filter(|prefixes| !prefixes.is_empty()) { - // Split the comment prefix's trailing whitespace into a separate string, - // as that portion won't be used for detecting if a line is a comment. - struct Comment { - full_prefix: Arc, - trimmed_prefix_len: usize, - } - let prefixes: SmallVec<[Comment; 4]> = full_comment_prefixes + let first_prefix = full_comment_prefixes + .first() + .expect("prefixes is non-empty"); + let prefix_trimmed_lengths = full_comment_prefixes .iter() - .map(|full_prefix| { - let trimmed_prefix_len = full_prefix.trim_end_matches(' ').len(); - Comment { - trimmed_prefix_len, - full_prefix: full_prefix.clone(), - } - }) - .collect(); + .map(|p| p.trim_end_matches(' ').len()) + .collect::>(); let mut all_selection_lines_are_comments = true; @@ -7122,28 +7113,25 @@ impl Editor { continue; } - let Some((prefix, prefix_range)) = prefixes + let prefix_range = full_comment_prefixes .iter() - .map(|prefix| { - ( - prefix, - comment_prefix_range( - snapshot.deref(), - row, - &prefix.full_prefix[..prefix.trimmed_prefix_len], - &prefix.full_prefix[prefix.trimmed_prefix_len..], - ), + .zip(prefix_trimmed_lengths.iter().copied()) + .map(|(prefix, trimmed_prefix_len)| { + comment_prefix_range( + snapshot.deref(), + row, + &prefix[..trimmed_prefix_len], + &prefix[trimmed_prefix_len..], ) }) - .max_by_key(|(_, range)| range.end.column - range.start.column) - else { - // There has to be at least one prefix. - break; - }; + .max_by_key(|range| range.end.column - range.start.column) + .expect("prefixes is non-empty"); + if prefix_range.is_empty() { all_selection_lines_are_comments = false; } - selection_edit_ranges.push((prefix_range, prefix.full_prefix.clone())); + + selection_edit_ranges.push(prefix_range); } if all_selection_lines_are_comments { @@ -7151,17 +7139,17 @@ impl Editor { selection_edit_ranges .iter() .cloned() - .map(|(range, _)| (range, empty_str.clone())), + .map(|range| (range, empty_str.clone())), ); } else { let min_column = selection_edit_ranges .iter() - .map(|(range, _)| range.start.column) + .map(|range| range.start.column) .min() .unwrap_or(0); - edits.extend(selection_edit_ranges.iter().map(|(range, prefix)| { + edits.extend(selection_edit_ranges.iter().map(|range| { let position = Point::new(range.start.row, min_column); - (position..position, prefix.clone()) + (position..position, first_prefix.clone()) })); } } else if let Some((full_comment_prefix, comment_suffix)) = diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 48c894e575..25e144af8c 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -6566,7 +6566,7 @@ async fn test_toggle_comment(cx: &mut gpui::TestAppContext) { let mut cx = EditorTestContext::new(cx).await; let language = Arc::new(Language::new( LanguageConfig { - line_comments: vec!["// ".into()], + line_comments: vec!["// ".into(), "//! ".into(), "/// ".into()], ..Default::default() }, Some(tree_sitter_rust::language()), @@ -6660,6 +6660,25 @@ async fn test_toggle_comment(cx: &mut gpui::TestAppContext) { // c();ˇ» } "}); + + // If a selection includes multiple comment prefixes, all lines are uncommented. + cx.set_state(indoc! {" + fn a() { + «// a(); + /// b(); + //! c();ˇ» + } + "}); + + cx.update_editor(|e, cx| e.toggle_comments(&ToggleComments::default(), cx)); + + cx.assert_editor_state(indoc! {" + fn a() { + «a(); + b(); + c();ˇ» + } + "}); } #[gpui::test] diff --git a/crates/languages/src/rust/config.toml b/crates/languages/src/rust/config.toml index e05234c774..d01f62e354 100644 --- a/crates/languages/src/rust/config.toml +++ b/crates/languages/src/rust/config.toml @@ -1,7 +1,7 @@ name = "Rust" grammar = "rust" path_suffixes = ["rs"] -line_comments = [ "/// ", "//! ", "// "] +line_comments = ["// ", "/// ", "//! "] autoclose_before = ";:.,=}])>" brackets = [ { start = "{", end = "}", close = true, newline = true },