search.rs

 1use std::{
 2    cmp::{self, Ordering},
 3    ops::Range,
 4};
 5
 6use editor::{Anchor, MultiBufferSnapshot};
 7use gpui::{action, MutableAppContext};
 8
 9mod buffer_search;
10mod project_search;
11
12pub fn init(cx: &mut MutableAppContext) {
13    buffer_search::init(cx);
14    project_search::init(cx);
15}
16
17action!(ToggleSearchOption, SearchOption);
18action!(SelectMatch, Direction);
19
20#[derive(Clone, Copy)]
21pub enum SearchOption {
22    WholeWord,
23    CaseSensitive,
24    Regex,
25}
26
27#[derive(Clone, Copy, PartialEq, Eq)]
28pub enum Direction {
29    Prev,
30    Next,
31}
32
33pub(crate) fn active_match_index(
34    ranges: &[Range<Anchor>],
35    cursor: &Anchor,
36    buffer: &MultiBufferSnapshot,
37) -> Option<usize> {
38    if ranges.is_empty() {
39        None
40    } else {
41        match ranges.binary_search_by(|probe| {
42            if probe.end.cmp(&cursor, &*buffer).unwrap().is_lt() {
43                Ordering::Less
44            } else if probe.start.cmp(&cursor, &*buffer).unwrap().is_gt() {
45                Ordering::Greater
46            } else {
47                Ordering::Equal
48            }
49        }) {
50            Ok(i) | Err(i) => Some(cmp::min(i, ranges.len() - 1)),
51        }
52    }
53}
54
55pub(crate) fn match_index_for_direction(
56    ranges: &[Range<Anchor>],
57    cursor: &Anchor,
58    mut index: usize,
59    direction: Direction,
60    buffer: &MultiBufferSnapshot,
61) -> usize {
62    if ranges[index].start.cmp(&cursor, &buffer).unwrap().is_gt() {
63        if direction == Direction::Prev {
64            if index == 0 {
65                index = ranges.len() - 1;
66            } else {
67                index -= 1;
68            }
69        }
70    } else if ranges[index].end.cmp(&cursor, &buffer).unwrap().is_lt() {
71        if direction == Direction::Next {
72            index = 0;
73        }
74    } else if direction == Direction::Prev {
75        if index == 0 {
76            index = ranges.len() - 1;
77        } else {
78            index -= 1;
79        }
80    } else if direction == Direction::Next {
81        if index == ranges.len() - 1 {
82            index = 0
83        } else {
84            index += 1;
85        }
86    };
87    index
88}