diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index d23889b427..5bd3accc13 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -223,6 +223,7 @@ pub fn render_parsed_markdown( } }), ); + // hello let mut links = Vec::new(); let mut link_ranges = Vec::new(); @@ -3784,6 +3785,9 @@ impl Editor { pub fn newline_below(&mut self, _: &NewlineBelow, cx: &mut ViewContext) { let buffer = self.buffer.read(cx); let snapshot = buffer.snapshot(cx); + // + // + // let mut edits = Vec::new(); let mut rows = Vec::new(); diff --git a/crates/editor/src/test/editor_lsp_test_context.rs b/crates/editor/src/test/editor_lsp_test_context.rs index e32d590a60..b93b8d3e7e 100644 --- a/crates/editor/src/test/editor_lsp_test_context.rs +++ b/crates/editor/src/test/editor_lsp_test_context.rs @@ -123,6 +123,7 @@ impl EditorLspTestContext { path_suffixes: vec!["rs".to_string()], ..Default::default() }, + line_comments: vec!["// ".into(), "/// ".into(), "//! ".into()], ..Default::default() }, Some(tree_sitter_rust::LANGUAGE.into()), diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 5dad354a39..f4bdafc985 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -2862,6 +2862,30 @@ impl MultiBufferSnapshot { } } + pub fn indent_and_comment_for_line(&self, row: MultiBufferRow, cx: &AppContext) -> String { + let mut indent = self.indent_size_for_line(row).chars().collect::(); + + if self.settings_at(0, cx).extend_comment_on_newline { + if let Some(language_scope) = self.language_scope_at(Point::new(row.0, 0)) { + let delimiters = language_scope.line_comment_prefixes(); + for delimiter in delimiters { + if *self + .chars_at(Point::new(row.0, indent.len() as u32)) + .take(delimiter.chars().count()) + .collect::() + .as_str() + == **delimiter + { + indent.push_str(&delimiter); + break; + } + } + } + } + + indent + } + pub fn prev_non_blank_row(&self, mut row: MultiBufferRow) -> Option { while row.0 > 0 { row.0 -= 1; diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index 4a4927a2fc..aecd0f90b2 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -328,14 +328,18 @@ impl Vim { .into_iter() .map(|selection| selection.start.row) .collect(); - let edits = selection_start_rows.into_iter().map(|row| { - let indent = snapshot - .indent_size_for_line(MultiBufferRow(row)) - .chars() - .collect::(); - let start_of_line = Point::new(row, 0); - (start_of_line..start_of_line, indent + "\n") - }); + let edits = selection_start_rows + .into_iter() + .map(|row| { + let indent = snapshot + .indent_and_comment_for_line(MultiBufferRow(row), cx) + .chars() + .collect::(); + + let start_of_line = Point::new(row, 0); + (start_of_line..start_of_line, indent + "\n") + }) + .collect::>(); editor.edit_with_autoindent(edits, cx); editor.change_selections(Some(Autoscroll::fit()), cx, |s| { s.move_cursors_with(|map, cursor, _| { @@ -361,14 +365,18 @@ impl Vim { .into_iter() .map(|selection| selection.end.row) .collect(); - let edits = selection_end_rows.into_iter().map(|row| { - let indent = snapshot - .indent_size_for_line(MultiBufferRow(row)) - .chars() - .collect::(); - let end_of_line = Point::new(row, snapshot.line_len(MultiBufferRow(row))); - (end_of_line..end_of_line, "\n".to_string() + &indent) - }); + let edits = selection_end_rows + .into_iter() + .map(|row| { + let indent = snapshot + .indent_and_comment_for_line(MultiBufferRow(row), cx) + .chars() + .collect::(); + + let end_of_line = Point::new(row, snapshot.line_len(MultiBufferRow(row))); + (end_of_line..end_of_line, "\n".to_string() + &indent) + }) + .collect::>(); editor.change_selections(Some(Autoscroll::fit()), cx, |s| { s.maybe_move_cursors_with(|map, cursor, goal| { Motion::CurrentLine.move_point( @@ -1414,4 +1422,16 @@ mod test { .await .assert_eq("th th\nth th\nth th\nth th\nth th\nˇth th\n"); } + + #[gpui::test] + async fn test_o_comment(cx: &mut gpui::TestAppContext) { + let mut cx = NeovimBackedTestContext::new(cx).await; + cx.set_neovim_option("filetype=rust").await; + + cx.set_shared_state("// helloˇ\n").await; + cx.simulate_shared_keystrokes("o").await; + cx.shared_state().await.assert_eq("// hello\n// ˇ\n"); + cx.simulate_shared_keystrokes("x escape shift-o").await; + cx.shared_state().await.assert_eq("// hello\n// ˇ\n// x\n"); + } } diff --git a/crates/vim/test_data/test_o_comment.json b/crates/vim/test_data/test_o_comment.json new file mode 100644 index 0000000000..b0b84da0e6 --- /dev/null +++ b/crates/vim/test_data/test_o_comment.json @@ -0,0 +1,8 @@ +{"SetOption":{"value":"filetype=rust"}} +{"Put":{"state":"// helloˇ\n"}} +{"Key":"o"} +{"Get":{"state":"// hello\n// ˇ\n","mode":"Insert"}} +{"Key":"x"} +{"Key":"escape"} +{"Key":"shift-o"} +{"Get":{"state":"// hello\n// ˇ\n// x\n","mode":"Insert"}}