first steps in reactivating pty-list editor

This commit is contained in:
Michael Sippel 2023-11-29 01:23:41 +01:00
parent 85b614a9bb
commit 25d8acdb72
Signed by: senvas
GPG key ID: F96CF119C34B64A6
12 changed files with 191 additions and 119 deletions

View file

@ -7,7 +7,7 @@ extern crate termion;
use { use {
cgmath::Vector2, cgmath::Vector2,
nested::{ nested::{
edit_tree::NestedNode, edit_tree::{NestedNode, TreeCursor, TreeNav},
repr_tree::{Context, ReprTree}, repr_tree::{Context, ReprTree},
}, },
nested_tty::{ nested_tty::{
@ -17,7 +17,8 @@ use {
}, },
r3vi::{ r3vi::{
buffer::singleton::*, buffer::singleton::*,
view::{port::UpdateTask, singleton::*, ViewPort}, view::{port::UpdateTask, singleton::*, sequence::*, ViewPort},
projection::decorate_sequence::*
}, },
std::sync::{Arc, Mutex, RwLock}, std::sync::{Arc, Mutex, RwLock},
termion::event::{Event, Key}, termion::event::{Event, Key},
@ -26,48 +27,134 @@ use {
fn node_make_char_view( fn node_make_char_view(
node: NestedNode node: NestedNode
) -> NestedNode { ) -> NestedNode {
let char_view = node.data node.display
.read() .write().unwrap()
.unwrap() .insert_branch(ReprTree::new_leaf(
.get_port::<dyn SingletonView<Item = char>>() Context::parse(&node.ctx, "TerminalView"),
.expect("unable to get Char-view") node.data
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c })) .read()
.to_grid(); .unwrap()
.get_port::<dyn SingletonView<Item = char>>()
.expect("unable to get Char-view")
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
.to_grid()
.into(),
));
let mut display_rt = ReprTree::new(Context::parse(&node.ctx, "Display")); node
}
display_rt.insert_branch(ReprTree::new_leaf( fn node_make_list_view(
Context::parse(&node.ctx, "TerminalView"), mut node: NestedNode
char_view.into(), ) -> NestedNode {
)); eprintln!("add list display type");
node.display
.write().unwrap()
.insert_branch(ReprTree::new_leaf(
Context::parse(&node.ctx, "TerminalView"),
node.set_view( node.data
Arc::new(RwLock::new(display_rt)) .read()
) .unwrap()
.get_port::< dyn SequenceView<Item = NestedNode> >()
.expect("unable to get Seq-view")
.map(move |char_node| node_make_view(char_node.clone()).display_view() )
.wrap(nested_tty::make_label("("), nested_tty::make_label(")"))
.to_grid_horizontal()
.flatten()
.into()
));
// nested_tty::editors::list::PTYListStyle::for_node( &mut node, ("(", ",", ")") );
nested_tty::editors::list::PTYListController::for_node( &mut node, None, None );
node
}
fn node_make_view(
node: NestedNode
) -> NestedNode {
if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "Char") {
node_make_char_view( node )
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<Seq Char>") {
node_make_list_view( node )
// node
} else if node.data.read().unwrap().get_type() == &Context::parse(&node.ctx, "<List Char>") {
node_make_list_view( node )
} else {
eprintln!("couldnt add view");
node
}
} }
#[async_std::main] #[async_std::main]
async fn main() { async fn main() {
let app = TTYApplication::new( |ev| { /* event handler */ } );
/* setup context & create Editor-Tree /* setup context & create Editor-Tree
*/ */
let ctx = Arc::new(RwLock::new(Context::default())); let ctx = Arc::new(RwLock::new(Context::default()));
let mut node = Context::make_node(
/* Create a Char-Node with editor & view
*/
let mut n1 = Context::make_node(
&ctx, &ctx,
// node type // node type
Context::parse(&ctx, "Char"), Context::parse(&ctx, "Char"),
// depth // depth
SingletonBuffer::new(0).get_port(), SingletonBuffer::new(0).get_port(),
) ).unwrap();
.unwrap();
// set abstract data
node.data = ReprTree::from_char(&ctx, 'Λ');
// add a display view to the node // add a display view to the node
node = node_make_char_view( node ); n1 = node_make_view( n1 );
/* Create a <List Char>-Node with editor & view
*/
let mut node2 = Context::make_node(
&ctx,
// node type
Context::parse(&ctx, "<List Char>"),
// depth
SingletonBuffer::new(0).get_port(),
).unwrap();
// add a display view to the node
node2 = node_make_view( node2 );
/* setup terminal
*/
let app = TTYApplication::new({
/* event handler
*/
let ctx = ctx.clone();
let mut node = n1.clone();
node.goto(TreeCursor::home());
let node2 = node2.clone();
move |ev| {
if let Some(cmd) =node2.cmd.get() {
cmd.write().unwrap().send_cmd_obj(
ReprTree::new_leaf(
Context::parse(&ctx, "TerminalEvent"),
SingletonBuffer::new(ev.clone()).get_port().into()
)
);
}
match ev {
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
if let Some(cmd) = node.cmd.get() {
cmd.write().unwrap().send_cmd_obj(
ReprTree::from_char(&ctx, c)
);
}
}
_ => {}
}
}
});
/* setup display view routed to `app.port` /* setup display view routed to `app.port`
*/ */
@ -82,17 +169,21 @@ async fn main() {
.offset(Vector2::new(5, 0)), .offset(Vector2::new(5, 0)),
); );
let label = ctx.read().unwrap().type_term_to_str( &n1.get_type() );
compositor.write().unwrap() compositor.write().unwrap()
.push(nested_tty::make_label("Char").offset(Vector2::new(0, 2))); .push(nested_tty::make_label( &label ).offset(Vector2::new(0, 2)));
compositor.write().unwrap() compositor.write().unwrap()
.push(node.display_view().offset(Vector2::new(15, 2))); .push(n1.display_view().offset(Vector2::new(15, 2)));
let label2 = ctx.read().unwrap().type_term_to_str( &node2.get_type() );
compositor.write().unwrap()
.push(nested_tty::make_label( &label2 ).offset(Vector2::new(0, 3)));
compositor.write().unwrap() compositor.write().unwrap()
.push(nested_tty::make_label("<List Char>").offset(Vector2::new(0, 3))); .push(node2.display_view().offset(Vector2::new(15, 3)));
compositor.write().unwrap()
.push(nested_tty::make_label("---").offset(Vector2::new(15, 3)));
/* write the changes in the view of `term_port` to the terminal /* write the changes in the view of `term_port` to the terminal
*/ */

