Detailed changes
@@ -399,8 +399,7 @@ dependencies = [
[[package]]
name = "cocoa"
version = "0.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832"
+source = "git+https://github.com/zed-industries/core-foundation-rs?rev=52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b#52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"
dependencies = [
"bitflags",
"block",
@@ -415,8 +414,7 @@ dependencies = [
[[package]]
name = "cocoa-foundation"
version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318"
+source = "git+https://github.com/zed-industries/core-foundation-rs?rev=52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b#52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"
dependencies = [
"bitflags",
"block",
@@ -445,8 +443,7 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "core-foundation"
version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
+source = "git+https://github.com/zed-industries/core-foundation-rs?rev=52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b#52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"
dependencies = [
"core-foundation-sys",
"libc",
@@ -455,14 +452,12 @@ dependencies = [
[[package]]
name = "core-foundation-sys"
version = "0.8.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
+source = "git+https://github.com/zed-industries/core-foundation-rs?rev=52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b#52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"
[[package]]
name = "core-graphics"
version = "0.22.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86"
+source = "git+https://github.com/zed-industries/core-foundation-rs?rev=52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b#52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"
dependencies = [
"bitflags",
"core-foundation",
@@ -474,8 +469,7 @@ dependencies = [
[[package]]
name = "core-graphics-types"
version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
+source = "git+https://github.com/zed-industries/core-foundation-rs?rev=52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b#52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"
dependencies = [
"bitflags",
"core-foundation",
@@ -3,3 +3,9 @@ members = ["zed", "gpui"]
[patch.crates-io]
async-task = {git = "https://github.com/zed-industries/async-task", rev = "341b57d6de98cdfd7b418567b8de2022ca993a6e"}
+
+# TODO - Remove when this is merged: https://github.com/servo/core-foundation-rs/pull/454
+cocoa = {git = "https://github.com/zed-industries/core-foundation-rs", rev = "52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"}
+cocoa-foundation = {git = "https://github.com/zed-industries/core-foundation-rs", rev = "52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"}
+core-foundation = {git = "https://github.com/zed-industries/core-foundation-rs", rev = "52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"}
+core-graphics = {git = "https://github.com/zed-industries/core-foundation-rs", rev = "52b7bc0a7026dbbe0da66f5e8de6ce1031476d5b"}
@@ -1,9 +1,13 @@
use super::{BoolExt as _, Dispatcher, FontSystem, Window};
use crate::{executor, platform};
use anyhow::Result;
-use cocoa::{appkit::NSApplication, base::nil};
+use cocoa::{
+ appkit::{NSApplication, NSOpenPanel, NSModalResponse},
+ base::nil,
+ foundation::{NSArray, NSString, NSURL},
+};
use objc::{msg_send, sel, sel_impl};
-use std::{rc::Rc, sync::Arc};
+use std::{path::PathBuf, rc::Rc, sync::Arc};
pub struct App {
dispatcher: Arc<Dispatcher>,
@@ -39,6 +43,37 @@ impl platform::App for App {
Ok(Box::new(Window::open(options, executor, self.fonts())?))
}
+ fn prompt_for_paths(
+ &self,
+ options: platform::PathPromptOptions,
+ ) -> Option<Vec<std::path::PathBuf>> {
+ unsafe {
+ let panel = NSOpenPanel::openPanel(nil);
+ panel.setCanChooseDirectories_(options.directories.to_objc());
+ panel.setCanChooseFiles_(options.files.to_objc());
+ panel.setAllowsMultipleSelection_(options.multiple.to_objc());
+ panel.setResolvesAliases_(false.to_objc());
+ let response = panel.runModal();
+ if response == NSModalResponse::NSModalResponseOk {
+ let mut result = Vec::new();
+ let urls = panel.URLs();
+ for i in 0..urls.count() {
+ let url = urls.objectAtIndex(i);
+ let string = url.absoluteString();
+ let string = std::ffi::CStr::from_ptr(string.UTF8String())
+ .to_string_lossy()
+ .to_string();
+ if let Some(path) = string.strip_prefix("file://") {
+ result.push(PathBuf::from(path));
+ }
+ }
+ Some(result)
+ } else {
+ None
+ }
+ }
+ }
+
fn fonts(&self) -> Arc<dyn platform::FontSystem> {
self.fonts.clone()
}
@@ -41,6 +41,7 @@ pub trait App {
options: WindowOptions,
executor: Rc<executor::Foreground>,
) -> Result<Box<dyn Window>>;
+ fn prompt_for_paths(&self, options: PathPromptOptions) -> Option<Vec<PathBuf>>;
fn fonts(&self) -> Arc<dyn FontSystem>;
fn quit(&self);
}
@@ -66,6 +67,12 @@ pub struct WindowOptions<'a> {
pub title: Option<&'a str>,
}
+pub struct PathPromptOptions {
+ pub files: bool,
+ pub directories: bool,
+ pub multiple: bool,
+}
+
pub trait FontSystem: Send + Sync {
fn load_family(&self, name: &str) -> anyhow::Result<Vec<FontId>>;
fn select_font(
@@ -48,6 +48,10 @@ impl super::App for App {
}
fn quit(&self) {}
+
+ fn prompt_for_paths(&self, _: super::PathPromptOptions) -> Option<Vec<std::path::PathBuf>> {
+ None
+ }
}
impl Window {
@@ -1,5 +1,5 @@
use fs::OpenOptions;
-use gpui::platform::{current as platform, Runner as _};
+use gpui::platform::{current as platform, PathPromptOptions, Runner as _};
use log::LevelFilter;
use simplelog::SimpleLogger;
use std::{fs, path::PathBuf};
@@ -18,9 +18,24 @@ fn main() {
.set_menus(menus::MENUS)
.on_menu_command({
let app = app.clone();
- move |command| {
- log::info!("menu command: {}", command);
- app.dispatch_global_action(command, ())
+ let settings_rx = settings_rx.clone();
+ move |command| match command {
+ "app:open" => {
+ if let Some(paths) = app.platform().prompt_for_paths(PathPromptOptions {
+ files: true,
+ directories: true,
+ multiple: true,
+ }) {
+ app.dispatch_global_action(
+ "workspace:open_paths",
+ OpenParams {
+ paths,
+ settings: settings_rx.clone(),
+ },
+ );
+ }
+ }
+ _ => app.dispatch_global_action(command, ()),
}
})
.on_finish_launching({
@@ -6,7 +6,7 @@ pub const MENUS: &'static [Menu] = &[
name: "Zed",
items: &[
MenuItem::Action {
- name: "About Zed...",
+ name: "About Zedβ¦",
keystroke: None,
action: "app:about-zed",
},
@@ -20,6 +20,14 @@ pub const MENUS: &'static [Menu] = &[
},
Menu {
name: "File",
+ items: &[MenuItem::Action {
+ name: "Openβ¦",
+ keystroke: Some("cmd-o"),
+ action: "app:open",
+ }],
+ },
+ Menu {
+ name: "Edit",
items: &[
MenuItem::Action {
name: "Undo",