Skip to content

Commit

Permalink
Option to insert comment character(s) at the beginning of the line(s) (
Browse files Browse the repository at this point in the history
…#19746)

Closes #19459


This PR adds the optional setting to insert comment character(s) at the
beginning of the line(s) instead of after the indentation. It can be
enabled via keybindings:

```
"ctrl-/": ["editor::ToggleComments", { "ignore_indent": true }]
```

As suggested by @notpeter in #19459, this is implemented in
`toggle_comments` (editor.rs) taking the existing `advance_downwards`
option as example.

There's also a test case for the setting, which mimics the test case for
the regular comment toggling behavior.

---

I am not entirely happy with the name `ignore_indent`. The default would
be a double negative now `ignore_indent=false`. A positive wording would
probably easier to understand, but I could not think of anything
concise. `insert_at_line_start` or just `at_line_start` might work, but
didn't convince me either. That said, I am happy to change the name if
there are better ideas.

---

Release Notes:

- Added optional setting to insert comment character(s) at the beginning
of the line(s) instead of after the indentation. It can be used by
changing the default mapping to toggle comments like this: `"ctrl-/":
["editor::ToggleComments", { "ignore_indent": true }]`
  • Loading branch information
NichtJens authored Oct 31, 2024
1 parent 7fd334f commit 633b665
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 2 deletions.
2 changes: 2 additions & 0 deletions crates/editor/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ pub struct ConfirmCodeAction {
pub struct ToggleComments {
#[serde(default)]
pub advance_downwards: bool,
#[serde(default)]
pub ignore_indent: bool,
}

#[derive(PartialEq, Clone, Deserialize, Default)]
Expand Down
23 changes: 21 additions & 2 deletions crates/editor/src/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8664,14 +8664,22 @@ impl Editor {
let snapshot = this.buffer.read(cx).read(cx);
let empty_str: Arc<str> = Arc::default();
let mut suffixes_inserted = Vec::new();
let ignore_indent = action.ignore_indent;

fn comment_prefix_range(
snapshot: &MultiBufferSnapshot,
row: MultiBufferRow,
comment_prefix: &str,
comment_prefix_whitespace: &str,
ignore_indent: bool,
) -> Range<Point> {
let start = Point::new(row.0, snapshot.indent_size_for_line(row).len);
let indent_size = if ignore_indent {
0
} else {
snapshot.indent_size_for_line(row).len
};

let start = Point::new(row.0, indent_size);

let mut line_bytes = snapshot
.bytes_in_range(start..snapshot.max_point())
Expand Down Expand Up @@ -8767,7 +8775,16 @@ impl Editor {
}

// If the language has line comments, toggle those.
let full_comment_prefixes = language.line_comment_prefixes();
let mut full_comment_prefixes = language.line_comment_prefixes().to_vec();

// If ignore_indent is set, trim spaces from the right side of all full_comment_prefixes
if ignore_indent {
full_comment_prefixes = full_comment_prefixes
.into_iter()
.map(|s| Arc::from(s.trim_end()))
.collect();
}

if !full_comment_prefixes.is_empty() {
let first_prefix = full_comment_prefixes
.first()
Expand All @@ -8794,6 +8811,7 @@ impl Editor {
row,
&prefix[..trimmed_prefix_len],
&prefix[trimmed_prefix_len..],
ignore_indent,
)
})
.max_by_key(|range| range.end.column - range.start.column)
Expand Down Expand Up @@ -8834,6 +8852,7 @@ impl Editor {
start_row,
comment_prefix,
comment_prefix_whitespace,
ignore_indent,
);
let suffix_range = comment_suffix_range(
snapshot.deref(),
Expand Down
126 changes: 126 additions & 0 deletions crates/editor/src/editor_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8533,6 +8533,131 @@ async fn test_toggle_comment(cx: &mut gpui::TestAppContext) {
"});
}

#[gpui::test]
async fn test_toggle_comment_ignore_indent(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
let mut cx = EditorTestContext::new(cx).await;
let language = Arc::new(Language::new(
LanguageConfig {
line_comments: vec!["// ".into(), "//! ".into(), "/// ".into()],
..Default::default()
},
Some(tree_sitter_rust::LANGUAGE.into()),
));
cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));

let toggle_comments = &ToggleComments {
advance_downwards: false,
ignore_indent: true,
};

// If multiple selections intersect a line, the line is only toggled once.
cx.set_state(indoc! {"
fn a() {
// «b();
// c();
// ˇ» d();
}
"});

cx.update_editor(|e, cx| e.toggle_comments(toggle_comments, cx));

cx.assert_editor_state(indoc! {"
fn a() {
«b();
c();
ˇ» d();
}
"});

// The comment prefix is inserted at the beginning of each line
cx.update_editor(|e, cx| e.toggle_comments(toggle_comments, cx));

cx.assert_editor_state(indoc! {"
fn a() {
// «b();
// c();
// ˇ» d();
}
"});

// If a selection ends at the beginning of a line, that line is not toggled.
cx.set_selections_state(indoc! {"
fn a() {
// b();
// «c();
ˇ»// d();
}
"});

cx.update_editor(|e, cx| e.toggle_comments(toggle_comments, cx));

cx.assert_editor_state(indoc! {"
fn a() {
// b();
«c();
ˇ»// d();
}
"});

// If a selection span a single line and is empty, the line is toggled.
cx.set_state(indoc! {"
fn a() {
a();
b();
ˇ
}
"});

cx.update_editor(|e, cx| e.toggle_comments(toggle_comments, cx));

cx.assert_editor_state(indoc! {"
fn a() {
a();
b();
//ˇ
}
"});

// If a selection span multiple lines, empty lines are not toggled.
cx.set_state(indoc! {"
fn a() {
«a();
c();ˇ»
}
"});

cx.update_editor(|e, cx| e.toggle_comments(toggle_comments, cx));

cx.assert_editor_state(indoc! {"
fn a() {
// «a();
// 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(toggle_comments, cx));

cx.assert_editor_state(indoc! {"
fn a() {
«a();
b();
c();ˇ»
}
"});
}

#[gpui::test]
async fn test_advance_downward_on_toggle_comment(cx: &mut gpui::TestAppContext) {
init_test(cx, |_| {});
Expand All @@ -8554,6 +8679,7 @@ async fn test_advance_downward_on_toggle_comment(cx: &mut gpui::TestAppContext)

let toggle_comments = &ToggleComments {
advance_downwards: true,
ignore_indent: false,
};

// Single cursor on one line -> advance
Expand Down

0 comments on commit 633b665

Please sign in to comment.