Very borken
This commit is contained in:
parent
92ef2d2360
commit
eb0f3b0285
12 changed files with 373 additions and 217 deletions
13
Cargo.toml
13
Cargo.toml
|
|
@ -21,21 +21,12 @@ termios = "0.3"
|
|||
unicode-truncate = "0.1.1"
|
||||
unicode-width = "0.1.8"
|
||||
vte = "0.8.0"
|
||||
wasmer = "1.0.0-rc"
|
||||
wasmer-wasi = "1.0.0-rc"
|
||||
|
||||
[dependencies.async-std]
|
||||
version = "1.3.0"
|
||||
features = ["unstable"]
|
||||
|
||||
[dependencies.wasmer]
|
||||
version = "1.0.0-rc"
|
||||
optional = true
|
||||
|
||||
[dependencies.wasmer-wasi]
|
||||
version = "1.0.0-rc"
|
||||
optional = true
|
||||
|
||||
[features]
|
||||
wasm-wip = ["wasmer", "wasmer-wasi"]
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "0.16.1"
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ impl Display for ErrorContext {
|
|||
pub enum ContextType {
|
||||
Screen(ScreenContext),
|
||||
Pty(PtyContext),
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
Plugin(PluginContext),
|
||||
App(AppContext),
|
||||
IPCServer,
|
||||
|
|
@ -117,7 +117,7 @@ impl Display for ContextType {
|
|||
match *self {
|
||||
ContextType::Screen(c) => write!(f, "{}screen_thread: {}{:?}", purple, green, c),
|
||||
ContextType::Pty(c) => write!(f, "{}pty_thread: {}{:?}", purple, green, c),
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
ContextType::Plugin(c) => write!(f, "{}plugin_thread: {}{:?}", purple, green, c),
|
||||
ContextType::App(c) => write!(f, "{}main_thread: {}{:?}", purple, green, c),
|
||||
ContextType::IPCServer => write!(f, "{}ipc_server: {}AcceptInput", purple, green),
|
||||
|
|
@ -225,21 +225,22 @@ impl From<&PtyInstruction> for PtyContext {
|
|||
}
|
||||
|
||||
// FIXME: This whole pattern *needs* a macro eventually, it's soul-crushing to write
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
use crate::wasm_vm::PluginInstruction;
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum PluginContext {
|
||||
Load,
|
||||
Draw,
|
||||
Unload,
|
||||
Quit,
|
||||
}
|
||||
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
impl From<&PluginInstruction> for PluginContext {
|
||||
fn from(plugin_instruction: &PluginInstruction) -> Self {
|
||||
match *plugin_instruction {
|
||||
PluginInstruction::Load(_) => PluginContext::Load,
|
||||
PluginInstruction::Load(..) => PluginContext::Load,
|
||||
PluginInstruction::Draw(..) => PluginContext::Draw,
|
||||
PluginInstruction::Unload(_) => PluginContext::Unload,
|
||||
PluginInstruction::Quit => PluginContext::Quit,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,8 +61,11 @@ fn split_space_to_parts_horizontally(
|
|||
split_parts
|
||||
}
|
||||
|
||||
fn split_space(space_to_split: &PositionAndSize, layout: &Layout) -> Vec<PositionAndSize> {
|
||||
let mut pane_positions: Vec<PositionAndSize> = vec![];
|
||||
fn split_space(
|
||||
space_to_split: &PositionAndSize,
|
||||
layout: &Layout,
|
||||
) -> Vec<(Layout, PositionAndSize)> {
|
||||
let mut pane_positions = Vec::new();
|
||||
let percentages: Vec<u8> = layout
|
||||
.parts
|
||||
.iter()
|
||||
|
|
@ -88,7 +91,7 @@ fn split_space(space_to_split: &PositionAndSize, layout: &Layout) -> Vec<Positio
|
|||
let mut part_positions = split_space(&part_position_and_size, part);
|
||||
pane_positions.append(&mut part_positions);
|
||||
} else {
|
||||
pane_positions.push(*part_position_and_size);
|
||||
pane_positions.push((part.clone(), *part_position_and_size)); // FIXME: Probably doesn't need to be cloned
|
||||
}
|
||||
}
|
||||
pane_positions
|
||||
|
|
@ -165,17 +168,20 @@ impl Layout {
|
|||
panic!("The total percent for each part should equal 100.");
|
||||
}
|
||||
}
|
||||
pub fn total_panes(&self) -> usize {
|
||||
|
||||
pub fn total_terminal_panes(&self) -> usize {
|
||||
let mut total_panes = 0;
|
||||
total_panes += self.parts.len();
|
||||
for part in self.parts.iter() {
|
||||
total_panes += part.total_panes();
|
||||
if part.plugin.is_none() {
|
||||
total_panes += part.total_terminal_panes();
|
||||
}
|
||||
}
|
||||
total_panes
|
||||
}
|
||||
|
||||
// FIXME: I probably shouldn't exist, much less with PathBuf (use &Path)
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
pub fn list_plugins(&self) -> Vec<&PathBuf> {
|
||||
let mut plugins: Vec<_> = self.parts.iter().flat_map(Layout::list_plugins).collect();
|
||||
if let Some(path) = &self.plugin {
|
||||
|
|
@ -184,7 +190,10 @@ impl Layout {
|
|||
plugins
|
||||
}
|
||||
|
||||
pub fn position_panes_in_space(&self, space: &PositionAndSize) -> Vec<PositionAndSize> {
|
||||
pub fn position_panes_in_space(
|
||||
&self,
|
||||
space: &PositionAndSize,
|
||||
) -> Vec<(Layout, PositionAndSize)> {
|
||||
split_space(space, &self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
73
src/main.rs
73
src/main.rs
|
|
@ -12,7 +12,7 @@ mod screen;
|
|||
mod tab;
|
||||
mod terminal_pane;
|
||||
mod utils;
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
mod wasm_vm;
|
||||
|
||||
use std::io::Write;
|
||||
|
|
@ -160,14 +160,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
let mut send_pty_instructions =
|
||||
SenderWithContext::new(err_ctx, SenderType::Sender(send_pty_instructions));
|
||||
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
use crate::wasm_vm::PluginInstruction;
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
let (send_plugin_instructions, receive_plugin_instructions): (
|
||||
Sender<(PluginInstruction, ErrorContext)>,
|
||||
Receiver<(PluginInstruction, ErrorContext)>,
|
||||
) = channel();
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
let send_plugin_instructions =
|
||||
SenderWithContext::new(err_ctx, SenderType::Sender(send_plugin_instructions));
|
||||
|
||||
|
|
@ -200,17 +199,8 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
.name("pty".to_string())
|
||||
.spawn({
|
||||
let mut command_is_executing = command_is_executing.clone();
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
let send_plugin_instructions = send_plugin_instructions.clone();
|
||||
move || {
|
||||
if let Some(layout) = maybe_layout {
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
for plugin_path in layout.list_plugins() {
|
||||
dbg!(send_plugin_instructions
|
||||
.send(PluginInstruction::Load(plugin_path.clone())))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pty_bus.spawn_terminals_for_layout(layout);
|
||||
} else {
|
||||
let pid = pty_bus.spawn_terminal(None);
|
||||
|
|
@ -281,6 +271,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
let mut command_is_executing = command_is_executing.clone();
|
||||
let os_input = os_input.clone();
|
||||
let send_pty_instructions = send_pty_instructions.clone();
|
||||
let send_plugin_instructions = send_plugin_instructions.clone();
|
||||
let send_app_instructions = send_app_instructions.clone();
|
||||
let max_panes = opts.max_panes;
|
||||
|
||||
|
|
@ -288,6 +279,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
let mut screen = Screen::new(
|
||||
receive_screen_instructions,
|
||||
send_pty_instructions,
|
||||
send_plugin_instructions,
|
||||
send_app_instructions,
|
||||
&full_screen_ws,
|
||||
os_input,
|
||||
|
|
@ -411,14 +403,13 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
// Here be dragons! This is very much a work in progress, and isn't quite functional
|
||||
// yet. It's being left out of the tests because is slows them down massively (by
|
||||
// recompiling a WASM module for every single test). Stay tuned for more updates!
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
active_threads.push(
|
||||
thread::Builder::new()
|
||||
.name("wasm".to_string())
|
||||
.spawn(move || {
|
||||
use crate::errors::PluginContext;
|
||||
use crate::wasm_vm::{mosaic_imports, wasi_stdout};
|
||||
use std::{io, collections::HashMap};
|
||||
use std::collections::HashMap;
|
||||
use wasmer::{ChainableNamedResolver, Instance, Module, Store, Value};
|
||||
use wasmer_wasi::{Pipe, WasiState};
|
||||
|
||||
|
|
@ -436,7 +427,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
// screen.send_app_instructions.update(err_ctx);
|
||||
// screen.send_pty_instructions.update(err_ctx);
|
||||
match event {
|
||||
PluginInstruction::Load(path) => {
|
||||
PluginInstruction::Load(pid_tx, path) => {
|
||||
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
|
||||
let module = Module::from_file(&store, &path).unwrap();
|
||||
|
||||
|
|
@ -459,50 +450,30 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
let mosaic = mosaic_imports(&store, &wasi_env);
|
||||
let instance = Instance::new(&module, &mosaic.chain_back(wasi)).unwrap();
|
||||
|
||||
debug_log_to_file(format!("Loaded {}({}) from {}", instance.module().name().unwrap(), plugin_id, path.display())).unwrap();
|
||||
plugin_map.insert(plugin_id, instance);
|
||||
plugin_id += 1;
|
||||
|
||||
// FIXME: End the loading block here
|
||||
|
||||
// FIXME: Yucky line
|
||||
let instance = plugin_map.get(&(plugin_id - 1)).unwrap();
|
||||
|
||||
let start = instance.exports.get_function("_start").unwrap();
|
||||
let handle_key = instance.exports.get_function("handle_key").unwrap();
|
||||
let draw = instance.exports.get_function("draw").unwrap();
|
||||
|
||||
// This eventually calls the `.init()` method
|
||||
start.call(&[]).unwrap();
|
||||
|
||||
#[warn(clippy::never_loop)]
|
||||
loop {
|
||||
let (cols, rows) = (80, 24); //terminal::size()?;
|
||||
draw.call(&[Value::I32(rows), Value::I32(cols)]).unwrap();
|
||||
debug_log_to_file(format!("Loaded {}({}) from {}", instance.module().name().unwrap(), plugin_id, path.display())).unwrap();
|
||||
plugin_map.insert(plugin_id, (instance, wasi_env));
|
||||
pid_tx.send(plugin_id).unwrap();
|
||||
plugin_id += 1;
|
||||
}
|
||||
PluginInstruction::Draw(buf_tx, pid, rows, cols) => {
|
||||
let (instance, wasi_env) = plugin_map.get(&pid).unwrap();
|
||||
|
||||
// Needed because raw mode doesn't implicitly return to the start of the line
|
||||
write!(
|
||||
io::stdout(),
|
||||
let draw = instance.exports.get_function("draw").unwrap();
|
||||
|
||||
draw.call(&[Value::I32(rows as i32), Value::I32(cols as i32)]).unwrap();
|
||||
|
||||
buf_tx.send(format!(
|
||||
"{}\n\r",
|
||||
wasi_stdout(&wasi_env)
|
||||
.lines()
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n\r")
|
||||
).unwrap();
|
||||
|
||||
/* match event::read().unwrap() {
|
||||
Event::Key(KeyEvent {
|
||||
code: KeyCode::Char('q'),
|
||||
..
|
||||
}) => break,
|
||||
Event::Key(e) => {
|
||||
wasi_write_string(&wasi_env, serde_json::to_string(&e).unwrap());
|
||||
handle_key.call(&[])?;
|
||||
}
|
||||
_ => (),
|
||||
} */
|
||||
break;
|
||||
}
|
||||
)).unwrap();
|
||||
}
|
||||
PluginInstruction::Quit => break,
|
||||
i => panic!("Yo, dawg, nice job calling the wasm thread!\n {:?} is defo not implemented yet...", i),
|
||||
|
|
@ -603,14 +574,14 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
|
|||
AppInstruction::Exit => {
|
||||
let _ = send_screen_instructions.send(ScreenInstruction::Quit);
|
||||
let _ = send_pty_instructions.send(PtyInstruction::Quit);
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
let _ = send_plugin_instructions.send(PluginInstruction::Quit);
|
||||
break;
|
||||
}
|
||||
AppInstruction::Error(backtrace) => {
|
||||
let _ = send_screen_instructions.send(ScreenInstruction::Quit);
|
||||
let _ = send_pty_instructions.send(PtyInstruction::Quit);
|
||||
#[cfg(feature = "wasm-wip")]
|
||||
|
||||
let _ = send_plugin_instructions.send(PluginInstruction::Quit);
|
||||
os_input.unset_raw_mode(0);
|
||||
let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.rows, 1);
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ impl PtyBus {
|
|||
pid_primary
|
||||
}
|
||||
pub fn spawn_terminals_for_layout(&mut self, layout: Layout) {
|
||||
let total_panes = layout.total_panes();
|
||||
let total_panes = layout.total_terminal_panes();
|
||||
let mut new_pane_pids = vec![];
|
||||
for _ in 0..total_panes {
|
||||
let (pid_primary, pid_secondary): (RawFd, RawFd) = self.os_input.spawn_terminal(None);
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ use std::collections::BTreeMap;
|
|||
use std::os::unix::io::RawFd;
|
||||
use std::sync::mpsc::Receiver;
|
||||
|
||||
use crate::errors::ErrorContext;
|
||||
use crate::layout::Layout;
|
||||
use crate::os_input_output::OsApi;
|
||||
use crate::pty_bus::{PtyInstruction, VteEvent};
|
||||
use crate::tab::Tab;
|
||||
use crate::terminal_pane::PositionAndSize;
|
||||
use crate::{errors::ErrorContext, wasm_vm::PluginInstruction};
|
||||
use crate::{AppInstruction, SenderWithContext};
|
||||
|
||||
/*
|
||||
|
|
@ -55,6 +55,7 @@ pub struct Screen {
|
|||
max_panes: Option<usize>,
|
||||
tabs: BTreeMap<usize, Tab>,
|
||||
pub send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
||||
full_screen_ws: PositionAndSize,
|
||||
active_tab_index: Option<usize>,
|
||||
|
|
@ -65,6 +66,7 @@ impl Screen {
|
|||
pub fn new(
|
||||
receive_screen_instructions: Receiver<(ScreenInstruction, ErrorContext)>,
|
||||
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
send_app_instructions: SenderWithContext<AppInstruction>,
|
||||
full_screen_ws: &PositionAndSize,
|
||||
os_api: Box<dyn OsApi>,
|
||||
|
|
@ -74,6 +76,7 @@ impl Screen {
|
|||
receiver: receive_screen_instructions,
|
||||
max_panes,
|
||||
send_pty_instructions,
|
||||
send_plugin_instructions,
|
||||
send_app_instructions,
|
||||
full_screen_ws: *full_screen_ws,
|
||||
active_tab_index: None,
|
||||
|
|
@ -88,6 +91,7 @@ impl Screen {
|
|||
&self.full_screen_ws,
|
||||
self.os_api.clone(),
|
||||
self.send_pty_instructions.clone(),
|
||||
self.send_plugin_instructions.clone(),
|
||||
self.send_app_instructions.clone(),
|
||||
self.max_panes,
|
||||
Some(pane_id),
|
||||
|
|
@ -181,6 +185,7 @@ impl Screen {
|
|||
&self.full_screen_ws,
|
||||
self.os_api.clone(),
|
||||
self.send_pty_instructions.clone(),
|
||||
self.send_plugin_instructions.clone(),
|
||||
self.send_app_instructions.clone(),
|
||||
self.max_panes,
|
||||
None,
|
||||
|
|
|
|||
223
src/tab.rs
223
src/tab.rs
|
|
@ -1,13 +1,12 @@
|
|||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::io::Write;
|
||||
use std::os::unix::io::RawFd;
|
||||
|
||||
use crate::boundaries::Boundaries;
|
||||
use crate::layout::Layout;
|
||||
use crate::os_input_output::OsApi;
|
||||
use crate::pty_bus::{PtyInstruction, VteEvent};
|
||||
use crate::terminal_pane::{PositionAndSize, TerminalPane};
|
||||
use crate::{boundaries::Boundaries, terminal_pane::PluginPane};
|
||||
use crate::{layout::Layout, wasm_vm::PluginInstruction};
|
||||
use crate::{AppInstruction, SenderWithContext};
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
use std::os::unix::io::RawFd;
|
||||
use std::{io::Write, sync::mpsc::channel};
|
||||
|
||||
/*
|
||||
* Tab
|
||||
|
|
@ -51,6 +50,7 @@ fn split_horizontally_with_gap(rect: &PositionAndSize) -> (PositionAndSize, Posi
|
|||
#[derive(PartialEq, Eq, Ord, PartialOrd, Hash, Clone, Copy)]
|
||||
enum PaneKind {
|
||||
Terminal(RawFd),
|
||||
PluginPane(u32), // FIXME: Drop the trait object, make this a wrapper for the struct?
|
||||
BuiltInPane(u32),
|
||||
}
|
||||
pub struct Tab {
|
||||
|
|
@ -63,6 +63,7 @@ pub struct Tab {
|
|||
fullscreen_is_active: bool,
|
||||
os_api: Box<dyn OsApi>,
|
||||
pub send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
pub send_app_instructions: SenderWithContext<AppInstruction>,
|
||||
}
|
||||
|
||||
|
|
@ -72,10 +73,7 @@ pub trait Pane {
|
|||
fn rows(&self) -> usize;
|
||||
fn columns(&self) -> usize;
|
||||
fn reset_size_and_position_override(&mut self);
|
||||
fn change_size_p(&mut self, position_and_size: &PositionAndSize);
|
||||
fn get_rows(&self) -> usize;
|
||||
fn get_columns(&self) -> usize;
|
||||
fn change_size(&mut self, ws: &PositionAndSize);
|
||||
fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize);
|
||||
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize);
|
||||
fn handle_event(&mut self, event: VteEvent);
|
||||
fn cursor_coordinates(&self) -> Option<(usize, usize)>;
|
||||
|
|
@ -84,7 +82,7 @@ pub trait Pane {
|
|||
fn position_and_size_override(&self) -> Option<PositionAndSize>;
|
||||
fn should_render(&self) -> bool;
|
||||
fn set_should_render(&mut self, should_render: bool);
|
||||
fn buffer_as_vte_output(&mut self) -> Option<String>;
|
||||
fn render(&mut self) -> Option<String>;
|
||||
fn pid(&self) -> RawFd;
|
||||
fn reduce_height_down(&mut self, count: usize);
|
||||
fn increase_height_down(&mut self, count: usize);
|
||||
|
|
@ -148,6 +146,7 @@ impl Tab {
|
|||
full_screen_ws: &PositionAndSize,
|
||||
mut os_api: Box<dyn OsApi>,
|
||||
send_pty_instructions: SenderWithContext<PtyInstruction>,
|
||||
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
send_app_instructions: SenderWithContext<AppInstruction>,
|
||||
max_panes: Option<usize>,
|
||||
pane_id: Option<RawFd>,
|
||||
|
|
@ -156,8 +155,8 @@ impl Tab {
|
|||
let new_terminal = TerminalPane::new(pid, *full_screen_ws, 0, 0);
|
||||
os_api.set_terminal_size_using_fd(
|
||||
new_terminal.pid,
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
new_terminal.columns() as u16,
|
||||
new_terminal.rows() as u16,
|
||||
);
|
||||
let mut panes: BTreeMap<PaneKind, Box<dyn Pane>> = BTreeMap::new();
|
||||
panes.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||
|
|
@ -176,6 +175,7 @@ impl Tab {
|
|||
os_api,
|
||||
send_app_instructions,
|
||||
send_pty_instructions,
|
||||
send_plugin_instructions,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,9 +194,9 @@ impl Tab {
|
|||
// for now the layout only supports terminal panes
|
||||
if let PaneKind::Terminal(pid) = pane_kind {
|
||||
match positions_and_size.next() {
|
||||
Some(position_and_size) => {
|
||||
Some((_, position_and_size)) => {
|
||||
terminal_pane.reset_size_and_position_override();
|
||||
terminal_pane.change_size_p(&position_and_size);
|
||||
terminal_pane.change_pos_and_size(&position_and_size);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*pid,
|
||||
position_and_size.columns as u16,
|
||||
|
|
@ -212,7 +212,25 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
let mut new_pids = new_pids.iter();
|
||||
for position_and_size in positions_and_size {
|
||||
for (layout, position_and_size) in positions_and_size {
|
||||
dbg!("Loopy", &layout.plugin, position_and_size);
|
||||
// Just a regular terminal
|
||||
if let Some(plugin) = &layout.plugin {
|
||||
dbg!("Starting here!");
|
||||
let (pid_tx, pid_rx) = channel();
|
||||
self.send_plugin_instructions
|
||||
.send(PluginInstruction::Load(pid_tx, plugin.clone()))
|
||||
.unwrap();
|
||||
let pid = pid_rx.recv().unwrap();
|
||||
let new_plugin = PluginPane::new(
|
||||
pid,
|
||||
*position_and_size,
|
||||
self.send_plugin_instructions.clone(),
|
||||
);
|
||||
dbg!(pid, position_and_size, plugin);
|
||||
self.panes
|
||||
.insert(PaneKind::PluginPane(pid), Box::new(new_plugin));
|
||||
} else {
|
||||
// there are still panes left to fill, use the pids we received in this method
|
||||
let pid = new_pids.next().unwrap(); // if this crashes it means we got less pids than there are panes in this layout
|
||||
let mut new_terminal = TerminalPane::new(
|
||||
|
|
@ -221,15 +239,16 @@ impl Tab {
|
|||
position_and_size.x,
|
||||
position_and_size.y,
|
||||
);
|
||||
new_terminal.change_size_p(position_and_size);
|
||||
new_terminal.change_pos_and_size(position_and_size);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
new_terminal.pid,
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
new_terminal.columns() as u16,
|
||||
new_terminal.rows() as u16,
|
||||
);
|
||||
self.panes
|
||||
.insert(PaneKind::Terminal(*pid), Box::new(new_terminal));
|
||||
}
|
||||
}
|
||||
for unused_pid in new_pids {
|
||||
// this is a bit of a hack and happens because we don't have any central location that
|
||||
// can query the screen as to how many panes it needs to create a layout
|
||||
|
|
@ -259,8 +278,8 @@ impl Tab {
|
|||
let new_terminal = TerminalPane::new(pid, self.full_screen_ws, x, y);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
new_terminal.pid,
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
new_terminal.columns() as u16,
|
||||
new_terminal.rows() as u16,
|
||||
);
|
||||
self.panes
|
||||
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||
|
|
@ -272,8 +291,8 @@ impl Tab {
|
|||
(0, 0),
|
||||
|(current_longest_edge, current_terminal_id_to_split), id_and_terminal_to_check| {
|
||||
let (id_of_terminal_to_check, terminal_to_check) = id_and_terminal_to_check;
|
||||
let terminal_size = (terminal_to_check.get_rows() * CURSOR_HEIGHT_WIDTH_RATIO)
|
||||
* terminal_to_check.get_columns();
|
||||
let terminal_size = (terminal_to_check.rows() * CURSOR_HEIGHT_WIDTH_RATIO)
|
||||
* terminal_to_check.columns();
|
||||
if terminal_size > current_longest_edge {
|
||||
(terminal_size, id_of_terminal_to_check)
|
||||
} else {
|
||||
|
|
@ -286,14 +305,12 @@ impl Tab {
|
|||
.get_mut(&PaneKind::Terminal(terminal_id_to_split))
|
||||
.unwrap();
|
||||
let terminal_ws = PositionAndSize {
|
||||
rows: terminal_to_split.get_rows(),
|
||||
columns: terminal_to_split.get_columns(),
|
||||
rows: terminal_to_split.rows(),
|
||||
columns: terminal_to_split.columns(),
|
||||
x: terminal_to_split.x(),
|
||||
y: terminal_to_split.y(),
|
||||
};
|
||||
if terminal_to_split.get_rows() * CURSOR_HEIGHT_WIDTH_RATIO
|
||||
> terminal_to_split.get_columns()
|
||||
{
|
||||
if terminal_to_split.rows() * CURSOR_HEIGHT_WIDTH_RATIO > terminal_to_split.columns() {
|
||||
let (top_winsize, bottom_winsize) = split_horizontally_with_gap(&terminal_ws);
|
||||
let bottom_half_y = terminal_ws.y + top_winsize.rows + 1;
|
||||
let new_terminal =
|
||||
|
|
@ -303,7 +320,7 @@ impl Tab {
|
|||
bottom_winsize.columns as u16,
|
||||
bottom_winsize.rows as u16,
|
||||
);
|
||||
terminal_to_split.change_size(&top_winsize);
|
||||
terminal_to_split.change_pos_and_size(&top_winsize);
|
||||
self.panes
|
||||
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
|
|
@ -322,7 +339,7 @@ impl Tab {
|
|||
right_winsize.columns as u16,
|
||||
right_winsize.rows as u16,
|
||||
);
|
||||
terminal_to_split.change_size(&left_winszie);
|
||||
terminal_to_split.change_pos_and_size(&left_winszie);
|
||||
self.panes
|
||||
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
|
|
@ -346,8 +363,8 @@ impl Tab {
|
|||
let new_terminal = TerminalPane::new(pid, self.full_screen_ws, x, y);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
new_terminal.pid,
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
new_terminal.columns() as u16,
|
||||
new_terminal.rows() as u16,
|
||||
);
|
||||
self.panes
|
||||
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||
|
|
@ -358,8 +375,8 @@ impl Tab {
|
|||
let active_terminal = &self.get_active_terminal().unwrap();
|
||||
(
|
||||
PositionAndSize {
|
||||
rows: active_terminal.get_rows(),
|
||||
columns: active_terminal.get_columns(),
|
||||
rows: active_terminal.rows(),
|
||||
columns: active_terminal.columns(),
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
|
|
@ -383,7 +400,7 @@ impl Tab {
|
|||
.panes
|
||||
.get_mut(&PaneKind::Terminal(*active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.change_size(&top_winsize);
|
||||
active_terminal.change_pos_and_size(&top_winsize);
|
||||
}
|
||||
|
||||
self.panes
|
||||
|
|
@ -409,8 +426,8 @@ impl Tab {
|
|||
let new_terminal = TerminalPane::new(pid, self.full_screen_ws, x, y);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
new_terminal.pid,
|
||||
new_terminal.get_columns() as u16,
|
||||
new_terminal.get_rows() as u16,
|
||||
new_terminal.columns() as u16,
|
||||
new_terminal.rows() as u16,
|
||||
);
|
||||
self.panes
|
||||
.insert(PaneKind::Terminal(pid), Box::new(new_terminal));
|
||||
|
|
@ -421,8 +438,8 @@ impl Tab {
|
|||
let active_terminal = &self.get_active_terminal().unwrap();
|
||||
(
|
||||
PositionAndSize {
|
||||
rows: active_terminal.get_rows(),
|
||||
columns: active_terminal.get_columns(),
|
||||
rows: active_terminal.rows(),
|
||||
columns: active_terminal.columns(),
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
|
|
@ -446,7 +463,7 @@ impl Tab {
|
|||
.panes
|
||||
.get_mut(&PaneKind::Terminal(*active_terminal_id))
|
||||
.unwrap();
|
||||
active_terminal.change_size(&left_winszie);
|
||||
active_terminal.change_pos_and_size(&left_winszie);
|
||||
}
|
||||
|
||||
self.panes
|
||||
|
|
@ -545,8 +562,8 @@ impl Tab {
|
|||
.unwrap();
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
active_terminal_id,
|
||||
active_terminal.get_columns() as u16,
|
||||
active_terminal.get_rows() as u16,
|
||||
active_terminal.columns() as u16,
|
||||
active_terminal.rows() as u16,
|
||||
);
|
||||
self.render();
|
||||
self.toggle_fullscreen_is_active();
|
||||
|
|
@ -571,7 +588,7 @@ impl Tab {
|
|||
PaneKind::Terminal(pid) => {
|
||||
if !self.panes_to_hide.contains(pid) {
|
||||
boundaries.add_rect(&terminal);
|
||||
if let Some(vte_output) = terminal.buffer_as_vte_output() {
|
||||
if let Some(vte_output) = terminal.render() {
|
||||
stdout
|
||||
.write_all(&vte_output.as_bytes())
|
||||
.expect("cannot write to stdout");
|
||||
|
|
@ -581,6 +598,16 @@ impl Tab {
|
|||
PaneKind::BuiltInPane(builtin_id) => {
|
||||
// TBD
|
||||
}
|
||||
PaneKind::PluginPane(_) => {
|
||||
if let Some(output) = terminal.render() {
|
||||
write!(
|
||||
stdout,
|
||||
"{}\n\r",
|
||||
output.lines().collect::<Vec<_>>().join("\n\r")
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -634,7 +661,7 @@ impl Tab {
|
|||
return None;
|
||||
}
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.x() + terminal.get_columns() == terminal_to_check.x() - 1 {
|
||||
if terminal.x() + terminal.columns() == terminal_to_check.x() - 1 {
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
|
|
@ -648,7 +675,7 @@ impl Tab {
|
|||
let mut ids = vec![];
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.get_columns() + 1 {
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 {
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
|
|
@ -662,7 +689,7 @@ impl Tab {
|
|||
let mut ids = vec![];
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.get_rows() + 1 {
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 {
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
|
|
@ -676,7 +703,7 @@ impl Tab {
|
|||
let mut ids = vec![];
|
||||
let terminal_to_check = self.panes.get(&PaneKind::Terminal(*id)).unwrap();
|
||||
for (pid, terminal) in self.get_terminals() {
|
||||
if terminal.y() + terminal.get_rows() + 1 == terminal_to_check.y() {
|
||||
if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() {
|
||||
ids.push(pid);
|
||||
}
|
||||
}
|
||||
|
|
@ -699,7 +726,7 @@ impl Tab {
|
|||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.filter(|terminal| {
|
||||
terminal.pid() != pane.pid()
|
||||
&& terminal.y() + terminal.get_rows() == pane.y() + pane.get_rows()
|
||||
&& terminal.y() + terminal.rows() == pane.y() + pane.rows()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -709,7 +736,7 @@ impl Tab {
|
|||
.map(|t_id| self.panes.get(&t_id).unwrap())
|
||||
.filter(|terminal| {
|
||||
terminal.pid() != pane.pid()
|
||||
&& terminal.x() + terminal.get_columns() == pane.x() + pane.get_columns()
|
||||
&& terminal.x() + terminal.columns() == pane.x() + pane.columns()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -735,14 +762,14 @@ impl Tab {
|
|||
right_aligned_terminals.sort_by(|a, b| b.y().cmp(&a.y()));
|
||||
for terminal in right_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() + terminal.get_rows() + 1 == terminal_to_check.y() {
|
||||
if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
// top-most border aligned with a pane border to the right
|
||||
let mut top_resize_border = 0;
|
||||
for terminal in &terminals {
|
||||
let bottom_terminal_boundary = terminal.y() + terminal.get_rows();
|
||||
let bottom_terminal_boundary = terminal.y() + terminal.rows();
|
||||
if terminal_borders_to_the_right
|
||||
.get(&(bottom_terminal_boundary + 1))
|
||||
.is_some()
|
||||
|
|
@ -777,7 +804,7 @@ impl Tab {
|
|||
right_aligned_terminals.sort_by(|a, b| a.y().cmp(&b.y()));
|
||||
for terminal in right_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.get_rows() + 1 {
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
|
|
@ -793,11 +820,11 @@ impl Tab {
|
|||
bottom_resize_border = top_terminal_boundary;
|
||||
}
|
||||
}
|
||||
terminals.retain(|terminal| terminal.y() + terminal.get_rows() <= bottom_resize_border);
|
||||
terminals.retain(|terminal| terminal.y() + terminal.rows() <= bottom_resize_border);
|
||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||
// resizing
|
||||
let bottom_resize_border = if terminals.is_empty() {
|
||||
terminal_to_check.y() + terminal_to_check.get_rows()
|
||||
terminal_to_check.y() + terminal_to_check.rows()
|
||||
} else {
|
||||
bottom_resize_border
|
||||
};
|
||||
|
|
@ -819,14 +846,14 @@ impl Tab {
|
|||
left_aligned_terminals.sort_by(|a, b| b.y().cmp(&a.y()));
|
||||
for terminal in left_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() + terminal.get_rows() + 1 == terminal_to_check.y() {
|
||||
if terminal.y() + terminal.rows() + 1 == terminal_to_check.y() {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
// top-most border aligned with a pane border to the right
|
||||
let mut top_resize_border = 0;
|
||||
for terminal in &terminals {
|
||||
let bottom_terminal_boundary = terminal.y() + terminal.get_rows();
|
||||
let bottom_terminal_boundary = terminal.y() + terminal.rows();
|
||||
if terminal_borders_to_the_left
|
||||
.get(&(bottom_terminal_boundary + 1))
|
||||
.is_some()
|
||||
|
|
@ -861,7 +888,7 @@ impl Tab {
|
|||
left_aligned_terminals.sort_by(|a, b| a.y().cmp(&b.y()));
|
||||
for terminal in left_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.get_rows() + 1 {
|
||||
if terminal.y() == terminal_to_check.y() + terminal_to_check.rows() + 1 {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
|
|
@ -878,13 +905,13 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
terminals.retain(|terminal| {
|
||||
// terminal.y() + terminal.get_rows() < bottom_resize_border
|
||||
terminal.y() + terminal.get_rows() <= bottom_resize_border
|
||||
// terminal.y() + terminal.rows() < bottom_resize_border
|
||||
terminal.y() + terminal.rows() <= bottom_resize_border
|
||||
});
|
||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||
// resizing
|
||||
let bottom_resize_border = if terminals.is_empty() {
|
||||
terminal_to_check.y() + terminal_to_check.get_rows()
|
||||
terminal_to_check.y() + terminal_to_check.rows()
|
||||
} else {
|
||||
bottom_resize_border
|
||||
};
|
||||
|
|
@ -906,14 +933,14 @@ impl Tab {
|
|||
top_aligned_terminals.sort_by(|a, b| b.x().cmp(&a.x()));
|
||||
for terminal in top_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.x() + terminal.get_columns() + 1 == terminal_to_check.x() {
|
||||
if terminal.x() + terminal.columns() + 1 == terminal_to_check.x() {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
// leftmost border aligned with a pane border above
|
||||
let mut left_resize_border = 0;
|
||||
for terminal in &terminals {
|
||||
let right_terminal_boundary = terminal.x() + terminal.get_columns();
|
||||
let right_terminal_boundary = terminal.x() + terminal.columns();
|
||||
if terminal_borders_above
|
||||
.get(&(right_terminal_boundary + 1))
|
||||
.is_some()
|
||||
|
|
@ -945,7 +972,7 @@ impl Tab {
|
|||
top_aligned_terminals.sort_by(|a, b| a.x().cmp(&b.x()));
|
||||
for terminal in top_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.get_columns() + 1 {
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
|
|
@ -961,11 +988,11 @@ impl Tab {
|
|||
right_resize_border = left_terminal_boundary;
|
||||
}
|
||||
}
|
||||
terminals.retain(|terminal| terminal.x() + terminal.get_columns() <= right_resize_border);
|
||||
terminals.retain(|terminal| terminal.x() + terminal.columns() <= right_resize_border);
|
||||
// if there are no adjacent panes to resize, we use the border of the main pane we're
|
||||
// resizing
|
||||
let right_resize_border = if terminals.is_empty() {
|
||||
terminal_to_check.x() + terminal_to_check.get_columns()
|
||||
terminal_to_check.x() + terminal_to_check.columns()
|
||||
} else {
|
||||
right_resize_border
|
||||
};
|
||||
|
|
@ -984,14 +1011,14 @@ impl Tab {
|
|||
// terminals that are next to each other up to current
|
||||
for terminal in bottom_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.x() + terminal.get_columns() + 1 == terminal_to_check.x() {
|
||||
if terminal.x() + terminal.columns() + 1 == terminal_to_check.x() {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
// leftmost border aligned with a pane border above
|
||||
let mut left_resize_border = 0;
|
||||
for terminal in &terminals {
|
||||
let right_terminal_boundary = terminal.x() + terminal.get_columns();
|
||||
let right_terminal_boundary = terminal.x() + terminal.columns();
|
||||
if terminal_borders_below
|
||||
.get(&(right_terminal_boundary + 1))
|
||||
.is_some()
|
||||
|
|
@ -1023,7 +1050,7 @@ impl Tab {
|
|||
// terminals that are next to each other up to current
|
||||
for terminal in bottom_aligned_terminals {
|
||||
let terminal_to_check = terminals.last().unwrap_or(&terminal_to_check);
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.get_columns() + 1 {
|
||||
if terminal.x() == terminal_to_check.x() + terminal_to_check.columns() + 1 {
|
||||
terminals.push(terminal);
|
||||
}
|
||||
}
|
||||
|
|
@ -1039,9 +1066,9 @@ impl Tab {
|
|||
right_resize_border = left_terminal_boundary;
|
||||
}
|
||||
}
|
||||
terminals.retain(|terminal| terminal.x() + terminal.get_columns() <= right_resize_border);
|
||||
terminals.retain(|terminal| terminal.x() + terminal.columns() <= right_resize_border);
|
||||
let right_resize_border = if terminals.is_empty() {
|
||||
terminal_to_check.x() + terminal_to_check.get_columns()
|
||||
terminal_to_check.x() + terminal_to_check.columns()
|
||||
} else {
|
||||
right_resize_border
|
||||
};
|
||||
|
|
@ -1053,8 +1080,8 @@ impl Tab {
|
|||
terminal.reduce_height_down(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*id,
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn reduce_pane_height_up(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1062,8 +1089,8 @@ impl Tab {
|
|||
terminal.reduce_height_up(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
*id,
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn increase_pane_height_down(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1071,8 +1098,8 @@ impl Tab {
|
|||
terminal.increase_height_down(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid(),
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn increase_pane_height_up(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1080,8 +1107,8 @@ impl Tab {
|
|||
terminal.increase_height_up(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid(),
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn increase_pane_width_right(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1089,8 +1116,8 @@ impl Tab {
|
|||
terminal.increase_width_right(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid(),
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn increase_pane_width_left(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1098,8 +1125,8 @@ impl Tab {
|
|||
terminal.increase_width_left(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid(),
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn reduce_pane_width_right(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1107,8 +1134,8 @@ impl Tab {
|
|||
terminal.reduce_width_right(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid(),
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn reduce_pane_width_left(&mut self, id: &RawFd, count: usize) {
|
||||
|
|
@ -1116,8 +1143,8 @@ impl Tab {
|
|||
terminal.reduce_width_left(count);
|
||||
self.os_api.set_terminal_size_using_fd(
|
||||
terminal.pid(),
|
||||
terminal.get_columns() as u16,
|
||||
terminal.get_rows() as u16,
|
||||
terminal.columns() as u16,
|
||||
terminal.rows() as u16,
|
||||
);
|
||||
}
|
||||
fn pane_is_between_vertical_borders(
|
||||
|
|
@ -1130,7 +1157,7 @@ impl Tab {
|
|||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("could not find terminal to check between borders");
|
||||
terminal.x() >= left_border_x && terminal.x() + terminal.get_columns() <= right_border_x
|
||||
terminal.x() >= left_border_x && terminal.x() + terminal.columns() <= right_border_x
|
||||
}
|
||||
fn pane_is_between_horizontal_borders(
|
||||
&self,
|
||||
|
|
@ -1142,7 +1169,7 @@ impl Tab {
|
|||
.panes
|
||||
.get(&PaneKind::Terminal(*id))
|
||||
.expect("could not find terminal to check between borders");
|
||||
terminal.y() >= top_border_y && terminal.y() + terminal.get_rows() <= bottom_border_y
|
||||
terminal.y() >= top_border_y && terminal.y() + terminal.rows() <= bottom_border_y
|
||||
}
|
||||
fn reduce_pane_and_surroundings_up(&mut self, id: &RawFd, count: usize) {
|
||||
let mut terminals_below = self
|
||||
|
|
@ -1352,14 +1379,14 @@ impl Tab {
|
|||
.panes
|
||||
.get(&PaneKind::Terminal(*pane_id))
|
||||
.expect("pane does not exist");
|
||||
pane.y() + pane.get_rows() < self.full_screen_ws.rows
|
||||
pane.y() + pane.rows() < self.full_screen_ws.rows
|
||||
}
|
||||
fn panes_exist_to_the_right(&self, pane_id: &RawFd) -> bool {
|
||||
let pane = self
|
||||
.panes
|
||||
.get(&PaneKind::Terminal(*pane_id))
|
||||
.expect("pane does not exist");
|
||||
pane.x() + pane.get_columns() < self.full_screen_ws.columns
|
||||
pane.x() + pane.columns() < self.full_screen_ws.columns
|
||||
}
|
||||
fn panes_exist_to_the_left(&self, pane_id: &RawFd) -> bool {
|
||||
let pane = self
|
||||
|
|
@ -1564,7 +1591,7 @@ impl Tab {
|
|||
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
||||
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
||||
borders.insert(terminal.y());
|
||||
borders.insert(terminal.y() + terminal.get_rows() + 1); // 1 for the border width
|
||||
borders.insert(terminal.y() + terminal.rows() + 1); // 1 for the border width
|
||||
borders
|
||||
})
|
||||
}
|
||||
|
|
@ -1572,14 +1599,14 @@ impl Tab {
|
|||
terminals.iter().fold(HashSet::new(), |mut borders, t| {
|
||||
let terminal = self.panes.get(&PaneKind::Terminal(*t)).unwrap();
|
||||
borders.insert(terminal.x());
|
||||
borders.insert(terminal.x() + terminal.get_columns() + 1); // 1 for the border width
|
||||
borders.insert(terminal.x() + terminal.columns() + 1); // 1 for the border width
|
||||
borders
|
||||
})
|
||||
}
|
||||
fn terminals_to_the_left_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let upper_close_border = terminal.y();
|
||||
let lower_close_border = terminal.y() + terminal.get_rows() + 1;
|
||||
let lower_close_border = terminal.y() + terminal.rows() + 1;
|
||||
|
||||
if let Some(mut terminals_to_the_left) = self.terminal_ids_directly_left_of(&id) {
|
||||
let terminal_borders_to_the_left = self.horizontal_borders(&terminals_to_the_left);
|
||||
|
|
@ -1602,7 +1629,7 @@ impl Tab {
|
|||
fn terminals_to_the_right_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let upper_close_border = terminal.y();
|
||||
let lower_close_border = terminal.y() + terminal.get_rows() + 1;
|
||||
let lower_close_border = terminal.y() + terminal.rows() + 1;
|
||||
|
||||
if let Some(mut terminals_to_the_right) = self.terminal_ids_directly_right_of(&id) {
|
||||
let terminal_borders_to_the_right =
|
||||
|
|
@ -1626,7 +1653,7 @@ impl Tab {
|
|||
fn terminals_above_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let left_close_border = terminal.x();
|
||||
let right_close_border = terminal.x() + terminal.get_columns() + 1;
|
||||
let right_close_border = terminal.x() + terminal.columns() + 1;
|
||||
|
||||
if let Some(mut terminals_above) = self.terminal_ids_directly_above(&id) {
|
||||
let terminal_borders_above = self.vertical_borders(&terminals_above);
|
||||
|
|
@ -1649,7 +1676,7 @@ impl Tab {
|
|||
fn terminals_below_between_aligning_borders(&self, id: RawFd) -> Option<Vec<RawFd>> {
|
||||
if let Some(terminal) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let left_close_border = terminal.x();
|
||||
let right_close_border = terminal.x() + terminal.get_columns() + 1;
|
||||
let right_close_border = terminal.x() + terminal.columns() + 1;
|
||||
|
||||
if let Some(mut terminals_below) = self.terminal_ids_directly_below(&id) {
|
||||
let terminal_borders_below = self.vertical_borders(&terminals_below);
|
||||
|
|
@ -1692,8 +1719,8 @@ impl Tab {
|
|||
}
|
||||
pub fn close_pane_without_rerender(&mut self, id: RawFd) {
|
||||
if let Some(terminal_to_close) = &self.panes.get(&PaneKind::Terminal(id)) {
|
||||
let terminal_to_close_width = terminal_to_close.get_columns();
|
||||
let terminal_to_close_height = terminal_to_close.get_rows();
|
||||
let terminal_to_close_width = terminal_to_close.columns();
|
||||
let terminal_to_close_height = terminal_to_close.rows();
|
||||
if let Some(terminals) = self.terminals_to_the_left_between_aligning_borders(id) {
|
||||
for terminal_id in terminals.iter() {
|
||||
self.increase_pane_width_right(&terminal_id, terminal_to_close_width + 1);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
mod plugin_pane;
|
||||
mod scroll;
|
||||
mod terminal_character;
|
||||
mod terminal_pane;
|
||||
|
||||
pub use plugin_pane::*;
|
||||
pub use scroll::*;
|
||||
pub use terminal_character::*;
|
||||
pub use terminal_pane::*;
|
||||
|
|
|
|||
168
src/terminal_pane/plugin_pane.rs
Normal file
168
src/terminal_pane/plugin_pane.rs
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
#![allow(clippy::clippy::if_same_then_else)]
|
||||
|
||||
use crate::{pty_bus::VteEvent, tab::Pane, wasm_vm::PluginInstruction, SenderWithContext};
|
||||
|
||||
use std::{os::unix::prelude::RawFd, sync::mpsc::channel};
|
||||
|
||||
use crate::terminal_pane::PositionAndSize;
|
||||
|
||||
pub struct PluginPane {
|
||||
pub pid: u32,
|
||||
pub should_render: bool,
|
||||
pub position_and_size: PositionAndSize,
|
||||
pub position_and_size_override: Option<PositionAndSize>,
|
||||
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
}
|
||||
|
||||
impl PluginPane {
|
||||
pub fn new(
|
||||
pid: u32,
|
||||
position_and_size: PositionAndSize,
|
||||
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||
) -> Self {
|
||||
Self {
|
||||
pid,
|
||||
should_render: true,
|
||||
position_and_size,
|
||||
position_and_size_override: None,
|
||||
send_plugin_instructions,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Pane for PluginPane {
|
||||
// FIXME: These position and size things should all be moved to default trait implementations,
|
||||
// with something like a get_pos_and_sz() method underpinning all of them. Alternatively and
|
||||
// preferably, just use an enum and not a trait object
|
||||
fn x(&self) -> usize {
|
||||
self.position_and_size_override
|
||||
.unwrap_or(self.position_and_size)
|
||||
.x
|
||||
}
|
||||
fn y(&self) -> usize {
|
||||
self.position_and_size_override
|
||||
.unwrap_or(self.position_and_size)
|
||||
.y
|
||||
}
|
||||
fn rows(&self) -> usize {
|
||||
self.position_and_size_override
|
||||
.unwrap_or(self.position_and_size)
|
||||
.rows
|
||||
}
|
||||
fn columns(&self) -> usize {
|
||||
self.position_and_size_override
|
||||
.unwrap_or(self.position_and_size)
|
||||
.columns
|
||||
}
|
||||
fn reset_size_and_position_override(&mut self) {
|
||||
self.position_and_size_override = None;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) {
|
||||
self.position_and_size = *position_and_size;
|
||||
self.should_render = true;
|
||||
}
|
||||
// FIXME: This is obviously a bit outdated and needs the x and y moved into `size`
|
||||
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) {
|
||||
let position_and_size_override = PositionAndSize {
|
||||
x,
|
||||
y,
|
||||
rows: size.rows,
|
||||
columns: size.columns,
|
||||
};
|
||||
self.position_and_size_override = Some(position_and_size_override);
|
||||
self.should_render = true;
|
||||
}
|
||||
fn handle_event(&mut self, event: VteEvent) {
|
||||
todo!()
|
||||
}
|
||||
fn cursor_coordinates(&self) -> Option<(usize, usize)> {
|
||||
None
|
||||
}
|
||||
fn adjust_input_to_terminal(&self, input_bytes: Vec<u8>) -> Vec<u8> {
|
||||
todo!() // FIXME: Shouldn't need this implmented?
|
||||
}
|
||||
|
||||
fn position_and_size_override(&self) -> Option<PositionAndSize> {
|
||||
self.position_and_size_override
|
||||
}
|
||||
fn should_render(&self) -> bool {
|
||||
self.should_render
|
||||
}
|
||||
fn set_should_render(&mut self, should_render: bool) {
|
||||
self.should_render = should_render;
|
||||
}
|
||||
fn render(&mut self) -> Option<String> {
|
||||
// if self.should_render {
|
||||
if true {
|
||||
// while checking should_render rather than rendering each pane every time
|
||||
// is more performant, it causes some problems when the pane to the left should be
|
||||
// rendered and has wide characters (eg. Chinese characters or emoji)
|
||||
// as a (hopefully) temporary hack, we render all panes until we find a better solution
|
||||
let (buf_tx, buf_rx) = channel();
|
||||
|
||||
self.send_plugin_instructions
|
||||
.send(PluginInstruction::Draw(
|
||||
buf_tx,
|
||||
self.pid,
|
||||
self.rows(),
|
||||
self.columns(),
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
self.should_render = false;
|
||||
Some(buf_rx.recv().unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
// FIXME: Really shouldn't be in this trait...
|
||||
fn pid(&self) -> RawFd {
|
||||
todo!()
|
||||
}
|
||||
fn reduce_height_down(&mut self, count: usize) {
|
||||
self.position_and_size.y += count;
|
||||
self.position_and_size.rows -= count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn increase_height_down(&mut self, count: usize) {
|
||||
self.position_and_size.rows += count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn increase_height_up(&mut self, count: usize) {
|
||||
self.position_and_size.y -= count;
|
||||
self.position_and_size.rows += count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn reduce_height_up(&mut self, count: usize) {
|
||||
self.position_and_size.rows -= count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn reduce_width_right(&mut self, count: usize) {
|
||||
self.position_and_size.x += count;
|
||||
self.position_and_size.columns -= count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn reduce_width_left(&mut self, count: usize) {
|
||||
self.position_and_size.columns -= count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn increase_width_left(&mut self, count: usize) {
|
||||
self.position_and_size.x -= count;
|
||||
self.position_and_size.columns += count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn increase_width_right(&mut self, count: usize) {
|
||||
self.position_and_size.columns += count;
|
||||
self.should_render = true;
|
||||
}
|
||||
fn scroll_up(&mut self, count: usize) {
|
||||
todo!()
|
||||
}
|
||||
fn scroll_down(&mut self, count: usize) {
|
||||
todo!()
|
||||
}
|
||||
fn clear_scroll(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
|
@ -58,30 +58,11 @@ impl Pane for TerminalPane {
|
|||
self.reflow_lines();
|
||||
self.mark_for_rerender();
|
||||
}
|
||||
fn change_size_p(&mut self, position_and_size: &PositionAndSize) {
|
||||
fn change_pos_and_size(&mut self, position_and_size: &PositionAndSize) {
|
||||
self.position_and_size = *position_and_size;
|
||||
self.reflow_lines();
|
||||
self.mark_for_rerender();
|
||||
}
|
||||
fn get_rows(&self) -> usize {
|
||||
match &self.position_and_size_override.as_ref() {
|
||||
Some(position_and_size_override) => position_and_size_override.rows,
|
||||
None => self.position_and_size.rows as usize,
|
||||
}
|
||||
}
|
||||
fn get_columns(&self) -> usize {
|
||||
match &self.position_and_size_override.as_ref() {
|
||||
Some(position_and_size_override) => position_and_size_override.columns,
|
||||
None => self.position_and_size.columns as usize,
|
||||
}
|
||||
}
|
||||
fn change_size(&mut self, ws: &PositionAndSize) {
|
||||
self.position_and_size.columns = ws.columns;
|
||||
self.position_and_size.rows = ws.rows;
|
||||
self.reflow_lines();
|
||||
self.mark_for_rerender();
|
||||
}
|
||||
|
||||
fn override_size_and_position(&mut self, x: usize, y: usize, size: &PositionAndSize) {
|
||||
let position_and_size_override = PositionAndSize {
|
||||
x,
|
||||
|
|
@ -179,8 +160,7 @@ impl Pane for TerminalPane {
|
|||
fn set_should_render(&mut self, should_render: bool) {
|
||||
self.should_render = should_render;
|
||||
}
|
||||
fn buffer_as_vte_output(&mut self) -> Option<String> {
|
||||
// TODO: rename to render
|
||||
fn render(&mut self) -> Option<String> {
|
||||
// if self.should_render {
|
||||
if true {
|
||||
// while checking should_render rather than rendering each pane every time
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ parts:
|
|||
Percent: 80
|
||||
split_size:
|
||||
Percent: 80
|
||||
plugin: strider.wasm
|
||||
- direction: Vertical
|
||||
split_size:
|
||||
Percent: 20
|
||||
plugin: strider.wasm
|
||||
#plugin: strider.wasm
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
use std::{
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
sync::mpsc::Sender,
|
||||
};
|
||||
use wasmer::{imports, Function, ImportObject, Store};
|
||||
use wasmer_wasi::WasiEnv;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum PluginInstruction {
|
||||
Load(PathBuf),
|
||||
Load(Sender<u32>, PathBuf), // FIXME: Maybe send a channel handle?
|
||||
// String buffer, plugin id, rows, cols
|
||||
Draw(Sender<String>, u32, usize, usize), // FIXME: This is super gross
|
||||
Unload(u32),
|
||||
Quit,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue