mirror of
https://github.com/zed-industries/zed.git
synced 2026-07-09 16:00:35 +00:00
Remove gpui's dependency on async-process (#59358)
This removes gpui's dependency on the `util` crate, which depends on async process. It now depends on `gpui_util` only, and uses `std::process::Command` for the two cases where it was previously using an async `Command`. This lifts the requirement of non-Zed consumers of gpui to depend on our forked async-process (see #59156). Release Notes: - N/A
This commit is contained in:
parent
33a54ce423
commit
a873cf402c
38 changed files with 213 additions and 189 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -7828,6 +7828,7 @@ dependencies = [
|
|||
"filedescriptor",
|
||||
"futures 0.3.32",
|
||||
"gpui",
|
||||
"gpui_util",
|
||||
"gpui_wgpu",
|
||||
"http_client",
|
||||
"image",
|
||||
|
|
@ -7846,7 +7847,6 @@ dependencies = [
|
|||
"strum 0.27.2",
|
||||
"swash",
|
||||
"url",
|
||||
"util",
|
||||
"uuid",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
|
|
@ -7885,6 +7885,7 @@ dependencies = [
|
|||
"foreign-types 0.5.0",
|
||||
"futures 0.3.32",
|
||||
"gpui",
|
||||
"gpui_util",
|
||||
"image",
|
||||
"itertools 0.14.0",
|
||||
"libc",
|
||||
|
|
@ -7902,7 +7903,6 @@ dependencies = [
|
|||
"semver",
|
||||
"smallvec",
|
||||
"strum 0.27.2",
|
||||
"util",
|
||||
"uuid",
|
||||
"zed-font-kit",
|
||||
]
|
||||
|
|
@ -7945,8 +7945,8 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"gpui",
|
||||
"gpui_util",
|
||||
"tokio",
|
||||
"util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -7955,6 +7955,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"log",
|
||||
"which 6.0.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -8017,9 +8018,11 @@ dependencies = [
|
|||
"accesskit_windows",
|
||||
"anyhow",
|
||||
"collections",
|
||||
"dunce",
|
||||
"etagere",
|
||||
"futures 0.3.32",
|
||||
"gpui",
|
||||
"gpui_util",
|
||||
"image",
|
||||
"itertools 0.14.0",
|
||||
"log",
|
||||
|
|
@ -8027,7 +8030,6 @@ dependencies = [
|
|||
"rand 0.9.4",
|
||||
"raw-window-handle",
|
||||
"smallvec",
|
||||
"util",
|
||||
"uuid",
|
||||
"windows 0.61.3",
|
||||
"windows-core 0.61.2",
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ collections.workspace = true
|
|||
image.workspace = true
|
||||
futures.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui_util.workspace = true
|
||||
gpui_wgpu = { workspace = true, optional = true, features = ["font-kit"] }
|
||||
http_client.workspace = true
|
||||
itertools.workspace = true
|
||||
|
|
@ -72,7 +73,6 @@ smallvec.workspace = true
|
|||
smol.workspace = true
|
||||
strum.workspace = true
|
||||
url.workspace = true
|
||||
util.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
# Always used
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use calloop::{
|
|||
channel::{self, Sender},
|
||||
timer::TimeoutAction,
|
||||
};
|
||||
use util::ResultExt;
|
||||
use gpui_util::ResultExt;
|
||||
|
||||
use std::{mem::MaybeUninit, thread, time::Duration};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::cell::RefCell;
|
|||
use std::rc::Rc;
|
||||
|
||||
use calloop::{EventLoop, LoopHandle};
|
||||
use util::ResultExt;
|
||||
use gpui_util::ResultExt;
|
||||
|
||||
use crate::linux::{LinuxClient, LinuxCommon, LinuxKeyboardLayout};
|
||||
use gpui::{
|
||||
|
|
|
|||
|
|
@ -16,8 +16,7 @@ use std::{
|
|||
use anyhow::{Context as _, anyhow};
|
||||
use calloop::LoopSignal;
|
||||
use futures::channel::oneshot;
|
||||
use util::ResultExt as _;
|
||||
use util::command::{new_command, new_std_command};
|
||||
use gpui_util::{ResultExt as _, new_std_command};
|
||||
#[cfg(any(feature = "wayland", feature = "x11"))]
|
||||
use xkbcommon::xkb::{self, Keycode, Keysym, State};
|
||||
|
||||
|
|
@ -461,15 +460,15 @@ impl<P: LinuxClient + 'static> Platform for LinuxPlatform<P> {
|
|||
let path = path.to_owned();
|
||||
self.background_executor()
|
||||
.spawn(async move {
|
||||
let _ = new_command("xdg-open")
|
||||
#[allow(
|
||||
clippy::disallowed_methods,
|
||||
reason = "running on a background thread, so blocking is fine"
|
||||
)]
|
||||
new_std_command("xdg-open")
|
||||
.arg(path)
|
||||
.spawn()
|
||||
.context("invoking xdg-open")
|
||||
.log_err()?
|
||||
.status()
|
||||
.await
|
||||
.log_err()?;
|
||||
Some(())
|
||||
.context("invoking xdg-open")
|
||||
.log_err();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ use calloop::{
|
|||
use calloop_wayland_source::WaylandSource;
|
||||
use collections::HashMap;
|
||||
use filedescriptor::Pipe;
|
||||
use gpui_util::ResultExt as _;
|
||||
use http_client::Url;
|
||||
use smallvec::SmallVec;
|
||||
use util::ResultExt as _;
|
||||
use wayland_backend::client::ObjectId;
|
||||
use wayland_backend::protocol::WEnum;
|
||||
use wayland_client::event_created_child;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::linux::Globals;
|
||||
use crate::linux::{DEFAULT_CURSOR_ICON_NAME, log_cursor_icon_warning};
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use util::ResultExt;
|
||||
use gpui_util::ResultExt;
|
||||
|
||||
use wayland_client::Connection;
|
||||
use wayland_client::protocol::wl_surface::WlSurface;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use calloop::{
|
|||
use collections::HashMap;
|
||||
use core::str;
|
||||
use gpui::{Capslock, profiler};
|
||||
use gpui_util::ResultExt as _;
|
||||
use http_client::Url;
|
||||
use log::Level;
|
||||
use smallvec::SmallVec;
|
||||
|
|
@ -18,7 +19,6 @@ use std::{
|
|||
rc::{Rc, Weak},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use util::ResultExt as _;
|
||||
|
||||
use x11rb::{
|
||||
connection::{Connection, RequestConnection},
|
||||
|
|
|
|||
|
|
@ -844,7 +844,7 @@ fn serve_requests(context: Arc<Inner>) -> Result<(), Box<dyn std::error::Error>>
|
|||
|
||||
log::trace!("Started serve requests thread.");
|
||||
|
||||
let _guard = util::defer(|| {
|
||||
let _guard = gpui_util::defer(|| {
|
||||
context.serve_stopped.store(true, Ordering::Relaxed);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ use gpui::{
|
|||
use gpui_wgpu::{CompositorGpuHint, WgpuRenderer, WgpuSurfaceConfig};
|
||||
|
||||
use collections::FxHashSet;
|
||||
use gpui_util::{ResultExt, maybe};
|
||||
use raw_window_handle as rwh;
|
||||
use util::{ResultExt, maybe};
|
||||
use x11rb::{
|
||||
connection::Connection,
|
||||
cookie::{Cookie, VoidCookie},
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ etagere = "0.2"
|
|||
font-kit = { git = "https://github.com/zed-industries/font-kit", rev = "94b0f28166665e8fd2f53ff6d268a14955c82269", package = "zed-font-kit", version = "0.14.1-zed", optional = true }
|
||||
foreign-types = "0.5"
|
||||
futures.workspace = true
|
||||
gpui_util.workspace = true
|
||||
image.workspace = true
|
||||
itertools.workspace = true
|
||||
libc.workspace = true
|
||||
|
|
@ -59,7 +60,6 @@ raw-window-handle = "0.6"
|
|||
semver.workspace = true
|
||||
smallvec.workspace = true
|
||||
strum.workspace = true
|
||||
util.workspace = true
|
||||
uuid.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "macos")'.build-dependencies]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use dispatch2::{DispatchQueue, DispatchQueueGlobalPriority, DispatchTime, GlobalQueueIdentifier};
|
||||
use gpui::{PlatformDispatcher, Priority, RunnableMeta, RunnableVariant};
|
||||
use gpui_util::ResultExt;
|
||||
use mach2::{
|
||||
kern_return::KERN_SUCCESS,
|
||||
mach_time::mach_timebase_info_data_t,
|
||||
|
|
@ -10,7 +11,6 @@ use mach2::{
|
|||
thread_precedence_policy_data_t, thread_time_constraint_policy_data_t,
|
||||
},
|
||||
};
|
||||
use util::ResultExt;
|
||||
|
||||
use async_task::Runnable;
|
||||
use objc::{
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use core_graphics::display::CGDirectDisplayID;
|
|||
use dispatch2::{
|
||||
_dispatch_source_type_data_add, DispatchObject, DispatchQueue, DispatchRetained, DispatchSource,
|
||||
};
|
||||
use gpui_util::ResultExt;
|
||||
use std::ffi::c_void;
|
||||
use util::ResultExt;
|
||||
|
||||
pub struct DisplayLink {
|
||||
display_link: Option<sys::DisplayLink>,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ use gpui::{
|
|||
PlatformDisplay, PlatformKeyboardLayout, PlatformKeyboardMapper, PlatformTextSystem,
|
||||
PlatformWindow, Result, SystemMenuType, Task, ThermalState, WindowAppearance, WindowParams,
|
||||
};
|
||||
use gpui_util::{ResultExt, new_std_command};
|
||||
use itertools::Itertools;
|
||||
use objc::{
|
||||
class,
|
||||
|
|
@ -57,10 +58,6 @@ use std::{
|
|||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
};
|
||||
use util::{
|
||||
ResultExt,
|
||||
command::{new_command, new_std_command},
|
||||
};
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
const NSUTF8StringEncoding: NSUInteger = 4;
|
||||
|
|
@ -880,15 +877,16 @@ impl Platform for MacPlatform {
|
|||
.lock()
|
||||
.background_executor
|
||||
.spawn(async move {
|
||||
if let Some(mut child) = new_command("open")
|
||||
#[allow(
|
||||
clippy::disallowed_methods,
|
||||
reason = "running on a background thread, so blocking is fine"
|
||||
)]
|
||||
new_std_command("open")
|
||||
.arg("--")
|
||||
.arg(path)
|
||||
.spawn()
|
||||
.status()
|
||||
.context("invoking open command")
|
||||
.log_err()
|
||||
{
|
||||
child.status().await.log_err();
|
||||
}
|
||||
.log_err();
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ use core_foundation_sys::number::{CFBooleanGetValue, CFBooleanRef};
|
|||
use core_graphics::display::{CGDirectDisplayID, CGRect};
|
||||
use ctor::ctor;
|
||||
use futures::channel::oneshot;
|
||||
use gpui_util::ResultExt;
|
||||
use objc::{
|
||||
class,
|
||||
declare::ClassDecl,
|
||||
|
|
@ -71,7 +72,6 @@ use std::{
|
|||
},
|
||||
time::Duration,
|
||||
};
|
||||
use util::ResultExt;
|
||||
|
||||
const WINDOW_STATE_IVAR: &str = "windowState";
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@ doctest = false
|
|||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
util.workspace = true
|
||||
gpui.workspace = true
|
||||
gpui_util.workspace = true
|
||||
tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::future::Future;
|
||||
|
||||
use gpui::{App, AppContext, Global, ReadGlobal, Task};
|
||||
use util::defer;
|
||||
use gpui_util::defer;
|
||||
|
||||
pub use tokio::task::JoinError;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@ edition.workspace = true
|
|||
log.workspace = true
|
||||
anyhow.workspace = true
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
which.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
use std::{
|
||||
env,
|
||||
ffi::OsStr,
|
||||
ops::AddAssign,
|
||||
panic::Location,
|
||||
pin::Pin,
|
||||
|
|
@ -13,6 +14,137 @@ use std::{
|
|||
|
||||
pub mod arc_cow;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const CREATE_NO_WINDOW: u32 = 0x0800_0000_u32;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn new_std_command(program: impl AsRef<OsStr>) -> std::process::Command {
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
let mut command = std::process::Command::new(program);
|
||||
command.creation_flags(CREATE_NO_WINDOW);
|
||||
command
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn new_std_command(program: impl AsRef<OsStr>) -> std::process::Command {
|
||||
std::process::Command::new(program)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn get_windows_system_shell() -> String {
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn find_pwsh_in_programfiles(find_alternate: bool, find_preview: bool) -> Option<PathBuf> {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
let env_var = if find_alternate {
|
||||
"ProgramFiles(x86)"
|
||||
} else {
|
||||
"ProgramFiles"
|
||||
};
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
let env_var = if find_alternate {
|
||||
"ProgramW6432"
|
||||
} else {
|
||||
"ProgramFiles"
|
||||
};
|
||||
|
||||
let install_base_dir = PathBuf::from(std::env::var_os(env_var)?).join("PowerShell");
|
||||
install_base_dir
|
||||
.read_dir()
|
||||
.ok()?
|
||||
.filter_map(Result::ok)
|
||||
.filter(|entry| matches!(entry.file_type(), Ok(ft) if ft.is_dir()))
|
||||
.filter_map(|entry| {
|
||||
let dir_name = entry.file_name();
|
||||
let dir_name = dir_name.to_string_lossy();
|
||||
|
||||
let version = if find_preview {
|
||||
let dash_index = dir_name.find('-')?;
|
||||
if &dir_name[dash_index + 1..] != "preview" {
|
||||
return None;
|
||||
};
|
||||
dir_name[..dash_index].parse::<u32>().ok()?
|
||||
} else {
|
||||
dir_name.parse::<u32>().ok()?
|
||||
};
|
||||
|
||||
let exe_path = entry.path().join("pwsh.exe");
|
||||
if exe_path.exists() {
|
||||
Some((version, exe_path))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.max_by_key(|(version, _)| *version)
|
||||
.map(|(_, path)| path)
|
||||
}
|
||||
|
||||
fn find_pwsh_in_msix(find_preview: bool) -> Option<PathBuf> {
|
||||
let msix_app_dir =
|
||||
PathBuf::from(std::env::var_os("LOCALAPPDATA")?).join("Microsoft\\WindowsApps");
|
||||
if !msix_app_dir.exists() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let prefix = if find_preview {
|
||||
"Microsoft.PowerShellPreview_"
|
||||
} else {
|
||||
"Microsoft.PowerShell_"
|
||||
};
|
||||
msix_app_dir
|
||||
.read_dir()
|
||||
.ok()?
|
||||
.filter_map(|entry| {
|
||||
let entry = entry.ok()?;
|
||||
if !matches!(entry.file_type(), Ok(ft) if ft.is_dir()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !entry.file_name().to_string_lossy().starts_with(prefix) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let exe_path = entry.path().join("pwsh.exe");
|
||||
exe_path.exists().then_some(exe_path)
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
fn find_pwsh_in_scoop() -> Option<PathBuf> {
|
||||
let pwsh_exe =
|
||||
PathBuf::from(std::env::var_os("USERPROFILE")?).join("scoop\\shims\\pwsh.exe");
|
||||
pwsh_exe.exists().then_some(pwsh_exe)
|
||||
}
|
||||
|
||||
static SYSTEM_SHELL: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
|
||||
let locations = [
|
||||
|| find_pwsh_in_programfiles(false, false),
|
||||
|| find_pwsh_in_programfiles(true, false),
|
||||
|| find_pwsh_in_msix(false),
|
||||
|| find_pwsh_in_programfiles(false, true),
|
||||
|| find_pwsh_in_msix(true),
|
||||
|| find_pwsh_in_programfiles(true, true),
|
||||
|| find_pwsh_in_scoop(),
|
||||
|| which::which_global("pwsh.exe").ok(),
|
||||
|| which::which_global("powershell.exe").ok(),
|
||||
];
|
||||
|
||||
locations
|
||||
.into_iter()
|
||||
.find_map(|f| f())
|
||||
.map(|p| p.to_string_lossy().trim().to_owned())
|
||||
.inspect(|shell| log::info!("Found powershell in: {}", shell))
|
||||
.unwrap_or_else(|| {
|
||||
log::warn!("Powershell not found, falling back to `cmd`");
|
||||
"cmd.exe".to_string()
|
||||
})
|
||||
});
|
||||
|
||||
(*SYSTEM_SHELL).clone()
|
||||
}
|
||||
|
||||
pub fn post_inc<T: From<u8> + AddAssign<T> + Copy>(value: &mut T) -> T {
|
||||
let prev = *value;
|
||||
*value += T::from(1);
|
||||
|
|
|
|||
|
|
@ -24,8 +24,10 @@ accesskit.workspace = true
|
|||
accesskit_windows.workspace = true
|
||||
anyhow.workspace = true
|
||||
collections.workspace = true
|
||||
dunce.workspace = true
|
||||
etagere = "0.2"
|
||||
futures.workspace = true
|
||||
gpui_util.workspace = true
|
||||
image.workspace = true
|
||||
itertools.workspace = true
|
||||
log.workspace = true
|
||||
|
|
@ -33,7 +35,6 @@ parking_lot.workspace = true
|
|||
rand.workspace = true
|
||||
raw-window-handle = "0.6"
|
||||
smallvec.workspace = true
|
||||
util.workspace = true
|
||||
uuid.workspace = true
|
||||
windows.workspace = true
|
||||
windows-core.workspace = true
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::Result;
|
||||
use gpui::*;
|
||||
use gpui_util::ResultExt;
|
||||
use windows::Win32::{
|
||||
Foundation::*,
|
||||
Graphics::{DirectManipulation::*, Gdi::*},
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use std::{
|
|||
mem::ManuallyDrop,
|
||||
};
|
||||
|
||||
use ::util::{ResultExt, maybe};
|
||||
use anyhow::{Context, Result};
|
||||
use collections::HashMap;
|
||||
use gpui_util::{ResultExt, maybe};
|
||||
use parking_lot::{RwLock, RwLockUpgradableReadGuard};
|
||||
use windows::{
|
||||
Win32::{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::{Context, Result};
|
||||
use gpui_util::ResultExt;
|
||||
use itertools::Itertools;
|
||||
use util::ResultExt;
|
||||
use windows::Win32::{
|
||||
Foundation::HMODULE,
|
||||
Graphics::{
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::{
|
|||
sync::{Arc, OnceLock},
|
||||
};
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::{Context, Result};
|
||||
use gpui_util::ResultExt;
|
||||
use windows::{
|
||||
Win32::{
|
||||
Foundation::HWND,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::{
|
|||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use util::ResultExt;
|
||||
use gpui_util::ResultExt;
|
||||
use windows::{
|
||||
System::Threading::{
|
||||
ThreadPool, ThreadPoolTimer, TimerElapsedHandler, WorkItemHandler, WorkItemPriority,
|
||||
|
|
@ -152,7 +152,7 @@ impl PlatformDispatcher for WindowsDispatcher {
|
|||
unsafe {
|
||||
timeBeginPeriod(1);
|
||||
}
|
||||
util::defer(Box::new(|| unsafe {
|
||||
gpui_util::defer(Box::new(|| unsafe {
|
||||
timeEndPeriod(1);
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use gpui_util::ResultExt;
|
||||
use itertools::Itertools;
|
||||
use smallvec::SmallVec;
|
||||
use std::rc::Rc;
|
||||
use util::ResultExt;
|
||||
use uuid::Uuid;
|
||||
use windows::{
|
||||
Win32::{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{rc::Rc, sync::atomic::Ordering};
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::Context as _;
|
||||
use gpui_util::ResultExt;
|
||||
use windows::{
|
||||
Win32::{
|
||||
Foundation::*,
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@ use std::{
|
|||
},
|
||||
};
|
||||
|
||||
use ::util::{ResultExt, paths::SanitizedPath};
|
||||
use anyhow::{Context as _, Result, anyhow};
|
||||
use futures::channel::oneshot::{self, Receiver};
|
||||
use gpui_util::{ResultExt, get_windows_system_shell, new_std_command};
|
||||
use itertools::Itertools;
|
||||
use parking_lot::RwLock;
|
||||
use smallvec::SmallVec;
|
||||
|
|
@ -467,11 +467,10 @@ impl Platform for WindowsPlatform {
|
|||
clippy::disallowed_methods,
|
||||
reason = "We are restarting ourselves, using std command thus is fine"
|
||||
)]
|
||||
let restart_process =
|
||||
::util::command::new_std_command(::util::shell::get_windows_system_shell())
|
||||
.arg("-command")
|
||||
.arg(script)
|
||||
.spawn();
|
||||
let restart_process = new_std_command(get_windows_system_shell())
|
||||
.arg("-command")
|
||||
.arg(script)
|
||||
.spawn();
|
||||
|
||||
match restart_process {
|
||||
Ok(_) => unsafe { PostQuitMessage(0) },
|
||||
|
|
@ -1186,8 +1185,8 @@ fn file_save_dialog(
|
|||
.context("failed to canonicalize directory")
|
||||
.log_err()
|
||||
{
|
||||
let full_path = SanitizedPath::new(&full_path);
|
||||
let full_path_string = full_path.to_string();
|
||||
let full_path = dunce::simplified(&full_path);
|
||||
let full_path_string = full_path.display().to_string();
|
||||
let path_item: IShellItem =
|
||||
unsafe { SHCreateItemFromParsingName(&HSTRING::from(full_path_string), None)? };
|
||||
unsafe {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{
|
|||
ffi::{c_uint, c_void},
|
||||
};
|
||||
|
||||
use ::util::ResultExt;
|
||||
use gpui_util::ResultExt;
|
||||
use windows::Win32::UI::WindowsAndMessaging::{
|
||||
SPI_GETWHEELSCROLLCHARS, SPI_GETWHEELSCROLLLINES, SYSTEM_PARAMETERS_INFO_ACTION,
|
||||
SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS, SystemParametersInfoW,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::sync::OnceLock;
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::Context;
|
||||
use gpui_util::ResultExt;
|
||||
use windows::{
|
||||
UI::{
|
||||
Color,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use std::{
|
|||
};
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use util::ResultExt;
|
||||
use gpui_util::ResultExt;
|
||||
use windows::Win32::{
|
||||
Foundation::HWND,
|
||||
Graphics::Dwm::{DWM_TIMING_INFO, DwmFlush, DwmGetCompositionTimingInfo},
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@ use std::{
|
|||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use ::util::ResultExt;
|
||||
use anyhow::{Context as _, Result};
|
||||
use futures::channel::oneshot::{self, Receiver};
|
||||
use gpui_util::ResultExt;
|
||||
use raw_window_handle as rwh;
|
||||
use smallvec::SmallVec;
|
||||
use windows::{
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ workspace = true
|
|||
|
||||
[features]
|
||||
test-support = []
|
||||
github-download = [
|
||||
"dep:async-fs",
|
||||
"dep:async-tar",
|
||||
"dep:sha2",
|
||||
"dep:tempfile",
|
||||
"dep:util",
|
||||
]
|
||||
|
||||
[lib]
|
||||
path = "src/http_client.rs"
|
||||
|
|
@ -32,8 +39,8 @@ serde_urlencoded.workspace = true
|
|||
url.workspace = true
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
util.workspace = true
|
||||
async-fs.workspace = true
|
||||
async-tar.workspace = true
|
||||
sha2.workspace = true
|
||||
tempfile.workspace = true
|
||||
util = { workspace = true, optional = true }
|
||||
async-fs = { workspace = true, optional = true }
|
||||
async-tar = { workspace = true, optional = true }
|
||||
sha2 = { workspace = true, optional = true }
|
||||
tempfile = { workspace = true, optional = true }
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
mod async_body;
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
pub mod github;
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
#[cfg(all(not(target_family = "wasm"), feature = "github-download"))]
|
||||
pub mod github_download;
|
||||
|
||||
pub use anyhow::{Result, anyhow};
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ futures.workspace = true
|
|||
globset.workspace = true
|
||||
gpui.workspace = true
|
||||
grammars.workspace = true
|
||||
http_client.workspace = true
|
||||
http_client = { workspace = true, features = ["github-download"] }
|
||||
itertools.workspace = true
|
||||
json_schema_store.workspace = true
|
||||
language.workspace = true
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ git.workspace = true
|
|||
git_hosting_providers.workspace = true
|
||||
globset.workspace = true
|
||||
gpui.workspace = true
|
||||
http_client.workspace = true
|
||||
http_client = { workspace = true, features = ["github-download"] }
|
||||
image.workspace = true
|
||||
itertools.workspace = true
|
||||
indexmap.workspace = true
|
||||
|
|
|
|||
|
|
@ -11,24 +11,12 @@ pub use darwin::{Child, Command, Stdio};
|
|||
#[cfg(target_os = "windows")]
|
||||
const CREATE_NO_WINDOW: u32 = 0x0800_0000_u32;
|
||||
|
||||
pub use gpui_util::new_std_command;
|
||||
|
||||
pub fn new_command(program: impl AsRef<OsStr>) -> Command {
|
||||
Command::new(program)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn new_std_command(program: impl AsRef<OsStr>) -> std::process::Command {
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
let mut command = std::process::Command::new(program);
|
||||
command.creation_flags(CREATE_NO_WINDOW);
|
||||
command
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn new_std_command(program: impl AsRef<OsStr>) -> std::process::Command {
|
||||
std::process::Command::new(program)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub type Child = smol::process::Child;
|
||||
|
||||
|
|
|
|||
|
|
@ -121,116 +121,11 @@ pub fn get_windows_bash() -> Option<String> {
|
|||
}
|
||||
|
||||
pub fn get_windows_system_shell() -> String {
|
||||
use std::path::PathBuf;
|
||||
#[cfg(windows)]
|
||||
return gpui_util::get_windows_system_shell();
|
||||
|
||||
fn find_pwsh_in_programfiles(find_alternate: bool, find_preview: bool) -> Option<PathBuf> {
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
let env_var = if find_alternate {
|
||||
"ProgramFiles(x86)"
|
||||
} else {
|
||||
"ProgramFiles"
|
||||
};
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
let env_var = if find_alternate {
|
||||
"ProgramW6432"
|
||||
} else {
|
||||
"ProgramFiles"
|
||||
};
|
||||
|
||||
let install_base_dir = PathBuf::from(std::env::var_os(env_var)?).join("PowerShell");
|
||||
install_base_dir
|
||||
.read_dir()
|
||||
.ok()?
|
||||
.filter_map(Result::ok)
|
||||
.filter(|entry| matches!(entry.file_type(), Ok(ft) if ft.is_dir()))
|
||||
.filter_map(|entry| {
|
||||
let dir_name = entry.file_name();
|
||||
let dir_name = dir_name.to_string_lossy();
|
||||
|
||||
let version = if find_preview {
|
||||
let dash_index = dir_name.find('-')?;
|
||||
if &dir_name[dash_index + 1..] != "preview" {
|
||||
return None;
|
||||
};
|
||||
dir_name[..dash_index].parse::<u32>().ok()?
|
||||
} else {
|
||||
dir_name.parse::<u32>().ok()?
|
||||
};
|
||||
|
||||
let exe_path = entry.path().join("pwsh.exe");
|
||||
if exe_path.exists() {
|
||||
Some((version, exe_path))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.max_by_key(|(version, _)| *version)
|
||||
.map(|(_, path)| path)
|
||||
}
|
||||
|
||||
fn find_pwsh_in_msix(find_preview: bool) -> Option<PathBuf> {
|
||||
let msix_app_dir =
|
||||
PathBuf::from(std::env::var_os("LOCALAPPDATA")?).join("Microsoft\\WindowsApps");
|
||||
if !msix_app_dir.exists() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let prefix = if find_preview {
|
||||
"Microsoft.PowerShellPreview_"
|
||||
} else {
|
||||
"Microsoft.PowerShell_"
|
||||
};
|
||||
msix_app_dir
|
||||
.read_dir()
|
||||
.ok()?
|
||||
.filter_map(|entry| {
|
||||
let entry = entry.ok()?;
|
||||
if !matches!(entry.file_type(), Ok(ft) if ft.is_dir()) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if !entry.file_name().to_string_lossy().starts_with(prefix) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let exe_path = entry.path().join("pwsh.exe");
|
||||
exe_path.exists().then_some(exe_path)
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
fn find_pwsh_in_scoop() -> Option<PathBuf> {
|
||||
let pwsh_exe =
|
||||
PathBuf::from(std::env::var_os("USERPROFILE")?).join("scoop\\shims\\pwsh.exe");
|
||||
pwsh_exe.exists().then_some(pwsh_exe)
|
||||
}
|
||||
|
||||
static SYSTEM_SHELL: LazyLock<String> = LazyLock::new(|| {
|
||||
let locations = [
|
||||
|| find_pwsh_in_programfiles(false, false),
|
||||
|| find_pwsh_in_programfiles(true, false),
|
||||
|| find_pwsh_in_msix(false),
|
||||
|| find_pwsh_in_programfiles(false, true),
|
||||
|| find_pwsh_in_msix(true),
|
||||
|| find_pwsh_in_programfiles(true, true),
|
||||
|| find_pwsh_in_scoop(),
|
||||
|| which::which_global("pwsh.exe").ok(),
|
||||
|| which::which_global("powershell.exe").ok(),
|
||||
];
|
||||
|
||||
locations
|
||||
.into_iter()
|
||||
.find_map(|f| f())
|
||||
.map(|p| p.to_string_lossy().trim().to_owned())
|
||||
.inspect(|shell| log::info!("Found powershell in: {}", shell))
|
||||
.unwrap_or_else(|| {
|
||||
log::warn!("Powershell not found, falling back to `cmd`");
|
||||
"cmd.exe".to_string()
|
||||
})
|
||||
});
|
||||
|
||||
(*SYSTEM_SHELL).clone()
|
||||
#[cfg(not(windows))]
|
||||
return "cmd.exe".to_string();
|
||||
}
|
||||
|
||||
impl fmt::Display for ShellKind {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue