#![feature(trait_alias)] // <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ pub mod atom; pub mod compositor; pub mod ansi_parser; pub mod terminal; pub mod tty_application; pub mod editors; pub mod edit_tree; //pub mod widgets; // <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ pub use { atom::{TerminalAtom, TerminalStyle}, terminal::{Terminal, TerminalEvent}, tty_application::TTYApplication, compositor::TerminalCompositor, }; use r3vi::view::grid::*; // <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ pub trait TerminalView = GridView<Item = TerminalAtom>; // <<<<>>>><<>><><<>><<< * >>><<>><><<>><<<<>>>> \\ use r3vi::view::OuterViewPort; pub trait DisplaySegment { fn display_view(&self) -> OuterViewPort<dyn TerminalView>; } use nested::repr_tree::{Context, ReprTreeExt}; use std::sync::{Arc, RwLock}; impl DisplaySegment for nested::edit_tree::EditTree { fn display_view(&self) -> OuterViewPort<dyn TerminalView> { if let Some( tv_repr ) = self.disp.view .descend( Context::parse(&self.ctx, "TerminalView") ) { if let Some(port) = tv_repr .read().unwrap() .get_port::<dyn TerminalView>() { port } else { make_label("# could not get ViewPort #") } } else { make_label("# No TTY View available #") .map_item(|_p,a| a.add_style_back(TerminalStyle::fg_color((220, 30, 30)))) } } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> use { r3vi::{ buffer::vec::*, }, cgmath::Point2, }; pub fn make_label(s: &str) -> OuterViewPort<dyn TerminalView> { let label = VecBuffer::with_data(s.chars().collect()); let v = label.get_port() .to_sequence() .map(|c| TerminalAtom::from(c)) .to_index() .map_key( |idx| Point2::new(*idx as i16, 0), |pt| if pt.y == 0 { Some(pt.x as usize) } else { None }, ); v } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub trait TerminalProjections { fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView>; fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>; fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView>; } impl TerminalProjections for OuterViewPort<dyn TerminalView> { fn with_style(&self, style: TerminalStyle) -> OuterViewPort<dyn TerminalView> { self.map_item( move |_idx, a| a.add_style_front(style) ) } fn with_fg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView> { self.with_style(TerminalStyle::fg_color(col)) } fn with_bg_color(&self, col: (u8, u8, u8)) -> OuterViewPort<dyn TerminalView> { self.with_style(TerminalStyle::bg_color(col)) } } //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> pub fn setup_edittree_hook(ctx: &Arc<RwLock<Context>>) { let char_type = Context::parse(&ctx, "Char"); let digit_type = Context::parse(&ctx, "<Digit Radix>"); let list_type = Context::parse(&ctx, "<List Item>"); let posint_bin_type = Context::parse(&ctx, "<PosInt 2 BigEndian>"); let posint_oct_type = Context::parse(&ctx, "<PosInt 8 BigEndian>"); let posint_dec_type = Context::parse(&ctx, "<PosInt 10 BigEndian>"); let posint_hex_type = Context::parse(&ctx, "<PosInt 16 BigEndian>"); let item_tyid = ctx.read().unwrap().get_var_typeid("Item").unwrap(); ctx.write().unwrap().meta_chars.push('\n'); //ctx.write().unwrap().meta_chars.push(','); //ctx.write().unwrap().meta_chars.push('\"'); //ctx.write().unwrap().meta_chars.push('}'); // Define a hook which is executed when a new editTree of type `t` is created. // this will setup the display and navigation elements of the editor. // It provides the necessary bridge to the rendering- & input-backend. ctx.write().unwrap().set_edittree_hook( Arc::new( move |et: &mut nested::edit_tree::EditTree, t: laddertypes::TypeTerm| { if let Ok(σ) = laddertypes::unify(&t, &char_type.clone()) { *et = crate::editors::edittree_make_char_view(et.clone()); } else if let Ok(σ) = laddertypes::unify(&t, &digit_type) { *et = crate::editors::edittree_make_digit_view(et.clone()); } else if let Ok(σ) = laddertypes::unify(&t, &posint_bin_type) { crate::editors::list::PTYListStyle::for_node( &mut *et, ("0b", "", "")); crate::editors::list::PTYListController::for_node( &mut *et, None, None ); } else if let Ok(σ) = laddertypes::unify(&t, &posint_oct_type) { crate::editors::list::PTYListStyle::for_node( &mut *et, ("0o", "", "")); crate::editors::list::PTYListController::for_node( &mut *et, None, None ); } else if let Ok(σ) = laddertypes::unify(&t, &posint_dec_type) { crate::editors::list::PTYListStyle::for_node( &mut *et, ("0d", "", "")); crate::editors::list::PTYListController::for_node( &mut *et, None, None ); } else if let Ok(σ) = laddertypes::unify(&t, &posint_hex_type) { crate::editors::list::PTYListStyle::for_node( &mut *et, ("0x", "", "")); crate::editors::list::PTYListController::for_node( &mut *et, None, None ); } else if let Ok(σ) = laddertypes::unify(&t, &list_type) { let item_type = σ.get( &laddertypes::TypeID::Var(item_tyid) ).unwrap(); // choose style based on element type if *item_type == char_type { crate::editors::list::PTYListStyle::for_node( &mut *et, ("\"", "", "\"")); crate::editors::list::PTYListController::for_node( &mut *et, None, Some('\"') ); } else { crate::editors::list::PTYListStyle::for_node( &mut *et, ("{", ", ", "}")); crate::editors::list::PTYListController::for_node( &mut *et, Some(','), Some('}') ); } //*et = nested_tty::editors::edittree_make_list_edit(et.clone()); } } ) ); }