fix: surprising behaviour when changing line above a comment (#12575)

Co-authored-by: Nikita Revenco <154856872+NikitaRevenco@users.noreply.github.com>
pull/12589/head
Nikita Revenco 2025-01-17 21:29:39 +00:00 committed by GitHub
parent 343397391f
commit 076d8bd173
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 12 deletions

View File

@ -2792,7 +2792,7 @@ fn delete_selection_impl(cx: &mut Context, op: Operation, yank: YankAction) {
} }
Operation::Change => { Operation::Change => {
if only_whole_lines { if only_whole_lines {
open_above(cx); open(cx, Open::Above, CommentContinuation::Disabled);
} else { } else {
enter_insert_mode(cx); enter_insert_mode(cx);
} }
@ -3471,9 +3471,16 @@ pub enum Open {
Above, 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(); let count = cx.count();
enter_insert_mode(cx); enter_insert_mode(cx);
let config = cx.editor.config();
let (view, doc) = current!(cx.editor); let (view, doc) = current!(cx.editor);
let text = doc.text().slice(..); 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 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| { let mut transaction = Transaction::change_by_selection(contents, selection, |range| {
// the line number, where the cursor is currently // the line number, where the cursor is currently
let curr_line_num = text.char_to_line(match open { 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 above_next_new_line_num = next_new_line_num.saturating_sub(1);
let continue_comment_token = if doc.config.load().continue_comments { let continue_comment_token = continue_comment_tokens
doc.language_config() .and_then(|tokens| comment::get_comment_token(text, tokens, curr_line_num));
.and_then(|config| config.comment_tokens.as_ref())
.and_then(|tokens| comment::get_comment_token(text, tokens, curr_line_num))
} else {
None
};
// Index to insert newlines after, as well as the char width // Index to insert newlines after, as well as the char width
// to use to compensate for those inserted newlines. // to use to compensate for those inserted newlines.
@ -3523,7 +3533,7 @@ fn open(cx: &mut Context, open: Open) {
_ => indent::indent_for_newline( _ => indent::indent_for_newline(
doc.language_config(), doc.language_config(),
doc.syntax(), doc.syntax(),
&doc.config.load().indent_heuristic, &config.indent_heuristic,
&doc.indent_style, &doc.indent_style,
doc.tab_width(), doc.tab_width(),
text, text,
@ -3586,12 +3596,12 @@ fn open(cx: &mut Context, open: Open) {
// o inserts a new line after each line with a selection // o inserts a new line after each line with a selection
fn open_below(cx: &mut Context) { 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 // O inserts a new line before each line with a selection
fn open_above(cx: &mut Context) { fn open_above(cx: &mut Context) {
open(cx, Open::Above) open(cx, Open::Above, CommentContinuation::Enabled)
} }
fn normal_mode(cx: &mut Context) { fn normal_mode(cx: &mut Context) {

View File

@ -1,5 +1,24 @@
use super::*; 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")] #[tokio::test(flavor = "multi_thread")]
async fn insert_newline_many_selections() -> anyhow::Result<()> { async fn insert_newline_many_selections() -> anyhow::Result<()> {
test(( test((