zed: Fix formatting in workspace initialization (#22152)

This PR fixes some formatting issues in the workspace initialization
code that stemmed from certain constructs causing `rustfmt` to bail out
of the formatting.

The bulk of the content of `initialize_workspace` has been factored out
into functions, as having nested closures within closures seems to be
the primary cause of `rustfmt` being unhappy.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2024-12-17 16:34:52 -05:00 committed by GitHub
parent fa1b1c6aff
commit e1ca5ed836
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -153,51 +153,19 @@ pub fn initialize_workspace(
.detach(); .detach();
#[cfg(any(target_os = "linux", target_os = "freebsd"))] #[cfg(any(target_os = "linux", target_os = "freebsd"))]
if let Err(e) = fs::linux_watcher::global(|_| {}) { initialize_linux_file_watcher(cx);
let message = format!(db::indoc!{r#"
inotify_init returned {}
This may be due to system-wide limits on inotify instances. For troubleshooting see: https://zed.dev/docs/linux
"#}, e);
let prompt = cx.prompt(PromptLevel::Critical, "Could not start inotify", Some(&message),
&["Troubleshoot and Quit"]);
cx.spawn(|_, mut cx| async move {
if prompt.await == Ok(0) {
cx.update(|cx| {
cx.open_url("https://zed.dev/docs/linux#could-not-start-inotify");
cx.quit();
}).ok();
}
}).detach()
}
if let Some(specs) = cx.gpu_specs() { if let Some(specs) = cx.gpu_specs() {
log::info!("Using GPU: {:?}", specs); log::info!("Using GPU: {:?}", specs);
if specs.is_software_emulated && std::env::var("ZED_ALLOW_EMULATED_GPU").is_err() { show_software_emulation_warning_if_needed(specs, cx);
let message = format!(db::indoc!{r#"
Zed uses Vulkan for rendering and requires a compatible GPU.
Currently you are using a software emulated GPU ({}) which
will result in awful performance.
For troubleshooting see: https://zed.dev/docs/linux
Set ZED_ALLOW_EMULATED_GPU=1 env var to permanently override.
"#}, specs.device_name);
let prompt = cx.prompt(PromptLevel::Critical, "Unsupported GPU", Some(&message),
&["Skip", "Troubleshoot and Quit"]);
cx.spawn(|_, mut cx| async move {
if prompt.await == Ok(1) {
cx.update(|cx| {
cx.open_url("https://zed.dev/docs/linux#zed-fails-to-open-windows");
cx.quit();
}).ok();
}
}).detach()
}
} }
let inline_completion_button = cx.new_view(|cx| { let inline_completion_button = cx.new_view(|cx| {
inline_completion_button::InlineCompletionButton::new(workspace.weak_handle(), app_state.fs.clone(), cx) inline_completion_button::InlineCompletionButton::new(
workspace.weak_handle(),
app_state.fs.clone(),
cx,
)
}); });
let diagnostic_summary = let diagnostic_summary =
@ -225,7 +193,6 @@ pub fn initialize_workspace(
let handle = cx.view().downgrade(); let handle = cx.view().downgrade();
cx.on_window_should_close(move |cx| { cx.on_window_should_close(move |cx| {
handle handle
.update(cx, |workspace, cx| { .update(cx, |workspace, cx| {
// We'll handle closing asynchronously // We'll handle closing asynchronously
@ -235,390 +202,8 @@ pub fn initialize_workspace(
.unwrap_or(true) .unwrap_or(true)
}); });
let release_channel = ReleaseChannel::global(cx); initialize_panels(prompt_builder.clone(), cx);
let assistant2_feature_flag = cx.wait_for_flag::<feature_flags::Assistant2FeatureFlag>(); register_actions(app_state.clone(), workspace, cx);
let git_ui_feature_flag = cx.wait_for_flag::<feature_flags::GitUiFeatureFlag>();
let prompt_builder = prompt_builder.clone();
cx.spawn(|workspace_handle, mut cx| async move {
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
let outline_panel = OutlinePanel::load(workspace_handle.clone(), cx.clone());
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
let channels_panel =
collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
let chat_panel =
collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
workspace_handle.clone(),
cx.clone(),
);
let assistant_panel =
assistant::AssistantPanel::load(workspace_handle.clone(), prompt_builder, cx.clone());
let (
project_panel,
outline_panel,
terminal_panel,
channels_panel,
chat_panel,
notification_panel,
assistant_panel,
) = futures::try_join!(
project_panel,
outline_panel,
terminal_panel,
channels_panel,
chat_panel,
notification_panel,
assistant_panel,
)?;
workspace_handle.update(&mut cx, |workspace, cx| {
workspace.add_panel(project_panel, cx);
workspace.add_panel(outline_panel, cx);
workspace.add_panel(terminal_panel, cx);
workspace.add_panel(channels_panel, cx);
workspace.add_panel(chat_panel, cx);
workspace.add_panel(notification_panel, cx);
workspace.add_panel(assistant_panel, cx);
})?;
let git_ui_enabled = git_ui_feature_flag.await;
let git_panel = if git_ui_enabled {
Some(git_ui::git_panel::GitPanel::load(workspace_handle.clone(), cx.clone()).await?)
} else {
None
};
workspace_handle.update(&mut cx, |workspace, cx| {
if let Some(git_panel) = git_panel {
workspace.add_panel(git_panel, cx);
}
})?;
let is_assistant2_enabled =
if cfg!(test) || release_channel != ReleaseChannel::Dev {
false
} else {
assistant2_feature_flag.await
};
let assistant2_panel = if is_assistant2_enabled {
Some(assistant2::AssistantPanel::load(workspace_handle.clone(), cx.clone()).await?)
} else {
None
};
workspace_handle.update(&mut cx, |workspace, cx| {
if let Some(assistant2_panel) = assistant2_panel {
workspace.add_panel(assistant2_panel, cx);
}
if is_assistant2_enabled {
workspace.register_action(assistant2::InlineAssistant::inline_assist);
} else {
workspace.register_action(assistant::AssistantPanel::inline_assist);
}
})
})
.detach();
workspace
.register_action(about)
.register_action(|_, _: &Minimize, cx| {
cx.minimize_window();
})
.register_action(|_, _: &Zoom, cx| {
cx.zoom_window();
})
.register_action(|_, _: &ToggleFullScreen, cx| {
cx.toggle_fullscreen();
})
.register_action(|_, action: &OpenZedUrl, cx| {
OpenListener::global(cx).open_urls(vec![action.url.clone()])
})
.register_action(|_, action: &OpenBrowser, cx| cx.open_url(&action.url))
.register_action(move |_, _: &zed_actions::IncreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size += px(1.0))
})
.register_action(|workspace, _: &workspace::Open, cx| {
workspace.client()
.telemetry()
.report_app_event("open project".to_string());
let paths = workspace.prompt_for_open_path(
PathPromptOptions {
files: true,
directories: true,
multiple: true,
},
DirectoryLister::Project(workspace.project().clone()),
cx,
);
cx.spawn(|this, mut cx| async move {
let Some(paths) = paths.await.log_err().flatten() else {
return;
};
if let Some(task) = this
.update(&mut cx, |this, cx| {
if this.project().read(cx).is_local() {
this.open_workspace_for_paths(false, paths, cx)
} else {
open_new_ssh_project_from_project(this, paths, cx)
}
})
.log_err()
{
task.await.log_err();
}
})
.detach()
})
.register_action(move |_, _: &zed_actions::DecreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size -= px(1.0))
})
.register_action(move |_, _: &zed_actions::ResetBufferFontSize, cx| {
theme::reset_buffer_font_size(cx)
})
.register_action(move |_, _: &zed_actions::IncreaseUiFontSize, cx| {
theme::adjust_ui_font_size(cx, |size| *size += px(1.0))
})
.register_action(move |_, _: &zed_actions::DecreaseUiFontSize, cx| {
theme::adjust_ui_font_size(cx, |size| *size -= px(1.0))
})
.register_action(move |_, _: &zed_actions::ResetUiFontSize, cx| {
theme::reset_ui_font_size(cx)
})
.register_action(move |_, _: &zed_actions::IncreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size += px(1.0))
})
.register_action(move |_, _: &zed_actions::DecreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size -= px(1.0))
})
.register_action(move |_, _: &zed_actions::ResetBufferFontSize, cx| {
theme::reset_buffer_font_size(cx)
})
.register_action(|_, _: &install_cli::Install, cx| {
cx.spawn(|workspace, mut cx| async move {
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
let prompt = cx.prompt(
PromptLevel::Warning,
"CLI should already be installed",
Some("If you installed Zed from our official release add ~/.local/bin to your PATH.\n\nIf you installed Zed from a different source like your package manager, then you may need to create an alias/symlink manually.\n\nDepending on your package manager, the CLI might be named zeditor, zedit, zed-editor or something else."),
&["Ok"],
);
cx.background_executor().spawn(prompt).detach();
return Ok(());
}
let path = install_cli::install_cli(cx.deref())
.await
.context("error creating CLI symlink")?;
workspace.update(&mut cx, |workspace, cx| {
struct InstalledZedCli;
workspace.show_toast(
Toast::new(
NotificationId::unique::<InstalledZedCli>(),
format!(
"Installed `zed` to {}. You can launch {} from your terminal.",
path.to_string_lossy(),
ReleaseChannel::global(cx).display_name()
),
),
cx,
)
})?;
register_zed_scheme(&cx).await.log_err();
Ok(())
})
.detach_and_prompt_err("Error installing zed cli", cx, |_, _| None);
})
.register_action(|_, _: &install_cli::RegisterZedScheme, cx| {
cx.spawn(|workspace, mut cx| async move {
register_zed_scheme(&cx).await?;
workspace.update(&mut cx, |workspace, cx| {
struct RegisterZedScheme;
workspace.show_toast(
Toast::new(
NotificationId::unique::<RegisterZedScheme>(),
format!(
"zed:// links will now open in {}.",
ReleaseChannel::global(cx).display_name()
),
),
cx,
)
})?;
Ok(())
})
.detach_and_prompt_err(
"Error registering zed:// scheme",
cx,
|_, _| None,
);
})
.register_action(|workspace, _: &OpenLog, cx| {
open_log_file(workspace, cx);
})
.register_action(|workspace, _: &zed_actions::OpenLicenses, cx| {
open_bundled_file(
workspace,
asset_str::<Assets>("licenses.md"),
"Open Source License Attribution",
"Markdown",
cx,
);
})
.register_action(
move |workspace: &mut Workspace,
_: &zed_actions::OpenTelemetryLog,
cx: &mut ViewContext<Workspace>| {
open_telemetry_log_file(workspace, cx);
},
)
.register_action(
move |_: &mut Workspace,
_: &zed_actions::OpenKeymap,
cx: &mut ViewContext<Workspace>| {
open_settings_file(paths::keymap_file(), || settings::initial_keymap_content().as_ref().into(), cx);
},
)
.register_action(
move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
open_settings_file(
paths::settings_file(),
|| settings::initial_user_settings_content().as_ref().into(),
cx,
);
},
)
.register_action(
|_: &mut Workspace, _: &OpenAccountSettings, cx: &mut ViewContext<Workspace>| {
cx.open_url(&zed_urls::account_url(cx));
},
)
.register_action(
move |_: &mut Workspace, _: &OpenTasks, cx: &mut ViewContext<Workspace>| {
open_settings_file(
paths::tasks_file(),
|| settings::initial_tasks_content().as_ref().into(),
cx,
);
},
)
.register_action(open_project_settings_file)
.register_action(open_project_tasks_file)
.register_action(
move |workspace: &mut Workspace,
_: &zed_actions::OpenDefaultKeymap,
cx: &mut ViewContext<Workspace>| {
open_bundled_file(
workspace,
settings::default_keymap(),
"Default Key Bindings",
"JSON",
cx,
);
},
)
.register_action(
move |workspace: &mut Workspace,
_: &OpenDefaultSettings,
cx: &mut ViewContext<Workspace>| {
open_bundled_file(
workspace,
settings::default_settings(),
"Default Settings",
"JSON",
cx,
);
},
)
.register_action(
|workspace: &mut Workspace,
_: &project_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<ProjectPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &outline_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<OutlinePanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &collab_ui::collab_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<collab_ui::collab_panel::CollabPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &collab_ui::chat_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<collab_ui::chat_panel::ChatPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &collab_ui::notification_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace
.toggle_panel_focus::<collab_ui::notification_panel::NotificationPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &terminal_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<TerminalPanel>(cx);
},
)
.register_action({
let app_state = Arc::downgrade(&app_state);
move |_, _: &NewWindow, cx| {
if let Some(app_state) = app_state.upgrade() {
open_new(Default::default(), app_state, cx, |workspace, cx| {
Editor::new_file(workspace, &Default::default(), cx)
})
.detach();
}
}
})
.register_action({
let app_state = Arc::downgrade(&app_state);
move |_, _: &NewFile, cx| {
if let Some(app_state) = app_state.upgrade() {
open_new(Default::default(), app_state, cx, |workspace, cx| {
Editor::new_file(workspace, &Default::default(), cx)
})
.detach();
}
}
});
if workspace.project().read(cx).is_via_ssh() {
workspace.register_action({
move |workspace, _: &OpenServerSettings, cx| {
let open_server_settings = workspace.project().update(cx, |project, cx| {
project.open_server_settings(cx)
});
cx.spawn(|workspace, mut cx| async move {
let buffer = open_server_settings.await?;
workspace.update(&mut cx, |workspace, cx| {
workspace.open_path(buffer.read(cx).project_path(cx).expect("Settings file must have a location"), None, true, cx)
})?.await?;
anyhow::Ok(())
}).detach_and_log_err(cx);
}
});
}
workspace.focus_handle(cx).focus(cx); workspace.focus_handle(cx).focus(cx);
}) })
@ -648,6 +233,441 @@ fn feature_gate_zed_pro_actions(cx: &mut AppContext) {
.detach(); .detach();
} }
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
fn initialize_linux_file_watcher(cx: &mut ViewContext<Workspace>) {
if let Err(e) = fs::linux_watcher::global(|_| {}) {
let message = format!(
db::indoc! {r#"
inotify_init returned {}
This may be due to system-wide limits on inotify instances. For troubleshooting see: https://zed.dev/docs/linux
"#},
e
);
let prompt = cx.prompt(
PromptLevel::Critical,
"Could not start inotify",
Some(&message),
&["Troubleshoot and Quit"],
);
cx.spawn(|_, mut cx| async move {
if prompt.await == Ok(0) {
cx.update(|cx| {
cx.open_url("https://zed.dev/docs/linux#could-not-start-inotify");
cx.quit();
})
.ok();
}
})
.detach()
}
}
fn show_software_emulation_warning_if_needed(
specs: gpui::GPUSpecs,
cx: &mut ViewContext<Workspace>,
) {
if specs.is_software_emulated && std::env::var("ZED_ALLOW_EMULATED_GPU").is_err() {
let message = format!(
db::indoc! {r#"
Zed uses Vulkan for rendering and requires a compatible GPU.
Currently you are using a software emulated GPU ({}) which
will result in awful performance.
For troubleshooting see: https://zed.dev/docs/linux
Set ZED_ALLOW_EMULATED_GPU=1 env var to permanently override.
"#},
specs.device_name
);
let prompt = cx.prompt(
PromptLevel::Critical,
"Unsupported GPU",
Some(&message),
&["Skip", "Troubleshoot and Quit"],
);
cx.spawn(|_, mut cx| async move {
if prompt.await == Ok(1) {
cx.update(|cx| {
cx.open_url("https://zed.dev/docs/linux#zed-fails-to-open-windows");
cx.quit();
})
.ok();
}
})
.detach()
}
}
fn initialize_panels(prompt_builder: Arc<PromptBuilder>, cx: &mut ViewContext<Workspace>) {
let release_channel = ReleaseChannel::global(cx);
let assistant2_feature_flag = cx.wait_for_flag::<feature_flags::Assistant2FeatureFlag>();
let git_ui_feature_flag = cx.wait_for_flag::<feature_flags::GitUiFeatureFlag>();
let prompt_builder = prompt_builder.clone();
cx.spawn(|workspace_handle, mut cx| async move {
let project_panel = ProjectPanel::load(workspace_handle.clone(), cx.clone());
let outline_panel = OutlinePanel::load(workspace_handle.clone(), cx.clone());
let terminal_panel = TerminalPanel::load(workspace_handle.clone(), cx.clone());
let channels_panel =
collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
let chat_panel =
collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
workspace_handle.clone(),
cx.clone(),
);
let assistant_panel =
assistant::AssistantPanel::load(workspace_handle.clone(), prompt_builder, cx.clone());
let (
project_panel,
outline_panel,
terminal_panel,
channels_panel,
chat_panel,
notification_panel,
assistant_panel,
) = futures::try_join!(
project_panel,
outline_panel,
terminal_panel,
channels_panel,
chat_panel,
notification_panel,
assistant_panel,
)?;
workspace_handle.update(&mut cx, |workspace, cx| {
workspace.add_panel(project_panel, cx);
workspace.add_panel(outline_panel, cx);
workspace.add_panel(terminal_panel, cx);
workspace.add_panel(channels_panel, cx);
workspace.add_panel(chat_panel, cx);
workspace.add_panel(notification_panel, cx);
workspace.add_panel(assistant_panel, cx);
})?;
let git_ui_enabled = git_ui_feature_flag.await;
let git_panel = if git_ui_enabled {
Some(git_ui::git_panel::GitPanel::load(workspace_handle.clone(), cx.clone()).await?)
} else {
None
};
workspace_handle.update(&mut cx, |workspace, cx| {
if let Some(git_panel) = git_panel {
workspace.add_panel(git_panel, cx);
}
})?;
let is_assistant2_enabled = if cfg!(test) || release_channel != ReleaseChannel::Dev {
false
} else {
assistant2_feature_flag.await
};
let assistant2_panel = if is_assistant2_enabled {
Some(assistant2::AssistantPanel::load(workspace_handle.clone(), cx.clone()).await?)
} else {
None
};
workspace_handle.update(&mut cx, |workspace, cx| {
if let Some(assistant2_panel) = assistant2_panel {
workspace.add_panel(assistant2_panel, cx);
}
if is_assistant2_enabled {
workspace.register_action(assistant2::InlineAssistant::inline_assist);
} else {
workspace.register_action(assistant::AssistantPanel::inline_assist);
}
})
})
.detach();
}
fn register_actions(
app_state: Arc<AppState>,
workspace: &mut Workspace,
cx: &mut ViewContext<Workspace>,
) {
workspace
.register_action(about)
.register_action(|_, _: &Minimize, cx| {
cx.minimize_window();
})
.register_action(|_, _: &Zoom, cx| {
cx.zoom_window();
})
.register_action(|_, _: &ToggleFullScreen, cx| {
cx.toggle_fullscreen();
})
.register_action(|_, action: &OpenZedUrl, cx| {
OpenListener::global(cx).open_urls(vec![action.url.clone()])
})
.register_action(|_, action: &OpenBrowser, cx| cx.open_url(&action.url))
.register_action(move |_, _: &zed_actions::IncreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size += px(1.0))
})
.register_action(|workspace, _: &workspace::Open, cx| {
workspace
.client()
.telemetry()
.report_app_event("open project".to_string());
let paths = workspace.prompt_for_open_path(
PathPromptOptions {
files: true,
directories: true,
multiple: true,
},
DirectoryLister::Project(workspace.project().clone()),
cx,
);
cx.spawn(|this, mut cx| async move {
let Some(paths) = paths.await.log_err().flatten() else {
return;
};
if let Some(task) = this
.update(&mut cx, |this, cx| {
if this.project().read(cx).is_local() {
this.open_workspace_for_paths(false, paths, cx)
} else {
open_new_ssh_project_from_project(this, paths, cx)
}
})
.log_err()
{
task.await.log_err();
}
})
.detach()
})
.register_action(move |_, _: &zed_actions::DecreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size -= px(1.0))
})
.register_action(move |_, _: &zed_actions::ResetBufferFontSize, cx| {
theme::reset_buffer_font_size(cx)
})
.register_action(move |_, _: &zed_actions::IncreaseUiFontSize, cx| {
theme::adjust_ui_font_size(cx, |size| *size += px(1.0))
})
.register_action(move |_, _: &zed_actions::DecreaseUiFontSize, cx| {
theme::adjust_ui_font_size(cx, |size| *size -= px(1.0))
})
.register_action(move |_, _: &zed_actions::ResetUiFontSize, cx| {
theme::reset_ui_font_size(cx)
})
.register_action(move |_, _: &zed_actions::IncreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size += px(1.0))
})
.register_action(move |_, _: &zed_actions::DecreaseBufferFontSize, cx| {
theme::adjust_buffer_font_size(cx, |size| *size -= px(1.0))
})
.register_action(move |_, _: &zed_actions::ResetBufferFontSize, cx| {
theme::reset_buffer_font_size(cx)
})
.register_action(install_cli)
.register_action(|_, _: &install_cli::RegisterZedScheme, cx| {
cx.spawn(|workspace, mut cx| async move {
register_zed_scheme(&cx).await?;
workspace.update(&mut cx, |workspace, cx| {
struct RegisterZedScheme;
workspace.show_toast(
Toast::new(
NotificationId::unique::<RegisterZedScheme>(),
format!(
"zed:// links will now open in {}.",
ReleaseChannel::global(cx).display_name()
),
),
cx,
)
})?;
Ok(())
})
.detach_and_prompt_err("Error registering zed:// scheme", cx, |_, _| None);
})
.register_action(|workspace, _: &OpenLog, cx| {
open_log_file(workspace, cx);
})
.register_action(|workspace, _: &zed_actions::OpenLicenses, cx| {
open_bundled_file(
workspace,
asset_str::<Assets>("licenses.md"),
"Open Source License Attribution",
"Markdown",
cx,
);
})
.register_action(
move |workspace: &mut Workspace,
_: &zed_actions::OpenTelemetryLog,
cx: &mut ViewContext<Workspace>| {
open_telemetry_log_file(workspace, cx);
},
)
.register_action(
move |_: &mut Workspace,
_: &zed_actions::OpenKeymap,
cx: &mut ViewContext<Workspace>| {
open_settings_file(
paths::keymap_file(),
|| settings::initial_keymap_content().as_ref().into(),
cx,
);
},
)
.register_action(
move |_: &mut Workspace, _: &OpenSettings, cx: &mut ViewContext<Workspace>| {
open_settings_file(
paths::settings_file(),
|| settings::initial_user_settings_content().as_ref().into(),
cx,
);
},
)
.register_action(
|_: &mut Workspace, _: &OpenAccountSettings, cx: &mut ViewContext<Workspace>| {
cx.open_url(&zed_urls::account_url(cx));
},
)
.register_action(
move |_: &mut Workspace, _: &OpenTasks, cx: &mut ViewContext<Workspace>| {
open_settings_file(
paths::tasks_file(),
|| settings::initial_tasks_content().as_ref().into(),
cx,
);
},
)
.register_action(open_project_settings_file)
.register_action(open_project_tasks_file)
.register_action(
move |workspace: &mut Workspace,
_: &zed_actions::OpenDefaultKeymap,
cx: &mut ViewContext<Workspace>| {
open_bundled_file(
workspace,
settings::default_keymap(),
"Default Key Bindings",
"JSON",
cx,
);
},
)
.register_action(
move |workspace: &mut Workspace,
_: &OpenDefaultSettings,
cx: &mut ViewContext<Workspace>| {
open_bundled_file(
workspace,
settings::default_settings(),
"Default Settings",
"JSON",
cx,
);
},
)
.register_action(
|workspace: &mut Workspace,
_: &project_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<ProjectPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &outline_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<OutlinePanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &collab_ui::collab_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<collab_ui::collab_panel::CollabPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &collab_ui::chat_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<collab_ui::chat_panel::ChatPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &collab_ui::notification_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace
.toggle_panel_focus::<collab_ui::notification_panel::NotificationPanel>(cx);
},
)
.register_action(
|workspace: &mut Workspace,
_: &terminal_panel::ToggleFocus,
cx: &mut ViewContext<Workspace>| {
workspace.toggle_panel_focus::<TerminalPanel>(cx);
},
)
.register_action({
let app_state = Arc::downgrade(&app_state);
move |_, _: &NewWindow, cx| {
if let Some(app_state) = app_state.upgrade() {
open_new(Default::default(), app_state, cx, |workspace, cx| {
Editor::new_file(workspace, &Default::default(), cx)
})
.detach();
}
}
})
.register_action({
let app_state = Arc::downgrade(&app_state);
move |_, _: &NewFile, cx| {
if let Some(app_state) = app_state.upgrade() {
open_new(Default::default(), app_state, cx, |workspace, cx| {
Editor::new_file(workspace, &Default::default(), cx)
})
.detach();
}
}
});
if workspace.project().read(cx).is_via_ssh() {
workspace.register_action({
move |workspace, _: &OpenServerSettings, cx| {
let open_server_settings = workspace
.project()
.update(cx, |project, cx| project.open_server_settings(cx));
cx.spawn(|workspace, mut cx| async move {
let buffer = open_server_settings.await?;
workspace
.update(&mut cx, |workspace, cx| {
workspace.open_path(
buffer
.read(cx)
.project_path(cx)
.expect("Settings file must have a location"),
None,
true,
cx,
)
})?
.await?;
anyhow::Ok(())
})
.detach_and_log_err(cx);
}
});
}
}
fn initialize_pane(workspace: &Workspace, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) { fn initialize_pane(workspace: &Workspace, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
pane.update(cx, |pane, cx| { pane.update(cx, |pane, cx| {
pane.toolbar().update(cx, |toolbar, cx| { pane.toolbar().update(cx, |toolbar, cx| {
@ -694,6 +714,45 @@ fn test_panic(_: &TestPanic, _: &mut AppContext) {
panic!("Ran the TestPanic action") panic!("Ran the TestPanic action")
} }
fn install_cli(_: &mut Workspace, _: &install_cli::Install, cx: &mut ViewContext<Workspace>) {
const LINUX_PROMPT_DETAIL: &str = "If you installed Zed from our official release add ~/.local/bin to your PATH.\n\nIf you installed Zed from a different source like your package manager, then you may need to create an alias/symlink manually.\n\nDepending on your package manager, the CLI might be named zeditor, zedit, zed-editor or something else.";
cx.spawn(|workspace, mut cx| async move {
if cfg!(any(target_os = "linux", target_os = "freebsd")) {
let prompt = cx.prompt(
PromptLevel::Warning,
"CLI should already be installed",
Some(LINUX_PROMPT_DETAIL),
&["Ok"],
);
cx.background_executor().spawn(prompt).detach();
return Ok(());
}
let path = install_cli::install_cli(cx.deref())
.await
.context("error creating CLI symlink")?;
workspace.update(&mut cx, |workspace, cx| {
struct InstalledZedCli;
workspace.show_toast(
Toast::new(
NotificationId::unique::<InstalledZedCli>(),
format!(
"Installed `zed` to {}. You can launch {} from your terminal.",
path.to_string_lossy(),
ReleaseChannel::global(cx).display_name()
),
),
cx,
)
})?;
register_zed_scheme(&cx).await.log_err();
Ok(())
})
.detach_and_prompt_err("Error installing zed cli", cx, |_, _| None);
}
fn quit(_: &Quit, cx: &mut AppContext) { fn quit(_: &Quit, cx: &mut AppContext) {
let should_confirm = WorkspaceSettings::get_global(cx).confirm_quit; let should_confirm = WorkspaceSettings::get_global(cx).confirm_quit;
cx.spawn(|mut cx| async move { cx.spawn(|mut cx| async move {