mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-23 18:32:17 +00:00
Order debug JSON and allow elements to be named; copy to clipboard
This commit is contained in:
parent
cbb23a93a6
commit
9f6f27f305
15 changed files with 104 additions and 32 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
@ -940,6 +940,12 @@ dependencies = [
|
||||||
"usvg",
|
"usvg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.18"
|
version = "0.1.18"
|
||||||
|
@ -973,6 +979,16 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
|
@ -1703,6 +1719,7 @@ version = "1.0.64"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -1120,6 +1120,10 @@ impl MutableAppContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn copy(&self, text: &str) {
|
||||||
|
self.platform.copy(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModelAsRef for MutableAppContext {
|
impl ModelAsRef for MutableAppContext {
|
||||||
|
|
|
@ -91,8 +91,8 @@ impl Element for Align {
|
||||||
) -> json::Value {
|
) -> json::Value {
|
||||||
json!({
|
json!({
|
||||||
"type": "Align",
|
"type": "Align",
|
||||||
"alignment": self.alignment.to_json(),
|
|
||||||
"bounds": bounds.to_json(),
|
"bounds": bounds.to_json(),
|
||||||
|
"alignment": self.alignment.to_json(),
|
||||||
"child": self.child.debug(ctx),
|
"child": self.child.debug(ctx),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,6 +201,7 @@ impl Element for Container {
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
json!({
|
json!({
|
||||||
"type": "Container",
|
"type": "Container",
|
||||||
|
"bounds": bounds.to_json(),
|
||||||
"details": {
|
"details": {
|
||||||
"margin": self.margin.to_json(),
|
"margin": self.margin.to_json(),
|
||||||
"padding": self.padding.to_json(),
|
"padding": self.padding.to_json(),
|
||||||
|
@ -209,7 +210,6 @@ impl Element for Container {
|
||||||
"corner_radius": self.corner_radius,
|
"corner_radius": self.corner_radius,
|
||||||
"shadow": self.shadow.to_json(),
|
"shadow": self.shadow.to_json(),
|
||||||
},
|
},
|
||||||
"bounds": bounds.to_json(),
|
|
||||||
"child": self.child.debug(ctx),
|
"child": self.child.debug(ctx),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,8 +173,8 @@ impl Element for Flex {
|
||||||
) -> json::Value {
|
) -> json::Value {
|
||||||
json!({
|
json!({
|
||||||
"type": "Flex",
|
"type": "Flex",
|
||||||
"axis": self.axis.to_json(),
|
|
||||||
"bounds": bounds.to_json(),
|
"bounds": bounds.to_json(),
|
||||||
|
"axis": self.axis.to_json(),
|
||||||
"children": self.children.iter().map(|child| child.debug(ctx)).collect::<Vec<json::Value>>()
|
"children": self.children.iter().map(|child| child.debug(ctx)).collect::<Vec<json::Value>>()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,11 +166,11 @@ impl Element for Label {
|
||||||
) -> Value {
|
) -> Value {
|
||||||
json!({
|
json!({
|
||||||
"type": "Label",
|
"type": "Label",
|
||||||
"font_size": self.font_size,
|
|
||||||
"bounds": bounds.to_json(),
|
"bounds": bounds.to_json(),
|
||||||
"text": &self.text,
|
"font_family": ctx.font_cache.family_name(self.family_id).unwrap(),
|
||||||
"family_id": ctx.font_cache.family_name(self.family_id).unwrap(),
|
"font_size": self.font_size,
|
||||||
"font_properties": self.font_properties.to_json(),
|
"font_properties": self.font_properties.to_json(),
|
||||||
|
"text": &self.text,
|
||||||
"highlights": self.highlights.to_json(),
|
"highlights": self.highlights.to_json(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,7 @@ impl Element for LineBox {
|
||||||
) -> serde_json::Value {
|
) -> serde_json::Value {
|
||||||
json!({
|
json!({
|
||||||
"bounds": bounds.to_json(),
|
"bounds": bounds.to_json(),
|
||||||
"family_id": ctx.font_cache.family_name(self.family_id).unwrap(),
|
"font_family": ctx.font_cache.family_name(self.family_id).unwrap(),
|
||||||
"font_size": self.font_size,
|
"font_size": self.font_size,
|
||||||
"font_properties": self.font_properties.to_json(),
|
"font_properties": self.font_properties.to_json(),
|
||||||
"child": self.child.debug(ctx),
|
"child": self.child.debug(ctx),
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use core::panic;
|
use core::panic;
|
||||||
use replace_with::replace_with_or_abort;
|
use replace_with::replace_with_or_abort;
|
||||||
use std::any::Any;
|
use std::{any::Any, borrow::Cow};
|
||||||
|
|
||||||
trait AnyElement {
|
trait AnyElement {
|
||||||
fn layout(&mut self, constraint: SizeConstraint, ctx: &mut LayoutContext) -> Vector2F;
|
fn layout(&mut self, constraint: SizeConstraint, ctx: &mut LayoutContext) -> Vector2F;
|
||||||
|
@ -67,7 +67,20 @@ pub trait Element {
|
||||||
where
|
where
|
||||||
Self: 'static + Sized,
|
Self: 'static + Sized,
|
||||||
{
|
{
|
||||||
ElementBox(Box::new(Lifecycle::Init { element: self }))
|
ElementBox {
|
||||||
|
name: None,
|
||||||
|
element: Box::new(Lifecycle::Init { element: self }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn named(self, name: impl Into<Cow<'static, str>>) -> ElementBox
|
||||||
|
where
|
||||||
|
Self: 'static + Sized,
|
||||||
|
{
|
||||||
|
ElementBox {
|
||||||
|
name: Some(name.into()),
|
||||||
|
element: Box::new(Lifecycle::Init { element: self }),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +100,10 @@ pub enum Lifecycle<T: Element> {
|
||||||
paint: T::PaintState,
|
paint: T::PaintState,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
pub struct ElementBox(Box<dyn AnyElement>);
|
pub struct ElementBox {
|
||||||
|
name: Option<Cow<'static, str>>,
|
||||||
|
element: Box<dyn AnyElement>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Element> AnyElement for Lifecycle<T> {
|
impl<T: Element> AnyElement for Lifecycle<T> {
|
||||||
fn layout(&mut self, constraint: SizeConstraint, ctx: &mut LayoutContext) -> Vector2F {
|
fn layout(&mut self, constraint: SizeConstraint, ctx: &mut LayoutContext) -> Vector2F {
|
||||||
|
@ -191,30 +207,41 @@ impl<T: Element> AnyElement for Lifecycle<T> {
|
||||||
|
|
||||||
impl ElementBox {
|
impl ElementBox {
|
||||||
pub fn layout(&mut self, constraint: SizeConstraint, ctx: &mut LayoutContext) -> Vector2F {
|
pub fn layout(&mut self, constraint: SizeConstraint, ctx: &mut LayoutContext) -> Vector2F {
|
||||||
self.0.layout(constraint, ctx)
|
self.element.layout(constraint, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn after_layout(&mut self, ctx: &mut AfterLayoutContext) {
|
pub fn after_layout(&mut self, ctx: &mut AfterLayoutContext) {
|
||||||
self.0.after_layout(ctx);
|
self.element.after_layout(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint(&mut self, origin: Vector2F, ctx: &mut PaintContext) {
|
pub fn paint(&mut self, origin: Vector2F, ctx: &mut PaintContext) {
|
||||||
self.0.paint(origin, ctx);
|
self.element.paint(origin, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispatch_event(&mut self, event: &Event, ctx: &mut EventContext) -> bool {
|
pub fn dispatch_event(&mut self, event: &Event, ctx: &mut EventContext) -> bool {
|
||||||
self.0.dispatch_event(event, ctx)
|
self.element.dispatch_event(event, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> Vector2F {
|
pub fn size(&self) -> Vector2F {
|
||||||
self.0.size()
|
self.element.size()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata(&self) -> Option<&dyn Any> {
|
pub fn metadata(&self) -> Option<&dyn Any> {
|
||||||
self.0.metadata()
|
self.element.metadata()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug(&self, ctx: &DebugContext) -> json::Value {
|
pub fn debug(&self, ctx: &DebugContext) -> json::Value {
|
||||||
self.0.debug(ctx)
|
let mut value = self.element.debug(ctx);
|
||||||
|
|
||||||
|
if let Some(name) = &self.name {
|
||||||
|
if let json::Value::Object(map) = &mut value {
|
||||||
|
let mut new_map: crate::json::Map<String, serde_json::Value> = Default::default();
|
||||||
|
new_map.insert("name".into(), json::Value::String(name.to_string()));
|
||||||
|
new_map.append(map);
|
||||||
|
return json::Value::Object(new_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
use super::{BoolExt as _, Dispatcher, FontSystem, Window};
|
use super::{BoolExt as _, Dispatcher, FontSystem, Window};
|
||||||
use crate::{executor, platform};
|
use crate::{executor, platform};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cocoa::base::id;
|
use cocoa::{
|
||||||
|
appkit::{NSPasteboard, NSPasteboardTypeString},
|
||||||
|
base::{id, nil},
|
||||||
|
foundation::NSData,
|
||||||
|
};
|
||||||
use objc::{class, msg_send, sel, sel_impl};
|
use objc::{class, msg_send, sel, sel_impl};
|
||||||
use std::{rc::Rc, sync::Arc};
|
use std::{ffi::c_void, rc::Rc, sync::Arc};
|
||||||
|
|
||||||
pub struct App {
|
pub struct App {
|
||||||
dispatcher: Arc<Dispatcher>,
|
dispatcher: Arc<Dispatcher>,
|
||||||
|
@ -42,4 +46,17 @@ impl platform::App for App {
|
||||||
fn fonts(&self) -> Arc<dyn platform::FontSystem> {
|
fn fonts(&self) -> Arc<dyn platform::FontSystem> {
|
||||||
self.fonts.clone()
|
self.fonts.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copy(&self, text: &str) {
|
||||||
|
unsafe {
|
||||||
|
let data = NSData::dataWithBytes_length_(
|
||||||
|
nil,
|
||||||
|
text.as_ptr() as *const c_void,
|
||||||
|
text.len() as u64,
|
||||||
|
);
|
||||||
|
let pasteboard = NSPasteboard::generalPasteboard(nil);
|
||||||
|
pasteboard.clearContents();
|
||||||
|
pasteboard.setData_forType(data, NSPasteboardTypeString);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub trait App {
|
||||||
executor: Rc<executor::Foreground>,
|
executor: Rc<executor::Foreground>,
|
||||||
) -> Result<Box<dyn Window>>;
|
) -> Result<Box<dyn Window>>;
|
||||||
fn fonts(&self) -> Arc<dyn FontSystem>;
|
fn fonts(&self) -> Arc<dyn FontSystem>;
|
||||||
|
fn copy(&self, text: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Dispatcher: Send + Sync {
|
pub trait Dispatcher: Send + Sync {
|
||||||
|
|
|
@ -46,6 +46,8 @@ impl super::App for App {
|
||||||
fn fonts(&self) -> std::sync::Arc<dyn super::FontSystem> {
|
fn fonts(&self) -> std::sync::Arc<dyn super::FontSystem> {
|
||||||
self.fonts.clone()
|
self.fonts.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn copy(&self, _: &str) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
|
|
@ -18,9 +18,9 @@ arrayvec = "0.5.2"
|
||||||
crossbeam-channel = "0.5.0"
|
crossbeam-channel = "0.5.0"
|
||||||
dirs = "3.0"
|
dirs = "3.0"
|
||||||
easy-parallel = "3.1.0"
|
easy-parallel = "3.1.0"
|
||||||
|
futures-core = "0.3"
|
||||||
gpui = {path = "../gpui"}
|
gpui = {path = "../gpui"}
|
||||||
ignore = {git = "https://github.com/zed-industries/ripgrep", rev = "1d152118f35b3e3590216709b86277062d79b8a0"}
|
ignore = {git = "https://github.com/zed-industries/ripgrep", rev = "1d152118f35b3e3590216709b86277062d79b8a0"}
|
||||||
futures-core = "0.3"
|
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
@ -33,6 +33,6 @@ smallvec = "1.6.1"
|
||||||
smol = "1.2.5"
|
smol = "1.2.5"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serde_json = "1.0.64"
|
serde_json = {version = "1.0.64", features = ["preserve_order"]}
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
unindent = "0.1.7"
|
unindent = "0.1.7"
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl View for FileFinder {
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.top_center()
|
.top_center()
|
||||||
.boxed()
|
.named("file finder")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
|
fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
|
||||||
|
@ -105,7 +105,7 @@ impl FileFinder {
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.with_margin_top(6.0)
|
.with_margin_top(6.0)
|
||||||
.boxed();
|
.named("empty matches");
|
||||||
}
|
}
|
||||||
|
|
||||||
let handle = self.handle.clone();
|
let handle = self.handle.clone();
|
||||||
|
@ -127,7 +127,7 @@ impl FileFinder {
|
||||||
.with_background_color(ColorU::from_u32(0xf7f7f7ff))
|
.with_background_color(ColorU::from_u32(0xf7f7f7ff))
|
||||||
.with_border(Border::all(1.0, ColorU::from_u32(0xdbdbdcff)))
|
.with_border(Border::all(1.0, ColorU::from_u32(0xdbdbdcff)))
|
||||||
.with_margin_top(6.0)
|
.with_margin_top(6.0)
|
||||||
.boxed()
|
.named("matches")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_match(
|
fn render_match(
|
||||||
|
@ -226,7 +226,7 @@ impl FileFinder {
|
||||||
ctx.dispatch_action("file_finder:select", (tree_id, entry_id));
|
ctx.dispatch_action("file_finder:select", (tree_id, entry_id));
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
.boxed()
|
.named("match")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,7 +244,7 @@ impl Pane {
|
||||||
.with_max_width(264.0)
|
.with_max_width(264.0)
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.boxed(),
|
.named("tab"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,10 +263,10 @@ impl Pane {
|
||||||
.with_border(Border::bottom(1.0, border_color))
|
.with_border(Border::bottom(1.0, border_color))
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.boxed(),
|
.named("filler"),
|
||||||
);
|
);
|
||||||
|
|
||||||
row.boxed()
|
row.named("tabs")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_modified_icon(is_modified: bool) -> ElementBox {
|
fn render_modified_icon(is_modified: bool) -> ElementBox {
|
||||||
|
@ -304,9 +304,9 @@ impl View for Pane {
|
||||||
Flex::column()
|
Flex::column()
|
||||||
.with_child(self.render_tabs(app))
|
.with_child(self.render_tabs(app))
|
||||||
.with_child(Expanded::new(1.0, ChildView::new(active_item.id()).boxed()).boxed())
|
.with_child(Expanded::new(1.0, ChildView::new(active_item.id()).boxed()).boxed())
|
||||||
.boxed()
|
.named("pane")
|
||||||
} else {
|
} else {
|
||||||
Empty::new().boxed()
|
Empty::new().named("pane")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,11 @@ impl WorkspaceView {
|
||||||
pub fn debug_elements(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
|
pub fn debug_elements(&mut self, _: &(), ctx: &mut ViewContext<Self>) {
|
||||||
match to_string_pretty(&ctx.debug_elements()) {
|
match to_string_pretty(&ctx.debug_elements()) {
|
||||||
Ok(json) => {
|
Ok(json) => {
|
||||||
log::info!("{}", json);
|
ctx.app_mut().copy(&json);
|
||||||
|
log::info!(
|
||||||
|
"copied {:.1} KiB of element debug JSON to the clipboard",
|
||||||
|
json.len() as f32 / 1024.
|
||||||
|
);
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
log::error!("error debugging elements: {}", error);
|
log::error!("error debugging elements: {}", error);
|
||||||
|
@ -373,7 +377,7 @@ impl View for WorkspaceView {
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.with_background_color(rgbu(0xea, 0xea, 0xeb))
|
.with_background_color(rgbu(0xea, 0xea, 0xeb))
|
||||||
.boxed()
|
.named("workspace")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
|
fn on_focus(&mut self, ctx: &mut ViewContext<Self>) {
|
||||||
|
|
Loading…
Reference in a new issue