Eliminate GPUI View, ViewContext, and WindowContext types (#22632)
There's still a bit more work to do on this, but this PR is compiling (with warnings) after eliminating the key types. When the tasks below are complete, this will be the new narrative for GPUI: - `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit of state, and if `T` implements `Render`, then `Entity<T>` implements `Element`. - `&mut App` This replaces `AppContext` and represents the app. - `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It is provided by the framework when updating an entity. - `&mut Window` Broken out of `&mut WindowContext` which no longer exists. Every method that once took `&mut WindowContext` now takes `&mut Window, &mut App` and every method that took `&mut ViewContext<T>` now takes `&mut Window, &mut Context<T>` Not pictured here are the two other failed attempts. It's been quite a month! Tasks: - [x] Remove `View`, `ViewContext`, `WindowContext` and thread through `Window` - [x] [@cole-miller @mikayla-maki] Redraw window when entities change - [x] [@cole-miller @mikayla-maki] Get examples and Zed running - [x] [@cole-miller @mikayla-maki] Fix Zed rendering - [x] [@mikayla-maki] Fix todo! macros and comments - [x] Fix a bug where the editor would not be redrawn because of view caching - [x] remove publicness window.notify() and replace with `AppContext::notify` - [x] remove `observe_new_window_models`, replace with `observe_new_models` with an optional window - [x] Fix a bug where the project panel would not be redrawn because of the wrong refresh() call being used - [x] Fix the tests - [x] Fix warnings by eliminating `Window` params or using `_` - [x] Fix conflicts - [x] Simplify generic code where possible - [x] Rename types - [ ] Update docs ### issues post merge - [x] Issues switching between normal and insert mode - [x] Assistant re-rendering failure - [x] Vim test failures - [x] Mac build issue Release Notes: - N/A --------- Co-authored-by: Antonio Scandurra <me@as-cii.com> Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Mikayla <mikayla@zed.dev> Co-authored-by: Joseph <joseph@zed.dev> Co-authored-by: max <max@zed.dev> Co-authored-by: Michael Sloan <michael@zed.dev> Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local> Co-authored-by: Mikayla <mikayla.c.maki@gmail.com> Co-authored-by: joão <joao@zed.dev>
This commit is contained in:
parent
21b4a0d50e
commit
6fca1d2b0b
648 changed files with 36248 additions and 28208 deletions
|
@ -14,9 +14,9 @@ use file_finder_settings::{FileFinderSettings, FileFinderWidth};
|
|||
use file_icons::FileIcons;
|
||||
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
||||
use gpui::{
|
||||
actions, Action, AnyElement, AppContext, DismissEvent, EventEmitter, FocusHandle,
|
||||
FocusableView, KeyContext, Model, Modifiers, ModifiersChangedEvent, ParentElement, Render,
|
||||
Styled, Task, View, ViewContext, VisualContext, WeakView,
|
||||
actions, Action, AnyElement, App, Context, DismissEvent, Entity, EventEmitter, FocusHandle,
|
||||
Focusable, KeyContext, Modifiers, ModifiersChangedEvent, ParentElement, Render, Styled, Task,
|
||||
WeakEntity, Window,
|
||||
};
|
||||
use new_path_prompt::NewPathPrompt;
|
||||
use open_path_prompt::OpenPathPrompt;
|
||||
|
@ -45,52 +45,63 @@ use workspace::{
|
|||
actions!(file_finder, [SelectPrev, ToggleMenu]);
|
||||
|
||||
impl ModalView for FileFinder {
|
||||
fn on_before_dismiss(&mut self, cx: &mut ViewContext<Self>) -> workspace::DismissDecision {
|
||||
fn on_before_dismiss(
|
||||
&mut self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> workspace::DismissDecision {
|
||||
let submenu_focused = self.picker.update(cx, |picker, cx| {
|
||||
picker.delegate.popover_menu_handle.is_focused(cx)
|
||||
picker.delegate.popover_menu_handle.is_focused(window, cx)
|
||||
});
|
||||
workspace::DismissDecision::Dismiss(!submenu_focused)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FileFinder {
|
||||
picker: View<Picker<FileFinderDelegate>>,
|
||||
picker: Entity<Picker<FileFinderDelegate>>,
|
||||
picker_focus_handle: FocusHandle,
|
||||
init_modifiers: Option<Modifiers>,
|
||||
}
|
||||
|
||||
pub fn init_settings(cx: &mut AppContext) {
|
||||
pub fn init_settings(cx: &mut App) {
|
||||
FileFinderSettings::register(cx);
|
||||
}
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
pub fn init(cx: &mut App) {
|
||||
init_settings(cx);
|
||||
cx.observe_new_views(FileFinder::register).detach();
|
||||
cx.observe_new_views(NewPathPrompt::register).detach();
|
||||
cx.observe_new_views(OpenPathPrompt::register).detach();
|
||||
cx.observe_new(FileFinder::register).detach();
|
||||
cx.observe_new(NewPathPrompt::register).detach();
|
||||
cx.observe_new(OpenPathPrompt::register).detach();
|
||||
}
|
||||
|
||||
impl FileFinder {
|
||||
fn register(workspace: &mut Workspace, _: &mut ViewContext<Workspace>) {
|
||||
workspace.register_action(|workspace, action: &workspace::ToggleFileFinder, cx| {
|
||||
let Some(file_finder) = workspace.active_modal::<Self>(cx) else {
|
||||
Self::open(workspace, action.separate_history, cx).detach();
|
||||
return;
|
||||
};
|
||||
fn register(
|
||||
workspace: &mut Workspace,
|
||||
_window: Option<&mut Window>,
|
||||
_: &mut Context<Workspace>,
|
||||
) {
|
||||
workspace.register_action(
|
||||
|workspace, action: &workspace::ToggleFileFinder, window, cx| {
|
||||
let Some(file_finder) = workspace.active_modal::<Self>(cx) else {
|
||||
Self::open(workspace, action.separate_history, window, cx).detach();
|
||||
return;
|
||||
};
|
||||
|
||||
file_finder.update(cx, |file_finder, cx| {
|
||||
file_finder.init_modifiers = Some(cx.modifiers());
|
||||
file_finder.picker.update(cx, |picker, cx| {
|
||||
picker.cycle_selection(cx);
|
||||
file_finder.update(cx, |file_finder, cx| {
|
||||
file_finder.init_modifiers = Some(window.modifiers());
|
||||
file_finder.picker.update(cx, |picker, cx| {
|
||||
picker.cycle_selection(window, cx);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn open(
|
||||
workspace: &mut Workspace,
|
||||
separate_history: bool,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>,
|
||||
) -> Task<()> {
|
||||
let project = workspace.project().read(cx);
|
||||
let fs = project.fs();
|
||||
|
@ -130,33 +141,34 @@ impl FileFinder {
|
|||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
cx.spawn(move |workspace, mut cx| async move {
|
||||
cx.spawn_in(window, move |workspace, mut cx| async move {
|
||||
let history_items = join_all(history_items).await.into_iter().flatten();
|
||||
|
||||
workspace
|
||||
.update(&mut cx, |workspace, cx| {
|
||||
.update_in(&mut cx, |workspace, window, cx| {
|
||||
let project = workspace.project().clone();
|
||||
let weak_workspace = cx.view().downgrade();
|
||||
workspace.toggle_modal(cx, |cx| {
|
||||
let weak_workspace = cx.model().downgrade();
|
||||
workspace.toggle_modal(window, cx, |window, cx| {
|
||||
let delegate = FileFinderDelegate::new(
|
||||
cx.view().downgrade(),
|
||||
cx.model().downgrade(),
|
||||
weak_workspace,
|
||||
project,
|
||||
currently_opened_path,
|
||||
history_items.collect(),
|
||||
separate_history,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
FileFinder::new(delegate, cx)
|
||||
FileFinder::new(delegate, window, cx)
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
}
|
||||
|
||||
fn new(delegate: FileFinderDelegate, cx: &mut ViewContext<Self>) -> Self {
|
||||
let picker = cx.new_view(|cx| Picker::uniform_list(delegate, cx));
|
||||
fn new(delegate: FileFinderDelegate, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx));
|
||||
let picker_focus_handle = picker.focus_handle(cx);
|
||||
picker.update(cx, |picker, _| {
|
||||
picker.delegate.focus_handle = picker_focus_handle.clone();
|
||||
|
@ -164,14 +176,15 @@ impl FileFinder {
|
|||
Self {
|
||||
picker,
|
||||
picker_focus_handle,
|
||||
init_modifiers: cx.modifiers().modified().then_some(cx.modifiers()),
|
||||
init_modifiers: window.modifiers().modified().then_some(window.modifiers()),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_modifiers_changed(
|
||||
&mut self,
|
||||
event: &ModifiersChangedEvent,
|
||||
cx: &mut ViewContext<Self>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
let Some(init_modifiers) = self.init_modifiers.take() else {
|
||||
return;
|
||||
|
@ -179,47 +192,68 @@ impl FileFinder {
|
|||
if self.picker.read(cx).delegate.has_changed_selected_index {
|
||||
if !event.modified() || !init_modifiers.is_subset_of(&event) {
|
||||
self.init_modifiers = None;
|
||||
cx.dispatch_action(menu::Confirm.boxed_clone());
|
||||
window.dispatch_action(menu::Confirm.boxed_clone(), cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_select_prev(&mut self, _: &SelectPrev, cx: &mut ViewContext<Self>) {
|
||||
self.init_modifiers = Some(cx.modifiers());
|
||||
cx.dispatch_action(Box::new(menu::SelectPrev));
|
||||
fn handle_select_prev(&mut self, _: &SelectPrev, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.init_modifiers = Some(window.modifiers());
|
||||
window.dispatch_action(Box::new(menu::SelectPrev), cx);
|
||||
}
|
||||
|
||||
fn handle_toggle_menu(&mut self, _: &ToggleMenu, cx: &mut ViewContext<Self>) {
|
||||
fn handle_toggle_menu(&mut self, _: &ToggleMenu, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.picker.update(cx, |picker, cx| {
|
||||
let menu_handle = &picker.delegate.popover_menu_handle;
|
||||
if menu_handle.is_deployed() {
|
||||
menu_handle.hide(cx);
|
||||
} else {
|
||||
menu_handle.show(cx);
|
||||
menu_handle.show(window, cx);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn go_to_file_split_left(&mut self, _: &pane::SplitLeft, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_file_split_inner(SplitDirection::Left, cx)
|
||||
fn go_to_file_split_left(
|
||||
&mut self,
|
||||
_: &pane::SplitLeft,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.go_to_file_split_inner(SplitDirection::Left, window, cx)
|
||||
}
|
||||
|
||||
fn go_to_file_split_right(&mut self, _: &pane::SplitRight, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_file_split_inner(SplitDirection::Right, cx)
|
||||
fn go_to_file_split_right(
|
||||
&mut self,
|
||||
_: &pane::SplitRight,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.go_to_file_split_inner(SplitDirection::Right, window, cx)
|
||||
}
|
||||
|
||||
fn go_to_file_split_up(&mut self, _: &pane::SplitUp, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_file_split_inner(SplitDirection::Up, cx)
|
||||
fn go_to_file_split_up(
|
||||
&mut self,
|
||||
_: &pane::SplitUp,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.go_to_file_split_inner(SplitDirection::Up, window, cx)
|
||||
}
|
||||
|
||||
fn go_to_file_split_down(&mut self, _: &pane::SplitDown, cx: &mut ViewContext<Self>) {
|
||||
self.go_to_file_split_inner(SplitDirection::Down, cx)
|
||||
fn go_to_file_split_down(
|
||||
&mut self,
|
||||
_: &pane::SplitDown,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.go_to_file_split_inner(SplitDirection::Down, window, cx)
|
||||
}
|
||||
|
||||
fn go_to_file_split_inner(
|
||||
&mut self,
|
||||
split_direction: SplitDirection,
|
||||
cx: &mut ViewContext<Self>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.picker.update(cx, |picker, cx| {
|
||||
let delegate = &mut picker.delegate;
|
||||
|
@ -239,7 +273,7 @@ impl FileFinder {
|
|||
},
|
||||
};
|
||||
let open_task = workspace.update(cx, move |workspace, cx| {
|
||||
workspace.split_path_preview(path, false, Some(split_direction), cx)
|
||||
workspace.split_path_preview(path, false, Some(split_direction), window, cx)
|
||||
});
|
||||
open_task.detach_and_log_err(cx);
|
||||
}
|
||||
|
@ -247,11 +281,8 @@ impl FileFinder {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn modal_max_width(
|
||||
width_setting: Option<FileFinderWidth>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Pixels {
|
||||
let window_width = cx.viewport_size().width;
|
||||
pub fn modal_max_width(width_setting: Option<FileFinderWidth>, window: &mut Window) -> Pixels {
|
||||
let window_width = window.viewport_size().width;
|
||||
let small_width = Pixels(545.);
|
||||
|
||||
match width_setting {
|
||||
|
@ -266,18 +297,18 @@ impl FileFinder {
|
|||
|
||||
impl EventEmitter<DismissEvent> for FileFinder {}
|
||||
|
||||
impl FocusableView for FileFinder {
|
||||
fn focus_handle(&self, _: &AppContext) -> FocusHandle {
|
||||
impl Focusable for FileFinder {
|
||||
fn focus_handle(&self, _: &App) -> FocusHandle {
|
||||
self.picker_focus_handle.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for FileFinder {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let key_context = self.picker.read(cx).delegate.key_context(cx);
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let key_context = self.picker.read(cx).delegate.key_context(window, cx);
|
||||
|
||||
let file_finder_settings = FileFinderSettings::get_global(cx);
|
||||
let modal_max_width = Self::modal_max_width(file_finder_settings.modal_max_width, cx);
|
||||
let modal_max_width = Self::modal_max_width(file_finder_settings.modal_max_width, window);
|
||||
|
||||
v_flex()
|
||||
.key_context(key_context)
|
||||
|
@ -294,9 +325,9 @@ impl Render for FileFinder {
|
|||
}
|
||||
|
||||
pub struct FileFinderDelegate {
|
||||
file_finder: WeakView<FileFinder>,
|
||||
workspace: WeakView<Workspace>,
|
||||
project: Model<Project>,
|
||||
file_finder: WeakEntity<FileFinder>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
search_count: usize,
|
||||
latest_search_id: usize,
|
||||
latest_search_did_cancel: bool,
|
||||
|
@ -613,16 +644,18 @@ impl FileSearchQuery {
|
|||
}
|
||||
|
||||
impl FileFinderDelegate {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new(
|
||||
file_finder: WeakView<FileFinder>,
|
||||
workspace: WeakView<Workspace>,
|
||||
project: Model<Project>,
|
||||
file_finder: WeakEntity<FileFinder>,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
project: Entity<Project>,
|
||||
currently_opened_path: Option<FoundPath>,
|
||||
history_items: Vec<FoundPath>,
|
||||
separate_history: bool,
|
||||
cx: &mut ViewContext<FileFinder>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<FileFinder>,
|
||||
) -> Self {
|
||||
Self::subscribe_to_updates(&project, cx);
|
||||
Self::subscribe_to_updates(&project, window, cx);
|
||||
Self {
|
||||
file_finder,
|
||||
workspace,
|
||||
|
@ -644,14 +677,18 @@ impl FileFinderDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
fn subscribe_to_updates(project: &Model<Project>, cx: &mut ViewContext<FileFinder>) {
|
||||
cx.subscribe(project, |file_finder, _, event, cx| {
|
||||
fn subscribe_to_updates(
|
||||
project: &Entity<Project>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<FileFinder>,
|
||||
) {
|
||||
cx.subscribe_in(project, window, |file_finder, _, event, window, cx| {
|
||||
match event {
|
||||
project::Event::WorktreeUpdatedEntries(_, _)
|
||||
| project::Event::WorktreeAdded(_)
|
||||
| project::Event::WorktreeRemoved(_) => file_finder
|
||||
.picker
|
||||
.update(cx, |picker, cx| picker.refresh(cx)),
|
||||
.update(cx, |picker, cx| picker.refresh(window, cx)),
|
||||
_ => {}
|
||||
};
|
||||
})
|
||||
|
@ -661,7 +698,8 @@ impl FileFinderDelegate {
|
|||
fn spawn_search(
|
||||
&mut self,
|
||||
query: FileSearchQuery,
|
||||
cx: &mut ViewContext<Picker<Self>>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let relative_to = self
|
||||
.currently_opened_path
|
||||
|
@ -692,7 +730,7 @@ impl FileFinderDelegate {
|
|||
self.cancel_flag.store(true, atomic::Ordering::Relaxed);
|
||||
self.cancel_flag = Arc::new(AtomicBool::new(false));
|
||||
let cancel_flag = self.cancel_flag.clone();
|
||||
cx.spawn(|picker, mut cx| async move {
|
||||
cx.spawn_in(window, |picker, mut cx| async move {
|
||||
let matches = fuzzy::match_path_sets(
|
||||
candidate_sets.as_slice(),
|
||||
query.path_query(),
|
||||
|
@ -722,7 +760,8 @@ impl FileFinderDelegate {
|
|||
did_cancel: bool,
|
||||
query: FileSearchQuery,
|
||||
matches: impl IntoIterator<Item = ProjectPanelOrdMatch>,
|
||||
cx: &mut ViewContext<Picker<Self>>,
|
||||
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) {
|
||||
if search_id >= self.latest_search_id {
|
||||
self.latest_search_id = search_id;
|
||||
|
@ -766,7 +805,7 @@ impl FileFinderDelegate {
|
|||
fn labels_for_match(
|
||||
&self,
|
||||
path_match: &Match,
|
||||
cx: &AppContext,
|
||||
cx: &App,
|
||||
ix: usize,
|
||||
) -> (String, Vec<usize>, String, Vec<usize>) {
|
||||
let (file_name, file_name_positions, full_path, full_path_positions) = match &path_match {
|
||||
|
@ -884,9 +923,10 @@ impl FileFinderDelegate {
|
|||
fn lookup_absolute_path(
|
||||
&self,
|
||||
query: FileSearchQuery,
|
||||
cx: &mut ViewContext<Picker<Self>>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
cx.spawn(|picker, mut cx| async move {
|
||||
cx.spawn_in(window, |picker, mut cx| async move {
|
||||
let Some(project) = picker
|
||||
.update(&mut cx, |picker, _| picker.delegate.project.clone())
|
||||
.log_err()
|
||||
|
@ -929,7 +969,7 @@ impl FileFinderDelegate {
|
|||
}
|
||||
|
||||
picker
|
||||
.update(&mut cx, |picker, cx| {
|
||||
.update_in(&mut cx, |picker, _, cx| {
|
||||
let picker_delegate = &mut picker.delegate;
|
||||
let search_id = util::post_inc(&mut picker_delegate.search_count);
|
||||
picker_delegate.set_search_matches(search_id, false, query, path_matches, cx);
|
||||
|
@ -954,10 +994,10 @@ impl FileFinderDelegate {
|
|||
0
|
||||
}
|
||||
|
||||
fn key_context(&self, cx: &WindowContext) -> KeyContext {
|
||||
fn key_context(&self, window: &Window, cx: &App) -> KeyContext {
|
||||
let mut key_context = KeyContext::new_with_defaults();
|
||||
key_context.add("FileFinder");
|
||||
if self.popover_menu_handle.is_focused(cx) {
|
||||
if self.popover_menu_handle.is_focused(window, cx) {
|
||||
key_context.add("menu_open");
|
||||
}
|
||||
key_context
|
||||
|
@ -967,7 +1007,7 @@ impl FileFinderDelegate {
|
|||
impl PickerDelegate for FileFinderDelegate {
|
||||
type ListItem = ListItem;
|
||||
|
||||
fn placeholder_text(&self, _cx: &mut WindowContext) -> Arc<str> {
|
||||
fn placeholder_text(&self, _window: &mut Window, _cx: &mut App) -> Arc<str> {
|
||||
"Search project files...".into()
|
||||
}
|
||||
|
||||
|
@ -979,7 +1019,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
self.selected_index
|
||||
}
|
||||
|
||||
fn set_selected_index(&mut self, ix: usize, cx: &mut ViewContext<Picker<Self>>) {
|
||||
fn set_selected_index(&mut self, ix: usize, _: &mut Window, cx: &mut Context<Picker<Self>>) {
|
||||
self.has_changed_selected_index = true;
|
||||
self.selected_index = ix;
|
||||
cx.notify();
|
||||
|
@ -1006,7 +1046,8 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
fn update_matches(
|
||||
&mut self,
|
||||
raw_query: String,
|
||||
cx: &mut ViewContext<Picker<Self>>,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Task<()> {
|
||||
let raw_query = raw_query.replace(' ', "");
|
||||
let raw_query = raw_query.trim();
|
||||
|
@ -1057,31 +1098,44 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
};
|
||||
|
||||
if Path::new(query.path_query()).is_absolute() {
|
||||
self.lookup_absolute_path(query, cx)
|
||||
self.lookup_absolute_path(query, window, cx)
|
||||
} else {
|
||||
self.spawn_search(query, cx)
|
||||
self.spawn_search(query, window, cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn confirm(&mut self, secondary: bool, cx: &mut ViewContext<Picker<FileFinderDelegate>>) {
|
||||
fn confirm(
|
||||
&mut self,
|
||||
secondary: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<FileFinderDelegate>>,
|
||||
) {
|
||||
if let Some(m) = self.matches.get(self.selected_index()) {
|
||||
if let Some(workspace) = self.workspace.upgrade() {
|
||||
let open_task = workspace.update(cx, move |workspace, cx| {
|
||||
let open_task = workspace.update(cx, |workspace, cx| {
|
||||
let split_or_open =
|
||||
|workspace: &mut Workspace,
|
||||
project_path,
|
||||
cx: &mut ViewContext<Workspace>| {
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Workspace>| {
|
||||
let allow_preview =
|
||||
PreviewTabsSettings::get_global(cx).enable_preview_from_file_finder;
|
||||
if secondary {
|
||||
workspace.split_path_preview(project_path, allow_preview, None, cx)
|
||||
workspace.split_path_preview(
|
||||
project_path,
|
||||
allow_preview,
|
||||
None,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
workspace.open_path_preview(
|
||||
project_path,
|
||||
None,
|
||||
true,
|
||||
allow_preview,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
|
@ -1101,6 +1155,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
worktree_id,
|
||||
path: Arc::clone(&path.project.path),
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
|
@ -1110,12 +1165,14 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
workspace.split_abs_path(
|
||||
abs_path.to_path_buf(),
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
} else {
|
||||
workspace.open_abs_path(
|
||||
abs_path.to_path_buf(),
|
||||
false,
|
||||
window,
|
||||
cx,
|
||||
)
|
||||
}
|
||||
|
@ -1126,6 +1183,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
worktree_id,
|
||||
path: Arc::clone(&path.project.path),
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
}
|
||||
|
@ -1137,6 +1195,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
worktree_id: WorktreeId::from_usize(m.0.worktree_id),
|
||||
path: m.0.path.clone(),
|
||||
},
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
}
|
||||
|
@ -1155,14 +1214,18 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
.saturating_sub(1);
|
||||
let finder = self.file_finder.clone();
|
||||
|
||||
cx.spawn(|_, mut cx| async move {
|
||||
cx.spawn_in(window, |_, mut cx| async move {
|
||||
let item = open_task.await.notify_async_err(&mut cx)?;
|
||||
if let Some(row) = row {
|
||||
if let Some(active_editor) = item.downcast::<Editor>() {
|
||||
active_editor
|
||||
.downgrade()
|
||||
.update(&mut cx, |editor, cx| {
|
||||
editor.go_to_singleton_buffer_point(Point::new(row, col), cx);
|
||||
.update_in(&mut cx, |editor, window, cx| {
|
||||
editor.go_to_singleton_buffer_point(
|
||||
Point::new(row, col),
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.log_err();
|
||||
}
|
||||
|
@ -1176,7 +1239,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
fn dismissed(&mut self, cx: &mut ViewContext<Picker<FileFinderDelegate>>) {
|
||||
fn dismissed(&mut self, _: &mut Window, cx: &mut Context<Picker<FileFinderDelegate>>) {
|
||||
self.file_finder
|
||||
.update(cx, |_, cx| cx.emit(DismissEvent))
|
||||
.log_err();
|
||||
|
@ -1186,7 +1249,8 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
&self,
|
||||
ix: usize,
|
||||
selected: bool,
|
||||
cx: &mut ViewContext<Picker<Self>>,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<Self::ListItem> {
|
||||
let settings = FileFinderSettings::get_global(cx);
|
||||
|
||||
|
@ -1237,7 +1301,11 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
)
|
||||
}
|
||||
|
||||
fn render_footer(&self, cx: &mut ViewContext<Picker<Self>>) -> Option<AnyElement> {
|
||||
fn render_footer(
|
||||
&self,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Picker<Self>>,
|
||||
) -> Option<AnyElement> {
|
||||
let context = self.focus_handle.clone();
|
||||
Some(
|
||||
h_flex()
|
||||
|
@ -1249,8 +1317,10 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
.border_color(cx.theme().colors().border_variant)
|
||||
.child(
|
||||
Button::new("open-selection", "Open")
|
||||
.key_binding(KeyBinding::for_action(&menu::Confirm, cx))
|
||||
.on_click(|_, cx| cx.dispatch_action(menu::Confirm.boxed_clone())),
|
||||
.key_binding(KeyBinding::for_action(&menu::Confirm, window))
|
||||
.on_click(|_, window, cx| {
|
||||
window.dispatch_action(menu::Confirm.boxed_clone(), cx)
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
PopoverMenu::new("menu-popover")
|
||||
|
@ -1260,13 +1330,17 @@ impl PickerDelegate for FileFinderDelegate {
|
|||
.trigger(
|
||||
Button::new("actions-trigger", "Split Options")
|
||||
.selected_label_color(Color::Accent)
|
||||
.key_binding(KeyBinding::for_action_in(&ToggleMenu, &context, cx)),
|
||||
.key_binding(KeyBinding::for_action_in(
|
||||
&ToggleMenu,
|
||||
&context,
|
||||
window,
|
||||
)),
|
||||
)
|
||||
.menu({
|
||||
move |cx| {
|
||||
Some(ContextMenu::build(cx, {
|
||||
move |window, cx| {
|
||||
Some(ContextMenu::build(window, cx, {
|
||||
let context = context.clone();
|
||||
move |menu, _| {
|
||||
move |menu, _, _| {
|
||||
menu.context(context)
|
||||
.action("Split Left", pane::SplitLeft.boxed_clone())
|
||||
.action("Split Right", pane::SplitRight.boxed_clone())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue