further refactor pty-list, node morphisms, commander
This commit is contained in:
parent
2bdea3e2a3
commit
cf313727a6
15 changed files with 468 additions and 349 deletions
|
@ -9,7 +9,8 @@ use std::sync::{Arc, RwLock};
|
|||
use crate::{
|
||||
type_system::ReprTree
|
||||
};
|
||||
use r3vi::view::singleton::*;
|
||||
|
||||
//use r3vi::view::singleton::*;
|
||||
|
||||
pub trait ObjCommander {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>);
|
||||
|
@ -20,12 +21,22 @@ impl<C: Commander> ObjCommander for C
|
|||
where C::Cmd: 'static
|
||||
{
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
|
||||
/*
|
||||
self.send_cmd(
|
||||
&cmd_obj.read().unwrap()
|
||||
.get_port::<dyn SingletonView<Item = C::Cmd>>().unwrap()
|
||||
.get_view().unwrap()
|
||||
.get()
|
||||
);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Send + Sync> Commander for r3vi::buffer::vec::VecBuffer<T> {
|
||||
type Cmd = r3vi::buffer::vec::VecDiff<T>;
|
||||
|
||||
fn send_cmd(&mut self, cmd: &Self::Cmd) {
|
||||
self.apply_diff(cmd.clone());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ use {
|
|||
buffer::singleton::*
|
||||
},
|
||||
crate::{
|
||||
type_system::{Context},
|
||||
type_system::{Context, ReprTree},
|
||||
terminal::{TerminalAtom, TerminalEvent, TerminalStyle},
|
||||
tree::NestedNode,
|
||||
commander::Commander
|
||||
commander::{ObjCommander}
|
||||
},
|
||||
std::sync::Arc,
|
||||
std::sync::RwLock,
|
||||
|
@ -18,16 +18,33 @@ use {
|
|||
};
|
||||
|
||||
pub struct CharEditor {
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
data: SingletonBuffer<Option<char>>
|
||||
}
|
||||
|
||||
impl Commander for CharEditor {
|
||||
type Cmd = TerminalEvent;
|
||||
impl ObjCommander for CharEditor {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
|
||||
let ctx = self.ctx.read().unwrap();
|
||||
|
||||
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||
let cmd_obj = cmd_obj.read().unwrap();
|
||||
let cmd_type = cmd_obj.get_type().clone();
|
||||
|
||||
let char_type = ctx.type_term_from_str("( Char )").unwrap();
|
||||
let term_event_type = ctx.type_term_from_str("( TerminalEvent )").unwrap();
|
||||
|
||||
if cmd_type == char_type {
|
||||
if let Some(cmd_view) = cmd_obj.get_view::<dyn SingletonView<Item = char>>() {
|
||||
let value = cmd_view.get();
|
||||
self.data.set(Some(value));
|
||||
}
|
||||
}
|
||||
/*
|
||||
if cmd_type == term_event_type {
|
||||
if let Some(te_view) = cmd_obj.get_view::<dyn SingletonView<Item = TerminalEvent>>() {
|
||||
let event = te_view.get();
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
self.data.set(Some(*c));
|
||||
self.data.set(Some(c));
|
||||
}
|
||||
|
||||
TerminalEvent::Input(Event::Key(Key::Backspace))
|
||||
|
@ -39,10 +56,14 @@ impl Commander for CharEditor {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
impl CharEditor {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>) -> Self {
|
||||
CharEditor {
|
||||
ctx,
|
||||
data: SingletonBuffer::new(None)
|
||||
}
|
||||
}
|
||||
|
@ -55,11 +76,19 @@ impl CharEditor {
|
|||
self.get_port().get_view().unwrap().get().unwrap_or('?')
|
||||
}
|
||||
|
||||
pub fn new_node(ctx: &Arc<RwLock<Context>>) -> NestedNode {
|
||||
pub fn new_node(ctx0: Arc<RwLock<Context>>) -> NestedNode {
|
||||
let data = SingletonBuffer::new(None);
|
||||
|
||||
NestedNode::new()
|
||||
.set_ctx(ctx.clone())
|
||||
let ctx = ctx0.clone();
|
||||
|
||||
NestedNode::new(0)
|
||||
.set_ctx(ctx0.clone())
|
||||
.set_data(
|
||||
ReprTree::new_leaf(
|
||||
ctx0.read().unwrap().type_term_from_str("( Char )").unwrap(),
|
||||
data.get_port().into()
|
||||
)
|
||||
)
|
||||
.set_view(data
|
||||
.get_port()
|
||||
.map(move |c| {
|
||||
|
@ -71,7 +100,7 @@ impl CharEditor {
|
|||
.to_grid()
|
||||
)
|
||||
.set_cmd(
|
||||
Arc::new(RwLock::new(CharEditor{ data }))
|
||||
Arc::new(RwLock::new(CharEditor{ ctx, data }))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use {
|
|||
},
|
||||
crate::{
|
||||
type_system::{Context, TypeTerm, ReprTree},
|
||||
editors::list::{PTYListEditor, ListStyle},
|
||||
editors::list::{PTYListEditor},
|
||||
terminal::{
|
||||
TerminalAtom, TerminalEvent, TerminalStyle, make_label
|
||||
},
|
||||
|
@ -76,13 +76,13 @@ impl DigitEditor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
pub fn into_node(self, depth: usize) -> NestedNode {
|
||||
let data = self.get_data();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
let mut ed = editor.write().unwrap();
|
||||
let r = ed.radix;
|
||||
|
||||
NestedNode::new()
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ed.ctx.clone())
|
||||
.set_cmd(editor.clone())
|
||||
.set_data(data)
|
||||
|
@ -140,7 +140,7 @@ pub struct PosIntEditor {
|
|||
|
||||
impl PosIntEditor {
|
||||
pub fn new(ctx: Arc<RwLock<Context>>, radix: u32) -> Self {
|
||||
let mut node = PTYListEditor::new(
|
||||
let mut editor = PTYListEditor::new(
|
||||
ctx.clone(),
|
||||
TypeTerm::Type {
|
||||
id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
|
||||
|
@ -148,12 +148,19 @@ impl PosIntEditor {
|
|||
TypeTerm::Num(radix as i64)
|
||||
]
|
||||
},
|
||||
match radix {
|
||||
16 => ListStyle::Hex,
|
||||
_ => ListStyle::Plain
|
||||
},
|
||||
None,
|
||||
0
|
||||
).into_node();
|
||||
);
|
||||
|
||||
let view = editor.pty_view((
|
||||
match radix {
|
||||
2 => "0d".into(),
|
||||
16 => "0x".into(),
|
||||
_ => "".into()
|
||||
},
|
||||
"".into(),
|
||||
"".into()));
|
||||
let mut node = editor.into_node().set_view(view);
|
||||
|
||||
// Set Type
|
||||
let data = node.data.clone().unwrap();
|
||||
|
|
|
@ -97,6 +97,37 @@ impl ListEditor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn into_node(self, depth: usize) -> NestedNode {
|
||||
let data = self.get_data();
|
||||
let ctx = self.ctx.clone();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
.set_data(data)
|
||||
.set_editor(editor.clone())
|
||||
.set_nav(editor.clone())
|
||||
// .set_cmd(editor.clone())
|
||||
}
|
||||
|
||||
pub fn new_node(
|
||||
node: NestedNode,
|
||||
item_type: TypeTerm
|
||||
) -> NestedNode {
|
||||
let ctx = node.ctx.clone().unwrap();
|
||||
|
||||
let editor = ListEditor::new(
|
||||
ctx.clone(),
|
||||
item_type,
|
||||
);
|
||||
let data = editor.get_data();
|
||||
let editor = Arc::new(RwLock::new(editor));
|
||||
|
||||
node.set_data(data)
|
||||
.set_editor(editor.clone())
|
||||
.set_nav(editor.clone())
|
||||
}
|
||||
|
||||
pub fn get_item_type(&self) -> TypeTerm {
|
||||
self.typ.clone()
|
||||
}
|
||||
|
@ -108,17 +139,6 @@ impl ListEditor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
let data = self.get_data();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
|
||||
NestedNode::new()
|
||||
.set_data(data)
|
||||
.set_editor(editor.clone())
|
||||
.set_nav(editor.clone())
|
||||
// .set_cmd(editor.clone())
|
||||
}
|
||||
|
||||
pub fn get_cursor_port(&self) -> OuterViewPort<dyn SingletonView<Item = ListCursor>> {
|
||||
self.cursor.get_port()
|
||||
}
|
||||
|
|
|
@ -10,6 +10,6 @@ pub use {
|
|||
cursor::{ListCursor, ListCursorMode},
|
||||
editor::ListEditor,
|
||||
segment::{ListSegment, ListSegmentSequence},
|
||||
pty_editor::{ListStyle, PTYListEditor}
|
||||
pty_editor::{PTYListEditor}
|
||||
};
|
||||
|
||||
|
|
|
@ -14,14 +14,13 @@ use {
|
|||
editor::ListEditor
|
||||
},
|
||||
terminal::{
|
||||
TerminalEditor, TerminalEvent,
|
||||
TerminalEvent,
|
||||
TerminalView,
|
||||
make_label
|
||||
},
|
||||
tree::{TreeCursor, TreeNav},
|
||||
diagnostics::{Diagnostics},
|
||||
tree::NestedNode,
|
||||
commander::Commander,
|
||||
PtySegment
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
|
@ -30,92 +29,9 @@ use {
|
|||
|
||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ListStyle {
|
||||
Plain,
|
||||
HorizontalSexpr,
|
||||
VerticalSexpr,
|
||||
DoubleQuote,
|
||||
Tuple,
|
||||
EnumSet,
|
||||
Path,
|
||||
Hex
|
||||
}
|
||||
|
||||
pub fn list_style_from_type(
|
||||
ctx: &Arc<RwLock<Context>>,
|
||||
typ: &TypeTerm
|
||||
) -> Option<ListStyle> {
|
||||
let ctx = ctx.read().unwrap();
|
||||
|
||||
match typ {
|
||||
TypeTerm::Type {
|
||||
id, args
|
||||
} => {
|
||||
if *id == ctx.get_typeid("List").unwrap() {
|
||||
Some(ListStyle::HorizontalSexpr)
|
||||
} else if *id == ctx.get_typeid("String").unwrap() {
|
||||
Some(ListStyle::DoubleQuote)
|
||||
} else if *id == ctx.get_typeid("Symbol").unwrap() {
|
||||
Some(ListStyle::Plain)
|
||||
} else if *id == ctx.get_typeid("PathSegment").unwrap() {
|
||||
Some(ListStyle::Plain)
|
||||
} else if *id == ctx.get_typeid("Path").unwrap() {
|
||||
Some(ListStyle::Path)
|
||||
} else if *id == ctx.get_typeid("PosInt").unwrap() {
|
||||
if args.len() > 0 {
|
||||
match args[0] {
|
||||
TypeTerm::Num(radix) => {
|
||||
match radix {
|
||||
16 => Some(ListStyle::Hex),
|
||||
_ => Some(ListStyle::Plain)
|
||||
}
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
impl ListStyle {
|
||||
fn get_split_char(&self) -> Option<char> {
|
||||
match self {
|
||||
ListStyle::Plain => None,
|
||||
ListStyle::DoubleQuote => None,
|
||||
ListStyle::HorizontalSexpr => Some(' '),
|
||||
ListStyle::VerticalSexpr => Some('\n'),
|
||||
ListStyle::Tuple => Some(','),
|
||||
ListStyle::EnumSet => Some(','),
|
||||
ListStyle::Path => Some('/'),
|
||||
ListStyle::Hex => None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_wrapper(&self) -> (&str, &str) {
|
||||
match self {
|
||||
ListStyle::Plain => ("", ""),
|
||||
ListStyle::HorizontalSexpr => ("(", ")"),
|
||||
ListStyle::VerticalSexpr => ("(", ")"),
|
||||
ListStyle::DoubleQuote => ("\"", "\""),
|
||||
ListStyle::Tuple => ("(", ")"),
|
||||
ListStyle::EnumSet => ("{", "}"),
|
||||
ListStyle::Path => ("<", ">"),
|
||||
ListStyle::Hex => ("0x", "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PTYListEditor {
|
||||
pub editor: Arc<RwLock<ListEditor>>,
|
||||
style: ListStyle,
|
||||
split_char: Option<char>,
|
||||
depth: usize
|
||||
}
|
||||
|
||||
|
@ -125,20 +41,23 @@ impl PTYListEditor {
|
|||
pub fn new(
|
||||
ctx: Arc<RwLock<Context>>,
|
||||
typ: TypeTerm,
|
||||
style: ListStyle,
|
||||
split_char: Option<char>,
|
||||
depth: usize
|
||||
) -> Self {
|
||||
Self::from_editor(
|
||||
Arc::new(RwLock::new(ListEditor::new(ctx, typ))), style, depth)
|
||||
Arc::new(RwLock::new(ListEditor::new(ctx, typ))),
|
||||
split_char,
|
||||
depth
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_editor(
|
||||
editor: Arc<RwLock<ListEditor>>,
|
||||
style: ListStyle,
|
||||
split_char: Option<char>,
|
||||
depth: usize
|
||||
) -> Self {
|
||||
PTYListEditor {
|
||||
style,
|
||||
split_char,
|
||||
depth,
|
||||
editor,
|
||||
}
|
||||
|
@ -154,7 +73,10 @@ impl PTYListEditor {
|
|||
se.get_view().map(move |segment| segment.pty_view())
|
||||
}
|
||||
|
||||
pub fn pty_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
pub fn pty_view(
|
||||
&self,
|
||||
display_style: (&str, &str, &str),
|
||||
) -> OuterViewPort<dyn TerminalView> {
|
||||
let editor = self.editor.read().unwrap();
|
||||
|
||||
let seg_seq = ListSegmentSequence::new(
|
||||
|
@ -167,26 +89,25 @@ impl PTYListEditor {
|
|||
seg_seq
|
||||
.get_view()
|
||||
.map(move |segment| segment.pty_view())
|
||||
.separate(make_label(&if let Some(c) = self.style.get_split_char() { format!("{}", c) } else { "".to_string() } ))
|
||||
.wrap(make_label(self.style.get_wrapper().0), make_label(self.style.get_wrapper().1))
|
||||
.separate(make_label(display_style.1))
|
||||
.wrap(make_label(display_style.0), make_label(display_style.2))
|
||||
.to_grid_horizontal()
|
||||
.flatten()
|
||||
}
|
||||
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
let view = self.pty_view();
|
||||
let depth = self.depth;
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
|
||||
let ed = editor.read().unwrap();
|
||||
let edd = ed.editor.read().unwrap();
|
||||
|
||||
NestedNode::new()
|
||||
NestedNode::new(depth)
|
||||
.set_data(edd.get_data())
|
||||
.set_cmd(editor.clone())
|
||||
.set_editor(ed.editor.clone())
|
||||
.set_nav(ed.editor.clone())
|
||||
.set_ctx(edd.ctx.clone())
|
||||
.set_view(view)
|
||||
.set_diag(
|
||||
edd.get_data_port()
|
||||
.enumerate()
|
||||
|
@ -224,16 +145,18 @@ impl PTYListEditor {
|
|||
self.depth = depth;
|
||||
}
|
||||
|
||||
pub fn split(e: &mut ListEditor, depth: usize) {
|
||||
pub fn split(e: &mut ListEditor) {
|
||||
let cur = e.get_cursor();
|
||||
if let Some(item) = e.get_item_mut() {
|
||||
let depth = item.depth;
|
||||
|
||||
if let Some(head_editor) = item.editor.clone() {
|
||||
|
||||
let head = head_editor.downcast::<RwLock<ListEditor>>().unwrap();
|
||||
let mut head = head.write().unwrap();
|
||||
|
||||
if cur.tree_addr.len() > 2 {
|
||||
PTYListEditor::split(&mut head, depth+1);
|
||||
PTYListEditor::split(&mut head);
|
||||
}
|
||||
|
||||
let mut tail = head.split();
|
||||
|
@ -259,27 +182,11 @@ impl PTYListEditor {
|
|||
None
|
||||
};
|
||||
|
||||
let style =
|
||||
if let Some(item_type) = &item_type {
|
||||
list_style_from_type(&tail.ctx, item_type)
|
||||
.unwrap_or(
|
||||
ListStyle::HorizontalSexpr
|
||||
)
|
||||
} else {
|
||||
ListStyle::HorizontalSexpr
|
||||
};
|
||||
|
||||
let mut tail_node = PTYListEditor::from_editor(
|
||||
Arc::new(RwLock::new(tail)),
|
||||
style,
|
||||
depth+1
|
||||
).into_node();
|
||||
let mut tail_node = tail.into_node(depth);
|
||||
tail_node = tail_node.set_ctx(item.ctx.clone().unwrap());
|
||||
|
||||
if let Some(item_type) = item_type {
|
||||
tail_node.data = Some(ReprTree::ascend(
|
||||
&tail_node.data.unwrap(),
|
||||
item_type.clone()
|
||||
));
|
||||
tail_node = tail_node.morph(item_type);
|
||||
}
|
||||
|
||||
e.insert(
|
||||
|
@ -328,11 +235,26 @@ impl PTYListEditor {
|
|||
}
|
||||
}
|
||||
|
||||
impl Commander for PTYListEditor {
|
||||
type Cmd = TerminalEvent;
|
||||
use r3vi::view::singleton::SingletonView;
|
||||
use crate::commander::ObjCommander;
|
||||
|
||||
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||
impl ObjCommander for PTYListEditor {
|
||||
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
|
||||
let mut e = self.editor.write().unwrap();
|
||||
let cur = e.cursor.get();
|
||||
|
||||
let ctx = e.ctx.clone();
|
||||
let ctx = ctx.read().unwrap();
|
||||
|
||||
let co = cmd_obj.read().unwrap();
|
||||
let cmd_type = co.get_type().clone();
|
||||
let term_event_type = ctx.type_term_from_str("( TerminalEvent )").unwrap();
|
||||
let char_type = ctx.type_term_from_str("( Char )").unwrap();
|
||||
|
||||
if cmd_type == term_event_type {
|
||||
if let Some(te_view) = co.get_view::<dyn SingletonView<Item = TerminalEvent>>() {
|
||||
drop(co);
|
||||
let event = te_view.get();
|
||||
|
||||
match event {
|
||||
TerminalEvent::Input(Event::Key(Key::Char('\t')))
|
||||
|
@ -341,7 +263,6 @@ impl Commander for PTYListEditor {
|
|||
e.set_leaf_mode(ListCursorMode::Select);
|
||||
}
|
||||
_ => {
|
||||
let cur = e.cursor.get();
|
||||
if let Some(idx) = cur.idx {
|
||||
match cur.mode {
|
||||
ListCursorMode::Insert => {
|
||||
|
@ -355,7 +276,7 @@ impl Commander for PTYListEditor {
|
|||
_ => {
|
||||
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
|
||||
new_edit.goto(TreeCursor::home());
|
||||
new_edit.handle_terminal_event(event);
|
||||
new_edit.send_cmd_obj(cmd_obj);
|
||||
|
||||
e.insert(new_edit);
|
||||
}
|
||||
|
@ -375,14 +296,16 @@ impl Commander for PTYListEditor {
|
|||
)
|
||||
{
|
||||
PTYListEditor::join_pxev(&mut e, idx, &item);
|
||||
/*
|
||||
|
||||
/* Optional: recursive joining
|
||||
|
||||
if item_cur.tree_addr.len() > 1 {
|
||||
let mut item = e.get_item_mut().unwrap();
|
||||
item.handle_terminal_event(event);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
item.handle_terminal_event(event);
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||
|
@ -396,30 +319,32 @@ impl Commander for PTYListEditor {
|
|||
)
|
||||
{
|
||||
PTYListEditor::join_nexd(&mut e, next_idx, &item);
|
||||
/*
|
||||
|
||||
/* Optional: recursive joining
|
||||
|
||||
if item_cur.tree_addr.len() > 1 {
|
||||
let mut item = e.get_item_mut().unwrap();
|
||||
item.handle_terminal_event(event);
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
item.handle_terminal_event(event);
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
|
||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||
if Some(*c) == self.style.get_split_char() {
|
||||
PTYListEditor::split(&mut e, self.depth);
|
||||
if Some(c) == self.split_char {
|
||||
PTYListEditor::split(&mut e);
|
||||
} else {
|
||||
item.handle_terminal_event(event);
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
item.handle_terminal_event(event);
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
item.handle_terminal_event(event);
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -428,4 +353,36 @@ impl Commander for PTYListEditor {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if cmd_type == char_type && cur.mode == ListCursorMode::Select {
|
||||
if let Some(cmd_view) = co.get_view::<dyn SingletonView<Item = char>>() {
|
||||
drop(co);
|
||||
let c = cmd_view.get();
|
||||
|
||||
if Some(c) == self.split_char {
|
||||
PTYListEditor::split(&mut e);
|
||||
} else {
|
||||
if let Some(mut item) = e.get_item_mut() {
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
drop(co);
|
||||
|
||||
match cur.mode {
|
||||
ListCursorMode::Insert => {
|
||||
let mut new_edit = Context::make_node(&e.ctx, e.typ.clone(), self.depth).unwrap();
|
||||
new_edit.goto(TreeCursor::home());
|
||||
new_edit.send_cmd_obj(cmd_obj);
|
||||
|
||||
e.insert(new_edit);
|
||||
},
|
||||
ListCursorMode::Select => {
|
||||
if let Some(mut item) = e.get_item_mut() {
|
||||
item.send_cmd_obj(cmd_obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ impl SumEditor {
|
|||
pub fn into_node(self, ctx: Arc<RwLock<Context>>) -> NestedNode {
|
||||
let view = self.pty_view();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
NestedNode::new()
|
||||
NestedNode::new(0)
|
||||
.set_ctx(ctx)
|
||||
.set_view(view)
|
||||
.set_cmd(editor.clone())
|
||||
|
|
|
@ -3,6 +3,7 @@ pub mod atom;
|
|||
pub mod compositor;
|
||||
pub mod style;
|
||||
pub mod terminal;
|
||||
pub mod widgets;
|
||||
|
||||
pub use {
|
||||
atom::TerminalAtom,
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
use {
|
||||
cgmath::{Point2, Vector2},
|
||||
nested::{
|
||||
core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View},
|
||||
index::{IndexArea, IndexView},
|
||||
r3vi::{
|
||||
view::{
|
||||
InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View,
|
||||
index::*
|
||||
},
|
||||
},
|
||||
crate::{
|
||||
terminal::{TerminalAtom, TerminalView},
|
||||
},
|
||||
std::sync::{Arc, RwLock},
|
||||
|
|
3
nested/src/terminal/widgets/mod.rs
Normal file
3
nested/src/terminal/widgets/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
pub mod ascii_box;
|
||||
|
|
@ -10,7 +10,7 @@ use {
|
|||
buffer::{singleton::*}
|
||||
},
|
||||
crate::{
|
||||
type_system::{ReprTree, Context},
|
||||
type_system::{ReprTree, Context, TypeTerm},
|
||||
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
|
||||
diagnostics::{Diagnostics, Message},
|
||||
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||
|
@ -21,6 +21,9 @@ use {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct NestedNode {
|
||||
/// depth
|
||||
pub depth: usize,
|
||||
|
||||
/// context
|
||||
pub ctx: Option<Arc<RwLock<Context>>>,
|
||||
|
||||
|
@ -145,8 +148,9 @@ impl Diagnostics for NestedNode {
|
|||
}
|
||||
|
||||
impl NestedNode {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(depth: usize) -> Self {
|
||||
NestedNode {
|
||||
depth,
|
||||
ctx: None,
|
||||
data: None,
|
||||
editor: None,
|
||||
|
@ -199,5 +203,9 @@ impl NestedNode {
|
|||
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||
self.view.clone().unwrap_or(ViewPort::new().into_outer())
|
||||
}
|
||||
|
||||
pub fn morph(self, ty: TypeTerm) -> NestedNode {
|
||||
Context::morph_node(self, ty)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ pub struct Context {
|
|||
morphisms: HashMap<
|
||||
MorphismTypePattern,
|
||||
Arc<
|
||||
dyn Fn( NestedNode, TypeTerm, usize ) -> Option<NestedNode>
|
||||
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
|
||||
+ Send + Sync
|
||||
>
|
||||
>,
|
||||
|
@ -158,8 +158,9 @@ impl Context {
|
|||
dst_tyid: tyid
|
||||
};
|
||||
|
||||
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type, depth| {
|
||||
self.add_morphism(morphism_pattern, Arc::new(move |node, dst_type| {
|
||||
let ctx = node.ctx.clone().unwrap();
|
||||
let depth = node.depth;
|
||||
mk_editor(ctx, dst_type, depth)
|
||||
}));
|
||||
}
|
||||
|
@ -168,15 +169,14 @@ impl Context {
|
|||
&mut self,
|
||||
morph_type_pattern: MorphismTypePattern,
|
||||
morph_fn: Arc<
|
||||
dyn Fn( NestedNode, TypeTerm, usize ) -> Option<NestedNode>
|
||||
dyn Fn( NestedNode, TypeTerm ) -> Option<NestedNode>
|
||||
+ Send + Sync
|
||||
>
|
||||
) {
|
||||
self.morphisms.insert(morph_type_pattern, morph_fn);
|
||||
}
|
||||
|
||||
pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm, usize) -> Option<NestedNode> + Send + Sync>> {
|
||||
|
||||
pub fn get_morphism(&self, ty: MorphismType) -> Option<Arc<dyn Fn(NestedNode, TypeTerm) -> Option<NestedNode> + Send + Sync>> {
|
||||
let pattern = MorphismTypePattern::from(ty.clone());
|
||||
if let Some(morphism) = self.morphisms.get( &pattern ) {
|
||||
Some(morphism.clone())
|
||||
|
@ -193,10 +193,11 @@ impl Context {
|
|||
dst_type: type_term.clone()
|
||||
})?;
|
||||
|
||||
mk_node(NestedNode::new().set_ctx(ctx.clone()), type_term, depth)
|
||||
mk_node(NestedNode::new(depth).set_ctx(ctx.clone()), type_term)
|
||||
}
|
||||
|
||||
pub fn morph_node(ctx: Arc<RwLock<Self>>, mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
|
||||
pub fn morph_node(mut node: NestedNode, dst_type: TypeTerm) -> NestedNode {
|
||||
let ctx = node.ctx.clone().unwrap();
|
||||
let mut src_type = None;
|
||||
|
||||
if let Some(data) = node.data.clone() {
|
||||
|
@ -210,8 +211,9 @@ impl Context {
|
|||
}
|
||||
|
||||
let pattern = MorphismType { src_type, dst_type: dst_type.clone() }.into();
|
||||
if let Some(transform) = ctx.read().unwrap().get_morphism(pattern) {
|
||||
if let Some(new_node) = transform(node.clone(), dst_type, 0) {
|
||||
let ctx = ctx.read().unwrap();
|
||||
if let Some(transform) = ctx.get_morphism(pattern) {
|
||||
if let Some(new_node) = transform(node.clone(), dst_type) {
|
||||
new_node
|
||||
} else {
|
||||
node.clone()
|
||||
|
|
|
@ -20,7 +20,35 @@ use {
|
|||
pub fn init_mem_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||
let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
||||
|
||||
ctx.write().unwrap().add_typename("Vec".into());
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"Vec", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
|
||||
match ty {
|
||||
TypeTerm::Type {
|
||||
id: _, args
|
||||
} => {
|
||||
if args.len() > 0 {
|
||||
let mut buf = r3vi::buffer::vec::VecBuffer::<char>::new();
|
||||
let data = ReprTree::new_leaf(
|
||||
ctx.read().unwrap().type_term_from_str("( Char )").unwrap(),
|
||||
buf.get_port().into()
|
||||
);
|
||||
|
||||
Some(
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
.set_data(data)
|
||||
.set_editor(Arc::new(RwLock::new(buf)))
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx
|
||||
}
|
||||
|
@ -31,7 +59,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
ctx.write().unwrap().add_node_ctor(
|
||||
"Char", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, _depth: usize| {
|
||||
Some(CharEditor::new_node(&ctx))
|
||||
Some(CharEditor::new_node(ctx))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -46,14 +74,25 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
id: _, args
|
||||
} => {
|
||||
if args.len() > 0 {
|
||||
Some(
|
||||
PTYListEditor::new(
|
||||
|
||||
let editor = PTYListEditor::new(
|
||||
ctx,
|
||||
args[0].clone(),
|
||||
ListStyle::HorizontalSexpr,
|
||||
Some(','),
|
||||
depth + 1
|
||||
).into_node()
|
||||
);
|
||||
|
||||
let view = editor.pty_view(
|
||||
(
|
||||
"{".into(),
|
||||
", ".into(),
|
||||
"}".into()
|
||||
)
|
||||
);
|
||||
|
||||
Some(editor
|
||||
.into_node()
|
||||
.set_view(view))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -65,23 +104,24 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
);
|
||||
|
||||
ctx.write().unwrap().add_list_typename("Symbol".into());
|
||||
|
||||
let pattern = MorphismTypePattern {
|
||||
src_type: ctx.read().unwrap().type_term_from_str("( List Char )"),
|
||||
dst_tyid: ctx.read().unwrap().get_typeid("Symbol").unwrap()
|
||||
};
|
||||
|
||||
ctx.write().unwrap().add_morphism(pattern,
|
||||
Arc::new(
|
||||
|mut node, dst_type:_, depth| {
|
||||
|mut node, _dst_type:_| {
|
||||
let depth = node.depth;
|
||||
let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
|
||||
let pty_editor = PTYListEditor::from_editor(
|
||||
editor,
|
||||
ListStyle::Plain,
|
||||
None,
|
||||
depth
|
||||
);
|
||||
|
||||
node.view = Some(pty_editor.pty_view());
|
||||
node.view = Some(pty_editor.pty_view(
|
||||
("".into(), "".into(), "".into())
|
||||
));
|
||||
node.cmd = Some(Arc::new(RwLock::new(pty_editor)));
|
||||
Some(node)
|
||||
}
|
||||
|
@ -99,10 +139,10 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap())
|
||||
]
|
||||
},
|
||||
depth
|
||||
depth+1
|
||||
).unwrap();
|
||||
|
||||
node = Context::morph_node(ctx, node, dst_typ);
|
||||
node = node.morph(dst_typ);
|
||||
|
||||
Some(node)
|
||||
}
|
||||
|
@ -110,20 +150,47 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
);
|
||||
|
||||
ctx.write().unwrap().add_list_typename("String".into());
|
||||
let pattern = MorphismTypePattern {
|
||||
src_type: ctx.read().unwrap().type_term_from_str("( List Char )"),
|
||||
dst_tyid: ctx.read().unwrap().get_typeid("String").unwrap()
|
||||
};
|
||||
ctx.write().unwrap().add_morphism(pattern,
|
||||
Arc::new(
|
||||
|mut node, _dst_type:_| {
|
||||
let depth = node.depth;
|
||||
let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
|
||||
let pty_editor = PTYListEditor::from_editor(
|
||||
editor,
|
||||
None,
|
||||
depth
|
||||
);
|
||||
|
||||
node.view = Some(pty_editor.pty_view((
|
||||
"\"".into(),
|
||||
"".into(),
|
||||
"\"".into()
|
||||
)));
|
||||
node.cmd = Some(Arc::new(RwLock::new(pty_editor)));
|
||||
Some(node)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"String", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
let mut node = PTYListEditor::new(
|
||||
ctx.clone(),
|
||||
ctx.read().unwrap().type_term_from_str("( Char )").unwrap(),
|
||||
ListStyle::DoubleQuote,
|
||||
|ctx: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: usize| {
|
||||
let mut node = Context::make_node(
|
||||
&ctx,
|
||||
TypeTerm::Type {
|
||||
id: ctx.read().unwrap().get_typeid("List").unwrap(),
|
||||
args: vec![
|
||||
TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap())
|
||||
]
|
||||
},
|
||||
depth+1
|
||||
).into_node();
|
||||
).unwrap();
|
||||
|
||||
node.data = Some(ReprTree::ascend(
|
||||
&node.data.unwrap(),
|
||||
ctx.read().unwrap().type_term_from_str("( String )").unwrap()
|
||||
));
|
||||
node = node.morph(dst_typ);
|
||||
|
||||
Some(node)
|
||||
}
|
||||
|
@ -134,7 +201,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
ctx.write().unwrap().add_node_ctor(
|
||||
"TypeTerm", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
Some(TypeTermEditor::new(ctx, depth).into_node())
|
||||
Some(TypeTermEditor::new(ctx, depth).into_node(depth))
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -152,7 +219,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"Digit", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, depth: usize| {
|
||||
match ty {
|
||||
TypeTerm::Type {
|
||||
id: _, args
|
||||
|
@ -160,7 +227,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
if args.len() > 0 {
|
||||
match args[0] {
|
||||
TypeTerm::Num(radix) => {
|
||||
let node = DigitEditor::new(ctx.clone(), radix as u32).into_node();
|
||||
let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth);
|
||||
Some(
|
||||
node
|
||||
)
|
||||
|
@ -178,19 +245,39 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
);
|
||||
|
||||
ctx.write().unwrap().add_list_typename("PosInt".into());
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"PosInt", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
||||
match ty {
|
||||
let pattern = MorphismTypePattern {
|
||||
src_type: ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )"),
|
||||
dst_tyid: ctx.read().unwrap().get_typeid("PosInt").unwrap()
|
||||
};
|
||||
ctx.write().unwrap().add_morphism(pattern,
|
||||
Arc::new(
|
||||
|mut node, dst_type| {
|
||||
let depth = node.depth;
|
||||
let editor = node.editor.clone().unwrap().downcast::<RwLock<ListEditor>>().unwrap();
|
||||
|
||||
match dst_type {
|
||||
TypeTerm::Type {
|
||||
id: _, args
|
||||
} => {
|
||||
if args.len() > 0 {
|
||||
match args[0] {
|
||||
TypeTerm::Num(radix) => {
|
||||
Some(
|
||||
PosIntEditor::new(ctx.clone(), radix as u32).into_node()
|
||||
let pty_editor = PTYListEditor::from_editor(
|
||||
editor,
|
||||
Some(','),
|
||||
depth
|
||||
);
|
||||
|
||||
// todo: set data view
|
||||
node.view = Some(pty_editor.pty_view(
|
||||
(
|
||||
"{".into(),
|
||||
", ".into(),
|
||||
"}".into()
|
||||
)
|
||||
));
|
||||
node.cmd = Some(Arc::new(RwLock::new(pty_editor)));
|
||||
Some(node)
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
|
@ -204,6 +291,46 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
)
|
||||
);
|
||||
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"PosInt", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, dst_typ: TypeTerm, depth: usize| {
|
||||
match dst_typ.clone() {
|
||||
TypeTerm::Type {
|
||||
id: _, args
|
||||
} => {
|
||||
if args.len() > 0 {
|
||||
match args[0] {
|
||||
TypeTerm::Num(radix) => {
|
||||
|
||||
let mut node = Context::make_node(
|
||||
&ctx,
|
||||
TypeTerm::Type {
|
||||
id: ctx.read().unwrap().get_typeid("List").unwrap(),
|
||||
args: vec![
|
||||
TypeTerm::new(ctx.read().unwrap().get_typeid("Digit").unwrap())
|
||||
.num_arg(radix)
|
||||
.clone()
|
||||
]
|
||||
},
|
||||
depth+1
|
||||
).unwrap();
|
||||
|
||||
node = node.morph(dst_typ);
|
||||
|
||||
Some(node)
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx.write().unwrap().add_list_typename("RGB".into());
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"RGB", Arc::new(
|
||||
|
@ -230,7 +357,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
let diag = editor.get_msg_port();
|
||||
let editor = Arc::new(RwLock::new(editor));
|
||||
|
||||
let node = NestedNode::new()
|
||||
let node = NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
.set_cmd(editor.clone())
|
||||
.set_nav(editor.clone())
|
||||
|
@ -245,52 +372,3 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
|||
ctx
|
||||
}
|
||||
|
||||
pub fn init_os_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||
let ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
||||
|
||||
ctx.write().unwrap().add_list_typename("PathSegment".into());
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"PathSegment", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
let mut node = PTYListEditor::new(
|
||||
ctx.clone(),
|
||||
ctx.read().unwrap().type_term_from_str("( Char )").unwrap(),
|
||||
ListStyle::Plain,
|
||||
depth + 1
|
||||
).into_node();
|
||||
|
||||
node.data = Some(ReprTree::ascend(
|
||||
&node.data.unwrap(),
|
||||
ctx.read().unwrap().type_term_from_str("( PathSegment )").unwrap()
|
||||
));
|
||||
|
||||
Some(node)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx.write().unwrap().add_list_typename("Path".into());
|
||||
ctx.write().unwrap().add_node_ctor(
|
||||
"Path", Arc::new(
|
||||
|ctx: Arc<RwLock<Context>>, _ty: TypeTerm, depth: usize| {
|
||||
let mut node = PTYListEditor::new(
|
||||
ctx.clone(),
|
||||
ctx.read().unwrap().type_term_from_str("( PathSegment )").unwrap(),
|
||||
ListStyle::Path,
|
||||
depth + 1
|
||||
).into_node();
|
||||
|
||||
node.data = Some(ReprTree::ascend(
|
||||
&node.data.unwrap(),
|
||||
ctx.read().unwrap().type_term_from_str("( Path )").unwrap()
|
||||
));
|
||||
|
||||
Some(node)
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
ctx
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -201,7 +201,6 @@ impl ReprTree {
|
|||
_morphism_constructors: &HashMap<MorphismType, Box<dyn Fn(Object) -> Object>>,
|
||||
) {
|
||||
// todo
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -44,13 +44,13 @@ impl TypeTermEditor {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn into_node(self) -> NestedNode {
|
||||
pub fn into_node(self, depth: usize) -> NestedNode {
|
||||
let ctx = self.ctx.clone();
|
||||
let sum_edit = self.sum_edit.clone();
|
||||
let view = sum_edit.read().unwrap().pty_view();
|
||||
let editor = Arc::new(RwLock::new(self));
|
||||
|
||||
NestedNode::new()
|
||||
NestedNode::new(depth)
|
||||
.set_ctx(ctx)
|
||||
.set_nav(sum_edit)
|
||||
.set_cmd(editor.clone())
|
||||
|
|
Loading…
Reference in a new issue