add dynamic component names

pull/8675/merge^2
mattwparas 8 months ago
parent fb81eab093
commit a1b13e570d

8
Cargo.lock generated

@ -2357,7 +2357,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "steel-core"
version = "0.6.0"
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
dependencies = [
"abi_stable",
"anyhow",
@ -2395,7 +2395,7 @@ dependencies = [
[[package]]
name = "steel-derive"
version = "0.5.0"
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
dependencies = [
"proc-macro2",
"quote",
@ -2405,7 +2405,7 @@ dependencies = [
[[package]]
name = "steel-gen"
version = "0.2.0"
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
dependencies = [
"codegen",
"serde",
@ -2415,7 +2415,7 @@ dependencies = [
[[package]]
name = "steel-parser"
version = "0.6.0"
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
dependencies = [
"fxhash",
"lasso",

@ -26,7 +26,6 @@ use crate::{
Context,
},
compositor::{self, Component},
ctrl, key,
ui::overlay::overlaid,
};
@ -40,8 +39,6 @@ struct AsyncReader {
}
impl AsyncReader {
// TODO: Add &mut references to these async functions
// to avoid the cloning, and to ditch the arc and mutex
async fn read_line(self) -> Option<String> {
let mut buf = String::new();
@ -53,19 +50,34 @@ impl AsyncReader {
let fut = guard.recv();
match tokio::time::timeout(std::time::Duration::from_millis(2), fut).await {
Ok(Some(v)) => {
buf.push_str(&v);
Some(buf)
// If we haven't found any characters, just wait until we have something.
// Otherwise, we give this a 2 ms buffer to check if more things are
// coming through the pipe.
if buf.is_empty() {
let next = fut.await;
match next {
Some(v) => {
buf.push_str(&v);
Some(buf)
}
None => None,
}
Ok(None) => {
if buf.is_empty() {
None
} else {
} else {
match tokio::time::timeout(std::time::Duration::from_millis(2), fut).await {
Ok(Some(v)) => {
buf.push_str(&v);
Some(buf)
}
Ok(None) => {
if buf.is_empty() {
None
} else {
Some(buf)
}
}
Err(_) => Some(buf),
}
Err(_) => Some(buf),
}
}
}
@ -254,6 +266,12 @@ pub fn helix_component_module() -> BuiltInModule {
"event-result/consume",
SteelEventResult::Consumed.into_steelval().unwrap(),
)
.register_value(
"event-result/consume-without-rerender",
SteelEventResult::ConsumedWithoutRerender
.into_steelval()
.unwrap(),
)
.register_value(
"event-result/ignore",
SteelEventResult::Ignored.into_steelval().unwrap(),
@ -439,7 +457,7 @@ pub struct SteelDynamicComponent {
// TODO: currently the component id requires using a &'static str,
// however in a world with dynamic components that might not be
// the case anymore
_name: String,
name: String,
// This _should_ be a struct, but in theory can be whatever you want. It will be the first argument
// passed to the functions in the remainder of the struct.
state: SteelVal,
@ -463,7 +481,7 @@ impl SteelDynamicComponent {
h: HashMap<String, SteelVal>,
) -> Self {
Self {
_name: name,
name,
state,
render,
handle_event: h.get("handle_event").cloned(),
@ -522,11 +540,16 @@ enum SteelEventResult {
Consumed,
Ignored,
Close,
ConsumedWithoutRerender,
}
impl Custom for SteelEventResult {}
impl Component for SteelDynamicComponent {
fn name(&self) -> Option<&str> {
Some(&self.name)
}
fn render(
&mut self,
area: helix_view::graphics::Rect,
@ -646,6 +669,9 @@ impl Component for SteelDynamicComponent {
match value {
Ok(SteelEventResult::Close) => close_fn,
Ok(SteelEventResult::Consumed) => compositor::EventResult::Consumed(None),
Ok(SteelEventResult::ConsumedWithoutRerender) => {
compositor::EventResult::ConsumedWithoutRerender
}
Ok(SteelEventResult::Ignored) => compositor::EventResult::Ignored(None),
_ => match event {
// ctrl!('c') | key!(Esc) => close_fn,
@ -715,7 +741,7 @@ impl Component for SteelDynamicComponent {
Err(_e) => {
log::info!("Error: {:?}", _e);
(None, CursorKind::Block)
},
}
}
} else {
(None, helix_view::graphics::CursorKind::Hidden)

@ -1527,7 +1527,11 @@ impl Component for BoxDynComponent {
}
fn id(&self) -> Option<&'static str> {
None
Some(self.inner.type_name())
}
fn name(&self) -> Option<&str> {
self.inner.name()
}
fn render(
@ -1768,8 +1772,10 @@ fn load_misc_api(engine: &mut Engine, generate_sources: bool) {
// Arity 1
module.register_fn("hx.custom-insert-newline", custom_insert_newline);
module.register_fn("push-component!", push_component);
module.register_fn("pop-last-component!", pop_last_component_by_name);
module.register_fn("enqueue-thread-local-callback", enqueue_command);
template_function_arity_1("pop-last-component!");
template_function_arity_1("hx.custom-insert-newline");
template_function_arity_1("push-component!");
template_function_arity_1("enqueue-thread-local-callback");
@ -2286,10 +2292,12 @@ fn push_component(cx: &mut Context, component: &mut WrappedDynComponent) {
cx.jobs.local_callback(callback);
}
fn render(cx: &mut Context) {
fn pop_last_component_by_name(cx: &mut Context, name: SteelString) {
let callback = async move {
let call: Box<dyn FnOnce(&mut Editor, &mut Compositor, &mut job::Jobs)> = Box::new(
move |_editor: &mut Editor, _compositor: &mut Compositor, _jobs: &mut job::Jobs| {},
move |_editor: &mut Editor, compositor: &mut Compositor, _jobs: &mut job::Jobs| {
compositor.remove_by_dynamic_name(&name);
},
);
Ok(call)
};

@ -13,6 +13,7 @@ pub type SyncCallback = Box<dyn FnOnce(&mut Compositor, &mut Context) + Sync>;
pub enum EventResult {
Ignored(Option<Callback>),
Consumed(Option<Callback>),
ConsumedWithoutRerender,
}
use crate::job::Jobs;
@ -73,6 +74,10 @@ pub trait Component: Any + AnyComponent {
fn id(&self) -> Option<&'static str> {
None
}
fn name(&self) -> Option<&str> {
None
}
}
pub struct Compositor {
@ -136,6 +141,14 @@ impl Compositor {
Some(self.layers.remove(idx))
}
pub fn remove_by_dynamic_name(&mut self, id: &str) -> Option<Box<dyn Component>> {
let idx = self
.layers
.iter()
.position(|layer| layer.name() == Some(id))?;
Some(self.layers.remove(idx))
}
pub fn handle_event(&mut self, event: &Event, cx: &mut Context) -> bool {
// If it is a key event and a macro is being recorded, push the key event to the recording.
if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) {
@ -159,6 +172,10 @@ impl Compositor {
consumed = true;
break;
}
// Swallow the event, but don't trigger a re-render
EventResult::ConsumedWithoutRerender => {
break;
}
EventResult::Ignored(Some(callback)) => {
callbacks.push(callback);
}

Loading…
Cancel
Save