process editor: write keyboard input to pty

This commit is contained in:
Michael Sippel 2021-11-11 22:29:37 +01:00
parent b9e285acb4
commit c9c6958a62
Signed by: senvas
GPG key ID: F96CF119C34B64A6
5 changed files with 263 additions and 117 deletions
shell/src

View file

@ -15,7 +15,7 @@ use {
vec::VecBuffer,
terminal::{TerminalAtom, TerminalStyle, TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult, make_label},
tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor, TreeCursor},
list::{ListEditor, ListEditorStyle, sexpr::ListDecoration},
list::{ListCursorMode, ListEditor, ListEditorStyle, sexpr::ListDecoration},
string_editor::CharEditor,
}
};
@ -74,9 +74,11 @@ pub struct ProcessLauncher {
>,
pty: Option<crate::pty::PTY>,
ptybox: Arc<RwLock<crate::ascii_box::AsciiBox>>,
suspended: bool,
pty_port: ViewPort<dyn TerminalView>,
status_port: ViewPort<dyn SingletonView<Item = Option<portable_pty::ExitStatus>>>,
comp_port: ViewPort<dyn TerminalView>,
compositor: Arc<RwLock<nested::terminal::TerminalCompositor>>
}
@ -84,6 +86,7 @@ pub struct ProcessLauncher {
impl ProcessLauncher {
pub fn new() -> Self {
let pty_port = ViewPort::new();
let status_port = ViewPort::new();
let comp_port = ViewPort::new();
let box_port = ViewPort::<dyn TerminalView>::new();
let compositor = nested::terminal::TerminalCompositor::new(comp_port.inner());
@ -125,21 +128,16 @@ impl ProcessLauncher {
pty_port.outer()
.map_item(|_,a:&TerminalAtom| a.add_style_back(TerminalStyle::fg_color((230, 230, 230)))),
box_port.inner()
),
),
suspended: false,
pty_port,
status_port,
comp_port,
compositor
}
}
pub fn launch_pty2(&mut self) {
self.launch_pty(self.pty_port.inner());
}
pub fn launch_pty(&mut self, port: InnerViewPort<dyn TerminalView>) -> Option<crate::pty::PTY> {
self.up();
self.up();
pub fn launch_pty(&mut self) {
let mut strings = Vec::new();
let v = self.cmd_editor.get_data_port().get_view().unwrap();
@ -153,11 +151,18 @@ impl ProcessLauncher {
let mut cmd = crate::pty::CommandBuilder::new(strings[0].as_str());
cmd.args(&strings[1..]);
crate::pty::PTY::new(cmd, port)
} else {
None
self.cmd_editor.goto(TreeCursor {
leaf_mode: ListCursorMode::Insert,
tree_addr: vec![]
});
self.pty = crate::pty::PTY::new(cmd, self.pty_port.inner(), self.status_port.inner());
}
}
pub fn is_captured(&self) -> bool {
self.pty.is_some() && !self.suspended
}
}
impl TerminalEditor for ProcessLauncher {
@ -166,27 +171,94 @@ impl TerminalEditor for ProcessLauncher {
}
fn handle_terminal_event(&mut self, event: &TerminalEvent) -> TerminalEditorResult {
// todo: move to observer of status view
if let Some(status) = self.status_port.outer().get_view().get() {
self.pty = None;
self.suspended = false;
}
match event {
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
// launch command
self.cmd_editor.up();
self.cmd_editor.up();
TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) => {
self.pty = None;
self.suspended = false;
self.cmd_editor.goto(TreeCursor {
leaf_mode: ListCursorMode::Insert,
tree_addr: vec![]
});
TerminalEditorResult::Exit
},
TerminalEvent::Input(Event::Key(Key::Ctrl('z'))) => {
self.suspended = true;
self.cmd_editor.goto(TreeCursor {
leaf_mode: ListCursorMode::Insert,
tree_addr: vec![]
});
TerminalEditorResult::Exit
}
event => self.cmd_editor.handle_terminal_event(event)
event => {
if let Some(pty) = self.pty.as_mut() {
pty.handle_terminal_event(event);
TerminalEditorResult::Continue
} else {
match event {
TerminalEvent::Input(Event::Key(Key::Char('\n'))) => {
// launch command
self.launch_pty();
TerminalEditorResult::Continue
}
event => self.cmd_editor.handle_terminal_event(event)
}
}
}
}
}
}
impl TreeNav for ProcessLauncher {
fn get_cursor(&self) -> TreeCursor { self.cmd_editor.get_cursor() }
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult { self.cmd_editor.goto(cur) }
fn goto_home(&mut self) -> TreeNavResult { self.cmd_editor.goto_home() }
fn goto_end(&mut self) -> TreeNavResult { self.cmd_editor.goto_end() }
fn pxev(&mut self) -> TreeNavResult { self.cmd_editor.pxev() }
fn nexd(&mut self) -> TreeNavResult { self.cmd_editor.nexd() }
fn up(&mut self) -> TreeNavResult { self.cmd_editor.up() }
fn dn(&mut self) -> TreeNavResult { self.cmd_editor.dn() }
fn get_cursor(&self) -> TreeCursor {
self.cmd_editor.get_cursor()
}
fn goto(&mut self, cur: TreeCursor) -> TreeNavResult {
self.suspended = false;
if let Some(status) = self.status_port.outer().get_view().get() {
self.pty = None;
}
if self.pty.is_none() {
self.cmd_editor.goto(cur)
} else {
self.cmd_editor.goto(TreeCursor {
leaf_mode: ListCursorMode::Select,
tree_addr: vec![]
});
TreeNavResult::Continue
}
}
fn goto_home(&mut self) -> TreeNavResult {
self.cmd_editor.goto_home()
}
fn goto_end(&mut self) -> TreeNavResult {
self.cmd_editor.goto_end()
}
fn pxev(&mut self) -> TreeNavResult {
self.cmd_editor.pxev()
}
fn nexd(&mut self) -> TreeNavResult {
self.cmd_editor.nexd()
}
fn up(&mut self) -> TreeNavResult {
self.cmd_editor.up()
}
fn dn(&mut self) -> TreeNavResult {
self.cmd_editor.dn()
}
}