From ed89475cf63358d5e1997b78856ba355b5941064 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 28 Feb 2022 10:34:11 +0100 Subject: [PATCH] Extract a common `match_index_for_direction` and `active_match_index` --- crates/search/src/buffer_search.rs | 91 +++++++++-------------------- crates/search/src/project_search.rs | 86 ++++++++------------------- crates/search/src/search.rs | 63 ++++++++++++++++++++ 3 files changed, 115 insertions(+), 125 deletions(-) diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index c15f81ecf5..847345448a 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -1,4 +1,4 @@ -use crate::{Direction, SearchOption, SelectMatch}; +use crate::{active_match_index, match_index_for_direction, Direction, SearchOption, SelectMatch}; use collections::HashMap; use editor::{display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, Editor}; use gpui::{ @@ -8,10 +8,7 @@ use gpui::{ use language::AnchorRangeExt; use postage::watch; use project::search::SearchQuery; -use std::{ - cmp::{self, Ordering}, - ops::Range, -}; +use std::ops::Range; use workspace::{ItemViewHandle, Pane, Settings, Toolbar, Workspace}; action!(Deploy, bool); @@ -334,43 +331,23 @@ impl SearchBar { cx.notify(); } - fn select_match(&mut self, SelectMatch(direction): &SelectMatch, cx: &mut ViewContext) { - if let Some(mut index) = self.active_match_index { + fn select_match(&mut self, &SelectMatch(direction): &SelectMatch, cx: &mut ViewContext) { + if let Some(index) = self.active_match_index { if let Some(editor) = self.active_editor.as_ref() { editor.update(cx, |editor, cx| { - let newest_selection = editor.newest_anchor_selection().clone(); if let Some(ranges) = self.editors_with_matches.get(&cx.weak_handle()) { - let position = newest_selection.head(); - let buffer = editor.buffer().read(cx).read(cx); - if ranges[index].start.cmp(&position, &buffer).unwrap().is_gt() { - if *direction == Direction::Prev { - if index == 0 { - index = ranges.len() - 1; - } else { - index -= 1; - } - } - } else if ranges[index].end.cmp(&position, &buffer).unwrap().is_lt() { - if *direction == Direction::Next { - index = 0; - } - } else if *direction == Direction::Prev { - if index == 0 { - index = ranges.len() - 1; - } else { - index -= 1; - } - } else if *direction == Direction::Next { - if index == ranges.len() - 1 { - index = 0 - } else { - index += 1; - } - } - - let range_to_select = ranges[index].clone(); - drop(buffer); - editor.select_ranges([range_to_select], Some(Autoscroll::Fit), cx); + let new_index = match_index_for_direction( + ranges, + &editor.newest_anchor_selection().head(), + index, + direction, + &editor.buffer().read(cx).read(cx), + ); + editor.select_ranges( + [ranges[new_index].clone()], + Some(Autoscroll::Fit), + cx, + ); } }); } @@ -518,30 +495,18 @@ impl SearchBar { } fn update_match_index(&mut self, cx: &mut ViewContext) { - self.active_match_index = self.active_match_index(cx); - cx.notify(); - } - - fn active_match_index(&mut self, cx: &mut ViewContext) -> Option { - let editor = self.active_editor.as_ref()?; - let ranges = self.editors_with_matches.get(&editor.downgrade())?; - let editor = editor.read(cx); - let position = editor.newest_anchor_selection().head(); - if ranges.is_empty() { - None - } else { - let buffer = editor.buffer().read(cx).read(cx); - match ranges.binary_search_by(|probe| { - if probe.end.cmp(&position, &*buffer).unwrap().is_lt() { - Ordering::Less - } else if probe.start.cmp(&position, &*buffer).unwrap().is_gt() { - Ordering::Greater - } else { - Ordering::Equal - } - }) { - Ok(i) | Err(i) => Some(cmp::min(i, ranges.len() - 1)), - } + let new_index = self.active_editor.as_ref().and_then(|editor| { + let ranges = self.editors_with_matches.get(&editor.downgrade())?; + let editor = editor.read(cx); + active_match_index( + &ranges, + &editor.newest_anchor_selection().head(), + &editor.buffer().read(cx).read(cx), + ) + }); + if new_index != self.active_match_index { + self.active_match_index = new_index; + cx.notify(); } } } diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 449d9d3537..2a211a005a 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -1,4 +1,7 @@ -use crate::{Direction, SearchOption, SelectMatch, ToggleSearchOption}; +use crate::{ + active_match_index, match_index_for_direction, Direction, SearchOption, SelectMatch, + ToggleSearchOption, +}; use collections::HashMap; use editor::{Anchor, Autoscroll, Editor, MultiBuffer, SelectAll}; use gpui::{ @@ -10,7 +13,6 @@ use postage::watch; use project::{search::SearchQuery, Project}; use std::{ any::{Any, TypeId}, - cmp::{self, Ordering}, ops::Range, path::PathBuf, }; @@ -496,42 +498,17 @@ impl ProjectSearchView { } fn select_match(&mut self, &SelectMatch(direction): &SelectMatch, cx: &mut ViewContext) { - if let Some(mut index) = self.active_match_index { - let range_to_select = { - let model = self.model.read(cx); - let results_editor = self.results_editor.read(cx); - let buffer = results_editor.buffer().read(cx).read(cx); - let cursor = results_editor.newest_anchor_selection().head(); - let ranges = &model.match_ranges; - - if ranges[index].start.cmp(&cursor, &buffer).unwrap().is_gt() { - if direction == Direction::Prev { - if index == 0 { - index = ranges.len() - 1; - } else { - index -= 1; - } - } - } else if ranges[index].end.cmp(&cursor, &buffer).unwrap().is_lt() { - if direction == Direction::Next { - index = 0; - } - } else if direction == Direction::Prev { - if index == 0 { - index = ranges.len() - 1; - } else { - index -= 1; - } - } else if direction == Direction::Next { - if index == ranges.len() - 1 { - index = 0 - } else { - index += 1; - } - }; - ranges[index].clone() - }; - + if let Some(index) = self.active_match_index { + let model = self.model.read(cx); + let results_editor = self.results_editor.read(cx); + let new_index = match_index_for_direction( + &model.match_ranges, + &results_editor.newest_anchor_selection().head(), + index, + direction, + &results_editor.buffer().read(cx).read(cx), + ); + let range_to_select = model.match_ranges[new_index].clone(); self.results_editor.update(cx, |editor, cx| { editor.select_ranges([range_to_select], Some(Autoscroll::Fit), cx); }); @@ -595,30 +572,15 @@ impl ProjectSearchView { } fn update_match_index(&mut self, cx: &mut ViewContext) { - let match_ranges = self.model.read(cx).match_ranges.clone(); - if match_ranges.is_empty() { - self.active_match_index = None; - } else { - let results_editor = &self.results_editor.read(cx); - let cursor = results_editor.newest_anchor_selection().head(); - let new_index = { - let buffer = results_editor.buffer().read(cx).read(cx); - match match_ranges.binary_search_by(|probe| { - if probe.end.cmp(&cursor, &*buffer).unwrap().is_lt() { - Ordering::Less - } else if probe.start.cmp(&cursor, &*buffer).unwrap().is_gt() { - Ordering::Greater - } else { - Ordering::Equal - } - }) { - Ok(i) | Err(i) => Some(cmp::min(i, match_ranges.len() - 1)), - } - }; - if self.active_match_index != new_index { - self.active_match_index = new_index; - cx.notify(); - } + let results_editor = self.results_editor.read(cx); + let new_index = active_match_index( + &self.model.read(cx).match_ranges, + &results_editor.newest_anchor_selection().head(), + &results_editor.buffer().read(cx).read(cx), + ); + if self.active_match_index != new_index { + self.active_match_index = new_index; + cx.notify(); } } diff --git a/crates/search/src/search.rs b/crates/search/src/search.rs index 6e8e7e00f3..a1e335a035 100644 --- a/crates/search/src/search.rs +++ b/crates/search/src/search.rs @@ -1,3 +1,9 @@ +use std::{ + cmp::{self, Ordering}, + ops::Range, +}; + +use editor::{Anchor, MultiBufferSnapshot}; use gpui::{action, MutableAppContext}; mod buffer_search; @@ -23,3 +29,60 @@ pub enum Direction { Prev, Next, } + +pub(crate) fn active_match_index( + ranges: &[Range], + cursor: &Anchor, + buffer: &MultiBufferSnapshot, +) -> Option { + if ranges.is_empty() { + None + } else { + match ranges.binary_search_by(|probe| { + if probe.end.cmp(&cursor, &*buffer).unwrap().is_lt() { + Ordering::Less + } else if probe.start.cmp(&cursor, &*buffer).unwrap().is_gt() { + Ordering::Greater + } else { + Ordering::Equal + } + }) { + Ok(i) | Err(i) => Some(cmp::min(i, ranges.len() - 1)), + } + } +} + +pub(crate) fn match_index_for_direction( + ranges: &[Range], + cursor: &Anchor, + mut index: usize, + direction: Direction, + buffer: &MultiBufferSnapshot, +) -> usize { + if ranges[index].start.cmp(&cursor, &buffer).unwrap().is_gt() { + if direction == Direction::Prev { + if index == 0 { + index = ranges.len() - 1; + } else { + index -= 1; + } + } + } else if ranges[index].end.cmp(&cursor, &buffer).unwrap().is_lt() { + if direction == Direction::Next { + index = 0; + } + } else if direction == Direction::Prev { + if index == 0 { + index = ranges.len() - 1; + } else { + index -= 1; + } + } else if direction == Direction::Next { + if index == ranges.len() - 1 { + index = 0 + } else { + index += 1; + } + }; + index +}