Handle command line arguments and populate worktree
This commit is contained in:
parent
9bab29c72f
commit
f849857309
6 changed files with 93 additions and 45 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -435,10 +435,10 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-queue"
|
name = "crossbeam-channel"
|
||||||
version = "0.3.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0f6cb3c7f5b8e51bc3ebb73a2327ad4abdbd119dc13223f14f961d2f38486756"
|
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
"crossbeam-utils 0.8.2",
|
"crossbeam-utils 0.8.2",
|
||||||
|
@ -808,7 +808,7 @@ name = "ignore"
|
||||||
version = "0.4.11"
|
version = "0.4.11"
|
||||||
source = "git+https://github.com/zed-industries/ripgrep?rev=1d152118f35b3e3590216709b86277062d79b8a0#1d152118f35b3e3590216709b86277062d79b8a0"
|
source = "git+https://github.com/zed-industries/ripgrep?rev=1d152118f35b3e3590216709b86277062d79b8a0#1d152118f35b3e3590216709b86277062d79b8a0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-channel",
|
"crossbeam-channel 0.4.4",
|
||||||
"crossbeam-utils 0.7.2",
|
"crossbeam-utils 0.7.2",
|
||||||
"globset",
|
"globset",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
|
@ -1647,7 +1647,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"crossbeam-queue",
|
"crossbeam-channel 0.5.0",
|
||||||
"dirs",
|
"dirs",
|
||||||
"easy-parallel",
|
"easy-parallel",
|
||||||
"gpui",
|
"gpui",
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
elements::Element,
|
elements::Element,
|
||||||
executor,
|
executor::{self},
|
||||||
keymap::{self, Keystroke},
|
keymap::{self, Keystroke},
|
||||||
|
platform::{self, App as _},
|
||||||
util::post_inc,
|
util::post_inc,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
@ -66,16 +67,22 @@ pub struct App(Rc<RefCell<MutableAppContext>>);
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
pub fn test<T, F: Future<Output = T>>(f: impl FnOnce(App) -> F) -> T {
|
pub fn test<T, F: Future<Output = T>>(f: impl FnOnce(App) -> F) -> T {
|
||||||
|
let platform = platform::current::app(); // TODO: Make a test platform app
|
||||||
let foreground = Rc::new(executor::Foreground::test());
|
let foreground = Rc::new(executor::Foreground::test());
|
||||||
let app = Self(Rc::new(RefCell::new(
|
let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
|
||||||
MutableAppContext::with_foreground_executor(foreground.clone()),
|
foreground.clone(),
|
||||||
)));
|
Arc::new(platform),
|
||||||
|
))));
|
||||||
app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
|
app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
|
||||||
smol::block_on(foreground.run(f(app)))
|
smol::block_on(foreground.run(f(app)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let app = Self(Rc::new(RefCell::new(MutableAppContext::new()?)));
|
let platform = Arc::new(platform::current::app());
|
||||||
|
let foreground = Rc::new(executor::Foreground::platform(platform.dispatcher())?);
|
||||||
|
let app = Self(Rc::new(RefCell::new(MutableAppContext::new(
|
||||||
|
foreground, platform,
|
||||||
|
))));
|
||||||
app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
|
app.0.borrow_mut().weak_self = Some(Rc::downgrade(&app.0));
|
||||||
Ok(app)
|
Ok(app)
|
||||||
}
|
}
|
||||||
|
@ -269,6 +276,7 @@ type ActionCallback =
|
||||||
type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
|
type GlobalActionCallback = dyn FnMut(&dyn Any, &mut MutableAppContext);
|
||||||
|
|
||||||
pub struct MutableAppContext {
|
pub struct MutableAppContext {
|
||||||
|
platform: Arc<dyn platform::App>,
|
||||||
ctx: AppContext,
|
ctx: AppContext,
|
||||||
actions: HashMap<TypeId, HashMap<String, Vec<Box<ActionCallback>>>>,
|
actions: HashMap<TypeId, HashMap<String, Vec<Box<ActionCallback>>>>,
|
||||||
global_actions: HashMap<String, Vec<Box<GlobalActionCallback>>>,
|
global_actions: HashMap<String, Vec<Box<GlobalActionCallback>>>,
|
||||||
|
@ -292,14 +300,9 @@ pub struct MutableAppContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MutableAppContext {
|
impl MutableAppContext {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new(foreground: Rc<executor::Foreground>, platform: Arc<dyn platform::App>) -> Self {
|
||||||
Ok(Self::with_foreground_executor(Rc::new(
|
|
||||||
executor::Foreground::platform(todo!())?,
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_foreground_executor(foreground: Rc<executor::Foreground>) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
|
platform,
|
||||||
ctx: AppContext {
|
ctx: AppContext {
|
||||||
models: HashMap::new(),
|
models: HashMap::new(),
|
||||||
windows: HashMap::new(),
|
windows: HashMap::new(),
|
||||||
|
@ -1441,8 +1444,8 @@ impl<'a, T: Entity> ModelContext<'a, T> {
|
||||||
self.app
|
self.app
|
||||||
.background
|
.background
|
||||||
.spawn(async move {
|
.spawn(async move {
|
||||||
if let Err(_) = tx.send(future.await).await {
|
if let Err(e) = tx.send(future.await).await {
|
||||||
log::error!("Error sending background task result to main thread",);
|
log::error!("error sending background task result to main thread: {}", e);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
|
@ -15,7 +15,7 @@ path = "src/main.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.38"
|
anyhow = "1.0.38"
|
||||||
arrayvec = "0.5.2"
|
arrayvec = "0.5.2"
|
||||||
crossbeam-queue = "0.3.1"
|
crossbeam-channel = "0.5.0"
|
||||||
dirs = "3.0"
|
dirs = "3.0"
|
||||||
easy-parallel = "3.1.0"
|
easy-parallel = "3.1.0"
|
||||||
gpui = {path = "../gpui"}
|
gpui = {path = "../gpui"}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
mod editor;
|
pub mod editor;
|
||||||
mod operation_queue;
|
mod operation_queue;
|
||||||
mod settings;
|
pub mod settings;
|
||||||
mod sum_tree;
|
mod sum_tree;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
@ -8,5 +8,5 @@ mod time;
|
||||||
mod timer;
|
mod timer;
|
||||||
mod util;
|
mod util;
|
||||||
mod watch;
|
mod watch;
|
||||||
mod workspace;
|
pub mod workspace;
|
||||||
mod worktree;
|
mod worktree;
|
||||||
|
|
|
@ -3,10 +3,15 @@ use gpui::{
|
||||||
executor,
|
executor,
|
||||||
geometry::{rect::RectF, vector::vec2f},
|
geometry::{rect::RectF, vector::vec2f},
|
||||||
platform::{current as platform, App as _, Runner as _, WindowOptions},
|
platform::{current as platform, App as _, Runner as _, WindowOptions},
|
||||||
|
FontCache,
|
||||||
};
|
};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use simplelog::SimpleLogger;
|
use simplelog::SimpleLogger;
|
||||||
use std::{fs, mem, rc::Rc, sync::Arc};
|
use std::{fs, mem, rc::Rc, sync::Arc};
|
||||||
|
use zed::{
|
||||||
|
editor, settings,
|
||||||
|
workspace::{self, OpenParams},
|
||||||
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
init_logger();
|
init_logger();
|
||||||
|
@ -18,23 +23,56 @@ fn main() {
|
||||||
.expect("could not foreground create executor"),
|
.expect("could not foreground create executor"),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let font_cache = FontCache::new();
|
||||||
|
|
||||||
|
let (settings_tx, settings_rx) = settings::channel(&font_cache).unwrap();
|
||||||
|
|
||||||
|
let mut app = gpui::App::new().unwrap();
|
||||||
|
|
||||||
platform::runner()
|
platform::runner()
|
||||||
.on_finish_launching(move || {
|
.on_finish_launching(move || {
|
||||||
log::info!("finish launching");
|
log::info!("finish launching");
|
||||||
|
|
||||||
|
workspace::init(&mut app);
|
||||||
|
editor::init(&mut app);
|
||||||
|
|
||||||
if stdout_is_a_pty() {
|
if stdout_is_a_pty() {
|
||||||
platform.activate(true);
|
platform.activate(true);
|
||||||
}
|
}
|
||||||
let window = platform
|
|
||||||
.open_window(
|
|
||||||
WindowOptions {
|
|
||||||
bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
|
|
||||||
title: Some("Zed"),
|
|
||||||
},
|
|
||||||
foreground,
|
|
||||||
)
|
|
||||||
.expect("error opening window");
|
|
||||||
|
|
||||||
mem::forget(window); // Leak window for now so it doesn't close
|
let paths = std::env::args()
|
||||||
|
.skip(1)
|
||||||
|
.filter_map(|arg| match fs::canonicalize(arg) {
|
||||||
|
Ok(path) => Some(path),
|
||||||
|
Err(error) => {
|
||||||
|
log::error!("error parsing path argument: {}", error);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if !paths.is_empty() {
|
||||||
|
app.dispatch_global_action(
|
||||||
|
"workspace:open_paths",
|
||||||
|
OpenParams {
|
||||||
|
paths,
|
||||||
|
settings: settings_rx,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
mem::forget(app); // This is here until we hold on to the app for some reason
|
||||||
|
}
|
||||||
|
|
||||||
|
// let window = platform
|
||||||
|
// .open_window(
|
||||||
|
// WindowOptions {
|
||||||
|
// bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
|
||||||
|
// title: Some("Zed"),
|
||||||
|
// },
|
||||||
|
// foreground,
|
||||||
|
// )
|
||||||
|
// .expect("error opening window");
|
||||||
|
|
||||||
|
// mem::forget(window); // Leak window for now so it doesn't close
|
||||||
})
|
})
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use super::{
|
||||||
};
|
};
|
||||||
use crate::{editor::History, timer, util::post_inc};
|
use crate::{editor::History, timer, util::post_inc};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use crossbeam_queue::SegQueue;
|
use crossbeam_channel as channel;
|
||||||
use easy_parallel::Parallel;
|
use easy_parallel::Parallel;
|
||||||
use gpui::{AppContext, Entity, ModelContext, ModelHandle};
|
use gpui::{AppContext, Entity, ModelContext, ModelHandle};
|
||||||
use ignore::dir::{Ignore, IgnoreBuilder};
|
use ignore::dir::{Ignore, IgnoreBuilder};
|
||||||
|
@ -39,7 +39,7 @@ struct DirToScan {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
relative_path: PathBuf,
|
relative_path: PathBuf,
|
||||||
ignore: Option<Ignore>,
|
ignore: Option<Ignore>,
|
||||||
dirs_to_scan: Arc<SegQueue<io::Result<DirToScan>>>,
|
dirs_to_scan: channel::Sender<io::Result<DirToScan>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Worktree {
|
impl Worktree {
|
||||||
|
@ -61,10 +61,14 @@ impl Worktree {
|
||||||
|
|
||||||
let tree = tree.clone();
|
let tree = tree.clone();
|
||||||
let (tx, rx) = smol::channel::bounded(1);
|
let (tx, rx) = smol::channel::bounded(1);
|
||||||
std::thread::spawn(move || {
|
|
||||||
let _ = smol::block_on(tx.send(tree.scan_dirs()));
|
ctx.background_executor()
|
||||||
});
|
.spawn(async move {
|
||||||
let _ = ctx.spawn(async move { rx.recv().await.unwrap() }, Self::done_scanning);
|
tx.send(tree.scan_dirs()).await.unwrap();
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
|
||||||
|
let _ = ctx.spawn_local(async move { rx.recv().await.unwrap() }, Self::done_scanning);
|
||||||
|
|
||||||
let _ = ctx.spawn_stream_local(
|
let _ = ctx.spawn_stream_local(
|
||||||
timer::repeat(Duration::from_millis(100)).map(|_| ()),
|
timer::repeat(Duration::from_millis(100)).map(|_| ()),
|
||||||
|
@ -95,19 +99,22 @@ impl Worktree {
|
||||||
if metadata.file_type().is_dir() {
|
if metadata.file_type().is_dir() {
|
||||||
let is_ignored = is_ignored || name == ".git";
|
let is_ignored = is_ignored || name == ".git";
|
||||||
let id = self.push_dir(None, name, ino, is_symlink, is_ignored);
|
let id = self.push_dir(None, name, ino, is_symlink, is_ignored);
|
||||||
let queue = Arc::new(SegQueue::new());
|
let (tx, rx) = channel::unbounded();
|
||||||
|
|
||||||
queue.push(Ok(DirToScan {
|
let tx_ = tx.clone();
|
||||||
|
tx.send(Ok(DirToScan {
|
||||||
id,
|
id,
|
||||||
path,
|
path,
|
||||||
relative_path,
|
relative_path,
|
||||||
ignore: Some(ignore),
|
ignore: Some(ignore),
|
||||||
dirs_to_scan: queue.clone(),
|
dirs_to_scan: tx_,
|
||||||
}));
|
}))
|
||||||
|
.unwrap();
|
||||||
|
drop(tx);
|
||||||
|
|
||||||
Parallel::<io::Result<()>>::new()
|
Parallel::<io::Result<()>>::new()
|
||||||
.each(0..16, |_| {
|
.each(0..16, |_| {
|
||||||
while let Some(result) = queue.pop() {
|
while let Ok(result) = rx.recv() {
|
||||||
self.scan_dir(result?)?;
|
self.scan_dir(result?)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -150,7 +157,7 @@ impl Worktree {
|
||||||
new_children.push(id);
|
new_children.push(id);
|
||||||
|
|
||||||
let dirs_to_scan = to_scan.dirs_to_scan.clone();
|
let dirs_to_scan = to_scan.dirs_to_scan.clone();
|
||||||
let _ = to_scan.dirs_to_scan.push(Ok(DirToScan {
|
let _ = to_scan.dirs_to_scan.send(Ok(DirToScan {
|
||||||
id,
|
id,
|
||||||
path,
|
path,
|
||||||
relative_path,
|
relative_path,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue