Merge branch 'main' into element-types
This commit is contained in:
commit
7f72df6dcf
27 changed files with 3714 additions and 1471 deletions
26
Cargo.lock
generated
26
Cargo.lock
generated
|
@ -3061,6 +3061,31 @@ dependencies = [
|
||||||
"workspace",
|
"workspace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "file_finder2"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"collections",
|
||||||
|
"ctor",
|
||||||
|
"editor2",
|
||||||
|
"env_logger 0.9.3",
|
||||||
|
"fuzzy2",
|
||||||
|
"gpui2",
|
||||||
|
"language2",
|
||||||
|
"menu2",
|
||||||
|
"picker2",
|
||||||
|
"postage",
|
||||||
|
"project2",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"settings2",
|
||||||
|
"text2",
|
||||||
|
"theme2",
|
||||||
|
"ui2",
|
||||||
|
"util",
|
||||||
|
"workspace2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.22"
|
version = "0.2.22"
|
||||||
|
@ -11424,6 +11449,7 @@ dependencies = [
|
||||||
"editor2",
|
"editor2",
|
||||||
"env_logger 0.9.3",
|
"env_logger 0.9.3",
|
||||||
"feature_flags2",
|
"feature_flags2",
|
||||||
|
"file_finder2",
|
||||||
"fs2",
|
"fs2",
|
||||||
"fsevent",
|
"fsevent",
|
||||||
"futures 0.3.28",
|
"futures 0.3.28",
|
||||||
|
|
|
@ -9168,6 +9168,10 @@ impl Editor {
|
||||||
cx.focus(&self.focus_handle)
|
cx.focus(&self.focus_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_focused(&self, cx: &WindowContext) -> bool {
|
||||||
|
self.focus_handle.is_focused(cx)
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_focus_in(&mut self, cx: &mut ViewContext<Self>) {
|
fn handle_focus_in(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
if self.focus_handle.is_focused(cx) {
|
if self.focus_handle.is_focused(cx) {
|
||||||
// todo!()
|
// todo!()
|
||||||
|
@ -9379,8 +9383,8 @@ impl Render for Editor {
|
||||||
EditorMode::SingleLine => {
|
EditorMode::SingleLine => {
|
||||||
TextStyle {
|
TextStyle {
|
||||||
color: cx.theme().colors().text,
|
color: cx.theme().colors().text,
|
||||||
font_family: "Zed Sans".into(), // todo!()
|
font_family: settings.ui_font.family.clone(), // todo!()
|
||||||
font_features: FontFeatures::default(),
|
font_features: settings.ui_font.features,
|
||||||
font_size: rems(0.875).into(),
|
font_size: rems(0.875).into(),
|
||||||
font_weight: FontWeight::NORMAL,
|
font_weight: FontWeight::NORMAL,
|
||||||
font_style: FontStyle::Normal,
|
font_style: FontStyle::Normal,
|
||||||
|
|
|
@ -1448,6 +1448,7 @@ impl EditorElement {
|
||||||
|
|
||||||
let snapshot = editor.snapshot(cx);
|
let snapshot = editor.snapshot(cx);
|
||||||
let style = self.style.clone();
|
let style = self.style.clone();
|
||||||
|
|
||||||
let font_id = cx.text_system().font_id(&style.text.font()).unwrap();
|
let font_id = cx.text_system().font_id(&style.text.font()).unwrap();
|
||||||
let font_size = style.text.font_size.to_pixels(cx.rem_size());
|
let font_size = style.text.font_size.to_pixels(cx.rem_size());
|
||||||
let line_height = style.text.line_height_in_pixels(cx.rem_size());
|
let line_height = style.text.line_height_in_pixels(cx.rem_size());
|
||||||
|
|
37
crates/file_finder2/Cargo.toml
Normal file
37
crates/file_finder2/Cargo.toml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
[package]
|
||||||
|
name = "file_finder2"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/file_finder.rs"
|
||||||
|
doctest = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
editor = { package = "editor2", path = "../editor2" }
|
||||||
|
collections = { path = "../collections" }
|
||||||
|
fuzzy = { package = "fuzzy2", path = "../fuzzy2" }
|
||||||
|
gpui = { package = "gpui2", path = "../gpui2" }
|
||||||
|
menu = { package = "menu2", path = "../menu2" }
|
||||||
|
picker = { package = "picker2", path = "../picker2" }
|
||||||
|
project = { package = "project2", path = "../project2" }
|
||||||
|
settings = { package = "settings2", path = "../settings2" }
|
||||||
|
text = { package = "text2", path = "../text2" }
|
||||||
|
util = { path = "../util" }
|
||||||
|
theme = { package = "theme2", path = "../theme2" }
|
||||||
|
ui = { package = "ui2", path = "../ui2" }
|
||||||
|
workspace = { package = "workspace2", path = "../workspace2" }
|
||||||
|
postage.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
editor = { package = "editor2", path = "../editor2", features = ["test-support"] }
|
||||||
|
gpui = { package = "gpui2", path = "../gpui2", features = ["test-support"] }
|
||||||
|
language = { package = "language2", path = "../language2", features = ["test-support"] }
|
||||||
|
workspace = { package = "workspace2", path = "../workspace2", features = ["test-support"] }
|
||||||
|
theme = { package = "theme2", path = "../theme2", features = ["test-support"] }
|
||||||
|
|
||||||
|
serde_json.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
|
env_logger.workspace = true
|
1977
crates/file_finder2/src/file_finder.rs
Normal file
1977
crates/file_finder2/src/file_finder.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -234,10 +234,10 @@ impl AppContext {
|
||||||
app_version: platform.app_version().ok(),
|
app_version: platform.app_version().ok(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Rc::new_cyclic(|this| AppCell {
|
let app = Rc::new_cyclic(|this| AppCell {
|
||||||
app: RefCell::new(AppContext {
|
app: RefCell::new(AppContext {
|
||||||
this: this.clone(),
|
this: this.clone(),
|
||||||
platform,
|
platform: platform.clone(),
|
||||||
app_metadata,
|
app_metadata,
|
||||||
text_system,
|
text_system,
|
||||||
flushing_effects: false,
|
flushing_effects: false,
|
||||||
|
@ -269,12 +269,21 @@ impl AppContext {
|
||||||
layout_id_buffer: Default::default(),
|
layout_id_buffer: Default::default(),
|
||||||
propagate_event: true,
|
propagate_event: true,
|
||||||
}),
|
}),
|
||||||
})
|
});
|
||||||
|
|
||||||
|
platform.on_quit(Box::new({
|
||||||
|
let cx = app.clone();
|
||||||
|
move || {
|
||||||
|
cx.borrow_mut().shutdown();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
app
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Quit the application gracefully. Handlers registered with `ModelContext::on_app_quit`
|
/// Quit the application gracefully. Handlers registered with `ModelContext::on_app_quit`
|
||||||
/// will be given 100ms to complete before exiting.
|
/// will be given 100ms to complete before exiting.
|
||||||
pub fn quit(&mut self) {
|
pub fn shutdown(&mut self) {
|
||||||
let mut futures = Vec::new();
|
let mut futures = Vec::new();
|
||||||
|
|
||||||
for observer in self.quit_observers.remove(&()) {
|
for observer in self.quit_observers.remove(&()) {
|
||||||
|
@ -292,8 +301,10 @@ impl AppContext {
|
||||||
{
|
{
|
||||||
log::error!("timed out waiting on app_will_quit");
|
log::error!("timed out waiting on app_will_quit");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.globals_by_type.clear();
|
pub fn quit(&mut self) {
|
||||||
|
self.platform.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app_metadata(&self) -> AppMetadata {
|
pub fn app_metadata(&self) -> AppMetadata {
|
||||||
|
|
|
@ -26,7 +26,7 @@ impl EntityId {
|
||||||
|
|
||||||
impl Display for EntityId {
|
impl Display for EntityId {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{}", self)
|
write!(f, "{}", self.as_u64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
div, AnyView, AnyWindowHandle, AppCell, AppContext, AsyncAppContext, BackgroundExecutor,
|
div, Action, AnyView, AnyWindowHandle, AppCell, AppContext, AsyncAppContext,
|
||||||
Context, Div, EventEmitter, ForegroundExecutor, InputEvent, KeyDownEvent, Keystroke, Model,
|
BackgroundExecutor, Context, Div, EventEmitter, ForegroundExecutor, InputEvent, KeyDownEvent,
|
||||||
ModelContext, Render, Result, Task, TestDispatcher, TestPlatform, View, ViewContext,
|
Keystroke, Model, ModelContext, Render, Result, Task, TestDispatcher, TestPlatform, View,
|
||||||
VisualContext, WindowContext, WindowHandle, WindowOptions,
|
ViewContext, VisualContext, WindowContext, WindowHandle, WindowOptions,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, bail};
|
use anyhow::{anyhow, bail};
|
||||||
use futures::{Stream, StreamExt};
|
use futures::{Stream, StreamExt};
|
||||||
|
@ -14,6 +14,7 @@ pub struct TestAppContext {
|
||||||
pub background_executor: BackgroundExecutor,
|
pub background_executor: BackgroundExecutor,
|
||||||
pub foreground_executor: ForegroundExecutor,
|
pub foreground_executor: ForegroundExecutor,
|
||||||
pub dispatcher: TestDispatcher,
|
pub dispatcher: TestDispatcher,
|
||||||
|
pub test_platform: Rc<TestPlatform>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context for TestAppContext {
|
impl Context for TestAppContext {
|
||||||
|
@ -77,17 +78,16 @@ impl TestAppContext {
|
||||||
let arc_dispatcher = Arc::new(dispatcher.clone());
|
let arc_dispatcher = Arc::new(dispatcher.clone());
|
||||||
let background_executor = BackgroundExecutor::new(arc_dispatcher.clone());
|
let background_executor = BackgroundExecutor::new(arc_dispatcher.clone());
|
||||||
let foreground_executor = ForegroundExecutor::new(arc_dispatcher);
|
let foreground_executor = ForegroundExecutor::new(arc_dispatcher);
|
||||||
let platform = Rc::new(TestPlatform::new(
|
let platform = TestPlatform::new(background_executor.clone(), foreground_executor.clone());
|
||||||
background_executor.clone(),
|
|
||||||
foreground_executor.clone(),
|
|
||||||
));
|
|
||||||
let asset_source = Arc::new(());
|
let asset_source = Arc::new(());
|
||||||
let http_client = util::http::FakeHttpClient::with_404_response();
|
let http_client = util::http::FakeHttpClient::with_404_response();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
app: AppContext::new(platform, asset_source, http_client),
|
app: AppContext::new(platform.clone(), asset_source, http_client),
|
||||||
background_executor,
|
background_executor,
|
||||||
foreground_executor,
|
foreground_executor,
|
||||||
dispatcher: dispatcher.clone(),
|
dispatcher: dispatcher.clone(),
|
||||||
|
test_platform: platform,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ impl TestAppContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn quit(&self) {
|
pub fn quit(&self) {
|
||||||
self.app.borrow_mut().quit();
|
self.app.borrow_mut().shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refresh(&mut self) -> Result<()> {
|
pub fn refresh(&mut self) -> Result<()> {
|
||||||
|
@ -152,6 +152,21 @@ impl TestAppContext {
|
||||||
(view, VisualTestContext::from_window(*window.deref(), self))
|
(view, VisualTestContext::from_window(*window.deref(), self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn simulate_new_path_selection(
|
||||||
|
&self,
|
||||||
|
select_path: impl FnOnce(&std::path::Path) -> Option<std::path::PathBuf>,
|
||||||
|
) {
|
||||||
|
self.test_platform.simulate_new_path_selection(select_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn simulate_prompt_answer(&self, button_ix: usize) {
|
||||||
|
self.test_platform.simulate_prompt_answer(button_ix);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_pending_prompt(&self) -> bool {
|
||||||
|
self.test_platform.has_pending_prompt()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
|
pub fn spawn<Fut, R>(&self, f: impl FnOnce(AsyncAppContext) -> Fut) -> Task<R>
|
||||||
where
|
where
|
||||||
Fut: Future<Output = R> + 'static,
|
Fut: Future<Output = R> + 'static,
|
||||||
|
@ -199,6 +214,15 @@ impl TestAppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dispatch_action<A>(&mut self, window: AnyWindowHandle, action: A)
|
||||||
|
where
|
||||||
|
A: Action,
|
||||||
|
{
|
||||||
|
window
|
||||||
|
.update(self, |_, cx| cx.dispatch_action(action.boxed_clone()))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn dispatch_keystroke(
|
pub fn dispatch_keystroke(
|
||||||
&mut self,
|
&mut self,
|
||||||
window: AnyWindowHandle,
|
window: AnyWindowHandle,
|
||||||
|
@ -376,6 +400,13 @@ impl<'a> VisualTestContext<'a> {
|
||||||
pub fn from_window(window: AnyWindowHandle, cx: &'a mut TestAppContext) -> Self {
|
pub fn from_window(window: AnyWindowHandle, cx: &'a mut TestAppContext) -> Self {
|
||||||
Self { cx, window }
|
Self { cx, window }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dispatch_action<A>(&mut self, action: A)
|
||||||
|
where
|
||||||
|
A: Action,
|
||||||
|
{
|
||||||
|
self.cx.dispatch_action(self.window, action)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Context for VisualTestContext<'a> {
|
impl<'a> Context for VisualTestContext<'a> {
|
||||||
|
|
|
@ -14,7 +14,7 @@ use taffy::style::Overflow;
|
||||||
pub fn uniform_list<I, V, C>(
|
pub fn uniform_list<I, V, C>(
|
||||||
id: I,
|
id: I,
|
||||||
item_count: usize,
|
item_count: usize,
|
||||||
f: impl 'static + Fn(&mut V, Range<usize>, &mut ViewContext<V>) -> SmallVec<[C; 64]>,
|
f: impl 'static + Fn(&mut V, Range<usize>, &mut ViewContext<V>) -> Vec<C>,
|
||||||
) -> UniformList<V>
|
) -> UniformList<V>
|
||||||
where
|
where
|
||||||
I: Into<ElementId>,
|
I: Into<ElementId>,
|
||||||
|
|
|
@ -3,8 +3,15 @@ use crate::{
|
||||||
PlatformDisplay, PlatformTextSystem, TestDisplay, TestWindow, WindowOptions,
|
PlatformDisplay, PlatformTextSystem, TestDisplay, TestWindow, WindowOptions,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
use collections::VecDeque;
|
||||||
|
use futures::channel::oneshot;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{rc::Rc, sync::Arc};
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
path::PathBuf,
|
||||||
|
rc::{Rc, Weak},
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct TestPlatform {
|
pub struct TestPlatform {
|
||||||
background_executor: BackgroundExecutor,
|
background_executor: BackgroundExecutor,
|
||||||
|
@ -13,18 +20,60 @@ pub struct TestPlatform {
|
||||||
active_window: Arc<Mutex<Option<AnyWindowHandle>>>,
|
active_window: Arc<Mutex<Option<AnyWindowHandle>>>,
|
||||||
active_display: Rc<dyn PlatformDisplay>,
|
active_display: Rc<dyn PlatformDisplay>,
|
||||||
active_cursor: Mutex<CursorStyle>,
|
active_cursor: Mutex<CursorStyle>,
|
||||||
|
pub(crate) prompts: RefCell<TestPrompts>,
|
||||||
|
weak: Weak<Self>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub(crate) struct TestPrompts {
|
||||||
|
multiple_choice: VecDeque<oneshot::Sender<usize>>,
|
||||||
|
new_path: VecDeque<(PathBuf, oneshot::Sender<Option<PathBuf>>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestPlatform {
|
impl TestPlatform {
|
||||||
pub fn new(executor: BackgroundExecutor, foreground_executor: ForegroundExecutor) -> Self {
|
pub fn new(executor: BackgroundExecutor, foreground_executor: ForegroundExecutor) -> Rc<Self> {
|
||||||
TestPlatform {
|
Rc::new_cyclic(|weak| TestPlatform {
|
||||||
background_executor: executor,
|
background_executor: executor,
|
||||||
foreground_executor,
|
foreground_executor,
|
||||||
|
prompts: Default::default(),
|
||||||
active_cursor: Default::default(),
|
active_cursor: Default::default(),
|
||||||
active_display: Rc::new(TestDisplay::new()),
|
active_display: Rc::new(TestDisplay::new()),
|
||||||
active_window: Default::default(),
|
active_window: Default::default(),
|
||||||
|
weak: weak.clone(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn simulate_new_path_selection(
|
||||||
|
&self,
|
||||||
|
select_path: impl FnOnce(&std::path::Path) -> Option<std::path::PathBuf>,
|
||||||
|
) {
|
||||||
|
let (path, tx) = self
|
||||||
|
.prompts
|
||||||
|
.borrow_mut()
|
||||||
|
.new_path
|
||||||
|
.pop_front()
|
||||||
|
.expect("no pending new path prompt");
|
||||||
|
tx.send(select_path(&path)).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn simulate_prompt_answer(&self, response_ix: usize) {
|
||||||
|
let tx = self
|
||||||
|
.prompts
|
||||||
|
.borrow_mut()
|
||||||
|
.multiple_choice
|
||||||
|
.pop_front()
|
||||||
|
.expect("no pending multiple choice prompt");
|
||||||
|
tx.send(response_ix).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn has_pending_prompt(&self) -> bool {
|
||||||
|
!self.prompts.borrow().multiple_choice.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn prompt(&self) -> oneshot::Receiver<usize> {
|
||||||
|
let (tx, rx) = oneshot::channel();
|
||||||
|
self.prompts.borrow_mut().multiple_choice.push_back(tx);
|
||||||
|
rx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,9 +95,7 @@ impl Platform for TestPlatform {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn quit(&self) {
|
fn quit(&self) {}
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn restart(&self) {
|
fn restart(&self) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -88,7 +135,11 @@ impl Platform for TestPlatform {
|
||||||
options: WindowOptions,
|
options: WindowOptions,
|
||||||
) -> Box<dyn crate::PlatformWindow> {
|
) -> Box<dyn crate::PlatformWindow> {
|
||||||
*self.active_window.lock() = Some(handle);
|
*self.active_window.lock() = Some(handle);
|
||||||
Box::new(TestWindow::new(options, self.active_display.clone()))
|
Box::new(TestWindow::new(
|
||||||
|
options,
|
||||||
|
self.weak.clone(),
|
||||||
|
self.active_display.clone(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_display_link_output_callback(
|
fn set_display_link_output_callback(
|
||||||
|
@ -118,15 +169,20 @@ impl Platform for TestPlatform {
|
||||||
fn prompt_for_paths(
|
fn prompt_for_paths(
|
||||||
&self,
|
&self,
|
||||||
_options: crate::PathPromptOptions,
|
_options: crate::PathPromptOptions,
|
||||||
) -> futures::channel::oneshot::Receiver<Option<Vec<std::path::PathBuf>>> {
|
) -> oneshot::Receiver<Option<Vec<std::path::PathBuf>>> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_for_new_path(
|
fn prompt_for_new_path(
|
||||||
&self,
|
&self,
|
||||||
_directory: &std::path::Path,
|
directory: &std::path::Path,
|
||||||
) -> futures::channel::oneshot::Receiver<Option<std::path::PathBuf>> {
|
) -> oneshot::Receiver<Option<std::path::PathBuf>> {
|
||||||
unimplemented!()
|
let (tx, rx) = oneshot::channel();
|
||||||
|
self.prompts
|
||||||
|
.borrow_mut()
|
||||||
|
.new_path
|
||||||
|
.push_back((directory.to_path_buf(), tx));
|
||||||
|
rx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reveal_path(&self, _path: &std::path::Path) {
|
fn reveal_path(&self, _path: &std::path::Path) {
|
||||||
|
@ -141,9 +197,7 @@ impl Platform for TestPlatform {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_quit(&self, _callback: Box<dyn FnMut()>) {
|
fn on_quit(&self, _callback: Box<dyn FnMut()>) {}
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_reopen(&self, _callback: Box<dyn FnMut()>) {
|
fn on_reopen(&self, _callback: Box<dyn FnMut()>) {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
use std::{
|
|
||||||
rc::Rc,
|
|
||||||
sync::{self, Arc},
|
|
||||||
};
|
|
||||||
|
|
||||||
use collections::HashMap;
|
|
||||||
use parking_lot::Mutex;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
px, AtlasKey, AtlasTextureId, AtlasTile, Pixels, PlatformAtlas, PlatformDisplay,
|
px, AtlasKey, AtlasTextureId, AtlasTile, Pixels, PlatformAtlas, PlatformDisplay,
|
||||||
PlatformInputHandler, PlatformWindow, Point, Scene, Size, TileId, WindowAppearance,
|
PlatformInputHandler, PlatformWindow, Point, Scene, Size, TestPlatform, TileId,
|
||||||
WindowBounds, WindowOptions,
|
WindowAppearance, WindowBounds, WindowOptions,
|
||||||
|
};
|
||||||
|
use collections::HashMap;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use std::{
|
||||||
|
rc::{Rc, Weak},
|
||||||
|
sync::{self, Arc},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -25,16 +23,22 @@ pub struct TestWindow {
|
||||||
current_scene: Mutex<Option<Scene>>,
|
current_scene: Mutex<Option<Scene>>,
|
||||||
display: Rc<dyn PlatformDisplay>,
|
display: Rc<dyn PlatformDisplay>,
|
||||||
input_handler: Option<Box<dyn PlatformInputHandler>>,
|
input_handler: Option<Box<dyn PlatformInputHandler>>,
|
||||||
|
|
||||||
handlers: Mutex<Handlers>,
|
handlers: Mutex<Handlers>,
|
||||||
|
platform: Weak<TestPlatform>,
|
||||||
sprite_atlas: Arc<dyn PlatformAtlas>,
|
sprite_atlas: Arc<dyn PlatformAtlas>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestWindow {
|
impl TestWindow {
|
||||||
pub fn new(options: WindowOptions, display: Rc<dyn PlatformDisplay>) -> Self {
|
pub fn new(
|
||||||
|
options: WindowOptions,
|
||||||
|
platform: Weak<TestPlatform>,
|
||||||
|
display: Rc<dyn PlatformDisplay>,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bounds: options.bounds,
|
bounds: options.bounds,
|
||||||
current_scene: Default::default(),
|
current_scene: Default::default(),
|
||||||
display,
|
display,
|
||||||
|
platform,
|
||||||
input_handler: None,
|
input_handler: None,
|
||||||
sprite_atlas: Arc::new(TestAtlas::new()),
|
sprite_atlas: Arc::new(TestAtlas::new()),
|
||||||
handlers: Default::default(),
|
handlers: Default::default(),
|
||||||
|
@ -89,7 +93,7 @@ impl PlatformWindow for TestWindow {
|
||||||
_msg: &str,
|
_msg: &str,
|
||||||
_answers: &[&str],
|
_answers: &[&str],
|
||||||
) -> futures::channel::oneshot::Receiver<usize> {
|
) -> futures::channel::oneshot::Receiver<usize> {
|
||||||
todo!()
|
self.platform.upgrade().expect("platform dropped").prompt()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn activate(&self) {
|
fn activate(&self) {
|
||||||
|
|
|
@ -167,7 +167,7 @@ fn main() {
|
||||||
panic!("unexpected message");
|
panic!("unexpected message");
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.update(|cx| cx.quit()).ok();
|
cx.update(|cx| cx.shutdown()).ok();
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{anyhow, bail, Context, Result};
|
||||||
use async_compression::futures::bufread::GzipDecoder;
|
use async_compression::futures::bufread::GzipDecoder;
|
||||||
use async_tar::Archive;
|
use async_tar::Archive;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use smol::{fs, io::BufReader, process::Command};
|
use smol::{fs, io::BufReader, lock::Mutex, process::Command};
|
||||||
use std::process::{Output, Stdio};
|
use std::process::{Output, Stdio};
|
||||||
use std::{
|
use std::{
|
||||||
env::consts,
|
env::consts,
|
||||||
|
@ -45,14 +45,19 @@ pub trait NodeRuntime: Send + Sync {
|
||||||
|
|
||||||
pub struct RealNodeRuntime {
|
pub struct RealNodeRuntime {
|
||||||
http: Arc<dyn HttpClient>,
|
http: Arc<dyn HttpClient>,
|
||||||
|
installation_lock: Mutex<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RealNodeRuntime {
|
impl RealNodeRuntime {
|
||||||
pub fn new(http: Arc<dyn HttpClient>) -> Arc<dyn NodeRuntime> {
|
pub fn new(http: Arc<dyn HttpClient>) -> Arc<dyn NodeRuntime> {
|
||||||
Arc::new(RealNodeRuntime { http })
|
Arc::new(RealNodeRuntime {
|
||||||
|
http,
|
||||||
|
installation_lock: Mutex::new(()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn install_if_needed(&self) -> Result<PathBuf> {
|
async fn install_if_needed(&self) -> Result<PathBuf> {
|
||||||
|
let _lock = self.installation_lock.lock().await;
|
||||||
log::info!("Node runtime install_if_needed");
|
log::info!("Node runtime install_if_needed");
|
||||||
|
|
||||||
let arch = match consts::ARCH {
|
let arch = match consts::ARCH {
|
||||||
|
@ -73,6 +78,9 @@ impl RealNodeRuntime {
|
||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.stdout(Stdio::null())
|
.stdout(Stdio::null())
|
||||||
.stderr(Stdio::null())
|
.stderr(Stdio::null())
|
||||||
|
.args(["--cache".into(), node_dir.join("cache")])
|
||||||
|
.args(["--userconfig".into(), node_dir.join("blank_user_npmrc")])
|
||||||
|
.args(["--globalconfig".into(), node_dir.join("blank_global_npmrc")])
|
||||||
.status()
|
.status()
|
||||||
.await;
|
.await;
|
||||||
let valid = matches!(result, Ok(status) if status.success());
|
let valid = matches!(result, Ok(status) if status.success());
|
||||||
|
@ -96,6 +104,11 @@ impl RealNodeRuntime {
|
||||||
archive.unpack(&node_containing_dir).await?;
|
archive.unpack(&node_containing_dir).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: Not in the `if !valid {}` so we can populate these for existing installations
|
||||||
|
_ = fs::create_dir(node_dir.join("cache")).await;
|
||||||
|
_ = fs::write(node_dir.join("blank_user_npmrc"), []).await;
|
||||||
|
_ = fs::write(node_dir.join("blank_global_npmrc"), []).await;
|
||||||
|
|
||||||
anyhow::Ok(node_dir)
|
anyhow::Ok(node_dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +150,17 @@ impl NodeRuntime for RealNodeRuntime {
|
||||||
|
|
||||||
let mut command = Command::new(node_binary);
|
let mut command = Command::new(node_binary);
|
||||||
command.env("PATH", env_path);
|
command.env("PATH", env_path);
|
||||||
command.arg(npm_file).arg(subcommand).args(args);
|
command.arg(npm_file).arg(subcommand);
|
||||||
|
command.args(["--cache".into(), installation_path.join("cache")]);
|
||||||
|
command.args([
|
||||||
|
"--userconfig".into(),
|
||||||
|
installation_path.join("blank_user_npmrc"),
|
||||||
|
]);
|
||||||
|
command.args([
|
||||||
|
"--globalconfig".into(),
|
||||||
|
installation_path.join("blank_global_npmrc"),
|
||||||
|
]);
|
||||||
|
command.args(args);
|
||||||
|
|
||||||
if let Some(directory) = directory {
|
if let Some(directory) = directory {
|
||||||
command.current_dir(directory);
|
command.current_dir(directory);
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
self.editor.update(cx, |editor, cx| editor.focus(cx));
|
self.editor.update(cx, |editor, cx| editor.focus(cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn select_next(&mut self, _: &menu::SelectNext, cx: &mut ViewContext<Self>) {
|
pub fn select_next(&mut self, _: &menu::SelectNext, cx: &mut ViewContext<Self>) {
|
||||||
let count = self.delegate.match_count();
|
let count = self.delegate.match_count();
|
||||||
if count > 0 {
|
if count > 0 {
|
||||||
let index = self.delegate.selected_index();
|
let index = self.delegate.selected_index();
|
||||||
|
@ -98,6 +98,15 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cycle_selection(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
let count = self.delegate.match_count();
|
||||||
|
let index = self.delegate.selected_index();
|
||||||
|
let new_index = if index + 1 == count { 0 } else { index + 1 };
|
||||||
|
self.delegate.set_selected_index(new_index, cx);
|
||||||
|
self.scroll_handle.scroll_to_item(new_index);
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
|
fn cancel(&mut self, _: &menu::Cancel, cx: &mut ViewContext<Self>) {
|
||||||
self.delegate.dismissed(cx);
|
self.delegate.dismissed(cx);
|
||||||
}
|
}
|
||||||
|
@ -137,6 +146,11 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refresh(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
|
let query = self.editor.read(cx).text(cx);
|
||||||
|
self.update_matches(query, cx);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_matches(&mut self, query: String, cx: &mut ViewContext<Self>) {
|
pub fn update_matches(&mut self, query: String, cx: &mut ViewContext<Self>) {
|
||||||
let update = self.delegate.update_matches(query, cx);
|
let update = self.delegate.update_matches(query, cx);
|
||||||
self.matches_updated(cx);
|
self.matches_updated(cx);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -35,6 +35,7 @@ pub(crate) fn one_dark() -> Theme {
|
||||||
id: "one_dark".to_string(),
|
id: "one_dark".to_string(),
|
||||||
name: "One Dark".into(),
|
name: "One Dark".into(),
|
||||||
appearance: Appearance::Dark,
|
appearance: Appearance::Dark,
|
||||||
|
|
||||||
styles: ThemeStyles {
|
styles: ThemeStyles {
|
||||||
system: SystemColors::default(),
|
system: SystemColors::default(),
|
||||||
colors: ThemeColors {
|
colors: ThemeColors {
|
||||||
|
|
|
@ -19,6 +19,7 @@ const MIN_LINE_HEIGHT: f32 = 1.0;
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ThemeSettings {
|
pub struct ThemeSettings {
|
||||||
pub ui_font_size: Pixels,
|
pub ui_font_size: Pixels,
|
||||||
|
pub ui_font: Font,
|
||||||
pub buffer_font: Font,
|
pub buffer_font: Font,
|
||||||
pub buffer_font_size: Pixels,
|
pub buffer_font_size: Pixels,
|
||||||
pub buffer_line_height: BufferLineHeight,
|
pub buffer_line_height: BufferLineHeight,
|
||||||
|
@ -120,6 +121,12 @@ impl settings::Settings for ThemeSettings {
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
ui_font_size: defaults.ui_font_size.unwrap_or(16.).into(),
|
ui_font_size: defaults.ui_font_size.unwrap_or(16.).into(),
|
||||||
|
ui_font: Font {
|
||||||
|
family: "Helvetica".into(),
|
||||||
|
features: Default::default(),
|
||||||
|
weight: Default::default(),
|
||||||
|
style: Default::default(),
|
||||||
|
},
|
||||||
buffer_font: Font {
|
buffer_font: Font {
|
||||||
family: defaults.buffer_font_family.clone().unwrap().into(),
|
family: defaults.buffer_font_family.clone().unwrap().into(),
|
||||||
features: defaults.buffer_font_features.clone().unwrap(),
|
features: defaults.buffer_font_features.clone().unwrap(),
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl Icon {
|
||||||
|
|
||||||
#[derive(Component)]
|
#[derive(Component)]
|
||||||
pub struct IconElement {
|
pub struct IconElement {
|
||||||
icon: Icon,
|
path: SharedString,
|
||||||
color: TextColor,
|
color: TextColor,
|
||||||
size: IconSize,
|
size: IconSize,
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,15 @@ pub struct IconElement {
|
||||||
impl IconElement {
|
impl IconElement {
|
||||||
pub fn new(icon: Icon) -> Self {
|
pub fn new(icon: Icon) -> Self {
|
||||||
Self {
|
Self {
|
||||||
icon,
|
path: icon.path().into(),
|
||||||
|
color: TextColor::default(),
|
||||||
|
size: IconSize::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_path(path: impl Into<SharedString>) -> Self {
|
||||||
|
Self {
|
||||||
|
path: path.into(),
|
||||||
color: TextColor::default(),
|
color: TextColor::default(),
|
||||||
size: IconSize::default(),
|
size: IconSize::default(),
|
||||||
}
|
}
|
||||||
|
@ -162,7 +170,7 @@ impl IconElement {
|
||||||
svg()
|
svg()
|
||||||
.size(svg_size)
|
.size(svg_size)
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.path(self.icon.path())
|
.path(self.path)
|
||||||
.text_color(self.color.color(cx))
|
.text_color(self.color.color(cx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use gpui::{Div, ParentComponent, Render, SharedString, Styled, ViewContext};
|
use gpui::{Div, Render};
|
||||||
use theme2::ActiveTheme;
|
use settings2::Settings;
|
||||||
|
use theme2::{ActiveTheme, ThemeSettings};
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::{h_stack, v_stack, KeyBinding, Label, LabelSize, StyledExt, TextColor};
|
use crate::{h_stack, v_stack, KeyBinding, Label, LabelSize, StyledExt, TextColor};
|
||||||
|
@ -34,9 +35,10 @@ impl Render for TextTooltip {
|
||||||
type Element = Div<Self>;
|
type Element = Div<Self>;
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
|
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
|
||||||
v_stack()
|
v_stack()
|
||||||
.elevation_2(cx)
|
.elevation_2(cx)
|
||||||
.font("Zed Sans")
|
.font(ui_font)
|
||||||
.text_ui_sm()
|
.text_ui_sm()
|
||||||
.text_color(cx.theme().colors().text)
|
.text_color(cx.theme().colors().text)
|
||||||
.py_1()
|
.py_1()
|
||||||
|
|
|
@ -206,13 +206,14 @@ impl Render for Workspace {
|
||||||
.child(self.editor_1.clone())],
|
.child(self.editor_1.clone())],
|
||||||
SplitDirection::Horizontal,
|
SplitDirection::Horizontal,
|
||||||
);
|
);
|
||||||
|
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.relative()
|
.relative()
|
||||||
.size_full()
|
.size_full()
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.font("Zed Sans")
|
.font(ui_font)
|
||||||
.gap_0()
|
.gap_0()
|
||||||
.justify_start()
|
.justify_start()
|
||||||
.items_start()
|
.items_start()
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use crate::{status_bar::StatusItemView, Axis, Workspace};
|
use crate::{status_bar::StatusItemView, Axis, Workspace};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, Action, AnyView, AppContext, Div, Entity, EntityId, EventEmitter, FocusHandle,
|
div, px, Action, AnyView, AppContext, Component, Div, Entity, EntityId, EventEmitter,
|
||||||
ParentComponent, Render, Styled, Subscription, View, ViewContext, WeakView, WindowContext,
|
FocusHandle, ParentComponent, Render, Styled, Subscription, View, ViewContext, WeakView,
|
||||||
|
WindowContext,
|
||||||
};
|
};
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -429,7 +430,14 @@ impl Render for Dock {
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
if let Some(entry) = self.visible_entry() {
|
if let Some(entry) = self.visible_entry() {
|
||||||
div().size_full().child(entry.panel.to_any())
|
let size = entry.panel.size(cx);
|
||||||
|
|
||||||
|
div()
|
||||||
|
.map(|this| match self.position().axis() {
|
||||||
|
Axis::Horizontal => this.w(px(size)).h_full(),
|
||||||
|
Axis::Vertical => this.h(px(size)).w_full(),
|
||||||
|
})
|
||||||
|
.child(entry.panel.to_any())
|
||||||
} else {
|
} else {
|
||||||
div()
|
div()
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,14 @@ impl ModalLayer {
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_modal<V>(&self) -> Option<View<V>>
|
||||||
|
where
|
||||||
|
V: 'static,
|
||||||
|
{
|
||||||
|
let active_modal = self.active_modal.as_ref()?;
|
||||||
|
active_modal.modal.clone().downcast::<V>().ok()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for ModalLayer {
|
impl Render for ModalLayer {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::DraggedItem;
|
||||||
use crate::{Pane, SplitDirection, Workspace};
|
use crate::{Pane, SplitDirection, Workspace};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
color::Color,
|
color::Color,
|
||||||
elements::{Canvas, MouseEventHandler, ParentElement, Stack},
|
elements::{Canvas, MouseEventHandler, ParentComponent, Stack},
|
||||||
geometry::{rect::RectF, vector::Vector2F},
|
geometry::{rect::RectF, vector::Vector2F},
|
||||||
platform::MouseButton,
|
platform::MouseButton,
|
||||||
scene::MouseUp,
|
scene::MouseUp,
|
||||||
|
|
|
@ -66,9 +66,10 @@ use std::{
|
||||||
sync::{atomic::AtomicUsize, Arc},
|
sync::{atomic::AtomicUsize, Arc},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use theme2::ActiveTheme;
|
use theme2::{ActiveTheme, ThemeSettings};
|
||||||
pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
||||||
use ui::{h_stack, Button, ButtonVariant, KeyBinding, Label, TextColor, TextTooltip};
|
use ui::TextColor;
|
||||||
|
use ui::{h_stack, Button, ButtonVariant, KeyBinding, Label, TextTooltip};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
pub use workspace_settings::{AutosaveSetting, WorkspaceSettings};
|
pub use workspace_settings::{AutosaveSetting, WorkspaceSettings};
|
||||||
|
@ -1765,50 +1766,50 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn open_abs_path(
|
pub fn open_abs_path(
|
||||||
// &mut self,
|
&mut self,
|
||||||
// abs_path: PathBuf,
|
abs_path: PathBuf,
|
||||||
// visible: bool,
|
visible: bool,
|
||||||
// cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
// ) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
||||||
// cx.spawn(|workspace, mut cx| async move {
|
cx.spawn(|workspace, mut cx| async move {
|
||||||
// let open_paths_task_result = workspace
|
let open_paths_task_result = workspace
|
||||||
// .update(&mut cx, |workspace, cx| {
|
.update(&mut cx, |workspace, cx| {
|
||||||
// workspace.open_paths(vec![abs_path.clone()], visible, cx)
|
workspace.open_paths(vec![abs_path.clone()], visible, cx)
|
||||||
// })
|
})
|
||||||
// .with_context(|| format!("open abs path {abs_path:?} task spawn"))?
|
.with_context(|| format!("open abs path {abs_path:?} task spawn"))?
|
||||||
// .await;
|
.await;
|
||||||
// anyhow::ensure!(
|
anyhow::ensure!(
|
||||||
// open_paths_task_result.len() == 1,
|
open_paths_task_result.len() == 1,
|
||||||
// "open abs path {abs_path:?} task returned incorrect number of results"
|
"open abs path {abs_path:?} task returned incorrect number of results"
|
||||||
// );
|
);
|
||||||
// match open_paths_task_result
|
match open_paths_task_result
|
||||||
// .into_iter()
|
.into_iter()
|
||||||
// .next()
|
.next()
|
||||||
// .expect("ensured single task result")
|
.expect("ensured single task result")
|
||||||
// {
|
{
|
||||||
// Some(open_result) => {
|
Some(open_result) => {
|
||||||
// open_result.with_context(|| format!("open abs path {abs_path:?} task join"))
|
open_result.with_context(|| format!("open abs path {abs_path:?} task join"))
|
||||||
// }
|
}
|
||||||
// None => anyhow::bail!("open abs path {abs_path:?} task returned None"),
|
None => anyhow::bail!("open abs path {abs_path:?} task returned None"),
|
||||||
// }
|
}
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
// pub fn split_abs_path(
|
pub fn split_abs_path(
|
||||||
// &mut self,
|
&mut self,
|
||||||
// abs_path: PathBuf,
|
abs_path: PathBuf,
|
||||||
// visible: bool,
|
visible: bool,
|
||||||
// cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
// ) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
) -> Task<anyhow::Result<Box<dyn ItemHandle>>> {
|
||||||
// let project_path_task =
|
let project_path_task =
|
||||||
// Workspace::project_path_for_path(self.project.clone(), &abs_path, visible, cx);
|
Workspace::project_path_for_path(self.project.clone(), &abs_path, visible, cx);
|
||||||
// cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
// let (_, path) = project_path_task.await?;
|
let (_, path) = project_path_task.await?;
|
||||||
// this.update(&mut cx, |this, cx| this.split_path(path, cx))?
|
this.update(&mut cx, |this, cx| this.split_path(path, cx))?
|
||||||
// .await
|
.await
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub fn open_path(
|
pub fn open_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1835,37 +1836,37 @@ impl Workspace {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn split_path(
|
pub fn split_path(
|
||||||
// &mut self,
|
&mut self,
|
||||||
// path: impl Into<ProjectPath>,
|
path: impl Into<ProjectPath>,
|
||||||
// cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
// ) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
) -> Task<Result<Box<dyn ItemHandle>, anyhow::Error>> {
|
||||||
// let pane = self.last_active_center_pane.clone().unwrap_or_else(|| {
|
let pane = self.last_active_center_pane.clone().unwrap_or_else(|| {
|
||||||
// self.panes
|
self.panes
|
||||||
// .first()
|
.first()
|
||||||
// .expect("There must be an active pane")
|
.expect("There must be an active pane")
|
||||||
// .downgrade()
|
.downgrade()
|
||||||
// });
|
});
|
||||||
|
|
||||||
// if let Member::Pane(center_pane) = &self.center.root {
|
if let Member::Pane(center_pane) = &self.center.root {
|
||||||
// if center_pane.read(cx).items_len() == 0 {
|
if center_pane.read(cx).items_len() == 0 {
|
||||||
// return self.open_path(path, Some(pane), true, cx);
|
return self.open_path(path, Some(pane), true, cx);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// let task = self.load_path(path.into(), cx);
|
let task = self.load_path(path.into(), cx);
|
||||||
// cx.spawn(|this, mut cx| async move {
|
cx.spawn(|this, mut cx| async move {
|
||||||
// let (project_entry_id, build_item) = task.await?;
|
let (project_entry_id, build_item) = task.await?;
|
||||||
// this.update(&mut cx, move |this, cx| -> Option<_> {
|
this.update(&mut cx, move |this, cx| -> Option<_> {
|
||||||
// let pane = pane.upgrade(cx)?;
|
let pane = pane.upgrade()?;
|
||||||
// let new_pane = this.split_pane(pane, SplitDirection::Right, cx);
|
let new_pane = this.split_pane(pane, SplitDirection::Right, cx);
|
||||||
// new_pane.update(cx, |new_pane, cx| {
|
new_pane.update(cx, |new_pane, cx| {
|
||||||
// Some(new_pane.open_item(project_entry_id, true, cx, build_item))
|
Some(new_pane.open_item(project_entry_id, true, cx, build_item))
|
||||||
// })
|
})
|
||||||
// })
|
})
|
||||||
// .map(|option| option.ok_or_else(|| anyhow!("pane was dropped")))?
|
.map(|option| option.ok_or_else(|| anyhow!("pane was dropped")))?
|
||||||
// })
|
})
|
||||||
// }
|
}
|
||||||
|
|
||||||
pub(crate) fn load_path(
|
pub(crate) fn load_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -3029,10 +3030,10 @@ impl Workspace {
|
||||||
|
|
||||||
fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
|
fn force_remove_pane(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Workspace>) {
|
||||||
self.panes.retain(|p| p != pane);
|
self.panes.retain(|p| p != pane);
|
||||||
if true {
|
self.panes
|
||||||
todo!()
|
.last()
|
||||||
// cx.focus(self.panes.last().unwrap());
|
.unwrap()
|
||||||
}
|
.update(cx, |pane, cx| pane.focus(cx));
|
||||||
if self.last_active_center_pane == Some(pane.downgrade()) {
|
if self.last_active_center_pane == Some(pane.downgrade()) {
|
||||||
self.last_active_center_pane = None;
|
self.last_active_center_pane = None;
|
||||||
}
|
}
|
||||||
|
@ -3401,10 +3402,6 @@ impl Workspace {
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo!()
|
|
||||||
// #[cfg(any(test, feature = "test-support"))]
|
|
||||||
// pub fn test_new(project: ModelHandle<Project>, cx: &mut ViewContext<Self>) -> Self {
|
|
||||||
// use node_runtime::FakeNodeRuntime;
|
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
pub fn test_new(project: Model<Project>, cx: &mut ViewContext<Self>) -> Self {
|
pub fn test_new(project: Model<Project>, cx: &mut ViewContext<Self>) -> Self {
|
||||||
use node_runtime::FakeNodeRuntime;
|
use node_runtime::FakeNodeRuntime;
|
||||||
|
@ -3423,7 +3420,9 @@ impl Workspace {
|
||||||
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
initialize_workspace: |_, _, _, _| Task::ready(Ok(())),
|
||||||
node_runtime: FakeNodeRuntime::new(),
|
node_runtime: FakeNodeRuntime::new(),
|
||||||
});
|
});
|
||||||
Self::new(0, project, app_state, cx)
|
let workspace = Self::new(0, project, app_state, cx);
|
||||||
|
workspace.active_pane.update(cx, |pane, cx| pane.focus(cx));
|
||||||
|
workspace
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn render_dock(&self, position: DockPosition, cx: &WindowContext) -> Option<AnyElement<Self>> {
|
// fn render_dock(&self, position: DockPosition, cx: &WindowContext) -> Option<AnyElement<Self>> {
|
||||||
|
@ -3476,6 +3475,10 @@ impl Workspace {
|
||||||
div
|
div
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn current_modal<V: Modal + 'static>(&mut self, cx: &ViewContext<Self>) -> Option<View<V>> {
|
||||||
|
self.modal_layer.read(cx).current_modal()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toggle_modal<V: Modal, B>(&mut self, cx: &mut ViewContext<Self>, build: B)
|
pub fn toggle_modal<V: Modal, B>(&mut self, cx: &mut ViewContext<Self>, build: B)
|
||||||
where
|
where
|
||||||
B: FnOnce(&mut ViewContext<V>) -> V,
|
B: FnOnce(&mut ViewContext<V>) -> V,
|
||||||
|
@ -3699,6 +3702,7 @@ impl Render for Workspace {
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
let mut context = KeyContext::default();
|
let mut context = KeyContext::default();
|
||||||
context.add("Workspace");
|
context.add("Workspace");
|
||||||
|
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
|
||||||
|
|
||||||
self.add_workspace_actions_listeners(div())
|
self.add_workspace_actions_listeners(div())
|
||||||
.key_context(context)
|
.key_context(context)
|
||||||
|
@ -3706,7 +3710,7 @@ impl Render for Workspace {
|
||||||
.size_full()
|
.size_full()
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.font("Zed Sans")
|
.font(ui_font)
|
||||||
.gap_0()
|
.gap_0()
|
||||||
.justify_start()
|
.justify_start()
|
||||||
.items_start()
|
.items_start()
|
||||||
|
@ -3732,7 +3736,15 @@ impl Render for Workspace {
|
||||||
.flex_row()
|
.flex_row()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.h_full()
|
.h_full()
|
||||||
.child(div().flex().flex_1().child(self.left_dock.clone()))
|
// Left Dock
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex()
|
||||||
|
.flex_none()
|
||||||
|
.overflow_hidden()
|
||||||
|
.child(self.left_dock.clone()),
|
||||||
|
)
|
||||||
|
// Panes
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex()
|
.flex()
|
||||||
|
@ -3749,7 +3761,14 @@ impl Render for Workspace {
|
||||||
))
|
))
|
||||||
.child(div().flex().flex_1().child(self.bottom_dock.clone())),
|
.child(div().flex().flex_1().child(self.bottom_dock.clone())),
|
||||||
)
|
)
|
||||||
.child(div().flex().flex_1().child(self.right_dock.clone())),
|
// Right Dock
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex()
|
||||||
|
.flex_none()
|
||||||
|
.overflow_hidden()
|
||||||
|
.child(self.right_dock.clone()),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(self.status_bar.clone())
|
.child(self.status_bar.clone())
|
||||||
|
|
|
@ -36,7 +36,7 @@ copilot = { package = "copilot2", path = "../copilot2" }
|
||||||
db = { package = "db2", path = "../db2" }
|
db = { package = "db2", path = "../db2" }
|
||||||
editor = { package="editor2", path = "../editor2" }
|
editor = { package="editor2", path = "../editor2" }
|
||||||
# feedback = { path = "../feedback" }
|
# feedback = { path = "../feedback" }
|
||||||
# file_finder = { path = "../file_finder" }
|
file_finder = { package="file_finder2", path = "../file_finder2" }
|
||||||
# search = { path = "../search" }
|
# search = { path = "../search" }
|
||||||
fs = { package = "fs2", path = "../fs2" }
|
fs = { package = "fs2", path = "../fs2" }
|
||||||
fsevent = { path = "../fsevent" }
|
fsevent = { path = "../fsevent" }
|
||||||
|
|
|
@ -190,7 +190,7 @@ fn main() {
|
||||||
// recent_projects::init(cx);
|
// recent_projects::init(cx);
|
||||||
|
|
||||||
go_to_line::init(cx);
|
go_to_line::init(cx);
|
||||||
// file_finder::init(cx);
|
file_finder::init(cx);
|
||||||
// outline::init(cx);
|
// outline::init(cx);
|
||||||
// project_symbols::init(cx);
|
// project_symbols::init(cx);
|
||||||
project_panel::init(Assets, cx);
|
project_panel::init(Assets, cx);
|
||||||
|
|
|
@ -502,7 +502,6 @@ fn quit(_: &mut Workspace, _: &Quit, cx: &mut gpui::ViewContext<Workspace>) {
|
||||||
cx.update(|_, cx| {
|
cx.update(|_, cx| {
|
||||||
cx.quit();
|
cx.quit();
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
})
|
})
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue