Inline initialization (#19711)

This restores all the init behaviour into main again. This means we
never need to call init_ui (and so we can't call it more than once).

Release Notes:

- (Nightly only) fixes a panic when using the cli to open another file
in a running zed.
This commit is contained in:
Conrad Irwin 2024-10-24 20:43:40 -06:00 committed by GitHub
parent 42a7402cc5
commit ebc3031fd9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 133 additions and 177 deletions

View file

@ -7,7 +7,6 @@ mod reliability;
mod zed;
use anyhow::{anyhow, Context as _, Result};
use assistant::PromptBuilder;
use chrono::Offset;
use clap::{command, Parser};
use cli::FORCE_CLI_MODE_ENV_VAR_NAME;
@ -136,142 +135,6 @@ fn fail_to_open_window(e: anyhow::Error, _cx: &mut AppContext) {
}
}
// init_common is called for both headless and normal mode.
fn init_common(app_state: Arc<AppState>, cx: &mut AppContext) -> Arc<PromptBuilder> {
SystemAppearance::init(cx);
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
command_palette::init(cx);
let copilot_language_server_id = app_state.languages.next_language_server_id();
copilot::init(
copilot_language_server_id,
app_state.fs.clone(),
app_state.client.http_client(),
app_state.node_runtime.clone(),
cx,
);
supermaven::init(app_state.client.clone(), cx);
language_model::init(
app_state.user_store.clone(),
app_state.client.clone(),
app_state.fs.clone(),
cx,
);
snippet_provider::init(cx);
inline_completion_registry::init(app_state.client.telemetry().clone(), cx);
let prompt_builder = assistant::init(
app_state.fs.clone(),
app_state.client.clone(),
stdout_is_a_pty(),
cx,
);
repl::init(
app_state.fs.clone(),
app_state.client.telemetry().clone(),
cx,
);
extension::init(
app_state.fs.clone(),
app_state.client.clone(),
app_state.node_runtime.clone(),
app_state.languages.clone(),
ThemeRegistry::global(cx),
cx,
);
recent_projects::init(cx);
prompt_builder
}
fn init_ui(
app_state: Arc<AppState>,
prompt_builder: Arc<PromptBuilder>,
cx: &mut AppContext,
) -> Result<()> {
load_embedded_fonts(cx);
#[cfg(target_os = "linux")]
crate::zed::linux_prompts::init(cx);
app_state.languages.set_theme(cx.theme().clone());
editor::init(cx);
image_viewer::init(cx);
diagnostics::init(cx);
audio::init(Assets, cx);
workspace::init(app_state.clone(), cx);
go_to_line::init(cx);
file_finder::init(cx);
tab_switcher::init(cx);
outline::init(cx);
project_symbols::init(cx);
project_panel::init(Assets, cx);
outline_panel::init(Assets, cx);
tasks_ui::init(cx);
snippets_ui::init(cx);
channel::init(&app_state.client.clone(), app_state.user_store.clone(), cx);
search::init(cx);
vim::init(cx);
terminal_view::init(cx);
journal::init(app_state.clone(), cx);
language_selector::init(cx);
theme_selector::init(cx);
language_tools::init(cx);
call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
collab_ui::init(&app_state, cx);
feedback::init(cx);
markdown_preview::init(cx);
welcome::init(cx);
settings_ui::init(cx);
extensions_ui::init(cx);
cx.observe_global::<SettingsStore>({
let languages = app_state.languages.clone();
let http = app_state.client.http_client();
let client = app_state.client.clone();
move |cx| {
for &mut window in cx.windows().iter_mut() {
let background_appearance = cx.theme().window_background_appearance();
window
.update(cx, |_, cx| {
cx.set_background_appearance(background_appearance)
})
.ok();
}
languages.set_theme(cx.theme().clone());
let new_host = &client::ClientSettings::get_global(cx).server_url;
if &http.base_url() != new_host {
http.set_base_url(new_host);
if client.status().borrow().is_connected() {
client.reconnect(&cx.to_async());
}
}
}
})
.detach();
let telemetry = app_state.client.telemetry();
telemetry.report_setting_event("theme", cx.theme().name.to_string());
telemetry.report_setting_event("keymap", BaseKeymap::get_global(cx).to_string());
telemetry.flush_events();
let fs = app_state.fs.clone();
load_user_themes_in_background(fs.clone(), cx);
watch_themes(fs.clone(), cx);
watch_languages(fs.clone(), app_state.languages.clone(), cx);
watch_file_types(fs.clone(), cx);
cx.set_menus(app_menus());
initialize_workspace(app_state.clone(), prompt_builder, cx);
cx.activate(true);
cx.spawn(|cx| async move { authenticate(app_state.client.clone(), &cx).await })
.detach_and_log_err(cx);
Ok(())
}
fn main() {
menu::init();
zed_actions::init();
@ -509,7 +372,133 @@ fn main() {
installation_id.clone().map(|id| id.to_string()),
cx,
);
let prompt_builder = init_common(app_state.clone(), cx);
SystemAppearance::init(cx);
theme::init(theme::LoadThemes::All(Box::new(Assets)), cx);
command_palette::init(cx);
let copilot_language_server_id = app_state.languages.next_language_server_id();
copilot::init(
copilot_language_server_id,
app_state.fs.clone(),
app_state.client.http_client(),
app_state.node_runtime.clone(),
cx,
);
supermaven::init(app_state.client.clone(), cx);
language_model::init(
app_state.user_store.clone(),
app_state.client.clone(),
app_state.fs.clone(),
cx,
);
snippet_provider::init(cx);
inline_completion_registry::init(app_state.client.telemetry().clone(), cx);
let prompt_builder = assistant::init(
app_state.fs.clone(),
app_state.client.clone(),
stdout_is_a_pty(),
cx,
);
repl::init(
app_state.fs.clone(),
app_state.client.telemetry().clone(),
cx,
);
extension::init(
app_state.fs.clone(),
app_state.client.clone(),
app_state.node_runtime.clone(),
app_state.languages.clone(),
ThemeRegistry::global(cx),
cx,
);
recent_projects::init(cx);
load_embedded_fonts(cx);
#[cfg(target_os = "linux")]
crate::zed::linux_prompts::init(cx);
app_state.languages.set_theme(cx.theme().clone());
editor::init(cx);
image_viewer::init(cx);
diagnostics::init(cx);
audio::init(Assets, cx);
workspace::init(app_state.clone(), cx);
go_to_line::init(cx);
file_finder::init(cx);
tab_switcher::init(cx);
outline::init(cx);
project_symbols::init(cx);
project_panel::init(Assets, cx);
outline_panel::init(Assets, cx);
tasks_ui::init(cx);
snippets_ui::init(cx);
channel::init(&app_state.client.clone(), app_state.user_store.clone(), cx);
search::init(cx);
vim::init(cx);
terminal_view::init(cx);
journal::init(app_state.clone(), cx);
language_selector::init(cx);
theme_selector::init(cx);
language_tools::init(cx);
call::init(app_state.client.clone(), app_state.user_store.clone(), cx);
notifications::init(app_state.client.clone(), app_state.user_store.clone(), cx);
collab_ui::init(&app_state, cx);
feedback::init(cx);
markdown_preview::init(cx);
welcome::init(cx);
settings_ui::init(cx);
extensions_ui::init(cx);
cx.observe_global::<SettingsStore>({
let languages = app_state.languages.clone();
let http = app_state.client.http_client();
let client = app_state.client.clone();
move |cx| {
for &mut window in cx.windows().iter_mut() {
let background_appearance = cx.theme().window_background_appearance();
window
.update(cx, |_, cx| {
cx.set_background_appearance(background_appearance)
})
.ok();
}
languages.set_theme(cx.theme().clone());
let new_host = &client::ClientSettings::get_global(cx).server_url;
if &http.base_url() != new_host {
http.set_base_url(new_host);
if client.status().borrow().is_connected() {
client.reconnect(&cx.to_async());
}
}
}
})
.detach();
let telemetry = app_state.client.telemetry();
telemetry.report_setting_event("theme", cx.theme().name.to_string());
telemetry.report_setting_event("keymap", BaseKeymap::get_global(cx).to_string());
telemetry.flush_events();
let fs = app_state.fs.clone();
load_user_themes_in_background(fs.clone(), cx);
watch_themes(fs.clone(), cx);
watch_languages(fs.clone(), app_state.languages.clone(), cx);
watch_file_types(fs.clone(), cx);
cx.set_menus(app_menus());
initialize_workspace(app_state.clone(), prompt_builder, cx);
cx.activate(true);
cx.spawn({
let client = app_state.client.clone();
|cx| async move { authenticate(client, &cx).await }
})
.detach_and_log_err(cx);
let args = Args::parse();
let urls: Vec<_> = args
@ -529,10 +518,9 @@ fn main() {
.and_then(|urls| OpenRequest::parse(urls, cx).log_err())
{
Some(request) => {
handle_open_request(request, app_state.clone(), prompt_builder.clone(), cx);
handle_open_request(request, app_state.clone(), cx);
}
None => {
init_ui(app_state.clone(), prompt_builder.clone(), cx).unwrap();
cx.spawn({
let app_state = app_state.clone();
|mut cx| async move {
@ -546,12 +534,11 @@ fn main() {
}
let app_state = app_state.clone();
let prompt_builder = prompt_builder.clone();
cx.spawn(move |cx| async move {
while let Some(urls) = open_rx.next().await {
cx.update(|cx| {
if let Some(request) = OpenRequest::parse(urls, cx).log_err() {
handle_open_request(request, app_state.clone(), prompt_builder.clone(), cx);
handle_open_request(request, app_state.clone(), cx);
}
})
.ok();
@ -621,24 +608,14 @@ fn handle_settings_changed(error: Option<anyhow::Error>, cx: &mut AppContext) {
}
}
fn handle_open_request(
request: OpenRequest,
app_state: Arc<AppState>,
prompt_builder: Arc<PromptBuilder>,
cx: &mut AppContext,
) {
fn handle_open_request(request: OpenRequest, app_state: Arc<AppState>, cx: &mut AppContext) {
if let Some(connection) = request.cli_connection {
let app_state = app_state.clone();
cx.spawn(move |cx| handle_cli_connection(connection, app_state, prompt_builder, cx))
cx.spawn(move |cx| handle_cli_connection(connection, app_state, cx))
.detach();
return;
}
if let Err(e) = init_ui(app_state.clone(), prompt_builder, cx) {
fail_to_open_window(e, cx);
return;
};
if let Some(connection_info) = request.ssh_connection {
cx.spawn(|mut cx| async move {
let nickname = cx

View file

@ -1,7 +1,6 @@
use crate::handle_open_request;
use crate::restorable_workspace_locations;
use crate::{handle_open_request, init_ui};
use anyhow::{anyhow, Context, Result};
use assistant::PromptBuilder;
use cli::{ipc, IpcHandshake};
use cli::{ipc::IpcSender, CliRequest, CliResponse};
use client::parse_zed_link;
@ -252,7 +251,6 @@ pub async fn open_paths_with_positions(
pub async fn handle_cli_connection(
(mut requests, responses): (mpsc::Receiver<CliRequest>, IpcSender<CliResponse>),
app_state: Arc<AppState>,
prompt_builder: Arc<PromptBuilder>,
mut cx: AsyncAppContext,
) {
if let Some(request) = requests.next().await {
@ -262,19 +260,13 @@ pub async fn handle_cli_connection(
paths,
wait,
open_new_workspace,
env,
} => {
if !urls.is_empty() {
cx.update(|cx| {
match OpenRequest::parse(urls, cx) {
Ok(open_request) => {
handle_open_request(
open_request,
app_state.clone(),
prompt_builder.clone(),
cx,
);
handle_open_request(open_request, app_state.clone(), cx);
responses.send(CliResponse::Exit { status: 0 }).log_err();
}
Err(e) => {
@ -291,19 +283,6 @@ pub async fn handle_cli_connection(
return;
}
if let Err(e) = cx
.update(|cx| init_ui(app_state.clone(), prompt_builder.clone(), cx))
.and_then(|r| r)
{
responses
.send(CliResponse::Stderr {
message: format!("{e}"),
})
.log_err();
responses.send(CliResponse::Exit { status: 1 }).log_err();
return;
}
let open_workspace_result = open_workspaces(
paths,
open_new_workspace,