mirror of https://github.com/helix-editor/helix
add dynamic component names
parent
fb81eab093
commit
a1b13e570d
|
@ -2357,7 +2357,7 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-core"
|
name = "steel-core"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
|
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"abi_stable",
|
"abi_stable",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -2395,7 +2395,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-derive"
|
name = "steel-derive"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
|
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2405,7 +2405,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-gen"
|
name = "steel-gen"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
|
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"codegen",
|
"codegen",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -2415,7 +2415,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "steel-parser"
|
name = "steel-parser"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/mattwparas/steel.git#c10339bcda9808c326d5aebda610d920fc436a1f"
|
source = "git+https://github.com/mattwparas/steel.git#c5451eaf7fc8e4ba39eb0536b0ccc9b469c2e50b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"lasso",
|
"lasso",
|
||||||
|
|
|
@ -26,7 +26,6 @@ use crate::{
|
||||||
Context,
|
Context,
|
||||||
},
|
},
|
||||||
compositor::{self, Component},
|
compositor::{self, Component},
|
||||||
ctrl, key,
|
|
||||||
ui::overlay::overlaid,
|
ui::overlay::overlaid,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -40,8 +39,6 @@ struct AsyncReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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> {
|
async fn read_line(self) -> Option<String> {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
@ -53,6 +50,20 @@ impl AsyncReader {
|
||||||
|
|
||||||
let fut = guard.recv();
|
let fut = guard.recv();
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
match tokio::time::timeout(std::time::Duration::from_millis(2), fut).await {
|
match tokio::time::timeout(std::time::Duration::from_millis(2), fut).await {
|
||||||
Ok(Some(v)) => {
|
Ok(Some(v)) => {
|
||||||
buf.push_str(&v);
|
buf.push_str(&v);
|
||||||
|
@ -69,6 +80,7 @@ impl AsyncReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Custom for AsyncReader {}
|
impl Custom for AsyncReader {}
|
||||||
|
|
||||||
|
@ -254,6 +266,12 @@ pub fn helix_component_module() -> BuiltInModule {
|
||||||
"event-result/consume",
|
"event-result/consume",
|
||||||
SteelEventResult::Consumed.into_steelval().unwrap(),
|
SteelEventResult::Consumed.into_steelval().unwrap(),
|
||||||
)
|
)
|
||||||
|
.register_value(
|
||||||
|
"event-result/consume-without-rerender",
|
||||||
|
SteelEventResult::ConsumedWithoutRerender
|
||||||
|
.into_steelval()
|
||||||
|
.unwrap(),
|
||||||
|
)
|
||||||
.register_value(
|
.register_value(
|
||||||
"event-result/ignore",
|
"event-result/ignore",
|
||||||
SteelEventResult::Ignored.into_steelval().unwrap(),
|
SteelEventResult::Ignored.into_steelval().unwrap(),
|
||||||
|
@ -439,7 +457,7 @@ pub struct SteelDynamicComponent {
|
||||||
// TODO: currently the component id requires using a &'static str,
|
// TODO: currently the component id requires using a &'static str,
|
||||||
// however in a world with dynamic components that might not be
|
// however in a world with dynamic components that might not be
|
||||||
// the case anymore
|
// 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
|
// 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.
|
// passed to the functions in the remainder of the struct.
|
||||||
state: SteelVal,
|
state: SteelVal,
|
||||||
|
@ -463,7 +481,7 @@ impl SteelDynamicComponent {
|
||||||
h: HashMap<String, SteelVal>,
|
h: HashMap<String, SteelVal>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_name: name,
|
name,
|
||||||
state,
|
state,
|
||||||
render,
|
render,
|
||||||
handle_event: h.get("handle_event").cloned(),
|
handle_event: h.get("handle_event").cloned(),
|
||||||
|
@ -522,11 +540,16 @@ enum SteelEventResult {
|
||||||
Consumed,
|
Consumed,
|
||||||
Ignored,
|
Ignored,
|
||||||
Close,
|
Close,
|
||||||
|
ConsumedWithoutRerender,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Custom for SteelEventResult {}
|
impl Custom for SteelEventResult {}
|
||||||
|
|
||||||
impl Component for SteelDynamicComponent {
|
impl Component for SteelDynamicComponent {
|
||||||
|
fn name(&self) -> Option<&str> {
|
||||||
|
Some(&self.name)
|
||||||
|
}
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
&mut self,
|
&mut self,
|
||||||
area: helix_view::graphics::Rect,
|
area: helix_view::graphics::Rect,
|
||||||
|
@ -646,6 +669,9 @@ impl Component for SteelDynamicComponent {
|
||||||
match value {
|
match value {
|
||||||
Ok(SteelEventResult::Close) => close_fn,
|
Ok(SteelEventResult::Close) => close_fn,
|
||||||
Ok(SteelEventResult::Consumed) => compositor::EventResult::Consumed(None),
|
Ok(SteelEventResult::Consumed) => compositor::EventResult::Consumed(None),
|
||||||
|
Ok(SteelEventResult::ConsumedWithoutRerender) => {
|
||||||
|
compositor::EventResult::ConsumedWithoutRerender
|
||||||
|
}
|
||||||
Ok(SteelEventResult::Ignored) => compositor::EventResult::Ignored(None),
|
Ok(SteelEventResult::Ignored) => compositor::EventResult::Ignored(None),
|
||||||
_ => match event {
|
_ => match event {
|
||||||
// ctrl!('c') | key!(Esc) => close_fn,
|
// ctrl!('c') | key!(Esc) => close_fn,
|
||||||
|
@ -715,7 +741,7 @@ impl Component for SteelDynamicComponent {
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
log::info!("Error: {:?}", _e);
|
log::info!("Error: {:?}", _e);
|
||||||
(None, CursorKind::Block)
|
(None, CursorKind::Block)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(None, helix_view::graphics::CursorKind::Hidden)
|
(None, helix_view::graphics::CursorKind::Hidden)
|
||||||
|
|
|
@ -1527,7 +1527,11 @@ impl Component for BoxDynComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn id(&self) -> Option<&'static str> {
|
fn id(&self) -> Option<&'static str> {
|
||||||
None
|
Some(self.inner.type_name())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> Option<&str> {
|
||||||
|
self.inner.name()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(
|
fn render(
|
||||||
|
@ -1768,8 +1772,10 @@ fn load_misc_api(engine: &mut Engine, generate_sources: bool) {
|
||||||
// Arity 1
|
// Arity 1
|
||||||
module.register_fn("hx.custom-insert-newline", custom_insert_newline);
|
module.register_fn("hx.custom-insert-newline", custom_insert_newline);
|
||||||
module.register_fn("push-component!", push_component);
|
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);
|
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("hx.custom-insert-newline");
|
||||||
template_function_arity_1("push-component!");
|
template_function_arity_1("push-component!");
|
||||||
template_function_arity_1("enqueue-thread-local-callback");
|
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);
|
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 callback = async move {
|
||||||
let call: Box<dyn FnOnce(&mut Editor, &mut Compositor, &mut job::Jobs)> = Box::new(
|
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)
|
Ok(call)
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub type SyncCallback = Box<dyn FnOnce(&mut Compositor, &mut Context) + Sync>;
|
||||||
pub enum EventResult {
|
pub enum EventResult {
|
||||||
Ignored(Option<Callback>),
|
Ignored(Option<Callback>),
|
||||||
Consumed(Option<Callback>),
|
Consumed(Option<Callback>),
|
||||||
|
ConsumedWithoutRerender,
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::job::Jobs;
|
use crate::job::Jobs;
|
||||||
|
@ -73,6 +74,10 @@ pub trait Component: Any + AnyComponent {
|
||||||
fn id(&self) -> Option<&'static str> {
|
fn id(&self) -> Option<&'static str> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> Option<&str> {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Compositor {
|
pub struct Compositor {
|
||||||
|
@ -136,6 +141,14 @@ impl Compositor {
|
||||||
Some(self.layers.remove(idx))
|
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 {
|
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 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) {
|
if let (Event::Key(key), Some((_, keys))) = (event, &mut cx.editor.macro_recording) {
|
||||||
|
@ -159,6 +172,10 @@ impl Compositor {
|
||||||
consumed = true;
|
consumed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Swallow the event, but don't trigger a re-render
|
||||||
|
EventResult::ConsumedWithoutRerender => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
EventResult::Ignored(Some(callback)) => {
|
EventResult::Ignored(Some(callback)) => {
|
||||||
callbacks.push(callback);
|
callbacks.push(callback);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue