Files
zed/crates/git_ui_core/src/notifications.rs
T
Kirill Bulatov 21f16f7b5b Speed up cargo build -p zed compilation (#62059)
Splits the crate graph.
Before, the compilation graph: `editor → picker_preview → search →
project_panel → open_path_prompt → recent_projects → title_bar →
collab_ui → zed`
After, the compilation graph: `editor → picker_preview → search →
agent_ui → sidebar → zed`

With sccache disabled and project fully built, `touch
crates/editor/src/editor.rs` and `cargo build -p zed` took time
Before (5e1fd392f6): 13.19s
After: 11.85s (-10.2% speed up)

Each commit contains a separate compilation instructions, and a test in
the final commit.
The main approach is to split coupled crates and replace them with
`zed_actions` and move some shared functionality into `git_ui_core` new,
shared module.

I've also tried to add a test to prevent common pitfalls, but not sure
I'm happy with the end result — can remove it if it looks too synthetic.

Release Notes:

- N/A
2026-08-01 19:42:37 +00:00

134 lines
4.2 KiB
Rust

use editor::Editor;
use gpui::{App, Context, Entity, SharedString};
use language::Buffer;
use notifications::status_toast::StatusToast;
use proto::RpcError;
use ui::prelude::*;
use workspace::Workspace;
pub fn open_output(
operation: impl Into<SharedString>,
workspace: &mut Workspace,
output: &str,
window: &mut Window,
cx: &mut Context<Workspace>,
) {
let operation = operation.into();
let plain_text = terminal::strip_ansi_text(output.as_bytes());
let buffer = cx.new(|cx| Buffer::local(plain_text.as_str(), cx));
buffer.update(cx, |buffer, cx| {
buffer.set_capability(language::Capability::ReadOnly, cx);
});
let editor = cx.new(|cx| {
let mut editor = Editor::for_buffer(buffer, None, window, cx);
editor.buffer().update(cx, |buffer, cx| {
buffer.set_title(format!("Output from git {operation}"), cx);
});
editor.set_read_only(true);
editor
});
workspace.add_item_to_center(Box::new(editor), window, cx);
}
pub fn show_error_toast(
workspace: Entity<Workspace>,
action: impl Into<SharedString>,
e: anyhow::Error,
cx: &mut App,
) {
let action = action.into();
let message = format_git_error_toast_message(&e);
if message
.matches(git::repository::REMOTE_CANCELLED_BY_USER)
.next()
.is_some()
{ // Hide the cancelled by user message
} else {
cx.defer(move |cx| {
workspace.update(cx, |workspace, cx| {
let workspace_weak = cx.weak_entity();
let toast = StatusToast::new(format!("git {} failed", action), cx, |this, _cx| {
this.icon(
Icon::new(IconName::XCircle)
.size(IconSize::Small)
.color(Color::Error),
)
.action("View Log", move |window, cx| {
let message = message.clone();
let action = action.clone();
workspace_weak
.update(cx, move |workspace, cx| {
open_output(action, workspace, &message, window, cx)
})
.ok();
})
});
workspace.toggle_status_toast(toast, cx)
});
});
}
}
fn rpc_error_raw_message_from_chain(error: &anyhow::Error) -> Option<&str> {
error
.chain()
.find_map(|cause| cause.downcast_ref::<RpcError>().map(RpcError::raw_message))
}
fn format_git_error_toast_message(error: &anyhow::Error) -> String {
if let Some(message) = rpc_error_raw_message_from_chain(error) {
message.trim().to_string()
} else {
error.to_string().trim().to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_git_error_toast_message_prefers_raw_rpc_message() {
let rpc_error = RpcError::from_proto(
&proto::Error {
message:
"Your local changes to the following files would be overwritten by merge\n"
.to_string(),
code: proto::ErrorCode::Internal as i32,
tags: Default::default(),
},
"Pull",
);
let message = format_git_error_toast_message(&rpc_error);
assert_eq!(
message,
"Your local changes to the following files would be overwritten by merge"
);
}
#[test]
fn test_format_git_error_toast_message_prefers_raw_rpc_message_when_wrapped() {
let rpc_error = RpcError::from_proto(
&proto::Error {
message:
"Your local changes to the following files would be overwritten by merge\n"
.to_string(),
code: proto::ErrorCode::Internal as i32,
tags: Default::default(),
},
"Pull",
);
let wrapped = rpc_error.context("sending pull request");
let message = format_git_error_toast_message(&wrapped);
assert_eq!(
message,
"Your local changes to the following files would be overwritten by merge"
);
}
}