View file

@ -73,7 +73,7 @@ pub struct NestedNode {
pub data: Arc<RwLock<ReprTree>>, pub data: Arc<RwLock<ReprTree>>,
/// display view /// display view
pub view: Option< Arc<RwLock<ReprTree>> >, pub display: Arc<RwLock<ReprTree>>,
/// diagnostics /// diagnostics
pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >, pub diag: Option< OuterViewPort<dyn SequenceView<Item = Message>> >,
@ -103,16 +103,17 @@ pub struct NestedNode {
impl NestedNode { impl NestedNode {
pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self { pub fn new(ctx: Arc<RwLock<Context>>, data: Arc<RwLock<ReprTree>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>) -> Self {
NestedNode { NestedNode {
ctx,
data, data,
view: None, display: Arc::new(RwLock::new(ReprTree::new(Context::parse(&ctx, "Display")))),
diag: None, diag: None,
depth, depth,
editor: SingletonBuffer::new(None), editor: SingletonBuffer::new(None),
spillbuf: Arc::new(RwLock::new(Vec::new())), spillbuf: Arc::new(RwLock::new(Vec::new())),
cmd: SingletonBuffer::new(None), cmd: SingletonBuffer::new(None),
close_char: SingletonBuffer::new(None), close_char: SingletonBuffer::new(None),
tree_nav: SingletonBuffer::new(None) tree_nav: SingletonBuffer::new(None),
ctx
} }
} }
@ -129,20 +130,7 @@ impl NestedNode {
), ),
SingletonBuffer::new(0).get_port() SingletonBuffer::new(0).get_port()
) )
/* // .set_editor(Arc::new(RwLock::new(buf)))
.set_view(buf.get_port()
.map(|c| TerminalAtom::from(c))
.to_index()
.map_key(
|_x| {
Point2::new(0, 0)
},
|p| {
if *p == Point2::new(0,0) { Some(()) } else { None }
})
)
*/
.set_editor(Arc::new(RwLock::new(buf)))
} }
@ -163,11 +151,6 @@ impl NestedNode {
self self
} }
pub fn set_view(mut self, view: Arc<RwLock<ReprTree>>) -> Self {
self.view = Some(view);
self
}
pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self { pub fn set_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
self.cmd.set(Some(cmd)); self.cmd.set(Some(cmd));
self self
@ -189,10 +172,6 @@ impl NestedNode {
self.diag.clone().unwrap_or(ViewPort::new().into_outer()) self.diag.clone().unwrap_or(ViewPort::new().into_outer())
} }
pub fn get_view(&self) -> Option< Arc<RwLock<ReprTree>> > {
self.view.clone()
}
pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>> pub fn get_data_port<'a, V: View + ?Sized + 'static>(&'a self, type_str: impl Iterator<Item = &'a str>) -> Option<OuterViewPort<V>>
where V::Msg: Clone { where V::Msg: Clone {
let ctx = self.ctx.clone(); let ctx = self.ctx.clone();
@ -245,29 +224,6 @@ impl TreeType for NestedNode {
} }
*/ */
/* TODO: remove that at some point
*/
/*
impl TerminalEditor for NestedNode {
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
self.get_view()
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
let buf = SingletonBuffer::new(event.clone());
if let Some(cmd) = self.cmd.get() {
cmd.write().unwrap().send_cmd_obj(
ReprTree::new_leaf(
self.ctx.read().unwrap().type_term_from_str("TerminalEvent").unwrap(),
AnyOuterViewPort::from(buf.get_port())
));
}
TerminalEditorResult::Continue
}
}
*/
impl TreeNav for NestedNode { impl TreeNav for NestedNode {
fn get_cursor(&self) -> TreeCursor { fn get_cursor(&self) -> TreeCursor {
if let Some(tn) = self.tree_nav.get() { if let Some(tn) = self.tree_nav.get() {

View file

@ -82,13 +82,6 @@ impl CharEditor {
), ),
depth depth
) )
/* todo: move to lib-nested-term
.set_view(data
.get_port()
.map(move |c| TerminalAtom::from(if c == '\0' { ' ' } else { c }))
.to_grid()
)
*/
.set_cmd( editor.clone() ) .set_cmd( editor.clone() )
.set_editor( editor.clone() ) .set_editor( editor.clone() )
} }

View file

@ -15,7 +15,7 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct ListEditor { pub struct ListEditor {
pub(super) cursor: SingletonBuffer<ListCursor>, pub cursor: SingletonBuffer<ListCursor>,
// todo: (?) remove RwLock<..> around NestedNode ?? // todo: (?) remove RwLock<..> around NestedNode ??
pub data: VecBuffer< Arc<RwLock<NestedNode>> >, pub data: VecBuffer< Arc<RwLock<NestedNode>> >,
@ -27,10 +27,10 @@ pub struct ListEditor {
depth: OuterViewPort<dyn SingletonView<Item = usize>>, depth: OuterViewPort<dyn SingletonView<Item = usize>>,
pub(crate) ctx: Arc<RwLock<Context>>, pub ctx: Arc<RwLock<Context>>,
/// item type /// item type
pub(super) typ: TypeTerm, pub typ: TypeTerm,
} }
impl ListEditor { impl ListEditor {

View file

@ -1,5 +1,5 @@
use { use {
crate::terminal::TerminalStyle, crate::atom::TerminalStyle,
}; };
pub fn bg_style_from_depth(depth: usize) -> TerminalStyle { pub fn bg_style_from_depth(depth: usize) -> TerminalStyle {

View file

@ -0,0 +1,3 @@
pub mod color;

View file

@ -4,23 +4,24 @@ use {
projection::decorate_sequence::*, projection::decorate_sequence::*,
}, },
nested::{ nested::{
type_system::{Context, ReprTree}, repr_tree::{Context, ReprTree},
editors::list::*, editors::list::*,
tree::{TreeCursor, TreeNav, TreeNavResult}, edit_tree::{TreeCursor, TreeNav, TreeNavResult, NestedNode},
tree::NestedNode,
PtySegment
}, },
crate::{ crate::{
TerminalEvent, TerminalView, make_label DisplaySegment,
} TerminalStyle,
TerminalEvent, TerminalView, make_label,
edit_tree::color::{bg_style_from_depth, fg_style_from_depth}
},
std::sync::{Arc, RwLock}, std::sync::{Arc, RwLock},
termion::event::{Event, Key} termion::event::{Event, Key}
}; };
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl PtySegment for ListSegment { impl DisplaySegment for ListSegment {
fn pty_view(&self) -> OuterViewPort<dyn TerminalView> { fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
match self { match self {
ListSegment::InsertCursor => { ListSegment::InsertCursor => {
make_label("|") make_label("|")
@ -32,7 +33,7 @@ impl PtySegment for ListSegment {
ListSegment::Item{ editor, cur_dist } => { ListSegment::Item{ editor, cur_dist } => {
let e = editor.clone(); let e = editor.clone();
let cur_dist = *cur_dist; let cur_dist = *cur_dist;
editor.get_view().map_item(move |_pt, atom| { editor.display_view().map_item(move |_pt, atom| {
let c = e.get_cursor(); let c = e.get_cursor();
let cur_depth = c.tree_addr.len(); let cur_depth = c.tree_addr.len();
let select = let select =
@ -71,7 +72,7 @@ impl PTYListStyle {
editor.get_data_port() editor.get_data_port()
); );
let se = seg_seq.read().unwrap(); let se = seg_seq.read().unwrap();
se.get_view().map(move |segment| segment.pty_view()) se.get_view().map(move |segment| segment.display_view())
} }
pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> { pub fn pty_view(&self, editor: &ListEditor) -> OuterViewPort<dyn TerminalView> {
@ -83,7 +84,7 @@ impl PTYListStyle {
seg_seq seg_seq
.get_view() .get_view()
.map(move |segment| segment.pty_view()) .map(move |segment| segment.display_view())
.separate(make_label(&self.style.1)) .separate(make_label(&self.style.1))
.wrap(make_label(&self.style.0), make_label(&self.style.2)) .wrap(make_label(&self.style.0), make_label(&self.style.2))
.to_grid_horizontal() .to_grid_horizontal()
@ -91,12 +92,15 @@ impl PTYListStyle {
} }
pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) { pub fn for_node(node: &mut NestedNode, style: (&str, &str, &str)) {
node.view = Some( node.display
Self::new(style) .write().unwrap()
.pty_view( .insert_branch(ReprTree::new_leaf(
&node.get_edit::<ListEditor>().unwrap().read().unwrap() Context::parse(&node.ctx, "TerminalView"),
) Self::new(style)
); .pty_view(
&node.get_edit::<ListEditor>().unwrap().read().unwrap()
).into()
));
} }
} }
@ -166,15 +170,22 @@ impl PTYListController {
self.editor.read().unwrap().get_item() self.editor.read().unwrap().get_item()
} }
pub fn handle_term_event(&mut self, event: &TerminalEvent, _cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { pub fn handle_term_event(&mut self, event: &TerminalEvent, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
let mut e = self.editor.write().unwrap(); let mut e = self.editor.write().unwrap();
match event { match event {
TerminalEvent::Input(Event::Key(Key::Insert)) => { TerminalEvent::Input(Event::Key(Key::Insert)) => {
e.toggle_leaf_mode(); e.toggle_leaf_mode();
TreeNavResult::Continue TreeNavResult::Continue
} }
_ => TreeNavResult::Continue TerminalEvent::Input(Event::Key(Key::Char(c))) => {
} let ctx = e.ctx.clone();
drop(e);
self.handle_any_event(
ReprTree::from_char(&ctx, *c)
)
}
_ => TreeNavResult::Continue
}
} }
pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult { pub fn handle_meta_char(&mut self, c: char, child_close_char: Option<char>) -> TreeNavResult {
@ -201,6 +212,7 @@ impl PTYListController {
} }
pub fn handle_any_event(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { pub fn handle_any_event(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {
eprintln!("ANY EVENT");
let mut e = self.editor.write().unwrap(); let mut e = self.editor.write().unwrap();
let cur = e.cursor.get(); let cur = e.cursor.get();
let ctx = e.ctx.clone(); let ctx = e.ctx.clone();
@ -255,7 +267,7 @@ impl PTYListController {
} }
use r3vi::view::singleton::SingletonView; use r3vi::view::singleton::SingletonView;
use crate::commander::ObjCommander; use nested::editors::ObjCommander;
impl ObjCommander for PTYListController { impl ObjCommander for PTYListController {
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult { fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) -> TreeNavResult {

View file

@ -0,0 +1,3 @@
pub mod list;

View file

@ -11,7 +11,8 @@ pub mod ansi_parser;
pub mod terminal; pub mod terminal;
pub mod tty_application; pub mod tty_application;
//pub mod edit_tree; pub mod editors;
pub mod edit_tree;
//pub mod widgets; //pub mod widgets;
// <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ // <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\
@ -43,11 +44,24 @@ use std::sync::{Arc, RwLock};
impl DisplaySegment for nested::edit_tree::NestedNode { impl DisplaySegment for nested::edit_tree::NestedNode {
fn display_view(&self) -> OuterViewPort<dyn TerminalView> { fn display_view(&self) -> OuterViewPort<dyn TerminalView> {
self.view.as_ref().unwrap() if let Some( tv_repr ) = self.display
.read().unwrap() .read().unwrap()
.descend( Context::parse(&self.ctx, "TerminalView") ).expect("terminal backend not supported by view") .descend( Context::parse(&self.ctx, "TerminalView") )
.read().unwrap() {
.get_port::<dyn TerminalView>().unwrap() if let Some(port) =
tv_repr
.read().unwrap()
.get_port::<dyn TerminalView>() {
port
}
else {
make_label("no TerminalView port found")
}
} else {
make_label("TTY Display not supported")
.map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30))))
}
} }
} }