begin refactor to node-struct and obj-commmander
This commit is contained in:
parent
bcbeb2298a
commit
35498a2fa7
19 changed files with 661 additions and 207 deletions
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
core::{OuterViewPort, ViewPort},
|
core::{OuterViewPort, ViewPort, Context},
|
||||||
list::{ListEditor},
|
list::{ListEditor},
|
||||||
sequence::{SequenceView, SequenceViewExt},
|
sequence::{SequenceView, SequenceViewExt},
|
||||||
singleton::{SingletonBuffer, SingletonView},
|
singleton::{SingletonBuffer, SingletonView},
|
||||||
|
@ -10,7 +10,7 @@ use {
|
||||||
},
|
},
|
||||||
tree::{TreeCursor, TreeNav, TreeNavResult},
|
tree::{TreeCursor, TreeNav, TreeNavResult},
|
||||||
diagnostics::Diagnostics,
|
diagnostics::Diagnostics,
|
||||||
Nested
|
Nested, tree::NestedNode, Commander
|
||||||
},
|
},
|
||||||
std::sync::Arc,
|
std::sync::Arc,
|
||||||
std::sync::RwLock,
|
std::sync::RwLock,
|
||||||
|
@ -22,6 +22,23 @@ pub struct CharEditor {
|
||||||
data: SingletonBuffer<Option<char>>
|
data: SingletonBuffer<Option<char>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Commander for CharEditor {
|
||||||
|
type Cmd = TerminalEvent;
|
||||||
|
|
||||||
|
fn send_cmd(&mut self, event: &TerminalEvent) {
|
||||||
|
match event {
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||||
|
self.data.set(Some(*c));
|
||||||
|
}
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Backspace))
|
||||||
|
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
||||||
|
self.data.set(None);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CharEditor {
|
impl CharEditor {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
CharEditor {
|
CharEditor {
|
||||||
|
@ -36,40 +53,32 @@ impl CharEditor {
|
||||||
pub fn get(&self) -> char {
|
pub fn get(&self) -> char {
|
||||||
self.get_port().get_view().unwrap().get().unwrap_or('?')
|
self.get_port().get_view().unwrap().get().unwrap_or('?')
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl TreeNav for CharEditor {}
|
pub fn new_node(ctx: &Arc<RwLock<Context>>) -> NestedNode {
|
||||||
impl Diagnostics for CharEditor {}
|
let data = SingletonBuffer::new(None);
|
||||||
|
|
||||||
impl TerminalEditor for CharEditor {
|
NestedNode::new()
|
||||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
.set_ctx(ctx.clone())
|
||||||
self.data
|
.set_view(data
|
||||||
.get_port()
|
.get_port()
|
||||||
.map(move |c| {
|
.map(move |c| {
|
||||||
TerminalAtom::from(
|
match c {
|
||||||
c.unwrap_or('?')
|
Some(c) => TerminalAtom::from(c),
|
||||||
)
|
None => TerminalAtom::new('*', TerminalStyle::fg_color((255,0,0)))
|
||||||
})
|
}
|
||||||
.to_grid()
|
})
|
||||||
}
|
.to_grid()
|
||||||
|
)
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
.with_cmd(
|
||||||
match event {
|
Arc::new(RwLock::new(CharEditor{ data }))
|
||||||
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
|
)
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
|
||||||
self.data.set(Some(*c));
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
}
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Backspace))
|
|
||||||
| TerminalEvent::Input(Event::Key(Key::Delete)) => {
|
|
||||||
self.data.set(None);
|
|
||||||
TerminalEditorResult::Exit
|
|
||||||
}
|
|
||||||
_ => TerminalEditorResult::Continue,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Nested for CharEditor {}
|
use crate::StringGen;
|
||||||
|
impl StringGen for CharEditor {
|
||||||
|
fn get_string(&self) -> String {
|
||||||
|
String::from(self.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ impl ReprTree {
|
||||||
Arc::new(RwLock::new(tree))
|
Arc::new(RwLock::new(tree))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_branch(&mut self, type_tag: TypeTerm, repr: Arc<RwLock<ReprTree>>) {
|
pub fn insert_branch(&mut self, repr: Arc<RwLock<ReprTree>>) {
|
||||||
self.branches.insert(type_tag, repr);
|
self.branches.insert(repr.clone().read().unwrap().type_tag.clone(), repr.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_leaf(
|
pub fn insert_leaf(
|
||||||
|
@ -51,7 +51,7 @@ impl ReprTree {
|
||||||
} else {
|
} else {
|
||||||
let mut next_repr = ReprTree::new(type_term.clone());
|
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(Arc::new(RwLock::new(next_repr)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.port = Some(port);
|
self.port = Some(port);
|
||||||
|
@ -73,6 +73,15 @@ impl ReprTree {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_view<V: View + ?Sized + 'static>(&self) -> Option<Arc<V>>
|
||||||
|
where
|
||||||
|
V::Msg: Clone,
|
||||||
|
{
|
||||||
|
self.get_port::<V>()?
|
||||||
|
.get_view()
|
||||||
|
}
|
||||||
|
|
||||||
|
// descend
|
||||||
pub fn downcast(&self, dst_type: &TypeTerm) -> Option<Arc<RwLock<ReprTree>>> {
|
pub fn downcast(&self, dst_type: &TypeTerm) -> Option<Arc<RwLock<ReprTree>>> {
|
||||||
self.branches.get(dst_type).cloned()
|
self.branches.get(dst_type).cloned()
|
||||||
}
|
}
|
||||||
|
@ -84,6 +93,13 @@ impl ReprTree {
|
||||||
|s, t| s?.read().unwrap().downcast(&t))
|
|s, t| s?.read().unwrap().downcast(&t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ascend
|
||||||
|
pub fn upcast(rt: &Arc<RwLock<Self>>, type_term: TypeTerm) -> Arc<RwLock<ReprTree>> {
|
||||||
|
let mut n = Self::new(type_term);
|
||||||
|
n.insert_branch(rt.clone());
|
||||||
|
Arc::new(RwLock::new(n))
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
pub fn add_iso_repr(
|
pub fn add_iso_repr(
|
||||||
&self,
|
&self,
|
||||||
|
@ -268,6 +284,7 @@ impl Context {
|
||||||
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
|
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
|
||||||
self.type_dict.read().unwrap().type_term_from_str(&tn)
|
self.type_dict.read().unwrap().type_term_from_str(&tn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
|
pub fn type_term_to_str(&self, t: &TypeTerm) -> String {
|
||||||
self.type_dict.read().unwrap().type_term_to_str(&t)
|
self.type_dict.read().unwrap().type_term_to_str(&t)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort},
|
core::{InnerViewPort, Observer, ObserverBroadcast, OuterViewPort, View, ViewPort, port::UpdateTask},
|
||||||
grid::{GridView, GridWindowIterator},
|
grid::{GridView, GridWindowIterator},
|
||||||
index::{IndexArea, IndexView},
|
index::{IndexArea, IndexView},
|
||||||
projection::ProjectionHelper,
|
projection::ProjectionHelper,
|
||||||
|
@ -113,15 +113,21 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(chunk) = s.chunks.get(&chunk_idx) {
|
if let Some(chunk) = s.chunks.get(&chunk_idx) {
|
||||||
s.cast.notify(&area.map(|pt| pt + chunk.offset));
|
s.cast.notify(&area.map(|pt| pt + chunk.offset));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(chunk) = self.chunks.get_mut(&chunk_idx) {
|
if let Some(chunk) = self.chunks.get_mut(&chunk_idx) {
|
||||||
chunk.view = view;
|
chunk.view = view;
|
||||||
self.cast
|
|
||||||
.notify(&chunk.view.area().map(|pt| pt + chunk.offset));
|
let old_limit = chunk.limit;
|
||||||
|
let new_limit = *chunk.view.area().range().end();
|
||||||
|
|
||||||
|
self.cast.notify(
|
||||||
|
&IndexArea::Range(
|
||||||
|
Point2::new(chunk.offset.x, chunk.offset.y) ..= Point2::new(chunk.offset.x + max(old_limit.x, new_limit.x), chunk.offset.y + max(old_limit.y, new_limit.y) )));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
self.chunks.insert(
|
self.chunks.insert(
|
||||||
chunk_idx,
|
chunk_idx,
|
||||||
|
@ -132,7 +138,7 @@ where
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.update_all_offsets();
|
self.update_all_offsets();
|
||||||
} else {
|
} else {
|
||||||
self.proj_helper.remove_arg(&chunk_idx);
|
self.proj_helper.remove_arg(&chunk_idx);
|
||||||
|
@ -168,15 +174,18 @@ where
|
||||||
|
|
||||||
for chunk_idx in GridWindowIterator::from(top_range.clone()) {
|
for chunk_idx in GridWindowIterator::from(top_range.clone()) {
|
||||||
if let Some(chunk) = self.chunks.get_mut(&chunk_idx) {
|
if let Some(chunk) = self.chunks.get_mut(&chunk_idx) {
|
||||||
let _old_offset = chunk.offset;
|
let old_offset = chunk.offset;
|
||||||
let _old_limit = chunk.limit;
|
let old_limit = chunk.limit;
|
||||||
|
|
||||||
|
//chunk.limit = Point2::new( col_widths[chunk_idx.x as usize]-1, row_heights[chunk_idx.y as usize]-1 );
|
||||||
chunk.limit = *chunk.view.area().range().end();
|
chunk.limit = *chunk.view.area().range().end();
|
||||||
|
|
||||||
chunk.offset = Vector2::new(
|
chunk.offset = Vector2::new(
|
||||||
(0..chunk_idx.x as usize).map(|x| col_widths[x]).sum(),
|
(0..chunk_idx.x as usize).map(|x| col_widths[x]).sum(),
|
||||||
(0..chunk_idx.y as usize).map(|y| row_heights[y]).sum(),
|
(0..chunk_idx.y as usize).map(|y| row_heights[y]).sum(),
|
||||||
);
|
);
|
||||||
/*
|
/*
|
||||||
|
|
||||||
if old_offset != chunk.offset {
|
if old_offset != chunk.offset {
|
||||||
self.cast.notify(
|
self.cast.notify(
|
||||||
&IndexArea::Range(
|
&IndexArea::Range(
|
||||||
|
@ -191,7 +200,7 @@ where
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +223,7 @@ where
|
||||||
max(self.limit.y, old_limit.y),
|
max(self.limit.y, old_limit.y),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// given an index in the flattened sequence,
|
/// given an index in the flattened sequence,
|
||||||
|
|
|
@ -65,7 +65,8 @@ impl TerminalEditor for DigitEditor {
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(' ')))
|
TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
|
||||||
|
| TerminalEvent::Input(Event::Key(Key::Char(' ')))
|
||||||
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
|
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => TerminalEditorResult::Exit,
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||||
self.data.set(Some(*c));
|
self.data.set(Some(*c));
|
||||||
|
@ -116,7 +117,7 @@ impl PosIntEditor {
|
||||||
digits_editor: PTYListEditor::new(
|
digits_editor: PTYListEditor::new(
|
||||||
Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>,
|
Box::new(move || Arc::new(RwLock::new(DigitEditor::new(radix)))) as Box<dyn Fn() -> Arc<RwLock<DigitEditor>> + Send + Sync>,
|
||||||
SeqDecorStyle::Hex,
|
SeqDecorStyle::Hex,
|
||||||
' ',
|
None,
|
||||||
0
|
0
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -195,7 +196,8 @@ impl TerminalEditor for PosIntEditor {
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
match event {
|
match event {
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(' ')))
|
TerminalEvent::Input(Event::Key(Key::Ctrl('x')))
|
||||||
|
| TerminalEvent::Input(Event::Key(Key::Char(' ')))
|
||||||
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
| TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
|
||||||
self.digits_editor.up();
|
self.digits_editor.up();
|
||||||
TerminalEditorResult::Exit
|
TerminalEditorResult::Exit
|
||||||
|
|
|
@ -16,10 +16,19 @@ pub struct RadixProjection {
|
||||||
|
|
||||||
impl RadixProjection {
|
impl RadixProjection {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
|
// static parameters
|
||||||
|
//---
|
||||||
src_radix: usize,
|
src_radix: usize,
|
||||||
dst_radix: usize,
|
dst_radix: usize,
|
||||||
|
//---
|
||||||
|
|
||||||
|
// dynamic parameters
|
||||||
|
//---
|
||||||
|
// input
|
||||||
src_digits: OuterViewPort<dyn SequenceView<Item = usize>>,
|
src_digits: OuterViewPort<dyn SequenceView<Item = usize>>,
|
||||||
|
// output
|
||||||
dst_digits: InnerViewPort<RwLock<Vec<usize>>>,
|
dst_digits: InnerViewPort<RwLock<Vec<usize>>>,
|
||||||
|
//---
|
||||||
) -> Arc<RwLock<Self>> {
|
) -> Arc<RwLock<Self>> {
|
||||||
dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone()));
|
dst_digits.0.add_update_hook(Arc::new(src_digits.0.clone()));
|
||||||
let proj = Arc::new(RwLock::new(RadixProjection {
|
let proj = Arc::new(RwLock::new(RadixProjection {
|
||||||
|
|
|
@ -27,6 +27,7 @@ pub mod diagnostics;
|
||||||
pub mod char_editor;
|
pub mod char_editor;
|
||||||
pub mod integer;
|
pub mod integer;
|
||||||
pub mod make_editor;
|
pub mod make_editor;
|
||||||
|
pub mod type_term_editor;
|
||||||
|
|
||||||
// display
|
// display
|
||||||
pub mod color;
|
pub mod color;
|
||||||
|
@ -36,16 +37,50 @@ pub fn magic_header() {
|
||||||
eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
|
eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::terminal::{TerminalEditor};
|
pub trait Commander {
|
||||||
use crate::diagnostics::{Diagnostics};
|
type Cmd;
|
||||||
use crate::tree::{TreeNav, TreeType};
|
|
||||||
|
fn send_cmd(&mut self, cmd: &Self::Cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
|
use crate::{
|
||||||
|
core::context::ReprTree,
|
||||||
|
singleton::SingletonView
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait ObjCommander {
|
||||||
|
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>);
|
||||||
|
}
|
||||||
|
|
||||||
|
//impl<Cmd: 'static, T: Commander<Cmd>> ObjCommander for T {
|
||||||
|
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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait StringGen {
|
||||||
|
fn get_string(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::terminal::TerminalEditor;
|
||||||
|
use crate::{tree::{TreeNav}, diagnostics::Diagnostics};
|
||||||
|
|
||||||
pub trait Nested
|
pub trait Nested
|
||||||
: TerminalEditor
|
: TerminalEditor
|
||||||
+ TreeNav
|
+ TreeNav
|
||||||
// + TreeType
|
// + TreeType
|
||||||
+ Diagnostics
|
+ Diagnostics
|
||||||
+ Send
|
+ Send
|
||||||
+ Sync
|
+ Sync
|
||||||
|
+ std::any::Any
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,12 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
|
||||||
pub struct ListEditor<ItemEditor>
|
pub struct ListEditor<ItemEditor>
|
||||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
pub(super) cursor: SingletonBuffer<ListCursor>,
|
pub(super) cursor: SingletonBuffer<ListCursor>,
|
||||||
pub(super) data: VecBuffer<Arc<RwLock<ItemEditor>>>,
|
pub(crate) data: VecBuffer<Arc<RwLock<ItemEditor>>>,
|
||||||
pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>,
|
pub(super) make_item_editor: Box<dyn Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync>,
|
||||||
|
|
||||||
pub(super) depth: usize,
|
pub(super) depth: usize,
|
||||||
|
|
|
@ -28,8 +28,8 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
pub editor: ListEditor<ItemEditor>,
|
pub editor: ListEditor<ItemEditor>,
|
||||||
|
|
||||||
split_char: char,
|
split_char: Option<char>,
|
||||||
|
|
||||||
style: SeqDecorStyle,
|
style: SeqDecorStyle,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
pub fn new(
|
pub fn new(
|
||||||
make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static,
|
make_item_editor: impl Fn() -> Arc<RwLock<ItemEditor>> + Send + Sync + 'static,
|
||||||
style: SeqDecorStyle,
|
style: SeqDecorStyle,
|
||||||
split_char: char,
|
split_char: Option<char>,
|
||||||
depth: usize
|
depth: usize
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth)
|
Self::from_editor(ListEditor::new(make_item_editor, depth), style, split_char, depth)
|
||||||
|
@ -51,7 +51,7 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
pub fn from_editor(
|
pub fn from_editor(
|
||||||
editor: ListEditor<ItemEditor>,
|
editor: ListEditor<ItemEditor>,
|
||||||
style: SeqDecorStyle,
|
style: SeqDecorStyle,
|
||||||
split_char: char,
|
split_char: Option<char>,
|
||||||
depth: usize
|
depth: usize
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let port = editor
|
let port = editor
|
||||||
|
@ -140,15 +140,15 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
let mut ne = new_edit.write().unwrap();
|
let mut ne = new_edit.write().unwrap();
|
||||||
ne.goto(TreeCursor::home());
|
ne.goto(TreeCursor::home());
|
||||||
|
|
||||||
match ne.handle_terminal_event(event) {
|
ne.handle_terminal_event(event);
|
||||||
TerminalEditorResult::Exit => {
|
|
||||||
self.editor.cursor.set(ListCursor {
|
if self.split_char.is_none() {
|
||||||
mode: ListCursorMode::Insert,
|
self.editor.cursor.set(ListCursor {
|
||||||
idx: Some(idx as isize + 1),
|
mode: ListCursorMode::Insert,
|
||||||
});
|
idx: Some(idx as isize + 1),
|
||||||
}
|
});
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalEditorResult::Continue
|
TerminalEditorResult::Continue
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -161,36 +161,41 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
TerminalEvent::Input(Event::Key(Key::Char(c))) => {
|
||||||
if *c == self.split_char {
|
if Some(*c) == self.split_char {
|
||||||
let c = self.editor.cursor.get();
|
let c = self.editor.cursor.get();
|
||||||
self.editor.goto(TreeCursor::none());
|
self.editor.goto(TreeCursor::none());
|
||||||
self.editor.cursor.set(ListCursor {
|
self.editor.cursor.set(ListCursor {
|
||||||
mode: ListCursorMode::Insert,
|
mode: ListCursorMode::Insert,
|
||||||
idx: Some(1 + c.idx.unwrap_or(0))
|
idx: Some(1 + c.idx.unwrap_or(0))
|
||||||
});
|
});
|
||||||
|
TerminalEditorResult::Continue
|
||||||
} else {
|
} else {
|
||||||
if let Some(e) = self.editor.get_item() {
|
if let Some(e) = self.editor.get_item() {
|
||||||
match e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c)))) {
|
e.write().unwrap().handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(*c))));
|
||||||
TerminalEditorResult::Exit => {
|
//match
|
||||||
|
if self.split_char.is_none() {
|
||||||
|
// TerminalEditorResult::Exit =>
|
||||||
|
{
|
||||||
self.editor.cursor.set(ListCursor {
|
self.editor.cursor.set(ListCursor {
|
||||||
mode: ListCursorMode::Insert,
|
mode: ListCursorMode::Insert,
|
||||||
idx: Some(idx as isize + 1),
|
idx: Some(idx as isize + 1),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TerminalEditorResult::Continue => {
|
// TerminalEditorResult::Continue => {
|
||||||
|
// }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
TerminalEditorResult::Exit
|
||||||
}
|
}
|
||||||
TerminalEditorResult::Continue
|
|
||||||
}
|
}
|
||||||
ev => {
|
ev => {
|
||||||
if let Some(e) = self.editor.get_item() {
|
if let Some(e) = self.editor.get_item() {
|
||||||
match e.write().unwrap().handle_terminal_event(ev) {
|
match e.write().unwrap().handle_terminal_event(ev) {
|
||||||
TerminalEditorResult::Exit => {
|
TerminalEditorResult::Exit => {
|
||||||
|
|
||||||
match ev {
|
match ev {
|
||||||
|
TerminalEvent::Input(Event::Key(Key::Ctrl('x'))) => {
|
||||||
|
return TerminalEditorResult::Exit
|
||||||
|
}
|
||||||
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
TerminalEvent::Input(Event::Key(Key::Backspace)) => {
|
||||||
self.editor.data.remove(idx as usize);
|
self.editor.data.remove(idx as usize);
|
||||||
self.editor.cursor.set(ListCursor {
|
self.editor.cursor.set(ListCursor {
|
||||||
|
@ -268,18 +273,32 @@ where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
impl<ItemEditor> TreeType for PTYListEditor<ItemEditor>
|
||||||
|
where ItemEditor: Nested + TreeType + ?Sized + Send + Sync + 'static
|
||||||
|
{
|
||||||
|
fn get_type(&self, addr: &Vec<usize>) -> TypeTerm {
|
||||||
|
TypeTerm::new(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
impl<ItemEditor> Nested for PTYListEditor<ItemEditor>
|
impl<ItemEditor> Nested for PTYListEditor<ItemEditor>
|
||||||
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
where ItemEditor: Nested + ?Sized + Send + Sync + 'static
|
||||||
{}
|
{}
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
char_editor::CharEditor,
|
char_editor::CharEditor,
|
||||||
sequence::SequenceViewExt
|
sequence::SequenceViewExt,
|
||||||
|
StringGen
|
||||||
};
|
};
|
||||||
|
|
||||||
impl PTYListEditor<CharEditor> {
|
impl<ItemEditor: StringGen + Nested + Send + Sync> StringGen for PTYListEditor<ItemEditor> {
|
||||||
pub fn get_string(&self) -> String {
|
|
||||||
self.get_data_port().map(|ce| ce.read().unwrap().get()).get_view().unwrap().iter().collect::<String>()
|
fn get_string(&self) -> String {
|
||||||
|
self.get_data_port()
|
||||||
|
.map(|ce| ce.read().unwrap().get_string())
|
||||||
|
.get_view().unwrap()
|
||||||
|
.iter().collect::<String>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
core::{TypeTerm, TypeLadder, Context, OuterViewPort},
|
core::{TypeTerm, TypeLadder, Context, OuterViewPort},
|
||||||
|
@ -17,38 +16,6 @@ use {
|
||||||
std::sync::{Arc, RwLock},
|
std::sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
enum RhsNode {
|
|
||||||
Sum (
|
|
||||||
Arc<RwLock< PTYListEditor< RhsNode > >>
|
|
||||||
),
|
|
||||||
Product (
|
|
||||||
Arc<RwLock< PTYListEditor< RhsNode > >>
|
|
||||||
),
|
|
||||||
String(
|
|
||||||
Arc<RwLock< PTYListEditor< CharEditor > >>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TreeNav for RhsNode {}
|
|
||||||
|
|
||||||
impl TerminalEditor for RhsNode {
|
|
||||||
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
|
||||||
make_label("todo")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
|
||||||
TerminalEditorResult::Continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Diagnostics for RhsNode {}
|
|
||||||
impl Nested for RhsNode {}
|
|
||||||
|
|
||||||
struct GrammarRuleEditor {
|
|
||||||
lhs: Arc<RwLock<PTYListEditor<CharEditor>>>,
|
|
||||||
rhs: Arc<RwLock<PTYListEditor<RhsNode>>>
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||||
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
||||||
|
|
||||||
|
@ -56,7 +23,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||||
"Char", Arc::new(
|
"Char", Arc::new(
|
||||||
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
|ctx: Arc<RwLock<Context>>, ty: TypeTerm, _depth: usize| {
|
||||||
Some(
|
Some(
|
||||||
Arc::new(RwLock::new(CharEditor::new()))
|
Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
|
||||||
as Arc<RwLock<dyn Nested + Send + Sync>>)
|
as Arc<RwLock<dyn Nested + Send + Sync>>)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -70,7 +37,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||||
id, args
|
id, args
|
||||||
} => {
|
} => {
|
||||||
if args.len() > 0 {
|
if args.len() > 0 {
|
||||||
// todod factor style out of type arGS
|
// todo: factor style out of type arGS
|
||||||
let style = if args.len() > 1 {
|
let style = if args.len() > 1 {
|
||||||
match args[1] {
|
match args[1] {
|
||||||
TypeTerm::Num(0) => SeqDecorStyle::Plain,
|
TypeTerm::Num(0) => SeqDecorStyle::Plain,
|
||||||
|
@ -82,23 +49,23 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||||
TypeTerm::Num(6) => SeqDecorStyle::Path,
|
TypeTerm::Num(6) => SeqDecorStyle::Path,
|
||||||
_ => SeqDecorStyle::HorizontalSexpr
|
_ => SeqDecorStyle::HorizontalSexpr
|
||||||
}
|
}
|
||||||
}else {
|
} else {
|
||||||
SeqDecorStyle::HorizontalSexpr
|
SeqDecorStyle::HorizontalSexpr
|
||||||
};
|
};
|
||||||
|
|
||||||
let delim = if args.len() > 1 {
|
let delim = if args.len() > 1 {
|
||||||
match args[1] {
|
match args[1] {
|
||||||
TypeTerm::Num(0) => ' ',
|
TypeTerm::Num(0) => Some(' '),
|
||||||
TypeTerm::Num(1) => ' ',
|
TypeTerm::Num(1) => Some(' '),
|
||||||
TypeTerm::Num(2) => '\n',
|
TypeTerm::Num(2) => Some('\n'),
|
||||||
TypeTerm::Num(3) => '"',
|
TypeTerm::Num(3) => None,
|
||||||
TypeTerm::Num(4) => ',',
|
TypeTerm::Num(4) => Some(','),
|
||||||
TypeTerm::Num(5) => ',',
|
TypeTerm::Num(5) => Some(','),
|
||||||
TypeTerm::Num(6) => '/',
|
TypeTerm::Num(6) => Some('/'),
|
||||||
_ => '\0'
|
_ => None
|
||||||
}
|
}
|
||||||
}else {
|
}else {
|
||||||
'\0'
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
|
@ -167,13 +134,16 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ctx.write().unwrap().add_typename("TerminalEvent".into());
|
||||||
ctx
|
ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
|
||||||
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
let mut ctx = Arc::new(RwLock::new(Context::with_parent(Some(parent))));
|
||||||
|
|
||||||
|
ctx.write().unwrap().add_typename("MachineInt".into());
|
||||||
|
ctx.write().unwrap().add_typename("Digit".into());
|
||||||
ctx.write().unwrap().add_typename("BigEndian".into());
|
ctx.write().unwrap().add_typename("BigEndian".into());
|
||||||
ctx.write().unwrap().add_editor_ctor(
|
ctx.write().unwrap().add_editor_ctor(
|
||||||
"PosInt", Arc::new(
|
"PosInt", Arc::new(
|
||||||
|
|
10
nested/src/path/mod.rs
Normal file
10
nested/src/path/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
pub struct PathSegmentEditor {
|
||||||
|
parent: Path,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PathEditor {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ where
|
||||||
pub fn get_port(&self) -> OuterViewPort<dyn SingletonView<Item = T>> {
|
pub fn get_port(&self) -> OuterViewPort<dyn SingletonView<Item = T>> {
|
||||||
self.port.0.outer()
|
self.port.0.outer()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> T {
|
pub fn get(&self) -> T {
|
||||||
self.value.read().unwrap().clone()
|
self.value.read().unwrap().clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use {
|
||||||
|
|
||||||
pub struct SumEditor {
|
pub struct SumEditor {
|
||||||
cur: usize,
|
cur: usize,
|
||||||
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync>> >,
|
pub editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >,
|
||||||
|
|
||||||
port: ViewPort< dyn TerminalView >,
|
port: ViewPort< dyn TerminalView >,
|
||||||
diag_port: ViewPort< dyn SequenceView<Item = Message> >
|
diag_port: ViewPort< dyn SequenceView<Item = Message> >
|
||||||
|
@ -31,7 +31,7 @@ pub struct SumEditor {
|
||||||
|
|
||||||
impl SumEditor {
|
impl SumEditor {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync>> >
|
editors: Vec< Arc<RwLock<dyn Nested + Send + Sync + 'static>> >
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let port = ViewPort::new();
|
let port = ViewPort::new();
|
||||||
//let mut diag_buf = VecBuffer::new();
|
//let mut diag_buf = VecBuffer::new();
|
||||||
|
@ -44,6 +44,10 @@ impl SumEditor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> Arc<RwLock<dyn Nested + Send + Sync>> {
|
||||||
|
self.editors[ self.cur ].clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn select(&mut self, idx: usize) {
|
pub fn select(&mut self, idx: usize) {
|
||||||
self.cur = idx;
|
self.cur = idx;
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ use {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub enum TerminalEvent {
|
pub enum TerminalEvent {
|
||||||
Resize(Vector2<i16>),
|
Resize(Vector2<i16>),
|
||||||
Input(termion::event::Event),
|
Input(termion::event::Event),
|
||||||
|
|
9
nested/src/tree/addr.rs
Normal file
9
nested/src/tree/addr.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
pub struct TreeAddr(Vec<usize>);
|
||||||
|
|
||||||
|
impl From<Vec<usize>> for TreeAddr {
|
||||||
|
fn from(v: Vec<usize>) -> TreeAddr {
|
||||||
|
TreeAddr(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,18 +1,12 @@
|
||||||
|
pub mod addr;
|
||||||
pub mod cursor;
|
pub mod cursor;
|
||||||
pub mod nav;
|
pub mod nav;
|
||||||
pub mod typeinfo;
|
pub mod node;
|
||||||
|
|
||||||
pub struct TreeAddr(Vec<usize>);
|
|
||||||
|
|
||||||
impl From<Vec<usize>> for TreeAddr {
|
|
||||||
fn from(v: Vec<usize>) -> TreeAddr {
|
|
||||||
TreeAddr(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
|
addr::TreeAddr,
|
||||||
cursor::TreeCursor,
|
cursor::TreeCursor,
|
||||||
nav::{TreeNav, TreeNavResult},
|
nav::{TreeNav, TreeNavResult},
|
||||||
typeinfo::TreeType
|
node::NestedNode
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
124
nested/src/tree/node.rs
Normal file
124
nested/src/tree/node.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
use {
|
||||||
|
std::sync::{Arc, RwLock},
|
||||||
|
cgmath::Vector2,
|
||||||
|
crate::{
|
||||||
|
core::{ViewPort, OuterViewPort, AnyOuterViewPort, context::ReprTree, Context},
|
||||||
|
singleton::{SingletonView, SingletonBuffer},
|
||||||
|
sequence::SequenceView,
|
||||||
|
terminal::{TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult},
|
||||||
|
diagnostics::{Diagnostics, Message},
|
||||||
|
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||||
|
Commander, ObjCommander,
|
||||||
|
Nested
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct NestedNode {
|
||||||
|
ctx: Option<Arc<RwLock<Context>>>,
|
||||||
|
view: Option<OuterViewPort<dyn TerminalView>>,
|
||||||
|
diag: Option<OuterViewPort<dyn SequenceView<Item = Message>>>,
|
||||||
|
cmd: Option<Arc<RwLock<dyn ObjCommander + Send + Sync>>>,
|
||||||
|
tree_nav: Option<Arc<RwLock<dyn TreeNav + Send + Sync>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjCommander for NestedNode {
|
||||||
|
fn send_cmd_obj(&mut self, cmd_obj: Arc<RwLock<ReprTree>>) {
|
||||||
|
if let Some(cmd) = self.cmd.as_ref() {
|
||||||
|
cmd.write().unwrap().send_cmd_obj(cmd_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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),Some(ctx)) = (self.cmd.as_ref(),self.ctx.as_ref()) {
|
||||||
|
cmd.write().unwrap().send_cmd_obj(
|
||||||
|
ReprTree::new_leaf(
|
||||||
|
ctx.read().unwrap().type_term_from_str("( TerminalEvent )").unwrap(),
|
||||||
|
AnyOuterViewPort::from(buf.get_port())
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl TreeNav for NestedNode {
|
||||||
|
fn get_cursor(&self) -> TreeCursor {
|
||||||
|
if let Some(tn) = self.tree_nav.as_ref() {
|
||||||
|
tn.read().unwrap().get_cursor()
|
||||||
|
} else {
|
||||||
|
TreeCursor::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cursor_warp(&self) -> TreeCursor {
|
||||||
|
if let Some(tn) = self.tree_nav.as_ref() {
|
||||||
|
tn.read().unwrap().get_cursor_warp()
|
||||||
|
} else {
|
||||||
|
TreeCursor::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_max_depth(&self) -> usize {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
|
||||||
|
if let Some(tn) = self.tree_nav.as_ref() {
|
||||||
|
tn.write().unwrap().goby(direction)
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
|
||||||
|
if let Some(tn) = self.tree_nav.as_ref() {
|
||||||
|
tn.write().unwrap().goto(new_cursor)
|
||||||
|
} else {
|
||||||
|
TreeNavResult::Exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Diagnostics for NestedNode {}
|
||||||
|
impl Nested for NestedNode {}
|
||||||
|
|
||||||
|
impl NestedNode {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
NestedNode {
|
||||||
|
ctx: None,
|
||||||
|
view: None,
|
||||||
|
diag: None,
|
||||||
|
cmd: None,
|
||||||
|
tree_nav: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_ctx(mut self, ctx: Arc<RwLock<Context>>) -> Self {
|
||||||
|
self.ctx = Some(ctx);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_view(mut self, view: OuterViewPort<dyn TerminalView>) -> Self {
|
||||||
|
self.view = Some(view);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_cmd(mut self, cmd: Arc<RwLock<dyn ObjCommander + Send + Sync>>) -> Self {
|
||||||
|
self.cmd = Some(cmd);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
|
self.view.clone().unwrap_or(ViewPort::new().into_outer())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
155
nested/src/type_term_editor.rs
Normal file
155
nested/src/type_term_editor.rs
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
use {
|
||||||
|
crate::{
|
||||||
|
core::{ViewPort, OuterViewPort, TypeLadder, Context},
|
||||||
|
terminal::{TerminalEvent, TerminalView, TerminalEditor, TerminalEditorResult},
|
||||||
|
sequence::{SequenceView, decorator::SeqDecorStyle},
|
||||||
|
list::{PTYListEditor},
|
||||||
|
tree::{TreeNav, TreeCursor, TreeNavResult},
|
||||||
|
diagnostics::{Diagnostics, Message},
|
||||||
|
sum::SumEditor,
|
||||||
|
char_editor::CharEditor,
|
||||||
|
integer::PosIntEditor,
|
||||||
|
Nested
|
||||||
|
},
|
||||||
|
cgmath::{Vector2, Point2},
|
||||||
|
termion::event::{Event, Key},
|
||||||
|
std::{
|
||||||
|
sync::{Arc, RwLock},
|
||||||
|
any::Any
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum TypeTermVar {
|
||||||
|
Any,
|
||||||
|
Symbol,
|
||||||
|
Num,
|
||||||
|
List
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TypeTermEditor {
|
||||||
|
ty: TypeTermVar,
|
||||||
|
node: SumEditor,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TypeTermEditor {
|
||||||
|
pub fn new(ctx: Arc<RwLock<Context>>, depth: usize) -> Self {
|
||||||
|
TypeTermEditor {
|
||||||
|
ty: TypeTermVar::Any,
|
||||||
|
node: SumEditor::new(
|
||||||
|
vec![
|
||||||
|
Arc::new(RwLock::new(PTYListEditor::new(
|
||||||
|
Box::new({
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
move || {
|
||||||
|
Arc::new(RwLock::new(TypeTermEditor::new(ctx.clone(), depth+1)))
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
SeqDecorStyle::HorizontalSexpr,
|
||||||
|
Some(' '),
|
||||||
|
depth
|
||||||
|
))),
|
||||||
|
Arc::new(RwLock::new(PosIntEditor::new(10))),
|
||||||
|
Arc::new(RwLock::new(PTYListEditor::new(
|
||||||
|
Box::new({
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
move || {
|
||||||
|
Arc::new(RwLock::new(CharEditor::new_node(&ctx)))
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
SeqDecorStyle::Plain,
|
||||||
|
None,
|
||||||
|
depth
|
||||||
|
))),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TreeNav for TypeTermEditor {
|
||||||
|
fn get_cursor(&self) -> TreeCursor {
|
||||||
|
self.node.get_cursor()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cursor_warp(&self) -> TreeCursor {
|
||||||
|
self.node.get_cursor_warp()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goby(&mut self, direction: Vector2<isize>) -> TreeNavResult {
|
||||||
|
self.node.goby( direction )
|
||||||
|
}
|
||||||
|
|
||||||
|
fn goto(&mut self, new_cursor: TreeCursor) -> TreeNavResult {
|
||||||
|
self.node.goto( new_cursor )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TerminalEditor for TypeTermEditor {
|
||||||
|
fn get_term_view(&self) -> OuterViewPort<dyn TerminalView> {
|
||||||
|
self.node.get_term_view()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
|
||||||
|
match event {
|
||||||
|
TerminalEvent::Input( termion::event::Event::Key(Key::Char(c)) ) => {
|
||||||
|
match self.ty {
|
||||||
|
TypeTermVar::Any => {
|
||||||
|
self.ty =
|
||||||
|
if *c == '(' {
|
||||||
|
self.node.select(0);
|
||||||
|
self.dn();
|
||||||
|
TypeTermVar::List
|
||||||
|
} else if c.to_digit(10).is_some() {
|
||||||
|
self.node.select(1);
|
||||||
|
self.dn();
|
||||||
|
self.node.handle_terminal_event( event );
|
||||||
|
TypeTermVar::Num
|
||||||
|
} else {
|
||||||
|
self.node.select(2);
|
||||||
|
self.dn();
|
||||||
|
self.node.handle_terminal_event( event );
|
||||||
|
TypeTermVar::Symbol
|
||||||
|
};
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
if *c == '(' {
|
||||||
|
let mut child = Arc::new(RwLock::new(TypeTermEditor {
|
||||||
|
ty: self.ty.clone(),
|
||||||
|
node: SumEditor::new(
|
||||||
|
vec![
|
||||||
|
self.node.editors[0].clone(),
|
||||||
|
self.node.editors[1].clone(),
|
||||||
|
self.node.editors[2].clone(),
|
||||||
|
])
|
||||||
|
}));
|
||||||
|
|
||||||
|
self.ty = TypeTermVar::List;
|
||||||
|
self.node.select(0);
|
||||||
|
/*
|
||||||
|
let l = self.node.editors[0].clone();
|
||||||
|
let l = l.downcast::<RwLock<PTYListEditor<TypeTermEditor>>>().unwrap();
|
||||||
|
l.write().unwrap().data.push(child);
|
||||||
|
*/
|
||||||
|
TerminalEditorResult::Continue
|
||||||
|
} else {
|
||||||
|
self.node.handle_terminal_event( event )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
event => {
|
||||||
|
self.node.handle_terminal_event( event )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Diagnostics for TypeTermEditor {
|
||||||
|
fn get_msg_port(&self) -> OuterViewPort<dyn SequenceView<Item = Message>> {
|
||||||
|
self.node.get_msg_port()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Nested for TypeTermEditor {}
|
||||||
|
|
|
@ -2,19 +2,19 @@ extern crate portable_pty;
|
||||||
|
|
||||||
mod ascii_box;
|
mod ascii_box;
|
||||||
mod monstera;
|
mod monstera;
|
||||||
mod process;
|
//mod process;
|
||||||
mod pty;
|
mod pty;
|
||||||
mod command;
|
//mod command;
|
||||||
mod plot;
|
mod plot;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
process::ProcessLauncher,
|
// process::ProcessLauncher,
|
||||||
command::Commander
|
// command::Commander
|
||||||
},
|
},
|
||||||
cgmath::{Point2, Vector2},
|
cgmath::{Point2, Vector2},
|
||||||
nested::{
|
nested::{
|
||||||
core::{port::UpdateTask, Observer, OuterViewPort, View, ViewPort, Context, TypeTerm},
|
core::{port::UpdateTask, Observer, OuterViewPort, AnyOuterViewPort, View, ViewPort, Context, TypeTerm, ReprTree},
|
||||||
index::IndexArea,
|
index::IndexArea,
|
||||||
list::{ListCursorMode, PTYListEditor},
|
list::{ListCursorMode, PTYListEditor},
|
||||||
sequence::{SequenceView, decorator::{SeqDecorStyle, Separate}},
|
sequence::{SequenceView, decorator::{SeqDecorStyle, Separate}},
|
||||||
|
@ -29,6 +29,7 @@ use {
|
||||||
product::ProductEditor,
|
product::ProductEditor,
|
||||||
sum::SumEditor,
|
sum::SumEditor,
|
||||||
diagnostics::{Diagnostics},
|
diagnostics::{Diagnostics},
|
||||||
|
index::{buffer::IndexBuffer},
|
||||||
Nested
|
Nested
|
||||||
},
|
},
|
||||||
std::sync::{Arc, RwLock},
|
std::sync::{Arc, RwLock},
|
||||||
|
@ -43,12 +44,20 @@ async fn main() {
|
||||||
let mut term = Terminal::new(term_port.outer());
|
let mut term = Terminal::new(term_port.outer());
|
||||||
let term_writer = term.get_writer();
|
let term_writer = term.get_writer();
|
||||||
|
|
||||||
|
let mut portmutex = Arc::new(RwLock::new(()));
|
||||||
|
|
||||||
// Update Loop //
|
// Update Loop //
|
||||||
let tp = term_port.clone();
|
let tp = term_port.clone();
|
||||||
async_std::task::spawn(async move {
|
async_std::task::spawn({
|
||||||
loop {
|
let portmutex = portmutex.clone();
|
||||||
tp.update();
|
async move {
|
||||||
async_std::task::sleep(std::time::Duration::from_millis(30)).await;
|
loop {
|
||||||
|
{
|
||||||
|
let l = portmutex.write().unwrap();
|
||||||
|
tp.update();
|
||||||
|
}
|
||||||
|
async_std::task::sleep(std::time::Duration::from_millis(10)).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -58,16 +67,53 @@ async fn main() {
|
||||||
let ctx = nested::make_editor::init_math_ctx(ctx);
|
let ctx = nested::make_editor::init_math_ctx(ctx);
|
||||||
let ctx = nested::make_editor::init_os_ctx(ctx);
|
let ctx = nested::make_editor::init_os_ctx(ctx);
|
||||||
|
|
||||||
|
let mut vb = VecBuffer::<char>::new();
|
||||||
|
let mut rt_char = ReprTree::new_leaf(
|
||||||
|
ctx.read().unwrap().type_term_from_str("( List Char )").unwrap(),
|
||||||
|
AnyOuterViewPort::from(vb.get_port())
|
||||||
|
);
|
||||||
|
let mut rt_digit = ReprTree::upcast(&rt_char, ctx.read().unwrap().type_term_from_str("( List ( Digit 10 ) )").unwrap());
|
||||||
|
rt_digit.write().unwrap().insert_branch(
|
||||||
|
ReprTree::new_leaf(
|
||||||
|
ctx.read().unwrap().type_term_from_str("( List MachineInt )").unwrap(),
|
||||||
|
AnyOuterViewPort::from(
|
||||||
|
vb.get_port().to_sequence().map(
|
||||||
|
|c: &char| {
|
||||||
|
c.to_digit(10).unwrap()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
ctx.write().unwrap().add_morphism(
|
||||||
|
MorphismType{
|
||||||
|
mode: MorphismMode::Iso,
|
||||||
|
src_type:
|
||||||
|
},
|
||||||
|
Box::new(
|
||||||
|
|repr| {
|
||||||
|
RadixProjection::new(
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
let c = ctx.clone();
|
let c = ctx.clone();
|
||||||
let mut process_list_editor =
|
let mut process_list_editor =
|
||||||
PTYListEditor::new(
|
PTYListEditor::new(
|
||||||
Box::new( move || {
|
Box::new( move || {
|
||||||
Arc::new(RwLock::new(Commander::new(ctx.clone())))
|
Arc::new(RwLock::new(nested::type_term_editor::TypeTermEditor::new(c.clone(), 1)))
|
||||||
|
// Arc::new(RwLock::new(CharEditor::new_node(&c)))
|
||||||
|
//Context::make_editor( c.clone(), c.read().unwrap().type_term_from_str("( String )").unwrap(), 1 ).unwrap()
|
||||||
}),
|
}),
|
||||||
SeqDecorStyle::Plain,
|
SeqDecorStyle::Plain,
|
||||||
'\0',
|
Some('\n'),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
|
|
||||||
async_std::task::spawn(async move {
|
async_std::task::spawn(async move {
|
||||||
let mut table = nested::index::buffer::IndexBuffer::new();
|
let mut table = nested::index::buffer::IndexBuffer::new();
|
||||||
|
@ -84,7 +130,7 @@ async fn main() {
|
||||||
|
|
||||||
let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10));
|
let mut cur_size = nested::singleton::SingletonBuffer::new(Vector2::new(10, 10));
|
||||||
let mut status_chars = VecBuffer::new();
|
let mut status_chars = VecBuffer::new();
|
||||||
|
|
||||||
table.insert_iter(vec![
|
table.insert_iter(vec![
|
||||||
(Point2::new(0, 0), magic.clone()),
|
(Point2::new(0, 0), magic.clone()),
|
||||||
(
|
(
|
||||||
|
@ -96,12 +142,49 @@ async fn main() {
|
||||||
(Point2::new(0, 4),
|
(Point2::new(0, 4),
|
||||||
process_list_editor.editor
|
process_list_editor.editor
|
||||||
.get_seg_seq_view()
|
.get_seg_seq_view()
|
||||||
.separate(
|
.enumerate()
|
||||||
make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~")
|
.map(
|
||||||
.map_item(|p,a| a.add_style_front(TerminalStyle::fg_color((40,40,40))))
|
|(n, segment)| {
|
||||||
|
let mut buf = IndexBuffer::new();
|
||||||
|
buf.insert_iter(vec![
|
||||||
|
(Point2::new(0, 0),
|
||||||
|
make_label(match n+1 {
|
||||||
|
1 => "I) ",
|
||||||
|
2 => "II) ",
|
||||||
|
3 => "III) ",
|
||||||
|
4 => "IV) ",
|
||||||
|
5 => "V) ",
|
||||||
|
6 => "VI) ",
|
||||||
|
7 => "VII) ",
|
||||||
|
8 => "IIX) ",
|
||||||
|
9 => "IX) ",
|
||||||
|
10 => "X) ",
|
||||||
|
_ => ""
|
||||||
|
})),
|
||||||
|
(Point2::new(1, 0), segment.clone())
|
||||||
|
]);
|
||||||
|
|
||||||
|
buf.get_port()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
/*
|
||||||
|
.separate({
|
||||||
|
let mut buf = IndexBuffer::new();
|
||||||
|
buf.insert(Point2::new(1,0),
|
||||||
|
make_label(" ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~ ~~")
|
||||||
|
.map_item(
|
||||||
|
|p,a|
|
||||||
|
a.add_style_front(TerminalStyle::fg_color((40,40,40)))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
buf.get_port()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
*/
|
||||||
.to_grid_vertical()
|
.to_grid_vertical()
|
||||||
.flatten()),
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
),
|
||||||
|
|
||||||
(Point2::new(0, 5), make_label(" ")),
|
(Point2::new(0, 5), make_label(" ")),
|
||||||
(Point2::new(0, 6), magic.clone()),
|
(Point2::new(0, 6), magic.clone()),
|
||||||
|
@ -165,62 +248,18 @@ async fn main() {
|
||||||
tree_addr: vec![0],
|
tree_addr: vec![0],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
status_chars.clear();
|
|
||||||
let cur = process_list_editor.get_cursor();
|
|
||||||
|
|
||||||
if cur.tree_addr.len() > 0 {
|
|
||||||
status_chars.push(TerminalAtom::new(
|
|
||||||
'@',
|
|
||||||
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
|
|
||||||
));
|
|
||||||
for x in cur.tree_addr {
|
|
||||||
for c in format!("{}", x).chars() {
|
|
||||||
status_chars
|
|
||||||
.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20))));
|
|
||||||
}
|
|
||||||
status_chars.push(TerminalAtom::new(
|
|
||||||
'.',
|
|
||||||
TerminalStyle::fg_color((150, 80,230))
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
status_chars.push(TerminalAtom::new(
|
|
||||||
':',
|
|
||||||
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
|
|
||||||
));
|
|
||||||
for c in match cur.leaf_mode {
|
|
||||||
ListCursorMode::Insert => "INSERT",
|
|
||||||
ListCursorMode::Select => "SELECT"
|
|
||||||
}
|
|
||||||
.chars()
|
|
||||||
{
|
|
||||||
status_chars.push(TerminalAtom::new(
|
|
||||||
c,
|
|
||||||
TerminalStyle::fg_color((200, 200, 20)),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
status_chars.push(TerminalAtom::new(
|
|
||||||
':',
|
|
||||||
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
|
|
||||||
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
for c in "Press <DN> to enter".chars() {
|
|
||||||
status_chars.push(TerminalAtom::new(
|
|
||||||
c,
|
|
||||||
TerminalStyle::fg_color((200, 200, 20)),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let ev = term.next_event().await;
|
let ev = term.next_event().await;
|
||||||
|
let l = portmutex.write().unwrap();
|
||||||
|
|
||||||
if let TerminalEvent::Resize(new_size) = ev {
|
if let TerminalEvent::Resize(new_size) = ev {
|
||||||
cur_size.set(new_size);
|
cur_size.set(new_size);
|
||||||
term_port.inner().get_broadcast().notify(&IndexArea::Full);
|
term_port.inner().get_broadcast().notify(&IndexArea::Full);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if let Some(process_editor) = process_list_editor.get_item() {
|
if let Some(process_editor) = process_list_editor.get_item() {
|
||||||
let mut pe = process_editor.write().unwrap();
|
let mut pe = process_editor.write().unwrap();
|
||||||
|
@ -235,7 +274,7 @@ async fn main() {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
match ev {
|
match ev {
|
||||||
TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
|
TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break,
|
||||||
TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => {
|
TerminalEvent::Input(Event::Key(Key::Ctrl('l'))) => {
|
||||||
|
@ -284,6 +323,54 @@ async fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_chars.clear();
|
||||||
|
let cur = process_list_editor.get_cursor();
|
||||||
|
|
||||||
|
if cur.tree_addr.len() > 0 {
|
||||||
|
status_chars.push(TerminalAtom::new(
|
||||||
|
'@',
|
||||||
|
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
|
||||||
|
));
|
||||||
|
for x in cur.tree_addr {
|
||||||
|
for c in format!("{}", x).chars() {
|
||||||
|
status_chars
|
||||||
|
.push(TerminalAtom::new(c, TerminalStyle::fg_color((0, 100, 20))));
|
||||||
|
}
|
||||||
|
status_chars.push(TerminalAtom::new(
|
||||||
|
'.',
|
||||||
|
TerminalStyle::fg_color((150, 80,230))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
status_chars.push(TerminalAtom::new(
|
||||||
|
':',
|
||||||
|
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
|
||||||
|
));
|
||||||
|
for c in match cur.leaf_mode {
|
||||||
|
ListCursorMode::Insert => "INSERT",
|
||||||
|
ListCursorMode::Select => "SELECT"
|
||||||
|
}
|
||||||
|
.chars()
|
||||||
|
{
|
||||||
|
status_chars.push(TerminalAtom::new(
|
||||||
|
c,
|
||||||
|
TerminalStyle::fg_color((200, 200, 20)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
status_chars.push(TerminalAtom::new(
|
||||||
|
':',
|
||||||
|
TerminalStyle::fg_color((150, 80,230)).add(TerminalStyle::bold(true)),
|
||||||
|
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
for c in "Press <DN> to enter".chars() {
|
||||||
|
status_chars.push(TerminalAtom::new(
|
||||||
|
c,
|
||||||
|
TerminalStyle::fg_color((200, 200, 20)),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(term);
|
drop(term);
|
||||||
|
|
|
@ -21,7 +21,7 @@ use {
|
||||||
};
|
};
|
||||||
|
|
||||||
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
|
||||||
|
/*
|
||||||
pub struct ProcessArg {
|
pub struct ProcessArg {
|
||||||
editor:
|
editor:
|
||||||
PTYListEditor<CharEditor>,
|
PTYListEditor<CharEditor>,
|
||||||
|
@ -274,4 +274,4 @@ impl Diagnostics for ProcessLauncher {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Nested for ProcessLauncher {}
|
impl Nested for ProcessLauncher {}
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in a new issue