summaryrefslogtreecommitdiff
path: root/helix-term/src
diff options
context:
space:
mode:
Diffstat (limited to 'helix-term/src')
-rw-r--r--helix-term/src/commands.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index d1092f20..5964e354 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -1041,7 +1041,25 @@ fn split_selection_on_newline(cx: &mut Context) {
fn search_impl(doc: &mut Document, view: &mut View, contents: &str, regex: &Regex, extend: bool) {
let text = doc.text();
let selection = doc.selection(view.id);
- let start = text.char_to_byte(selection.cursor(text.slice(..)));
+ let start = {
+ let range = selection.primary();
+
+ // This is a little bit weird. Due to 1-width cursor semantics, we
+ // would typically want the search to always begin at the visual left-side
+ // of the head. However, when there's already a selection from e.g. a
+ // previous search result, we don't want to include any of that selection
+ // in the subsequent search. The code below makes a compromise between the
+ // two behaviors that hopefully behaves the way most people expect most of
+ // the time.
+ if range.anchor <= range.head {
+ text.char_to_byte(range.head)
+ } else {
+ text.char_to_byte(graphemes::next_grapheme_boundary(
+ text.slice(..),
+ range.head,
+ ))
+ }
+ };
// use find_at to find the next match after the cursor, loop around the end
// Careful, `Regex` uses `bytes` as offsets, not character indices!