Skip to content

Commit aeed9d0

Browse files
authored
Scroll project search results to the top (#8329)
Scroll project search results to the top after every new search. Release Notes: - Fixed autoscrolling of the project search results ([8237](#8237))
1 parent d6492d0 commit aeed9d0

File tree

1 file changed

+99
-16
lines changed

1 file changed

+99
-16
lines changed

crates/search/src/project_search.rs

Lines changed: 99 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,18 @@ use crate::{
77
use anyhow::{Context as _, Result};
88
use collections::HashMap;
99
use editor::{
10-
actions::SelectAll, items::active_match_index, scroll::Autoscroll, Anchor, Editor, EditorEvent,
11-
MultiBuffer, MAX_TAB_TITLE_LEN,
10+
actions::SelectAll,
11+
items::active_match_index,
12+
scroll::{Autoscroll, Axis},
13+
Anchor, Editor, EditorEvent, MultiBuffer, MAX_TAB_TITLE_LEN,
1214
};
1315
use editor::{EditorElement, EditorStyle};
1416
use gpui::{
1517
actions, div, Action, AnyElement, AnyView, AppContext, Context as _, Element, EntityId,
1618
EventEmitter, FocusHandle, FocusableView, FontStyle, FontWeight, Global, Hsla,
17-
InteractiveElement, IntoElement, KeyContext, Model, ModelContext, ParentElement, PromptLevel,
18-
Render, SharedString, Styled, Subscription, Task, TextStyle, View, ViewContext, VisualContext,
19-
WeakModel, WeakView, WhiteSpace, WindowContext,
19+
InteractiveElement, IntoElement, KeyContext, Model, ModelContext, ParentElement, Point,
20+
PromptLevel, Render, SharedString, Styled, Subscription, Task, TextStyle, View, ViewContext,
21+
VisualContext, WeakModel, WeakView, WhiteSpace, WindowContext,
2022
};
2123
use menu::Confirm;
2224
use project::{
@@ -1302,6 +1304,7 @@ impl ProjectSearchView {
13021304
editor.change_selections(Some(Autoscroll::fit()), cx, |s| {
13031305
s.select_ranges(range_to_select)
13041306
});
1307+
editor.scroll(Point::default(), Some(Axis::Vertical), cx);
13051308
}
13061309
editor.highlight_background::<Self>(
13071310
match_ranges,
@@ -2094,11 +2097,12 @@ fn register_workspace_action_for_present_search<A: Action>(
20942097
pub mod tests {
20952098
use super::*;
20962099
use editor::DisplayPoint;
2097-
use gpui::{Action, TestAppContext};
2100+
use gpui::{Action, TestAppContext, WindowHandle};
20982101
use project::FakeFs;
20992102
use semantic_index::semantic_index_settings::SemanticIndexSettings;
21002103
use serde_json::json;
21012104
use settings::{Settings, SettingsStore};
2105+
use std::sync::Arc;
21022106
use workspace::DeploySearch;
21032107

21042108
#[gpui::test]
@@ -2120,15 +2124,7 @@ pub mod tests {
21202124
let search = cx.new_model(|cx| ProjectSearch::new(project, cx));
21212125
let search_view = cx.add_window(|cx| ProjectSearchView::new(search.clone(), cx, None));
21222126

2123-
search_view
2124-
.update(cx, |search_view, cx| {
2125-
search_view
2126-
.query_editor
2127-
.update(cx, |query_editor, cx| query_editor.set_text("TWO", cx));
2128-
search_view.search(cx);
2129-
})
2130-
.unwrap();
2131-
cx.background_executor.run_until_parked();
2127+
perform_search(search_view, "TWO", cx);
21322128
search_view.update(cx, |search_view, cx| {
21332129
assert_eq!(
21342130
search_view
@@ -3377,7 +3373,78 @@ pub mod tests {
33773373
.unwrap();
33783374
}
33793375

3380-
pub fn init_test(cx: &mut TestAppContext) {
3376+
#[gpui::test]
3377+
async fn test_scroll_search_results_to_top(cx: &mut TestAppContext) {
3378+
init_test(cx);
3379+
3380+
// We need many lines in the search results to be able to scroll the window
3381+
let fs = FakeFs::new(cx.background_executor.clone());
3382+
fs.insert_tree(
3383+
"/dir",
3384+
json!({
3385+
"1.txt": "\n\n\n\n\n A \n\n\n\n\n",
3386+
"2.txt": "\n\n\n\n\n A \n\n\n\n\n",
3387+
"3.rs": "\n\n\n\n\n A \n\n\n\n\n",
3388+
"4.rs": "\n\n\n\n\n A \n\n\n\n\n",
3389+
"5.rs": "\n\n\n\n\n A \n\n\n\n\n",
3390+
"6.rs": "\n\n\n\n\n A \n\n\n\n\n",
3391+
"7.rs": "\n\n\n\n\n A \n\n\n\n\n",
3392+
"8.rs": "\n\n\n\n\n A \n\n\n\n\n",
3393+
"9.rs": "\n\n\n\n\n A \n\n\n\n\n",
3394+
"a.rs": "\n\n\n\n\n A \n\n\n\n\n",
3395+
"b.rs": "\n\n\n\n\n B \n\n\n\n\n",
3396+
"c.rs": "\n\n\n\n\n B \n\n\n\n\n",
3397+
"d.rs": "\n\n\n\n\n B \n\n\n\n\n",
3398+
"e.rs": "\n\n\n\n\n B \n\n\n\n\n",
3399+
"f.rs": "\n\n\n\n\n B \n\n\n\n\n",
3400+
"g.rs": "\n\n\n\n\n B \n\n\n\n\n",
3401+
"h.rs": "\n\n\n\n\n B \n\n\n\n\n",
3402+
"i.rs": "\n\n\n\n\n B \n\n\n\n\n",
3403+
"j.rs": "\n\n\n\n\n B \n\n\n\n\n",
3404+
"k.rs": "\n\n\n\n\n B \n\n\n\n\n",
3405+
}),
3406+
)
3407+
.await;
3408+
let project = Project::test(fs.clone(), ["/dir".as_ref()], cx).await;
3409+
let search = cx.new_model(|cx| ProjectSearch::new(project, cx));
3410+
let search_view = cx.add_window(|cx| ProjectSearchView::new(search.clone(), cx, None));
3411+
3412+
// First search
3413+
perform_search(search_view.clone(), "A", cx);
3414+
search_view
3415+
.update(cx, |search_view, cx| {
3416+
search_view.results_editor.update(cx, |results_editor, cx| {
3417+
// Results are correct and scrolled to the top
3418+
assert_eq!(
3419+
results_editor.display_text(cx).match_indices(" A ").count(),
3420+
10
3421+
);
3422+
assert_eq!(results_editor.scroll_position(cx), Point::default());
3423+
3424+
// Scroll results all the way down
3425+
results_editor.scroll(Point::new(0., f32::MAX), Some(Axis::Vertical), cx);
3426+
});
3427+
})
3428+
.expect("unable to update search view");
3429+
3430+
// Second search
3431+
perform_search(search_view.clone(), "B", cx);
3432+
search_view
3433+
.update(cx, |search_view, cx| {
3434+
search_view.results_editor.update(cx, |results_editor, cx| {
3435+
// Results are correct...
3436+
assert_eq!(
3437+
results_editor.display_text(cx).match_indices(" B ").count(),
3438+
10
3439+
);
3440+
// ...and scrolled back to the top
3441+
assert_eq!(results_editor.scroll_position(cx), Point::default());
3442+
});
3443+
})
3444+
.expect("unable to update search view");
3445+
}
3446+
3447+
fn init_test(cx: &mut TestAppContext) {
33813448
cx.update(|cx| {
33823449
let settings = SettingsStore::test(cx);
33833450
cx.set_global(settings);
@@ -3394,4 +3461,20 @@ pub mod tests {
33943461
super::init(cx);
33953462
});
33963463
}
3464+
3465+
fn perform_search(
3466+
search_view: WindowHandle<ProjectSearchView>,
3467+
text: impl Into<Arc<str>>,
3468+
cx: &mut TestAppContext,
3469+
) {
3470+
search_view
3471+
.update(cx, |search_view, cx| {
3472+
search_view
3473+
.query_editor
3474+
.update(cx, |query_editor, cx| query_editor.set_text(text, cx));
3475+
search_view.search(cx);
3476+
})
3477+
.unwrap();
3478+
cx.background_executor.run_until_parked();
3479+
}
33973480
}

0 commit comments

Comments
 (0)