From 06c28c65292235dd49cb3baa26ce5e1d7eea53f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=BA=E4=B8=8D=E5=8F=AB=E5=8C=96=E5=92=95=E9=BE=99?= <1801943622@qq.com> Date: Fri, 10 Jul 2026 20:09:30 +0800 Subject: [PATCH 1/2] fix: remap cursor position with display_point --- crates/vim/src/helix/duplicate.rs | 43 ++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/crates/vim/src/helix/duplicate.rs b/crates/vim/src/helix/duplicate.rs index 2069f61c29ca31..a19b6f3f4c7010 100644 --- a/crates/vim/src/helix/duplicate.rs +++ b/crates/vim/src/helix/duplicate.rs @@ -3,7 +3,7 @@ use std::ops::Range; use editor::{DisplayPoint, MultiBufferOffset, display_map::DisplaySnapshot}; use gpui::Context; use language::PointUtf16; -use multi_buffer::MultiBufferRow; +use multi_buffer::{MultiBufferPoint, MultiBufferRow}; use text::Bias; use ui::Window; @@ -126,8 +126,10 @@ fn find_next_valid_duplicate_space( .point_utf16_to_point(PointUtf16::new(end_row, end_col_utf16)) .column; - let candidate_start = DisplayPoint::new(candidate.start.row(), start_col); - let candidate_end = DisplayPoint::new(candidate.end.row(), end_col); + let candidate_start = + map.point_to_display_point(MultiBufferPoint::new(start_row, start_col), Bias::Left); + let candidate_end = + map.point_to_display_point(MultiBufferPoint::new(end_row, end_col), Bias::Right); if map.clip_point(candidate_start, Bias::Left) == candidate_start && map.clip_point(candidate_end, Bias::Right) == candidate_end @@ -147,6 +149,7 @@ fn display_point_range_to_offset_range( #[cfg(test)] mod tests { use db::indoc; + use editor::{Inlay, MultiBufferOffset}; use crate::{state::Mode, test::VimTestContext}; @@ -310,4 +313,38 @@ mod tests { Mode::HelixNormal, ); } + + #[gpui::test] + async fn test_selection_duplication_with_inlay_hints(cx: &mut gpui::TestAppContext) { + let mut cx = VimTestContext::new(cx, true).await; + cx.enable_helix(); + + cx.set_state( + indoc! {" + let x = «1ˇ»; + let y = 2;"}, + Mode::HelixNormal, + ); + + cx.update_editor(|editor, window, cx| { + let buffer = &editor.snapshot(window, cx).buffer; + editor.splice_inlays( + &[], + vec![ + Inlay::mock_hint(0, buffer.anchor_after(MultiBufferOffset(6)), ": i32"), + Inlay::mock_hint(1, buffer.anchor_after(MultiBufferOffset(15)), ": i32"), + ], + cx, + ); + }); + + cx.simulate_keystrokes("C"); + + cx.assert_state( + indoc! {" + let x = «1ˇ»; + let y = «2ˇ»;"}, + Mode::HelixNormal, + ); + } } From 13e619bd7ee6b87a60017bdf6e64f64e4962036b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BF=BA=E4=B8=8D=E5=8F=AB=E5=8C=96=E5=92=95=E9=BE=99?= <1801943622@qq.com> Date: Fri, 10 Jul 2026 20:32:36 +0800 Subject: [PATCH 2/2] fix inlays hints' position && verify display --- crates/vim/src/helix/duplicate.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/vim/src/helix/duplicate.rs b/crates/vim/src/helix/duplicate.rs index a19b6f3f4c7010..19d44d23a99cb1 100644 --- a/crates/vim/src/helix/duplicate.rs +++ b/crates/vim/src/helix/duplicate.rs @@ -331,8 +331,8 @@ mod tests { editor.splice_inlays( &[], vec![ - Inlay::mock_hint(0, buffer.anchor_after(MultiBufferOffset(6)), ": i32"), - Inlay::mock_hint(1, buffer.anchor_after(MultiBufferOffset(15)), ": i32"), + Inlay::mock_hint(0, buffer.anchor_after(MultiBufferOffset(5)), ": i32"), + Inlay::mock_hint(1, buffer.anchor_after(MultiBufferOffset(16)), ": i32"), ], cx, ); @@ -340,6 +340,12 @@ mod tests { cx.simulate_keystrokes("C"); + assert_eq!( + cx.display_text(), + "let x: i32 = 1; +let y: i32 = 2;", + ); + cx.assert_state( indoc! {" let x = «1ˇ»;