cleanup editor constructors
This commit is contained in:
parent
2db92ef6aa
commit
bed4bc329b
10 changed files with 248 additions and 303 deletions
|
@ -16,20 +16,22 @@ use {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ReprTree {
|
pub struct ReprTree {
|
||||||
|
type_tag: TypeTerm,
|
||||||
port: Option<AnyOuterViewPort>,
|
port: Option<AnyOuterViewPort>,
|
||||||
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
branches: HashMap<TypeTerm, Arc<RwLock<ReprTree>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReprTree {
|
impl ReprTree {
|
||||||
pub fn new() -> Self {
|
pub fn new(type_tag: TypeTerm) -> Self {
|
||||||
ReprTree {
|
ReprTree {
|
||||||
|
type_tag,
|
||||||
port: None,
|
port: None,
|
||||||
branches: HashMap::new(),
|
branches: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_leaf(port: AnyOuterViewPort) -> Arc<RwLock<Self>> {
|
pub fn new_leaf(type_tag: TypeTerm, port: AnyOuterViewPort) -> Arc<RwLock<Self>> {
|
||||||
let mut tree = ReprTree::new();
|
let mut tree = ReprTree::new(type_tag);
|
||||||
tree.insert_leaf(vec![].into_iter(), port);
|
tree.insert_leaf(vec![].into_iter(), port);
|
||||||
Arc::new(RwLock::new(tree))
|
Arc::new(RwLock::new(tree))
|
||||||
}
|
}
|
||||||
|
@ -47,7 +49,7 @@ impl ReprTree {
|
||||||
if let Some(next_repr) = self.branches.get(&type_term) {
|
if let Some(next_repr) = self.branches.get(&type_term) {
|
||||||
next_repr.write().unwrap().insert_leaf(type_ladder, port);
|
next_repr.write().unwrap().insert_leaf(type_ladder, port);
|
||||||
} else {
|
} else {
|
||||||
let mut next_repr = ReprTree::new();
|
let mut next_repr = ReprTree::new(type_term.clone());
|
||||||
next_repr.insert_leaf(type_ladder, port);
|
next_repr.insert_leaf(type_ladder, port);
|
||||||
self.insert_branch(type_term, Arc::new(RwLock::new(next_repr)));
|
self.insert_branch(type_term, Arc::new(RwLock::new(next_repr)));
|
||||||
}
|
}
|
||||||
|
@ -55,48 +57,34 @@ impl ReprTree {
|
||||||
self.port = Some(port);
|
self.port = Some(port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Object {
|
|
||||||
pub type_tag: TypeTerm,
|
|
||||||
pub repr: Arc<RwLock<ReprTree>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Object {
|
|
||||||
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
|
pub fn get_port<V: View + ?Sized + 'static>(&self) -> Option<OuterViewPort<V>>
|
||||||
where
|
where
|
||||||
V::Msg: Clone,
|
V::Msg: Clone,
|
||||||
{
|
{
|
||||||
Some(
|
Some(
|
||||||
self.repr
|
self.port
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.port
|
|
||||||
.clone()?
|
.clone()?
|
||||||
.downcast::<V>()
|
.downcast::<V>()
|
||||||
.ok()
|
.ok()
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn downcast(&self, dst_type: TypeTerm) -> Option<Object> {
|
pub fn downcast(&self, dst_type: &TypeTerm) -> Option<Arc<RwLock<ReprTree>>> {
|
||||||
if let Some(repr) = self.repr.read().unwrap().branches.get(&dst_type) {
|
self.branches.get(dst_type).cloned()
|
||||||
Some(Object {
|
|
||||||
type_tag: dst_type,
|
|
||||||
repr: repr.clone(),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn downcast_ladder(&self, repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Object> {
|
pub fn downcast_ladder(&self, mut repr_ladder: impl Iterator<Item = TypeTerm>) -> Option<Arc<RwLock<ReprTree>>> {
|
||||||
repr_ladder.fold(Some(self.clone()), |s, t| s?.downcast(t.clone()))
|
let first = repr_ladder.next()?;
|
||||||
|
repr_ladder.fold(
|
||||||
|
self.downcast(&first),
|
||||||
|
|s, t| s?.read().unwrap().downcast(&t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn add_iso_repr(
|
pub fn add_iso_repr(
|
||||||
&self,
|
&self,
|
||||||
type_ladder: impl Iterator<Item = TypeTerm>,
|
type_ladder: impl Iterator<Item = TypeTerm>,
|
||||||
|
@ -198,7 +186,9 @@ impl Object {
|
||||||
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
||||||
) {
|
) {
|
||||||
// todo
|
// todo
|
||||||
}
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
@ -239,14 +229,14 @@ pub struct Context {
|
||||||
type_dict: TypeDict,
|
type_dict: TypeDict,
|
||||||
|
|
||||||
/// objects
|
/// objects
|
||||||
objects: HashMap<String, Object>,
|
objects: HashMap<String, Arc<RwLock<ReprTree>>>,
|
||||||
|
|
||||||
/// editors
|
/// editors
|
||||||
editor_ctors: HashMap<TypeID, Box<dyn Fn(&Self, TypeTerm) -> Option<Arc<RwLock<dyn Nested>>> + Send + Sync>>,
|
editor_ctors: HashMap<TypeID, Box<dyn Fn(&Self, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested+ Send + Sync>>> + Send + Sync>>,
|
||||||
|
|
||||||
/// morphisms
|
/// morphisms
|
||||||
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Object + Send + Sync>>,
|
default_constructors: HashMap<TypeTerm, Box<dyn Fn() -> Arc<RwLock<ReprTree>> + Send + Sync>>,
|
||||||
morphism_constructors: HashMap<MorphismType, Box<dyn Fn(Object) -> Object + Send + Sync>>,
|
morphism_constructors: HashMap<MorphismType, Box<dyn Fn(Arc<RwLock<ReprTree>>) -> Arc<RwLock<ReprTree>> + Send + Sync>>,
|
||||||
|
|
||||||
/// recursion
|
/// recursion
|
||||||
parent: Option<Arc<RwLock<Context>>>,
|
parent: Option<Arc<RwLock<Context>>>,
|
||||||
|
@ -279,7 +269,7 @@ impl Context {
|
||||||
self.type_dict.type_term_to_str(&t)
|
self.type_dict.type_term_to_str(&t)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Box<dyn Fn(&Self, TypeTerm) -> Option<Arc<RwLock<dyn Nested>>> + Send + Sync>) {
|
pub fn add_editor_ctor(&mut self, tn: &str, mk_editor: Box<dyn Fn(&Self, TypeTerm, usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> + Send + Sync>) {
|
||||||
if let Some(tid) = self.type_dict.get_typeid(&tn.into()) {
|
if let Some(tid) = self.type_dict.get_typeid(&tn.into()) {
|
||||||
self.editor_ctors.insert(tid, mk_editor);
|
self.editor_ctors.insert(tid, mk_editor);
|
||||||
} else {
|
} else {
|
||||||
|
@ -287,10 +277,10 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_editor(&self, type_term: TypeTerm) -> Option<Arc<RwLock<dyn Nested>>> {
|
pub fn make_editor(&self, type_term: TypeTerm, depth: usize) -> Option<Arc<RwLock<dyn Nested + Send + Sync>>> {
|
||||||
if let TypeTerm::Type{ id, args } = type_term.clone() {
|
if let TypeTerm::Type{ id, args } = type_term.clone() {
|
||||||
let mk_editor = self.editor_ctors.get(&id)?;
|
let mk_editor = self.editor_ctors.get(&id)?;
|
||||||
mk_editor(self, type_term)
|
mk_editor(self, type_term, depth)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -299,7 +289,7 @@ impl Context {
|
||||||
pub fn add_morphism(
|
pub fn add_morphism(
|
||||||
&mut self,
|
&mut self,
|
||||||
morph_type: MorphismType,
|
morph_type: MorphismType,
|
||||||
morph_fn: Box<dyn Fn(Object) -> Object + Send + Sync>,
|
morph_fn: Box<dyn Fn(Arc<RwLock<ReprTree>>) -> Arc<RwLock<ReprTree>> + Send + Sync>,
|
||||||
) {
|
) {
|
||||||
self.morphism_constructors.insert(morph_type, morph_fn);
|
self.morphism_constructors.insert(morph_type, morph_fn);
|
||||||
}
|
}
|
||||||
|
@ -313,15 +303,12 @@ impl Context {
|
||||||
if let Some(ctor) = self.default_constructors.get(&type_tag) {
|
if let Some(ctor) = self.default_constructors.get(&type_tag) {
|
||||||
ctor()
|
ctor()
|
||||||
} else {
|
} else {
|
||||||
Object {
|
Arc::new(RwLock::new(ReprTree::new(type_tag)))
|
||||||
type_tag,
|
|
||||||
repr: Arc::new(RwLock::new(ReprTree::new())),
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_obj(&self, name: &String) -> Option<Object> {
|
pub fn get_obj(&self, name: &String) -> Option<Arc<RwLock<ReprTree>>> {
|
||||||
if let Some(obj) = self.objects.get(name) {
|
if let Some(obj) = self.objects.get(name) {
|
||||||
Some(obj.clone())
|
Some(obj.clone())
|
||||||
} else if let Some(parent) = self.parent.as_ref() {
|
} else if let Some(parent) = self.parent.as_ref() {
|
||||||
|
@ -331,6 +318,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
|
pub fn get_obj_port<'a, V: View + ?Sized + 'static>(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
@ -371,10 +359,7 @@ impl Context {
|
||||||
}) {
|
}) {
|
||||||
ctor(old_obj.clone())
|
ctor(old_obj.clone())
|
||||||
} else {
|
} else {
|
||||||
Object {
|
Arc::new(RwLock::new(ReprTree::new(dst_type)))
|
||||||
type_tag: dst_type,
|
|
||||||
repr: Arc::new(RwLock::new(ReprTree::new())),
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
new_obj
|
new_obj
|
||||||
|
@ -409,7 +394,8 @@ impl Context {
|
||||||
*/
|
*/
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub mod view;
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
channel::{queue_channel, set_channel, singleton_channel, ChannelReceiver, ChannelSender},
|
channel::{queue_channel, set_channel, singleton_channel, ChannelReceiver, ChannelSender},
|
||||||
context::{Context, MorphismMode, MorphismType, Object, ReprTree},
|
context::{Context, MorphismMode, MorphismType, ReprTree},
|
||||||
observer::{NotifyFnObserver, Observer, ObserverBroadcast, ObserverExt, ResetFnObserver},
|
observer::{NotifyFnObserver, Observer, ObserverBroadcast, ObserverExt, ResetFnObserver},
|
||||||
port::{
|
port::{
|
||||||
AnyInnerViewPort, AnyOuterViewPort, AnyViewPort, InnerViewPort, OuterViewPort, ViewPort,
|
AnyInnerViewPort, AnyOuterViewPort, AnyViewPort, InnerViewPort, OuterViewPort, ViewPort,
|
||||||
|
|
|
@ -46,5 +46,6 @@ pub trait Nested
|
||||||
// + TreeType
|
// + TreeType
|
||||||
+ Diagnostics
|
+ Diagnostics
|
||||||
+ Send
|
+ Send
|
||||||
|
+ Sync
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
core::{OuterViewPort, ViewPort},
|
core::{OuterViewPort, ViewPort, TypeTerm},
|
||||||
list::{
|
list::{
|
||||||
ListCursor, ListCursorMode,
|
ListCursor, ListCursorMode,
|
||||||
ListSegment, ListSegmentSequence,
|
ListSegment, ListSegmentSequence,
|
||||||
|
@ -33,7 +33,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
style: SeqDecorStyle,
|
style: SeqDecorStyle,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
|
|
||||||
port: ViewPort<dyn TerminalView>
|
port: OuterViewPort<dyn TerminalView>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ItemEditor> PTYListEditor<ItemEditor>
|
impl<ItemEditor> PTYListEditor<ItemEditor>
|
||||||
|
@ -45,14 +45,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
split_char: char,
|
split_char: char,
|
||||||
depth: usize
|
depth: usize
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let port = ViewPort::new();
|
Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth)
|
||||||
PTYListEditor {
|
|
||||||
editor: ListEditor::new(make_item_editor, depth),
|
|
||||||
style,
|
|
||||||
depth,
|
|
||||||
split_char,
|
|
||||||
port
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_editor(
|
pub fn from_editor(
|
||||||
|
@ -61,7 +54,10 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
split_char: char,
|
split_char: char,
|
||||||
depth: usize
|
depth: usize
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let port = ViewPort::new();
|
let port = editor
|
||||||
|
.get_seg_seq_view()
|
||||||
|
.pty_decorate(style, depth);
|
||||||
|
|
||||||
PTYListEditor {
|
PTYListEditor {
|
||||||
editor,
|
editor,
|
||||||
split_char,
|
split_char,
|
||||||
|
@ -96,9 +92,7 @@ impl<ItemEditor> TerminalEditor for PTYListEditor<ItemEditor>
|
||||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
self.editor
|
self.port.clone()
|
||||||
.get_seg_seq_view()
|
|
||||||
.pty_decorate(self.style, self.depth)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
|
@ -250,7 +244,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<ItemEditor> Diagnostics for PTYListEditor<ItemEditor>
|
impl<ItemEditor> Diagnostics for PTYListEditor<ItemEditor>
|
||||||
where ItemEditor: Nested + Diagnostics + ?Sized + Send + Sync + 'static
|
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
|
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = crate::diagnostics::Message>> {
|
||||||
self.editor
|
self.editor
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
core::{TypeLadder, Context, OuterViewPort},
|
core::{TypeTerm, TypeLadder, Context, OuterViewPort},
|
||||||
terminal::{TerminalView, TerminalEditor, TerminalEvent, TerminalEditorResult, make_label},
|
terminal::{TerminalView, TerminalEditor, TerminalEvent, TerminalEditorResult, make_label},
|
||||||
tree::{TreeNav},
|
tree::{TreeNav},
|
||||||
integer::PosIntEditor,
|
integer::PosIntEditor,
|
||||||
list::{ListEditor, PTYListEditor},
|
list::{ListEditor, PTYListEditor},
|
||||||
sequence::{decorator::{SeqDecorStyle}},
|
sequence::{decorator::{SeqDecorStyle}},
|
||||||
product::editor::ProductEditor,
|
product::editor::ProductEditor,
|
||||||
|
sum::SumEditor,
|
||||||
char_editor::CharEditor,
|
char_editor::CharEditor,
|
||||||
diagnostics::Diagnostics,
|
diagnostics::Diagnostics,
|
||||||
Nested
|
Nested
|
||||||
|
@ -48,226 +49,197 @@ struct GrammarRuleEditor {
|
||||||
rhs: Arc<RwLock<PTYListEditor<RhsNode>>>
|
rhs: Arc<RwLock<PTYListEditor<RhsNode>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_editor(ctx: Arc<RwLock<Context>>, t: &TypeLadder, depth: usize) -> Arc<RwLock<dyn Nested + Send + Sync>> {
|
|
||||||
let c = ctx.read().unwrap();
|
|
||||||
if t[0] == c.type_term_from_str("( PosInt 16 BigEndian )").unwrap() {
|
|
||||||
Arc::new(RwLock::new(PosIntEditor::new(16))) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( PosInt 10 BigEndian )").unwrap() {
|
pub fn init_ctx() -> Arc<RwLock<Context>> {
|
||||||
Arc::new(RwLock::new(PosIntEditor::new(10))) as Arc<RwLock<dyn Nested + Send + Sync>>
|
let mut ctx = Arc::new(RwLock::new(Context::new()));
|
||||||
|
for tn in vec![
|
||||||
|
"MachineWord", "MachineInt", "MachineSyllab", "Bits",
|
||||||
|
"Vec", "Stream", "Json",
|
||||||
|
"Sequence", "AsciiString", "UTF-8-String", "Char", "String", "Symbol",
|
||||||
|
"PosInt", "Digit", "LittleEndian", "BigEndian",
|
||||||
|
"DiffStream", "ℕ", "List", "PathSegment", "Path", "Term", "RGB", "Vec3i"
|
||||||
|
] { ctx.write().unwrap().add_typename(tn.into()); }
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( String )").unwrap() {
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
Arc::new(RwLock::new(
|
"Char", Box::new(
|
||||||
PTYListEditor::new(
|
|ctx: &Context, ty: TypeTerm, _depth: usize| {
|
||||||
Box::new(|| {
|
Some(
|
||||||
Arc::new(RwLock::new(CharEditor::new()))
|
Arc::new(RwLock::new(CharEditor::new()))
|
||||||
}),
|
as Arc<RwLock<dyn Nested + Send + Sync>>)
|
||||||
SeqDecorStyle::DoubleQuote,
|
}
|
||||||
'"',
|
)
|
||||||
depth
|
);
|
||||||
)
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
))
|
"Symbol", Box::new(
|
||||||
|
|ctx: &Context, ty: TypeTerm, depth: usize| {
|
||||||
} else if t[0] == c.type_term_from_str("( Symbol )").unwrap() {
|
ctx.make_editor(
|
||||||
Arc::new(RwLock::new(
|
ctx.type_term_from_str("( List Char 0 )").unwrap(),
|
||||||
PTYListEditor::new(
|
depth
|
||||||
Box::new(|| {
|
)
|
||||||
Arc::new(RwLock::new(CharEditor::new()))
|
}
|
||||||
}),
|
)
|
||||||
SeqDecorStyle::Plain,
|
);
|
||||||
' ',
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
depth
|
"String", Box::new(
|
||||||
)
|
|ctx: &Context, ty: TypeTerm, depth: usize| {
|
||||||
))
|
ctx.make_editor(
|
||||||
|
ctx.type_term_from_str("( List Char 3 )").unwrap(),
|
||||||
} else if t[0] == c.type_term_from_str("( List String )").unwrap() {
|
depth
|
||||||
Arc::new(RwLock::new(
|
)
|
||||||
PTYListEditor::new(
|
}
|
||||||
Box::new({
|
)
|
||||||
let d = depth + 1;
|
);
|
||||||
let ctx = ctx.clone();
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
move || {
|
"PosInt", Box::new(
|
||||||
make_editor(
|
|ctx: &Context, ty: TypeTerm, _depth: usize| {
|
||||||
ctx.clone(),
|
match ty {
|
||||||
&vec![ctx.read().unwrap().type_term_from_str("( String )").unwrap()],
|
TypeTerm::Type {
|
||||||
d
|
id, args
|
||||||
)
|
} => {
|
||||||
|
if args.len() > 0 {
|
||||||
|
match args[0] {
|
||||||
|
TypeTerm::Num(radix) => {
|
||||||
|
Some(
|
||||||
|
Arc::new(RwLock::new(PosIntEditor::new(radix as u32)))
|
||||||
|
as Arc<RwLock<dyn Nested + Send + Sync>>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
_ => None
|
||||||
SeqDecorStyle::EnumSet,
|
}
|
||||||
'"',
|
}
|
||||||
depth
|
)
|
||||||
)
|
);
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
} else if t[0] == c.type_term_from_str("( List Symbol )").unwrap() {
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
Arc::new(RwLock::new(
|
"List", Box::new({
|
||||||
PTYListEditor::new(
|
let ctx = ctx.clone();
|
||||||
Box::new({
|
move |c_: &Context, ty: TypeTerm, depth: usize| {
|
||||||
let d = depth + 1;
|
match ty {
|
||||||
let ctx = ctx.clone();
|
TypeTerm::Type {
|
||||||
move || {
|
id, args
|
||||||
make_editor(
|
} => {
|
||||||
ctx.clone(),
|
if args.len() > 0 {
|
||||||
&vec![ctx.read().unwrap().type_term_from_str("( Symbol )").unwrap()],
|
// todod factor style out of type arGS
|
||||||
d
|
let style = if args.len() > 1 {
|
||||||
)
|
match args[1] {
|
||||||
|
TypeTerm::Num(0) => SeqDecorStyle::Plain,
|
||||||
|
TypeTerm::Num(1) => SeqDecorStyle::HorizontalSexpr,
|
||||||
|
TypeTerm::Num(2) => SeqDecorStyle::VerticalSexpr,
|
||||||
|
TypeTerm::Num(3) => SeqDecorStyle::DoubleQuote,
|
||||||
|
TypeTerm::Num(4) => SeqDecorStyle::Tuple,
|
||||||
|
TypeTerm::Num(5) => SeqDecorStyle::EnumSet,
|
||||||
|
TypeTerm::Num(6) => SeqDecorStyle::Path,
|
||||||
|
_ => SeqDecorStyle::HorizontalSexpr
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
SeqDecorStyle::HorizontalSexpr
|
||||||
|
};
|
||||||
|
|
||||||
|
let delim = if args.len() > 1 {
|
||||||
|
match args[1] {
|
||||||
|
TypeTerm::Num(0) => ' ',
|
||||||
|
TypeTerm::Num(1) => ' ',
|
||||||
|
TypeTerm::Num(2) => '\n',
|
||||||
|
TypeTerm::Num(3) => '"',
|
||||||
|
TypeTerm::Num(4) => ',',
|
||||||
|
TypeTerm::Num(5) => ',',
|
||||||
|
TypeTerm::Num(6) => '/',
|
||||||
|
_ => '\0'
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
'\0'
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(
|
||||||
|
Arc::new(RwLock::new(PTYListEditor::new(
|
||||||
|
Box::new({
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
move || {
|
||||||
|
ctx.read().unwrap().make_editor(args[0].clone(), depth + 1).unwrap()
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
style,
|
||||||
|
delim,
|
||||||
|
depth
|
||||||
|
)))
|
||||||
|
as Arc<RwLock<dyn Nested + Send + Sync>>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
_ => None
|
||||||
SeqDecorStyle::EnumSet,
|
}
|
||||||
' ',
|
}
|
||||||
depth
|
}
|
||||||
)
|
));
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List Char )").unwrap() {
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
Arc::new(RwLock::new(
|
"RGB", Box::new({
|
||||||
PTYListEditor::new(
|
let c = ctx.clone();
|
||||||
Box::new(
|
move |ctx: &Context, ty: TypeTerm, depth: usize| {
|
||||||
|| { Arc::new(RwLock::new(CharEditor::new())) }
|
Some(Arc::new(RwLock::new(ProductEditor::new(depth, c.clone())
|
||||||
),
|
.with_t(Point2::new(0, 0), "{ ")
|
||||||
SeqDecorStyle::Plain,
|
.with_t(Point2::new(1, 1), "r: ")
|
||||||
'\n',
|
.with_n(Point2::new(2, 1), vec![ ctx.type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
|
||||||
depth+1
|
.with_t(Point2::new(1, 2), "g: ")
|
||||||
)
|
.with_n(Point2::new(2, 2), vec![ ctx.type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
.with_t(Point2::new(1, 3), "b: ")
|
||||||
|
.with_n(Point2::new(2, 3), vec![ ctx.type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
|
||||||
|
.with_t(Point2::new(0, 4), "} ")
|
||||||
|
)) as Arc<RwLock<dyn Nested + Send + Sync>>)
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List ℕ )").unwrap() {
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
Arc::new(RwLock::new(
|
"PathSegment", Box::new(
|
||||||
PTYListEditor::new(
|
|ctx: &Context, ty: TypeTerm, depth: usize| {
|
||||||
Box::new(|| {
|
ctx.make_editor(
|
||||||
Arc::new(RwLock::new(PosIntEditor::new(16)))
|
ctx.type_term_from_str("( List Char 0 )").unwrap(),
|
||||||
}),
|
depth
|
||||||
SeqDecorStyle::EnumSet,
|
)
|
||||||
',',
|
}
|
||||||
depth
|
)
|
||||||
)
|
);
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
|
"Path", Box::new(
|
||||||
|
|ctx: &Context, ty: TypeTerm, depth: usize| {
|
||||||
|
ctx.make_editor(
|
||||||
|
ctx.type_term_from_str("( List PathSegment 6 )").unwrap(),
|
||||||
|
depth+1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( Path )").unwrap() {
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
Arc::new(RwLock::new(PTYListEditor::new(
|
"Term", Box::new(
|
||||||
Box::new({
|
|ctx: &Context, ty: TypeTerm, depth: usize| {
|
||||||
let d= depth+1;
|
let mut s = SumEditor::new(
|
||||||
move || {
|
vec![
|
||||||
Arc::new(RwLock::new(PTYListEditor::new(
|
ctx.make_editor(ctx.type_term_from_str("( Symbol )").unwrap(), depth+1).unwrap(),
|
||||||
Box::new(|| {
|
ctx.make_editor(ctx.type_term_from_str("( PosInt 10 )").unwrap(), depth+1).unwrap(),
|
||||||
Arc::new(RwLock::new(CharEditor::new()))
|
ctx.make_editor(ctx.type_term_from_str("( List Term )").unwrap(), depth+1).unwrap(),
|
||||||
}),
|
]
|
||||||
SeqDecorStyle::Plain,
|
);
|
||||||
'\n',
|
s.select(0);
|
||||||
d
|
Some(
|
||||||
)))
|
Arc::new(RwLock::new(
|
||||||
}}),
|
s
|
||||||
SeqDecorStyle::Path,
|
))
|
||||||
'/',
|
)
|
||||||
depth
|
}
|
||||||
))) as Arc<RwLock<dyn Nested + Send + Sync>>
|
)
|
||||||
|
);
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List Path )").unwrap() {
|
ctx
|
||||||
Arc::new(RwLock::new(
|
|
||||||
PTYListEditor::new(
|
|
||||||
Box::new({
|
|
||||||
let d = depth + 1;
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
move || {
|
|
||||||
make_editor(
|
|
||||||
ctx.clone(),
|
|
||||||
&vec![ctx.read().unwrap().type_term_from_str("( Path )").unwrap()],
|
|
||||||
d
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
SeqDecorStyle::EnumSet,
|
|
||||||
',',
|
|
||||||
depth
|
|
||||||
)
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List RGB )").unwrap() {
|
|
||||||
Arc::new(RwLock::new(
|
|
||||||
PTYListEditor::<dyn Nested + Send +Sync>::new(
|
|
||||||
{
|
|
||||||
let d = depth+1;
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
Box::new(move || {
|
|
||||||
make_editor(ctx.clone(), &vec![ ctx.read().unwrap().type_term_from_str("( RGB )").unwrap() ], d)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
SeqDecorStyle::VerticalSexpr,
|
|
||||||
',',
|
|
||||||
depth
|
|
||||||
)
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( RGB )").unwrap() {
|
|
||||||
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
|
||||||
.with_t(Point2::new(0, 0), "{ ")
|
|
||||||
.with_t(Point2::new(1, 1), "r: ")
|
|
||||||
.with_n(Point2::new(2, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(1, 2), "g: ")
|
|
||||||
.with_n(Point2::new(2, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(1, 3), "b: ")
|
|
||||||
.with_n(Point2::new(2, 3), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 16 BigEndian )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(0, 4), "} ")
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( Vec3i )").unwrap() {
|
|
||||||
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
|
||||||
.with_t(Point2::new(0, 0), "{")
|
|
||||||
.with_t(Point2::new(1, 1), "x: ")
|
|
||||||
.with_n(Point2::new(2, 1), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(1, 2), "y: ")
|
|
||||||
.with_n(Point2::new(2, 2), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(1, 3), "z: ")
|
|
||||||
.with_n(Point2::new(2, 3), vec![ ctx.read().unwrap().type_term_from_str("( PosInt 10 BigEndian )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(0, 4), "}")
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( Json )").unwrap() {
|
|
||||||
Arc::new(RwLock::new(
|
|
||||||
PTYListEditor::<dyn Nested + Send + Sync>::new(
|
|
||||||
Box::new({
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
move || {
|
|
||||||
Arc::new(RwLock::new(ProductEditor::new(depth, ctx.clone())
|
|
||||||
.with_n(Point2::new(0, 0), vec![ ctx.read().unwrap().type_term_from_str("( String )").unwrap() ] )
|
|
||||||
.with_t(Point2::new(1, 0), ": ")
|
|
||||||
.with_n(Point2::new(2, 0), vec![ ctx.read().unwrap().type_term_from_str("( Json )").unwrap() ] )
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
SeqDecorStyle::VerticalSexpr,
|
|
||||||
'\n',
|
|
||||||
depth
|
|
||||||
)
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else if t[0] == c.type_term_from_str("( List Term )").unwrap() {
|
|
||||||
Arc::new(RwLock::new(
|
|
||||||
PTYListEditor::<dyn Nested + Send + Sync>::new(
|
|
||||||
Box::new({
|
|
||||||
let ctx = ctx.clone();
|
|
||||||
move || {
|
|
||||||
make_editor(ctx.clone(), &vec![ ctx.read().unwrap().type_term_from_str("( Term )").unwrap() ], depth+1)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
SeqDecorStyle::Tuple,
|
|
||||||
'\n',
|
|
||||||
depth
|
|
||||||
)
|
|
||||||
)) as Arc<RwLock<dyn Nested + Send + Sync>>
|
|
||||||
|
|
||||||
} else { // else: term
|
|
||||||
Arc::new(RwLock::new(
|
|
||||||
PTYListEditor::new(
|
|
||||||
|| {
|
|
||||||
Arc::new(RwLock::new(CharEditor::new()))
|
|
||||||
},
|
|
||||||
SeqDecorStyle::DoubleQuote,
|
|
||||||
' ',
|
|
||||||
depth
|
|
||||||
)
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,9 @@ use {
|
||||||
list::ListCursorMode,
|
list::ListCursorMode,
|
||||||
product::{segment::ProductEditorSegment},
|
product::{segment::ProductEditorSegment},
|
||||||
sequence::{SequenceView},
|
sequence::{SequenceView},
|
||||||
make_editor::make_editor,
|
|
||||||
|
|
||||||
tree::{TreeNav, TreeNavResult},
|
tree::{TreeNav, TreeNavResult},
|
||||||
diagnostics::{Diagnostics, Message},
|
diagnostics::{Diagnostics, Message},
|
||||||
terminal::{TerminalStyle},
|
terminal::{TerminalStyle},
|
||||||
|
|
||||||
Nested
|
Nested
|
||||||
},
|
},
|
||||||
cgmath::{Vector2, Point2},
|
cgmath::{Vector2, Point2},
|
||||||
|
@ -140,7 +137,6 @@ impl ProductEditor {
|
||||||
*cur_depth = cur.tree_addr.len();
|
*cur_depth = cur.tree_addr.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
*cur_dist = cur.tree_addr[0] - idx
|
*cur_dist = cur.tree_addr[0] - idx
|
||||||
} else {
|
} else {
|
||||||
*cur_dist = isize::MAX;
|
*cur_dist = isize::MAX;
|
||||||
|
@ -221,7 +217,7 @@ impl TerminalEditor for ProductEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let e = make_editor(self.ctx.clone(), t, *ed_depth+1);
|
let e = self.ctx.read().unwrap().make_editor(t[0].clone(), *ed_depth+1).unwrap();
|
||||||
*editor = Some(e.clone());
|
*editor = Some(e.clone());
|
||||||
update_segment = true;
|
update_segment = true;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ use {
|
||||||
list::ListCursorMode,
|
list::ListCursorMode,
|
||||||
tree::{TreeNav, TreeNavResult, TreeCursor},
|
tree::{TreeNav, TreeNavResult, TreeCursor},
|
||||||
product::{segment::ProductEditorSegment, ProductEditor},
|
product::{segment::ProductEditorSegment, ProductEditor},
|
||||||
make_editor::{make_editor},
|
|
||||||
Nested
|
Nested
|
||||||
},
|
},
|
||||||
cgmath::{Point2, Vector2},
|
cgmath::{Point2, Vector2},
|
||||||
|
@ -66,14 +65,13 @@ impl TreeNav for ProductEditor {
|
||||||
|
|
||||||
if c.tree_addr.len() > 0 {
|
if c.tree_addr.len() > 0 {
|
||||||
self.cursor = Some(crate::modulo(c.tree_addr.remove(0), self.n_indices.len() as isize));
|
self.cursor = Some(crate::modulo(c.tree_addr.remove(0), self.n_indices.len() as isize));
|
||||||
|
|
||||||
if let Some(mut element) = self.get_cur_segment_mut() {
|
if let Some(mut element) = self.get_cur_segment_mut() {
|
||||||
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist:_ }) = element.deref_mut() {
|
if let Some(ProductEditorSegment::N{ t, editor, ed_depth, cur_depth, cur_dist:_ }) = element.deref_mut() {
|
||||||
if let Some(e) = editor {
|
if let Some(e) = editor {
|
||||||
e.write().unwrap().goto(c.clone());
|
e.write().unwrap().goto(c.clone());
|
||||||
} else if c.tree_addr.len() > 0 {
|
} else if c.tree_addr.len() > 0 {
|
||||||
// create editor
|
// create editor
|
||||||
let e = make_editor(self.ctx.clone(), t, *ed_depth+1);
|
let e = self.ctx.read().unwrap().make_editor(t[0].clone(), *ed_depth+1).unwrap();
|
||||||
*editor = Some(e.clone());
|
*editor = Some(e.clone());
|
||||||
let mut e = e.write().unwrap();
|
let mut e = e.write().unwrap();
|
||||||
e.goto(c.clone());
|
e.goto(c.clone());
|
||||||
|
@ -91,6 +89,10 @@ impl TreeNav for ProductEditor {
|
||||||
|
|
||||||
TreeNavResult::Continue
|
TreeNavResult::Continue
|
||||||
} else {
|
} else {
|
||||||
|
if let Some(mut ed) = self.get_cur_editor() {
|
||||||
|
ed.write().unwrap().goto(TreeCursor::none());
|
||||||
|
}
|
||||||
|
|
||||||
self.cursor = None;
|
self.cursor = None;
|
||||||
|
|
||||||
if let Some(i) = old_cursor {
|
if let Some(i) = old_cursor {
|
||||||
|
@ -127,7 +129,8 @@ impl TreeNav for ProductEditor {
|
||||||
e.goby(direction);
|
e.goby(direction);
|
||||||
} else {
|
} else {
|
||||||
// create editor
|
// create editor
|
||||||
let e = make_editor(self.ctx.clone(), t, *ed_depth+1);
|
|
||||||
|
let e = self.ctx.read().unwrap().make_editor(t[0].clone(), *ed_depth+1).unwrap();
|
||||||
*editor = Some(e.clone());
|
*editor = Some(e.clone());
|
||||||
let mut e = e.write().unwrap();
|
let mut e = e.write().unwrap();
|
||||||
e.goby(direction);
|
e.goby(direction);
|
||||||
|
|
|
@ -10,8 +10,6 @@ use {
|
||||||
list::ListCursorMode,
|
list::ListCursorMode,
|
||||||
product::{segment::ProductEditorSegment},
|
product::{segment::ProductEditorSegment},
|
||||||
sequence::{SequenceView},
|
sequence::{SequenceView},
|
||||||
make_editor::make_editor,
|
|
||||||
|
|
||||||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||||
diagnostics::{Diagnostics, Message},
|
diagnostics::{Diagnostics, Message},
|
||||||
terminal::{TerminalStyle},
|
terminal::{TerminalStyle},
|
||||||
|
|
|
@ -18,7 +18,6 @@ use {
|
||||||
},
|
},
|
||||||
tree::{TreeCursor, TreeNav, TreeNavResult},
|
tree::{TreeCursor, TreeNav, TreeNavResult},
|
||||||
diagnostics::{Diagnostics},
|
diagnostics::{Diagnostics},
|
||||||
make_editor::make_editor,
|
|
||||||
product::ProductEditor,
|
product::ProductEditor,
|
||||||
sum::SumEditor,
|
sum::SumEditor,
|
||||||
Nested
|
Nested
|
||||||
|
@ -227,11 +226,9 @@ impl TerminalEditor for Commander {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||||
let mut c = cmd_editor.write().unwrap();
|
let mut c = cmd_editor.write().unwrap();
|
||||||
if let TerminalEditorResult::Exit = c.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('\n')))) {
|
if c.nexd() == TreeNavResult::Exit {
|
||||||
|
|
||||||
// run
|
// run
|
||||||
c.goto(TreeCursor::none());
|
c.goto(TreeCursor::none());
|
||||||
c.up();
|
|
||||||
|
|
||||||
TerminalEditorResult::Exit
|
TerminalEditorResult::Exit
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,6 +25,9 @@ use {
|
||||||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||||
vec::VecBuffer,
|
vec::VecBuffer,
|
||||||
integer::{PosIntEditor},
|
integer::{PosIntEditor},
|
||||||
|
char_editor::CharEditor,
|
||||||
|
product::ProductEditor,
|
||||||
|
sum::SumEditor,
|
||||||
diagnostics::{Diagnostics},
|
diagnostics::{Diagnostics},
|
||||||
Nested
|
Nested
|
||||||
},
|
},
|
||||||
|
@ -50,15 +53,9 @@ async fn main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Type Context //
|
// Type Context //
|
||||||
let mut ctx = Arc::new(RwLock::new(Context::new()));
|
let ctx = nested::make_editor::init_ctx();
|
||||||
for tn in vec![
|
|
||||||
"MachineWord", "MachineInt", "MachineSyllab", "Bits",
|
|
||||||
"Vec", "Stream", "Json",
|
|
||||||
"Sequence", "AsciiString", "UTF-8-String", "Char", "String", "Symbol",
|
|
||||||
"PosInt", "Digit", "LittleEndian", "BigEndian",
|
|
||||||
"DiffStream", "ℕ", "List", "Path", "Term", "RGB", "Vec3i"
|
|
||||||
] { ctx.write().unwrap().add_typename(tn.into()); }
|
|
||||||
|
|
||||||
|
let c = ctx.clone();
|
||||||
let mut process_list_editor =
|
let mut process_list_editor =
|
||||||
PTYListEditor::new(
|
PTYListEditor::new(
|
||||||
Box::new( move || {
|
Box::new( move || {
|
||||||
|
@ -292,3 +289,4 @@ async fn main() {
|
||||||
|
|
||||||
term_writer.show().await.expect("output error!");
|
term_writer.show().await.expect("output error!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue