diff --git a/crates/context_server/src/transport/stdio_transport.rs b/crates/context_server/src/transport/stdio_transport.rs index 443b8c16f160394f4bede9a72315b4e80c652726..83908b46829c4cfe3b536ecca1155c909ee424dd 100644 --- a/crates/context_server/src/transport/stdio_transport.rs +++ b/crates/context_server/src/transport/stdio_transport.rs @@ -41,12 +41,9 @@ impl StdioTransport { command.current_dir(working_directory); } - let mut server = command.spawn().with_context(|| { - format!( - "failed to spawn command. (path={:?}, args={:?})", - binary.executable, &binary.args - ) - })?; + let mut server = command + .spawn() + .with_context(|| format!("failed to spawn command {command:?})",))?; let stdin = server.stdin.take().unwrap(); let stdout = server.stdout.take().unwrap(); diff --git a/crates/dap/src/transport.rs b/crates/dap/src/transport.rs index 7d0af4d0b3048092933c00bfe2f5d755e00d34d3..50ffb4b7820517f380909ae2ecad160a31afdd54 100644 --- a/crates/dap/src/transport.rs +++ b/crates/dap/src/transport.rs @@ -674,13 +674,7 @@ impl StdioTransport { command.args(&binary.arguments); command.envs(&binary.envs); - let mut process = Child::spawn(command, Stdio::piped()).with_context(|| { - format!( - "failed to spawn command `{} {}`.", - binary_command, - binary.arguments.join(" ") - ) - })?; + let mut process = Child::spawn(command, Stdio::piped())?; let err_task = process.stderr.take().map(|stderr| { cx.background_spawn(TransportDelegate::handle_adapter_log( @@ -1058,11 +1052,13 @@ impl Child { #[cfg(not(windows))] fn spawn(mut command: std::process::Command, stdin: Stdio) -> Result { util::set_pre_exec_to_start_new_session(&mut command); - let process = smol::process::Command::from(command) + let mut command = smol::process::Command::from(command); + let process = command .stdin(stdin) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()?; + .spawn() + .with_context(|| format!("failed to spawn command `{command:?}`",))?; Ok(Self { process }) } @@ -1070,11 +1066,13 @@ impl Child { fn spawn(command: std::process::Command, stdin: Stdio) -> Result { // TODO(windows): create a job object and add the child process handle to it, // see https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects - let process = smol::process::Command::from(command) + let mut command = smol::process::Command::from(command); + let process = command .stdin(stdin) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()?; + .spawn() + .with_context(|| format!("failed to spawn command `{command:?}`",))?; Ok(Self { process }) } diff --git a/crates/extensions_ui/src/extensions_ui.rs b/crates/extensions_ui/src/extensions_ui.rs index 7bf9fb15ce16b7b76c9c102cdf9ba3194b2881ee..dc40bad4e0476f5e714aa24fa3ef4d618d2bdcc9 100644 --- a/crates/extensions_ui/src/extensions_ui.rs +++ b/crates/extensions_ui/src/extensions_ui.rs @@ -29,7 +29,7 @@ use ui::{ }; use vim_mode_setting::VimModeSetting; use workspace::{ - Workspace, WorkspaceId, + Workspace, item::{Item, ItemEvent}, }; use zed_actions::ExtensionCategoryFilter; @@ -1551,15 +1551,6 @@ impl Item for ExtensionsPage { false } - fn clone_on_split( - &self, - _workspace_id: Option, - _window: &mut Window, - _: &mut Context, - ) -> Option> { - None - } - fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) { f(*event) } diff --git a/crates/gpui/src/platform/windows/clipboard.rs b/crates/gpui/src/platform/windows/clipboard.rs index 915dbab3901aef2fc092626f13fbad783f68858a..90d97a84c0bedcc241f7432a7f14f09d46018b49 100644 --- a/crates/gpui/src/platform/windows/clipboard.rs +++ b/crates/gpui/src/platform/windows/clipboard.rs @@ -3,7 +3,6 @@ use std::sync::LazyLock; use anyhow::Result; use collections::{FxHashMap, FxHashSet}; use itertools::Itertools; -use util::ResultExt; use windows::Win32::{ Foundation::{HANDLE, HGLOBAL}, System::{ @@ -76,14 +75,18 @@ enum ClipboardFormatType { } pub(crate) fn write_to_clipboard(item: ClipboardItem) { - write_to_clipboard_inner(item).log_err(); - unsafe { CloseClipboard().log_err() }; + with_clipboard(|| write_to_clipboard_inner(item)); } pub(crate) fn read_from_clipboard() -> Option { - let result = read_from_clipboard_inner(); - unsafe { CloseClipboard().log_err() }; - result + with_clipboard(|| { + with_best_match_format(|item_format| match format_to_type(item_format) { + ClipboardFormatType::Text => read_string_from_clipboard(), + ClipboardFormatType::Image => read_image_from_clipboard(item_format), + ClipboardFormatType::Files => read_files_from_clipboard(), + }) + }) + .flatten() } pub(crate) fn with_file_names(hdrop: HDROP, mut f: F) @@ -96,11 +99,33 @@ where let mut buffer = vec![0u16; filename_length + 1]; let ret = unsafe { DragQueryFileW(hdrop, file_index, Some(buffer.as_mut_slice())) }; if ret == 0 { - log::error!("unable to read file name"); + log::error!("unable to read file name of dragged file"); continue; } - if let Some(file_name) = String::from_utf16(&buffer[0..filename_length]).log_err() { - f(file_name); + match String::from_utf16(&buffer[0..filename_length]) { + Ok(file_name) => f(file_name), + Err(e) => { + log::error!("dragged file name is not UTF-16: {}", e) + } + } + } +} + +fn with_clipboard(f: F) -> Option +where + F: FnOnce() -> T, +{ + match unsafe { OpenClipboard(None) } { + Ok(()) => { + let result = f(); + if let Err(e) = unsafe { CloseClipboard() } { + log::error!("Failed to close clipboard: {e}",); + } + Some(result) + } + Err(e) => { + log::error!("Failed to open clipboard: {e}",); + None } } } @@ -124,7 +149,6 @@ fn format_to_type(item_format: u32) -> &'static ClipboardFormatType { // Currently, we only write the first item. fn write_to_clipboard_inner(item: ClipboardItem) -> Result<()> { unsafe { - OpenClipboard(None)?; EmptyClipboard()?; } match item.entries().first() { @@ -215,15 +239,6 @@ fn convert_image_to_png_format(bytes: &[u8], image_format: ImageFormat) -> Resul Ok(output_buf) } -fn read_from_clipboard_inner() -> Option { - unsafe { OpenClipboard(None) }.log_err()?; - with_best_match_format(|item_format| match format_to_type(item_format) { - ClipboardFormatType::Text => read_string_from_clipboard(), - ClipboardFormatType::Image => read_image_from_clipboard(item_format), - ClipboardFormatType::Files => read_files_from_clipboard(), - }) -} - // Here, we enumerate all formats on the clipboard and find the first one that we can process. // The reason we don't use `GetPriorityClipboardFormat` is that it sometimes returns the // wrong format. @@ -266,7 +281,7 @@ where } fn read_string_from_clipboard() -> Option { - let text = with_clipboard_data(CF_UNICODETEXT.0 as u32, |data_ptr| { + let text = with_clipboard_data(CF_UNICODETEXT.0 as u32, |data_ptr, _| { let pcwstr = PCWSTR(data_ptr as *const u16); String::from_utf16_lossy(unsafe { pcwstr.as_wide() }) })?; @@ -290,20 +305,22 @@ fn read_hash_from_clipboard() -> Option { if unsafe { IsClipboardFormatAvailable(*CLIPBOARD_HASH_FORMAT).is_err() } { return None; } - with_clipboard_data(*CLIPBOARD_HASH_FORMAT, |data_ptr| { + with_clipboard_data(*CLIPBOARD_HASH_FORMAT, |data_ptr, size| { + if size < 8 { + return None; + } let hash_bytes: [u8; 8] = unsafe { std::slice::from_raw_parts(data_ptr.cast::(), 8) - .to_vec() .try_into() - .log_err() + .ok() }?; Some(u64::from_ne_bytes(hash_bytes)) })? } fn read_metadata_from_clipboard() -> Option { - unsafe { IsClipboardFormatAvailable(*CLIPBOARD_METADATA_FORMAT).log_err()? }; - with_clipboard_data(*CLIPBOARD_METADATA_FORMAT, |data_ptr| { + unsafe { IsClipboardFormatAvailable(*CLIPBOARD_METADATA_FORMAT).ok()? }; + with_clipboard_data(*CLIPBOARD_METADATA_FORMAT, |data_ptr, _size| { let pcwstr = PCWSTR(data_ptr as *const u16); String::from_utf16_lossy(unsafe { pcwstr.as_wide() }) }) @@ -320,7 +337,7 @@ fn format_number_to_image_format(format_number: u32) -> Option<&'static ImageFor } fn read_image_for_type(format_number: u32, format: ImageFormat) -> Option { - let (bytes, id) = with_clipboard_data_and_size(format_number, |data_ptr, size| { + let (bytes, id) = with_clipboard_data(format_number, |data_ptr, size| { let bytes = unsafe { std::slice::from_raw_parts(data_ptr as *mut u8 as _, size).to_vec() }; let id = hash(&bytes); (bytes, id) @@ -329,7 +346,7 @@ fn read_image_for_type(format_number: u32, format: ImageFormat) -> Option Option { - let text = with_clipboard_data(CF_HDROP.0 as u32, |data_ptr| { + let text = with_clipboard_data(CF_HDROP.0 as u32, |data_ptr, _size| { let hdrop = HDROP(data_ptr); let mut filenames = String::new(); with_file_names(hdrop, |file_name| { @@ -344,25 +361,14 @@ fn read_files_from_clipboard() -> Option { } fn with_clipboard_data(format: u32, f: F) -> Option -where - F: FnOnce(*mut std::ffi::c_void) -> R, -{ - let global = HGLOBAL(unsafe { GetClipboardData(format).log_err() }?.0); - let data_ptr = unsafe { GlobalLock(global) }; - let result = f(data_ptr); - unsafe { GlobalUnlock(global).log_err() }; - Some(result) -} - -fn with_clipboard_data_and_size(format: u32, f: F) -> Option where F: FnOnce(*mut std::ffi::c_void, usize) -> R, { - let global = HGLOBAL(unsafe { GetClipboardData(format).log_err() }?.0); + let global = HGLOBAL(unsafe { GetClipboardData(format).ok() }?.0); let size = unsafe { GlobalSize(global) }; let data_ptr = unsafe { GlobalLock(global) }; let result = f(data_ptr, size); - unsafe { GlobalUnlock(global).log_err() }; + unsafe { GlobalUnlock(global).ok() }; Some(result) } diff --git a/crates/lsp/src/lsp.rs b/crates/lsp/src/lsp.rs index fda188be8bec8b8c8a48b888243290b31c10f149..0af69a0fb1f50268c54b8f943a73a03ae54d3cae 100644 --- a/crates/lsp/src/lsp.rs +++ b/crates/lsp/src/lsp.rs @@ -336,21 +336,18 @@ impl LanguageServer { &binary.arguments ); - let mut server = util::command::new_smol_command(&binary.path) + let mut command = util::command::new_smol_command(&binary.path); + command .current_dir(working_dir) .args(&binary.arguments) .envs(binary.env.clone().unwrap_or_default()) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .kill_on_drop(true) + .kill_on_drop(true); + let mut server = command .spawn() - .with_context(|| { - format!( - "failed to spawn command. path: {:?}, working directory: {:?}, args: {:?}", - binary.path, working_dir, &binary.arguments - ) - })?; + .with_context(|| format!("failed to spawn command {command:?}",))?; let stdin = server.stdin.take().unwrap(); let stdout = server.stdout.take().unwrap(); diff --git a/crates/onboarding/src/welcome.rs b/crates/onboarding/src/welcome.rs index 8ff55d812b007d1b210781ec747b30cd1f505f35..0bc4bd94b33d1faa31ef6a347ae553e23a6d6f2e 100644 --- a/crates/onboarding/src/welcome.rs +++ b/crates/onboarding/src/welcome.rs @@ -5,7 +5,7 @@ use gpui::{ use menu::{SelectNext, SelectPrevious}; use ui::{ButtonLike, Divider, DividerColor, KeyBinding, Vector, VectorName, prelude::*}; use workspace::{ - NewFile, Open, WorkspaceId, + NewFile, Open, item::{Item, ItemEvent}, with_active_or_new_workspace, }; @@ -339,15 +339,6 @@ impl Item for WelcomePage { false } - fn clone_on_split( - &self, - _workspace_id: Option, - _: &mut Window, - _: &mut Context, - ) -> Option> { - None - } - fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) { f(*event) } diff --git a/crates/repl/src/repl_sessions_ui.rs b/crates/repl/src/repl_sessions_ui.rs index 493b8aa950fb6fe9750fbc31c29d237b26d11d72..36936641b050012968ec4ac586c540c2567db350 100644 --- a/crates/repl/src/repl_sessions_ui.rs +++ b/crates/repl/src/repl_sessions_ui.rs @@ -6,7 +6,6 @@ use gpui::{ use project::ProjectItem as _; use ui::{ButtonLike, ElevationIndex, KeyBinding, prelude::*}; use util::ResultExt as _; -use workspace::WorkspaceId; use workspace::item::ItemEvent; use workspace::{Workspace, item::Item}; @@ -192,15 +191,6 @@ impl Item for ReplSessionsPage { false } - fn clone_on_split( - &self, - _workspace_id: Option, - _window: &mut Window, - _: &mut Context, - ) -> Option> { - None - } - fn to_item_events(event: &Self::Event, mut f: impl FnMut(workspace::item::ItemEvent)) { f(*event) } diff --git a/crates/util/src/util.rs b/crates/util/src/util.rs index da1dcb6d172dbefeb6086d7482b4ac83f60a77c0..f2efc4532a594eb156f742483f804906314a7d73 100644 --- a/crates/util/src/util.rs +++ b/crates/util/src/util.rs @@ -605,13 +605,15 @@ where // so discard the prefix up to that segment to find the crate name let target = file .split_once("crates/") - .and_then(|(_, s)| s.split_once('/')) - .map(|(p, _)| p); + .and_then(|(_, s)| s.split_once("/src/")); + let module_path = target.map(|(krate, module)| { + krate.to_owned() + "::" + &module.trim_end_matches(".rs").replace('/', "::") + }); log::logger().log( &log::Record::builder() - .target(target.unwrap_or("")) - .module_path(target) + .target(target.map_or("", |(krate, _)| krate)) + .module_path(module_path.as_deref()) .args(format_args!("{:?}", error)) .file(Some(caller.file())) .line(Some(caller.line())) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 4b19cc8c0ae06a8713f7fa67e35f3314db2510c1..f7a48999d24dba04b34b87236e3674b3076218fa 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -4106,11 +4106,11 @@ impl Workspace { pane.add_item(clone, true, true, None, window, cx) }); self.center.split(&pane, &new_pane, direction).unwrap(); + cx.notify(); Some(new_pane) } else { None }; - cx.notify(); maybe_pane_handle } diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index a63f1a566dd8c9d1640915445866860162fa525a..f439ccf7ef267c21d6ecdbad2c22c5dcd9a83866 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1231,54 +1231,57 @@ pub fn handle_settings_file_changes( MigrationNotification::set_global(cx.new(|_| MigrationNotification), cx); // Helper function to process settings content - let process_settings = move |content: String, - is_user: bool, - store: &mut SettingsStore, - cx: &mut App| - -> bool { - let id = NotificationId::Named("failed-to-migrate-settings".into()); - // Apply migrations to both user and global settings - let (processed_content, content_migrated) = match migrate_settings(&content) { - Ok(result) => { - dismiss_app_notification(&id, cx); - if let Some(migrated_content) = result { - (migrated_content, true) - } else { - (content, false) + let process_settings = + move |content: String, is_user: bool, store: &mut SettingsStore, cx: &mut App| -> bool { + let id = NotificationId::Named("failed-to-migrate-settings".into()); + // Apply migrations to both user and global settings + let (processed_content, content_migrated) = match migrate_settings(&content) { + Ok(result) => { + dismiss_app_notification(&id, cx); + if let Some(migrated_content) = result { + (migrated_content, true) + } else { + (content, false) + } } - } - Err(err) => { - show_app_notification(id, cx, move |cx| { - cx.new(|cx| { - MessageNotification::new(format!("Failed to migrate settings\n{err}"), cx) + Err(err) => { + show_app_notification(id, cx, move |cx| { + cx.new(|cx| { + MessageNotification::new( + format!( + "Failed to migrate settings\n\ + {err}" + ), + cx, + ) .primary_message("Open Settings File") .primary_icon(IconName::Settings) .primary_on_click(|window, cx| { window.dispatch_action(zed_actions::OpenSettings.boxed_clone(), cx); cx.emit(DismissEvent); }) - }) - }); - // notify user here - (content, false) - } - }; + }) + }); + // notify user here + (content, false) + } + }; - let result = if is_user { - store.set_user_settings(&processed_content, cx) - } else { - store.set_global_settings(&processed_content, cx) - }; + let result = if is_user { + store.set_user_settings(&processed_content, cx) + } else { + store.set_global_settings(&processed_content, cx) + }; - if let Err(err) = &result { - let settings_type = if is_user { "user" } else { "global" }; - log::error!("Failed to load {} settings: {err}", settings_type); - } + if let Err(err) = &result { + let settings_type = if is_user { "user" } else { "global" }; + log::error!("Failed to load {} settings: {err}", settings_type); + } - settings_changed(result.err(), cx); + settings_changed(result.err(), cx); - content_migrated - }; + content_migrated + }; // Initial load of both settings files let global_content = cx