From 47f8f891c8ffbad7f6669e5ee74a14ce48193486 Mon Sep 17 00:00:00 2001 From: 0x2CA <2478557459@qq.com> Date: Wed, 5 Mar 2025 12:46:58 +0800 Subject: [PATCH] vim: Fix `"seed_search_query_from_cursor" : "selection"` (#26107) Closes #9311 Closes #14843 Release Notes: - Fixed vim `"seed_search_query_from_cursor" : "selection"` --- crates/vim/src/normal/search.rs | 7 ++++++- crates/vim/src/vim.rs | 24 +++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/vim/src/normal/search.rs b/crates/vim/src/normal/search.rs index 24adfabdfb..e32d34f32b 100644 --- a/crates/vim/src/normal/search.rs +++ b/crates/vim/src/normal/search.rs @@ -304,6 +304,7 @@ impl Vim { }; let count = Vim::take_count(cx).unwrap_or(1); let prior_selections = self.editor_selections(window, cx); + let cursor_word = self.editor_cursor_word(window, cx); let vim = cx.entity().clone(); let searched = pane.update(cx, |pane, cx| { @@ -325,10 +326,14 @@ impl Vim { if !search_bar.show(window, cx) { return None; } - let Some(query) = search_bar.query_suggestion(window, cx) else { + let Some(query) = search_bar + .query_suggestion(window, cx) + .or_else(|| cursor_word) + else { drop(search_bar.search("", None, window, cx)); return None; }; + let query = regex::escape(&query); Some(search_bar.search(&query, Some(options), window, cx)) }); diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index d437d980fd..efd80c9395 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -30,7 +30,7 @@ use gpui::{ KeyContext, KeystrokeEvent, Render, Subscription, Task, WeakEntity, Window, }; use insert::{NormalBefore, TemporaryNormal}; -use language::{CursorShape, Point, Selection, SelectionGoal, TransactionId}; +use language::{CharKind, CursorShape, Point, Selection, SelectionGoal, TransactionId}; pub use mode_indicator::ModeIndicator; use motion::Motion; use normal::search::SearchSubmit; @@ -1199,6 +1199,28 @@ impl Vim { .unwrap_or_default() } + fn editor_cursor_word( + &mut self, + window: &mut Window, + cx: &mut Context, + ) -> Option { + self.update_editor(window, cx, |_, editor, window, cx| { + let selection = editor.selections.newest::(cx); + + let snapshot = &editor.snapshot(window, cx).buffer_snapshot; + let (range, kind) = snapshot.surrounding_word(selection.start, true); + if kind == Some(CharKind::Word) { + let text: String = snapshot.text_for_range(range).collect(); + if !text.trim().is_empty() { + return Some(text); + } + } + + None + }) + .unwrap_or_default() + } + /// When doing an action that modifies the buffer, we start recording so that `.` /// will replay the action. pub fn start_recording(&mut self, cx: &mut Context) {