Unnamed repository; edit this file 'description' to name the repository.
fix: surprising behaviour when changing line above a comment (#12575)
Co-authored-by: Nikita Revenco <[email protected]>
Nikita Revenco 2025-01-18
parent 3433973 · commit 076d8bd
-rw-r--r--helix-term/src/commands.rs34
-rw-r--r--helix-term/tests/test/commands/insert.rs19
2 files changed, 41 insertions, 12 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 583f46c3..52efcf22 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -2792,7 +2792,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation, yank: YankAction) {
}
Operation::Change => {
if only_whole_lines {
- open_above(cx);
+ open(cx, Open::Above, CommentContinuation::Disabled);
} else {
enter_insert_mode(cx);
}
@@ -3471,9 +3471,16 @@ pub enum Open {
Above,
}
-fn open(cx: &mut Context, open: Open) {
+#[derive(PartialEq)]
+pub enum CommentContinuation {
+ Enabled,
+ Disabled,
+}
+
+fn open(cx: &mut Context, open: Open, comment_continuation: CommentContinuation) {
let count = cx.count();
enter_insert_mode(cx);
+ let config = cx.editor.config();
let (view, doc) = current!(cx.editor);
let text = doc.text().slice(..);
@@ -3483,6 +3490,14 @@ fn open(cx: &mut Context, open: Open) {
let mut ranges = SmallVec::with_capacity(selection.len());
+ let continue_comment_tokens =
+ if comment_continuation == CommentContinuation::Enabled && config.continue_comments {
+ doc.language_config()
+ .and_then(|config| config.comment_tokens.as_ref())
+ } else {
+ None
+ };
+
let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
// the line number, where the cursor is currently
let curr_line_num = text.char_to_line(match open {
@@ -3498,13 +3513,8 @@ fn open(cx: &mut Context, open: Open) {
let above_next_new_line_num = next_new_line_num.saturating_sub(1);
- let continue_comment_token = if doc.config.load().continue_comments {
- doc.language_config()
- .and_then(|config| config.comment_tokens.as_ref())
- .and_then(|tokens| comment::get_comment_token(text, tokens, curr_line_num))
- } else {
- None
- };
+ let continue_comment_token = continue_comment_tokens
+ .and_then(|tokens| comment::get_comment_token(text, tokens, curr_line_num));
// Index to insert newlines after, as well as the char width
// to use to compensate for those inserted newlines.
@@ -3523,7 +3533,7 @@ fn open(cx: &mut Context, open: Open) {
_ => indent::indent_for_newline(
doc.language_config(),
doc.syntax(),
- &doc.config.load().indent_heuristic,
+ &config.indent_heuristic,
&doc.indent_style,
doc.tab_width(),
text,
@@ -3586,12 +3596,12 @@ fn open(cx: &mut Context, open: Open) {
// o inserts a new line after each line with a selection
fn open_below(cx: &mut Context) {
- open(cx, Open::Below)
+ open(cx, Open::Below, CommentContinuation::Enabled)
}
// O inserts a new line before each line with a selection
fn open_above(cx: &mut Context) {
- open(cx, Open::Above)
+ open(cx, Open::Above, CommentContinuation::Enabled)
}
fn normal_mode(cx: &mut Context) {
diff --git a/helix-term/tests/test/commands/insert.rs b/helix-term/tests/test/commands/insert.rs
index 9352f737..a3da5fb2 100644
--- a/helix-term/tests/test/commands/insert.rs
+++ b/helix-term/tests/test/commands/insert.rs
@@ -1,6 +1,25 @@
use super::*;
#[tokio::test(flavor = "multi_thread")]
+async fn change_line_above_comment() -> anyhow::Result<()> {
+ // <https://github.com/helix-editor/helix/issues/12570>
+ test((
+ indoc! {"\
+ #[fn main() {}
+ |]#// a comment
+ "},
+ ":lang rust<ret>c",
+ indoc! {"\
+ #[
+ |]#// a comment
+ "},
+ ))
+ .await?;
+
+ Ok(())
+}
+
+#[tokio::test(flavor = "multi_thread")]
async fn insert_newline_many_selections() -> anyhow::Result<()> {
test((
indoc! {"\