From a47759fd03b2f2b6666f545e1a85b6fe5660bd89 Mon Sep 17 00:00:00 2001 From: Caleb Heydon Date: Mon, 11 Nov 2024 12:39:05 -0500 Subject: [PATCH] Add initial FreeBSD support (#20480) This PR adds initial support for FreeBSD (https://github.com/zed-industries/zed/issues/15309). While there is still work left to be done, it seems to be usable. As discussed by @syobocat (https://github.com/zed-industries/zed/discussions/10247), the changes were just adding ```target_os = "freebsd"``` to wherever it checks if the OS is Linux. ![image](https://github.com/user-attachments/assets/80ea5b29-047f-4cbd-8263-42e5fa6c94b7) Needs to be build with ```RUSTFLAGS="-C link-dead-code"``` Known Issues: - There's an issue in ```crates/project/src/environment.rs``` where a command fails because ```/bin/sh``` on FreeBSD doesn't support the ```-l``` option. ![image](https://github.com/user-attachments/assets/c3c38633-160f-4f47-8840-e3da67f6ebc8) - The file/folder choosers provided by the ```ashpd``` crate don't work on FreeBSD (at least with KDE). This isn't that bad since a fallback dialog is used. ![image](https://github.com/user-attachments/assets/29373006-1eb9-4ed0-bd52-2d0047fab418) - Moving to trash won't work. - Numerous tests fail (when running on FreeBSD). While I haven't looked into this much, it appears that the corresponding features seem to work fine. Release Notes: - Added initial support for FreeBSD --- crates/cli/Cargo.toml | 2 +- crates/cli/src/main.rs | 13 +++-- crates/client/src/telemetry.rs | 4 +- crates/editor/src/editor.rs | 2 +- crates/editor/src/element.rs | 6 ++- crates/extension/src/extension_builder.rs | 2 +- crates/fs/Cargo.toml | 2 +- crates/fs/src/fs.rs | 18 +++---- crates/fs/src/linux_watcher.rs | 3 ++ crates/gpui/Cargo.toml | 4 +- crates/gpui/src/app.rs | 4 +- crates/gpui/src/keymap/context.rs | 9 +++- crates/gpui/src/platform.rs | 49 ++++++++++++------- crates/gpui/src/platform/keystroke.rs | 4 +- .../src/platform/linux/xdg_desktop_portal.rs | 2 +- crates/gpui/src/platform/test/platform.rs | 10 ++-- crates/gpui/src/scene.rs | 25 ++++++++-- crates/gpui/src/style.rs | 2 +- crates/gpui/src/window.rs | 2 +- crates/markdown/src/markdown.rs | 2 +- crates/paths/src/paths.rs | 6 +-- crates/sqlez/src/connection.rs | 10 ++-- crates/sqlez_macros/src/sqlez_macros.rs | 6 +-- crates/terminal/src/terminal.rs | 8 +-- crates/title_bar/src/title_bar.rs | 2 +- crates/ui/src/styles/platform.rs | 2 +- crates/util/src/paths.rs | 4 +- crates/vim/src/replace.rs | 2 +- crates/vim/src/state.rs | 8 +-- crates/worktree/src/worktree_tests.rs | 2 +- crates/zed/Cargo.toml | 2 +- crates/zed/src/main.rs | 10 ++-- crates/zed/src/zed.rs | 6 +-- crates/zed/src/zed/open_listener.rs | 2 +- 34 files changed, 139 insertions(+), 96 deletions(-) diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 426fa25f3e975261027d82d3e65868568b406c28..5dd53b5a09e6c9c92a5a47e4093c8d318ca6b1e2 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -29,7 +29,7 @@ serde.workspace = true util.workspace = true tempfile.workspace = true -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] exec.workspace = true fork.workspace = true diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index cb457b8a9d6ccd7c739ea56e6bbfe741ddb44edf..002b0c017319079ee9068c40a762e83c4418e36e 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -1,4 +1,7 @@ -#![cfg_attr(any(target_os = "linux", target_os = "windows"), allow(dead_code))] +#![cfg_attr( + any(target_os = "linux", target_os = "freebsd", target_os = "windows"), + allow(dead_code) +)] use anyhow::{Context, Result}; use clap::Parser; @@ -88,7 +91,7 @@ fn parse_path_with_position(argument_str: &str) -> anyhow::Result { fn main() -> Result<()> { // Exit flatpak sandbox if needed - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { flatpak::try_restart_to_host(); flatpak::ld_extra_libs(); @@ -106,7 +109,7 @@ fn main() -> Result<()> { } let args = Args::parse(); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let args = flatpak::set_bin_if_no_escape(args); let app = Detect::detect(args.zed.as_deref()).context("Bundle detection")?; @@ -220,7 +223,7 @@ fn main() -> Result<()> { Ok(()) } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux { use std::{ env, @@ -344,7 +347,7 @@ mod linux { } } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod flatpak { use std::ffi::OsString; use std::path::PathBuf; diff --git a/crates/client/src/telemetry.rs b/crates/client/src/telemetry.rs index a061d19749aa2d59667f3c58f4d1039c089305c5..6386c4bf702353f591345c76e0ccc5253dfc3e1d 100644 --- a/crates/client/src/telemetry.rs +++ b/crates/client/src/telemetry.rs @@ -100,7 +100,7 @@ pub fn os_name() -> String { { "macOS".to_string() } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { format!("Linux {}", gpui::guess_compositor()) } @@ -129,7 +129,7 @@ pub fn os_version() -> String { .to_string() } } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { use std::path::Path; diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 8ccfc1b6a306b18826463f6b224310647af57ae4..bd78020608f91b7636895e9bdd17f267ebd05527 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2564,7 +2564,7 @@ impl Editor { cx.invalidate_character_coordinates(); // Copy selections to primary selection buffer - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if local { let selections = self.selections.all::(cx); let buffer_handle = self.buffer.read(cx).read(cx); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 4323ea0ad70b8f8571d3f06c8bb729586808b6a2..423d4e8be673d0baf93ff1d4078a2a99aee6f2d8 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -650,12 +650,14 @@ impl EditorElement { cx.stop_propagation(); } else if end_selection && pending_nonempty_selections { cx.stop_propagation(); - } else if cfg!(target_os = "linux") && event.button == MouseButton::Middle { + } else if cfg!(any(target_os = "linux", target_os = "freebsd")) + && event.button == MouseButton::Middle + { if !text_hitbox.is_hovered(cx) || editor.read_only(cx) { return; } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if EditorSettings::get_global(cx).middle_click_paste { if let Some(text) = cx.read_from_primary().and_then(|item| item.text()) { let point_for_position = diff --git a/crates/extension/src/extension_builder.rs b/crates/extension/src/extension_builder.rs index ebb46993f43d14599307760ce9ef28839d83208a..25e6a1a48501ddd841488c93a02bf83fd87da759 100644 --- a/crates/extension/src/extension_builder.rs +++ b/crates/extension/src/extension_builder.rs @@ -36,7 +36,7 @@ const WASI_ADAPTER_URL: &str = const WASI_SDK_URL: &str = "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/"; const WASI_SDK_ASSET_NAME: Option<&str> = if cfg!(target_os = "macos") { Some("wasi-sdk-21.0-macos.tar.gz") -} else if cfg!(target_os = "linux") { +} else if cfg!(any(target_os = "linux", target_os = "freebsd")) { Some("wasi-sdk-21.0-linux.tar.gz") } else if cfg!(target_os = "windows") { Some("wasi-sdk-21.0.m-mingw.tar.gz") diff --git a/crates/fs/Cargo.toml b/crates/fs/Cargo.toml index ade2ec0f53ff737df54b520155f190a29994b174..a9dbb751b6455ead1ab06029e694567d5d782313 100644 --- a/crates/fs/Cargo.toml +++ b/crates/fs/Cargo.toml @@ -43,7 +43,7 @@ notify = "6.1.1" [target.'cfg(target_os = "windows")'.dependencies] windows.workspace = true -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] ashpd.workspace = true [dev-dependencies] diff --git a/crates/fs/src/fs.rs b/crates/fs/src/fs.rs index de43dc8e979675733db2532df1b48eef45989a8d..268a9d3f3217b449bf1f926a25e992062eafb5a2 100644 --- a/crates/fs/src/fs.rs +++ b/crates/fs/src/fs.rs @@ -1,15 +1,15 @@ #[cfg(target_os = "macos")] mod mac_watcher; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub mod linux_watcher; use anyhow::{anyhow, Result}; use git::GitHostingProviderRegistry; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] use ashpd::desktop::trash; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] use std::fs::File; #[cfg(unix)] use std::os::fd::AsFd; @@ -217,7 +217,7 @@ impl FileHandle for std::fs::File { Ok(path) } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn current_path(&self, _: &Arc) -> Result { let fd = self.as_fd(); let fd_path = format!("/proc/self/fd/{}", fd.as_raw_fd()); @@ -391,7 +391,7 @@ impl Fs for RealFs { Ok(()) } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] async fn trash_file(&self, path: &Path, _options: RemoveOptions) -> Result<()> { let file = File::open(path)?; match trash::trash_file(&file.as_fd()).await { @@ -423,7 +423,7 @@ impl Fs for RealFs { self.trash_file(path, options).await } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] async fn trash_dir(&self, path: &Path, options: RemoveOptions) -> Result<()> { self.trash_file(path, options).await } @@ -468,7 +468,7 @@ impl Fs for RealFs { async fn atomic_write(&self, path: PathBuf, data: String) -> Result<()> { smol::unblock(move || { - let mut tmp_file = if cfg!(target_os = "linux") { + let mut tmp_file = if cfg!(any(target_os = "linux", target_os = "freebsd")) { // Use the directory of the destination as temp dir to avoid // invalid cross-device link error, and XDG_CACHE_DIR for fallback. // See https://github.com/zed-industries/zed/pull/8437 for more details. @@ -634,7 +634,7 @@ impl Fs for RealFs { ) } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] async fn watch( &self, path: &Path, @@ -781,7 +781,7 @@ impl Fs for RealFs { } } -#[cfg(not(target_os = "linux"))] +#[cfg(not(any(target_os = "linux", target_os = "freebsd")))] impl Watcher for RealWatcher { fn add(&self, _: &Path) -> Result<()> { Ok(()) diff --git a/crates/fs/src/linux_watcher.rs b/crates/fs/src/linux_watcher.rs index 04244c69567299d405595688d42fbd334191e067..cb2ac4826f4cbbfc760bcb9c1079457842f961ec 100644 --- a/crates/fs/src/linux_watcher.rs +++ b/crates/fs/src/linux_watcher.rs @@ -85,7 +85,10 @@ impl Watcher for LinuxWatcher { pub struct GlobalWatcher { // two mutexes because calling inotify.add triggers an inotify.event, which needs watchers. + #[cfg(target_os = "linux")] pub(super) inotify: Mutex, + #[cfg(target_os = "freebsd")] + pub(super) inotify: Mutex, pub(super) watchers: Mutex>>, } diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 3a4fdd5014107e34829870e39d178df4121fd51c..347e5502ca39d2bf5b2bed51245fe5feccc06741 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -139,10 +139,10 @@ media.workspace = true metal = "0.29" objc = "0.2" -[target.'cfg(any(target_os = "linux", target_os = "macos"))'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))'.dependencies] pathfinder_geometry = "0.5" -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] # Always used flume = "0.11" oo7 = "0.3.0" diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index a3c097455e2e1ad07933cead3a77a2f45e2de30e..2a8da1c506e5968f981101dd053a793732790627 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -614,7 +614,7 @@ impl AppContext { /// Writes data to the primary selection buffer. /// Only available on Linux. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] pub fn write_to_primary(&self, item: ClipboardItem) { self.platform.write_to_primary(item) } @@ -626,7 +626,7 @@ impl AppContext { /// Reads data from the primary selection buffer. /// Only available on Linux. - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] pub fn read_from_primary(&self) -> Option { self.platform.read_from_primary() } diff --git a/crates/gpui/src/keymap/context.rs b/crates/gpui/src/keymap/context.rs index c7be02f8d38efaec40d50fbf12170f4ce53b8265..dbc3f50f320c31a0437c6c0022d401730b33124c 100644 --- a/crates/gpui/src/keymap/context.rs +++ b/crates/gpui/src/keymap/context.rs @@ -33,11 +33,16 @@ impl KeyContext { let mut context = Self::default(); #[cfg(target_os = "macos")] context.set("os", "macos"); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] context.set("os", "linux"); #[cfg(target_os = "windows")] context.set("os", "windows"); - #[cfg(not(any(target_os = "macos", target_os = "linux", target_os = "windows")))] + #[cfg(not(any( + target_os = "macos", + target_os = "linux", + target_os = "freebsd", + target_os = "windows" + )))] context.set("os", "unknown"); context } diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 070f29842ec63eeff4e7f4d48ae3a8802b197956..45b50b1120802464c4bcc91b39c4e1e5067c8721 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -4,14 +4,17 @@ mod app_menu; mod keystroke; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] mod linux; #[cfg(target_os = "macos")] mod mac; #[cfg(any( - all(target_os = "linux", any(feature = "x11", feature = "wayland")), + all( + any(target_os = "linux", target_os = "freebsd"), + any(feature = "x11", feature = "wayland") + ), target_os = "windows", feature = "macos-blade" ))] @@ -57,7 +60,7 @@ use uuid::Uuid; pub use app_menu::*; pub use keystroke::*; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub(crate) use linux::*; #[cfg(target_os = "macos")] pub(crate) use mac::*; @@ -72,7 +75,7 @@ pub(crate) fn current_platform(headless: bool) -> Rc { Rc::new(MacPlatform::new(headless)) } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub(crate) fn current_platform(headless: bool) -> Rc { if headless { return Rc::new(HeadlessClient::new()); @@ -92,7 +95,7 @@ pub(crate) fn current_platform(headless: bool) -> Rc { /// Return which compositor we're guessing we'll use. /// Does not attempt to connect to the given compositor -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] #[inline] pub fn guess_compositor() -> &'static str { if std::env::var_os("ZED_HEADLESS").is_some() { @@ -192,10 +195,10 @@ pub(crate) trait Platform: 'static { fn set_cursor_style(&self, style: CursorStyle); fn should_auto_hide_scrollbars(&self) -> bool; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn write_to_primary(&self, item: ClipboardItem); fn write_to_clipboard(&self, item: ClipboardItem); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn read_from_primary(&self) -> Option; fn read_from_clipboard(&self) -> Option; @@ -508,7 +511,10 @@ pub(crate) enum AtlasKey { impl AtlasKey { #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub(crate) fn texture_kind(&self) -> AtlasTextureKind { @@ -572,7 +578,10 @@ pub(crate) struct AtlasTextureId { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[repr(C)] #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub(crate) enum AtlasTextureKind { @@ -603,7 +612,10 @@ pub(crate) struct PlatformInputHandler { } #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] impl PlatformInputHandler { @@ -625,7 +637,7 @@ impl PlatformInputHandler { .flatten() } - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] fn text_for_range(&mut self, range_utf16: Range) -> Option { self.cx .update(|cx| self.handler.text_for_range(range_utf16, cx)) @@ -814,7 +826,10 @@ pub struct WindowOptions { /// The variables that can be configured when creating a new window #[derive(Debug)] #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub(crate) struct WindowParams { @@ -825,17 +840,17 @@ pub(crate) struct WindowParams { pub titlebar: Option, /// The kind of window to create - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] pub kind: WindowKind, /// Whether the window should be movable by the user - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] pub is_movable: bool, - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] pub focus: bool, - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] pub show: bool, #[cfg_attr(feature = "wayland", allow(dead_code))] @@ -1341,7 +1356,7 @@ impl ClipboardString { .and_then(|m| serde_json::from_str(m).ok()) } - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] pub(crate) fn text_hash(text: &str) -> u64 { let mut hasher = SeaHasher::new(); text.hash(&mut hasher); diff --git a/crates/gpui/src/platform/keystroke.rs b/crates/gpui/src/platform/keystroke.rs index 38000f4fb165fb4e475428c0ffe990727eab6704..73cd83d123f931e6c0ef9ca774ff8a099e2c813b 100644 --- a/crates/gpui/src/platform/keystroke.rs +++ b/crates/gpui/src/platform/keystroke.rs @@ -134,7 +134,7 @@ impl Keystroke { #[cfg(target_os = "macos")] str.push_str("cmd-"); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] str.push_str("super-"); #[cfg(target_os = "windows")] @@ -234,7 +234,7 @@ impl std::fmt::Display for Keystroke { #[cfg(target_os = "macos")] f.write_char('⌘')?; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] f.write_char('❖')?; #[cfg(target_os = "windows")] diff --git a/crates/gpui/src/platform/linux/xdg_desktop_portal.rs b/crates/gpui/src/platform/linux/xdg_desktop_portal.rs index ade7833eab254d61a1e03d122a8fb5f4efb5093f..64aa3975b86afb39b0216f2a722176e2752a6c8e 100644 --- a/crates/gpui/src/platform/linux/xdg_desktop_portal.rs +++ b/crates/gpui/src/platform/linux/xdg_desktop_portal.rs @@ -162,7 +162,7 @@ impl WindowAppearance { } } - #[cfg_attr(target_os = "linux", allow(dead_code))] + #[cfg_attr(any(target_os = "linux", target_os = "freebsd"), allow(dead_code))] fn set_native(&mut self, cs: ColorScheme) { *self = Self::from_native(cs); } diff --git a/crates/gpui/src/platform/test/platform.rs b/crates/gpui/src/platform/test/platform.rs index 59aef9029ecde5383da41f3a7bc1820674746980..aadbe9b5953d8b05179230b3d6838f3e445a3b23 100644 --- a/crates/gpui/src/platform/test/platform.rs +++ b/crates/gpui/src/platform/test/platform.rs @@ -28,7 +28,7 @@ pub(crate) struct TestPlatform { active_display: Rc, active_cursor: Mutex, current_clipboard_item: Mutex>, - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] current_primary_item: Mutex>, pub(crate) prompts: RefCell, pub opened_url: RefCell>, @@ -59,7 +59,7 @@ impl TestPlatform { #[cfg(target_os = "macos")] let text_system = Arc::new(crate::platform::mac::MacTextSystem::new()); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let text_system = Arc::new(crate::platform::linux::CosmicTextSystem::new()); #[cfg(target_os = "windows")] @@ -76,7 +76,7 @@ impl TestPlatform { active_display: Rc::new(TestDisplay::new()), active_window: Default::default(), current_clipboard_item: Mutex::new(None), - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] current_primary_item: Mutex::new(None), weak: weak.clone(), opened_url: Default::default(), @@ -291,7 +291,7 @@ impl Platform for TestPlatform { false } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn write_to_primary(&self, item: ClipboardItem) { *self.current_primary_item.lock() = Some(item); } @@ -300,7 +300,7 @@ impl Platform for TestPlatform { *self.current_clipboard_item.lock() = Some(item); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fn read_from_primary(&self) -> Option { self.current_primary_item.lock().clone() } diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index d3eee39aa77bf3e80701703e710abe7cdf0947ac..9787ec5d87f1372894ca42243662e7c936249bf3 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -41,7 +41,10 @@ impl Scene { } #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub fn paths(&self) -> &[Path] { @@ -135,7 +138,10 @@ impl Scene { } #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub(crate) fn batches(&self) -> impl Iterator { @@ -167,7 +173,10 @@ impl Scene { #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Default)] #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub(crate) enum PrimitiveKind { @@ -225,7 +234,10 @@ impl Primitive { } #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] struct BatchIterator<'a> { @@ -415,7 +427,10 @@ impl<'a> Iterator for BatchIterator<'a> { #[derive(Debug)] #[cfg_attr( - all(target_os = "linux", not(any(feature = "x11", feature = "wayland"))), + all( + any(target_os = "linux", target_os = "freebsd"), + not(any(feature = "x11", feature = "wayland")) + ), allow(dead_code) )] pub(crate) enum PrimitiveBatch<'a> { diff --git a/crates/gpui/src/style.rs b/crates/gpui/src/style.rs index 455a2e162d563ea50c0a7cb82cfc248bd52be798..cfe10348917441adad5d988b29a1070b4f7d23fe 100644 --- a/crates/gpui/src/style.rs +++ b/crates/gpui/src/style.rs @@ -344,7 +344,7 @@ impl Default for TextStyle { TextStyle { color: black(), // todo(linux) make this configurable or choose better default - font_family: if cfg!(target_os = "linux") { + font_family: if cfg!(any(target_os = "linux", target_os = "freebsd")) { "FreeMono".into() } else if cfg!(target_os = "windows") { "Segoe UI".into() diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index e4bea94da04a7fefb357179f6978712cd4fe3b13..b5aa39a9bb0b6b3d96ea768183ef39f36b20a95c 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -1240,7 +1240,7 @@ impl<'a> WindowContext<'a> { /// that currently owns the mouse cursor. /// On mac, this is equivalent to `is_window_active`. pub fn is_window_hovered(&self) -> bool { - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { self.window.hovered.get() } else { self.is_window_active() diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index 203d2df6a43744386a570e01cfc3c4b5942d864e..ff67c01a0ecc31251829a1fe521fa84b30694679 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -475,7 +475,7 @@ impl MarkdownElement { } } else if markdown.selection.pending { markdown.selection.pending = false; - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { let text = rendered_text .text_for_range(markdown.selection.start..markdown.selection.end); diff --git a/crates/paths/src/paths.rs b/crates/paths/src/paths.rs index fd118a3c49ca7da0cd064628f49401fb44aad5ee..63b717b4e0f9639168ad3c5db13874d44cdbe09b 100644 --- a/crates/paths/src/paths.rs +++ b/crates/paths/src/paths.rs @@ -20,7 +20,7 @@ pub fn config_dir() -> &'static PathBuf { .join("Zed"); } - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { return if let Ok(flatpak_xdg_config) = std::env::var("FLATPAK_XDG_CONFIG_HOME") { flatpak_xdg_config.into() } else { @@ -41,7 +41,7 @@ pub fn support_dir() -> &'static PathBuf { return home_dir().join("Library/Application Support/Zed"); } - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { return if let Ok(flatpak_xdg_data) = std::env::var("FLATPAK_XDG_DATA_HOME") { flatpak_xdg_data.into() } else { @@ -76,7 +76,7 @@ pub fn temp_dir() -> &'static PathBuf { .join("Zed"); } - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { return if let Ok(flatpak_xdg_cache) = std::env::var("FLATPAK_XDG_CACHE_HOME") { flatpak_xdg_cache.into() } else { diff --git a/crates/sqlez/src/connection.rs b/crates/sqlez/src/connection.rs index d1643782fa84385b3a577fe5a7834d81fb0a27d8..fdd8ec9ad49249f77bd746bd9f7bdaeae7418621 100644 --- a/crates/sqlez/src/connection.rs +++ b/crates/sqlez/src/connection.rs @@ -128,10 +128,10 @@ impl Connection { &mut remaining_sql_ptr, ); - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] let offset = sqlite3_error_offset(temp_connection.sqlite3); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let offset = 0; ( @@ -149,10 +149,10 @@ impl Connection { &mut remaining_sql_ptr, ); - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] let offset = sqlite3_error_offset(self.sqlite3); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let offset = 0; ( @@ -408,7 +408,7 @@ mod test { ); } - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] #[test] fn test_sql_has_syntax_errors() { let connection = Connection::open_memory(Some("test_sql_has_syntax_errors")); diff --git a/crates/sqlez_macros/src/sqlez_macros.rs b/crates/sqlez_macros/src/sqlez_macros.rs index ae6b757ce38dce67b2e0b8e5af8c77ae105dcfd2..5ddfe4cd87ea9dcdc1380a881f42b855949bacba 100644 --- a/crates/sqlez_macros/src/sqlez_macros.rs +++ b/crates/sqlez_macros/src/sqlez_macros.rs @@ -1,7 +1,7 @@ use proc_macro::{Delimiter, Span, TokenStream, TokenTree}; use syn::Error; -#[cfg(not(target_os = "linux"))] +#[cfg(not(any(target_os = "linux", target_os = "freebsd")))] static SQLITE: std::sync::LazyLock = std::sync::LazyLock::new(|| { sqlez::thread_safe_connection::ThreadSafeConnection::new( @@ -16,10 +16,10 @@ static SQLITE: std::sync::LazyLock TokenStream { let (spans, sql) = make_sql(tokens); - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] let error = SQLITE.sql_has_syntax_error(sql.trim()); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] let error: Option<(String, usize)> = None; let formatted_sql = sqlformat::format(&sql, &sqlformat::QueryParams::None, Default::default()); diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index c03af8d48e610c11a64cc00c7816bd37db216192..5a15723cee380eb0b0276cf124a5c169d3be852a 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -818,7 +818,7 @@ impl Terminal { selection.update(point, AlacDirection::Right); term.selection = Some(selection); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if let Some(selection_text) = term.selection_to_string() { cx.write_to_primary(ClipboardItem::new_string(selection_text)); } @@ -831,7 +831,7 @@ impl Terminal { InternalEvent::SetSelection(selection) => { term.selection = selection.as_ref().map(|(sel, _)| sel.clone()); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if let Some(selection_text) = term.selection_to_string() { cx.write_to_primary(ClipboardItem::new_string(selection_text)); } @@ -852,7 +852,7 @@ impl Terminal { selection.update(point, side); term.selection = Some(selection); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if let Some(selection_text) = term.selection_to_string() { cx.write_to_primary(ClipboardItem::new_string(selection_text)); } @@ -1512,7 +1512,7 @@ impl Terminal { .push_back(InternalEvent::SetSelection(Some((sel, point)))); } } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] MouseButton::Middle => { if let Some(item) = _cx.read_from_primary() { let text = item.text().unwrap_or_default().to_string(); diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index f58eaa89a0f9b69d5dfdb9b966f21e4fc89d7235..ba1a106413df5b526c8a7352ae1b6185d84cabb4 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -75,7 +75,7 @@ impl Render for TitleBar { let height = Self::height(cx); let supported_controls = cx.window_controls(); let decorations = cx.window_decorations(); - let titlebar_color = if cfg!(target_os = "linux") { + let titlebar_color = if cfg!(any(target_os = "linux", target_os = "freebsd")) { if cx.is_window_active() && !self.should_move { cx.theme().colors().title_bar_background } else { diff --git a/crates/ui/src/styles/platform.rs b/crates/ui/src/styles/platform.rs index bb2c3ea47b6639be8c83d68dae1d23be85bd57ab..0d873a2ff2cbe648c3e26c3a703b50ccdca67e8e 100644 --- a/crates/ui/src/styles/platform.rs +++ b/crates/ui/src/styles/platform.rs @@ -14,7 +14,7 @@ pub enum PlatformStyle { impl PlatformStyle { /// Returns the [`PlatformStyle`] for the current platform. pub const fn platform() -> Self { - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { Self::Linux } else if cfg!(target_os = "windows") { Self::Windows diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index 02e3ac59bed945c24559cddbbb5e3cda8736f7f7..d629c8facc59366ed8365386590922982f206358 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -57,7 +57,7 @@ impl> PathExt for T { /// does not have the user's home directory prefix, or if we are not on /// Linux or macOS, the original path is returned unchanged. fn compact(&self) -> PathBuf { - if cfg!(target_os = "linux") || cfg!(target_os = "macos") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) || cfg!(target_os = "macos") { match self.as_ref().strip_prefix(home_dir().as_path()) { Ok(relative_path) => { let mut shortened_path = PathBuf::new(); @@ -699,7 +699,7 @@ mod tests { ] .iter() .collect(); - if cfg!(target_os = "linux") || cfg!(target_os = "macos") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) || cfg!(target_os = "macos") { assert_eq!(path.compact().to_str(), Some("~/some_file.txt")); } else { assert_eq!(path.compact().to_str(), path.to_str()); diff --git a/crates/vim/src/replace.rs b/crates/vim/src/replace.rs index 201faa6443d1d8316128d1a1b8bbf876448f5971..753eec09717104e0e9108dd40dc3bce769ecc67d 100644 --- a/crates/vim/src/replace.rs +++ b/crates/vim/src/replace.rs @@ -135,7 +135,7 @@ mod test { } #[gpui::test] - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] async fn test_replace_mode(cx: &mut gpui::TestAppContext) { let mut cx: NeovimBackedTestContext = NeovimBackedTestContext::new(cx).await; diff --git a/crates/vim/src/state.rs b/crates/vim/src/state.rs index eb1abf1553fc5f83841766176842a77ad66668d4..b229f53142a5c8375395d77b06e163cef97f3cee 100644 --- a/crates/vim/src/state.rs +++ b/crates/vim/src/state.rs @@ -228,9 +228,9 @@ impl VimGlobals { } '*' => { self.registers.insert('"', content.clone()); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] cx.write_to_primary(content.into()); - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] cx.write_to_clipboard(content.into()); } '"' => { @@ -299,11 +299,11 @@ impl VimGlobals { '_' | ':' | '.' | '#' | '=' => None, '+' => cx.read_from_clipboard().map(|item| item.into()), '*' => { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { cx.read_from_primary().map(|item| item.into()) } - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] { cx.read_from_clipboard().map(|item| item.into()) } diff --git a/crates/worktree/src/worktree_tests.rs b/crates/worktree/src/worktree_tests.rs index bdda66c2e02c710bfa20d8dfd3670cf268ea43de..75f86fa606b69e89cce0c573c35b1523e2ad4362 100644 --- a/crates/worktree/src/worktree_tests.rs +++ b/crates/worktree/src/worktree_tests.rs @@ -842,7 +842,7 @@ async fn test_write_file(cx: &mut TestAppContext) { .await .unwrap(); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] fs::linux_watcher::global(|_| {}).unwrap(); cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 5fb94f2573c871680ca5a774ebd8d837b702b2fb..5da072488eb46d3b6fb3bd9df0fdfeeada9fac81 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -126,7 +126,7 @@ windows.workspace = true [target.'cfg(target_os = "windows")'.build-dependencies] winresource = "0.1" -[target.'cfg(target_os = "linux")'.dependencies] +[target.'cfg(any(target_os = "linux", target_os = "freebsd"))'.dependencies] ashpd.workspace = true [dev-dependencies] diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 0ba960c0aa717b5025f3b115c1f1618e74e52ecf..a5fc52e93372b787462c0aa3406ca9fea0a1ba67 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -100,12 +100,12 @@ fn fail_to_open_window(e: anyhow::Error, _cx: &mut AppContext) { eprintln!( "Zed failed to open a window: {e:?}. See https://zed.dev/docs/linux for troubleshooting steps." ); - #[cfg(not(target_os = "linux"))] + #[cfg(not(any(target_os = "linux", target_os = "freebsd")))] { process::exit(1); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { use ashpd::desktop::notification::{Notification, NotificationProxy, Priority}; _cx.spawn(|_cx| async move { @@ -172,7 +172,7 @@ fn main() { if *db::ZED_STATELESS || *release_channel::RELEASE_CHANNEL == ReleaseChannel::Dev { false } else { - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { crate::zed::listen_for_cli_connections(open_listener.clone()).is_err() } @@ -426,7 +426,7 @@ fn main() { load_embedded_fonts(cx); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] crate::zed::linux_prompts::init(cx); app_state.languages.set_theme(cx.theme().clone()); @@ -942,7 +942,7 @@ fn init_logger() { config_builder.set_time_offset(offset); } - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] { config_builder.add_filter_ignore_str("zbus"); config_builder.add_filter_ignore_str("blade_graphics::hal::resource"); diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 3b7c5703bc2aaee98903d8a3446d4e397c5a1726..e2dc36a21fe061e72bb849677e42e0d693934afa 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -1,6 +1,6 @@ mod app_menus; pub mod inline_completion_registry; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub(crate) mod linux_prompts; #[cfg(target_os = "macos")] pub(crate) mod mac_only_instance; @@ -153,7 +153,7 @@ pub fn initialize_workspace( }) .detach(); - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_os = "freebsd"))] if let Err(e) = fs::linux_watcher::global(|_| {}) { let message = format!(db::indoc!{r#" inotify_init returned {} @@ -361,7 +361,7 @@ pub fn initialize_workspace( }) .register_action(|_, _: &install_cli::Install, cx| { cx.spawn(|workspace, mut cx| async move { - if cfg!(target_os = "linux") { + if cfg!(any(target_os = "linux", target_os = "freebsd")) { let prompt = cx.prompt( PromptLevel::Warning, "CLI should already be installed", diff --git a/crates/zed/src/zed/open_listener.rs b/crates/zed/src/zed/open_listener.rs index b37bc78dcebbedeca2f65614ee103f4e4aa93fee..eaa912d990db3e633a0625ad6c521448cee23d32 100644 --- a/crates/zed/src/zed/open_listener.rs +++ b/crates/zed/src/zed/open_listener.rs @@ -144,7 +144,7 @@ impl OpenListener { } } -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", target_os = "freebsd"))] pub fn listen_for_cli_connections(opener: OpenListener) -> Result<()> { use release_channel::RELEASE_CHANNEL_NAME; use std::os::unix::net::UnixDatagram;