Finish implementing default layouts

This commit is contained in:
Brooks J Rady 2021-01-12 04:34:19 +00:00
parent 555f9af37a
commit 209cce96a5
6 changed files with 159 additions and 146 deletions

View file

@ -5,4 +5,4 @@ parts:
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 1 Fixed: 1
plugin: status-bar.wasm plugin: status-bar

View file

@ -6,9 +6,9 @@ parts:
- direction: Horizontal - direction: Horizontal
split_size: split_size:
Percent: 20 Percent: 20
plugin: strider.wasm plugin: strider
- direction: Horizontal - direction: Horizontal
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 1 Fixed: 1
plugin: status-bar.wasm plugin: status-bar

Binary file not shown.

View file

@ -317,8 +317,8 @@ pub fn get_help(mode: &InputMode) -> Vec<String> {
"<q> Quit".into(), "<q> Quit".into(),
"<PgUp/PgDown> Scroll".into(), "<PgUp/PgDown> Scroll".into(),
"<1> New Tab".into(), "<1> New Tab".into(),
"<2> Next Tab".into(), "<2/3> Move Tab".into(),
"<3> Last Tab".into(), "<4> Close Tab".into(),
]; ];
match mode { match mode {
InputMode::Normal => vec!["<Ctrl-g> Command Mode".into()], InputMode::Normal => vec!["<Ctrl-g> Command Mode".into()],

View file

@ -1,3 +1,4 @@
use directories_next::ProjectDirs;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{fs::File, io::prelude::*, path::PathBuf}; use std::{fs::File, io::prelude::*, path::PathBuf};
@ -179,7 +180,11 @@ pub struct Layout {
impl Layout { impl Layout {
pub fn new(layout_path: PathBuf) -> Self { pub fn new(layout_path: PathBuf) -> Self {
let project_dirs = ProjectDirs::from("org", "Mosaic Contributors", "Mosaic").unwrap();
let layout_dir = project_dirs.data_dir().join("layouts/");
let mut layout_file = File::open(&layout_path) let mut layout_file = File::open(&layout_path)
.or_else(|_| File::open(&layout_path.with_extension("yaml")))
.or_else(|_| File::open(&layout_dir.join(&layout_path).with_extension("yaml")))
.unwrap_or_else(|_| panic!("cannot find layout {}", &layout_path.display())); .unwrap_or_else(|_| panic!("cannot find layout {}", &layout_path.display()));
let mut layout = String::new(); let mut layout = String::new();

View file

@ -16,14 +16,15 @@ mod utils;
mod wasm_vm; mod wasm_vm;
use std::collections::HashMap;
use std::io::Write; use std::io::Write;
use std::os::unix::net::UnixStream; use std::os::unix::net::UnixStream;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::mpsc::{channel, sync_channel, Receiver, SendError, Sender, SyncSender}; use std::sync::mpsc::{channel, sync_channel, Receiver, SendError, Sender, SyncSender};
use std::thread; use std::thread;
use std::{cell::RefCell, sync::mpsc::TrySendError}; use std::{cell::RefCell, sync::mpsc::TrySendError};
use std::{collections::HashMap, fs};
use directories_next::ProjectDirs;
use input::InputMode; use input::InputMode;
use panes::PaneId; use panes::PaneId;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -208,7 +209,12 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
os_input.clone(), os_input.clone(),
opts.debug, opts.debug,
); );
let maybe_layout = opts.layout.map(Layout::new); // Don't use default layouts in tests, but do everywhere else
#[cfg(not(test))]
let default_layout = Some(PathBuf::from("default"));
#[cfg(test)]
let default_layout = None;
let maybe_layout = opts.layout.or(default_layout).map(Layout::new);
#[cfg(not(test))] #[cfg(not(test))]
std::panic::set_hook({ std::panic::set_hook({
@ -224,18 +230,8 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
.name("pty".to_string()) .name("pty".to_string())
.spawn({ .spawn({
let mut command_is_executing = command_is_executing.clone(); let mut command_is_executing = command_is_executing.clone();
move || { send_pty_instructions.send(PtyInstruction::NewTab).unwrap();
if let Some(layout) = maybe_layout { move || loop {
pty_bus.spawn_terminals_for_layout(layout);
} else {
let pid = pty_bus.spawn_terminal(None);
pty_bus
.send_screen_instructions
.send(ScreenInstruction::NewTab(pid))
.unwrap();
}
loop {
let (event, mut err_ctx) = pty_bus let (event, mut err_ctx) = pty_bus
.receive_pty_instructions .receive_pty_instructions
.recv() .recv()
@ -265,12 +261,16 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
.unwrap(); .unwrap();
} }
PtyInstruction::NewTab => { PtyInstruction::NewTab => {
if let Some(layout) = maybe_layout.clone() {
pty_bus.spawn_terminals_for_layout(layout);
} else {
let pid = pty_bus.spawn_terminal(None); let pid = pty_bus.spawn_terminal(None);
pty_bus pty_bus
.send_screen_instructions .send_screen_instructions
.send(ScreenInstruction::NewTab(pid)) .send(ScreenInstruction::NewTab(pid))
.unwrap(); .unwrap();
} }
}
PtyInstruction::ClosePane(id) => { PtyInstruction::ClosePane(id) => {
pty_bus.close_pane(id); pty_bus.close_pane(id);
command_is_executing.done_closing_pane(); command_is_executing.done_closing_pane();
@ -284,7 +284,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
} }
} }
} }
}
}) })
.unwrap(), .unwrap(),
); );
@ -421,7 +420,8 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
ScreenInstruction::SwitchTabPrev => screen.switch_tab_prev(), ScreenInstruction::SwitchTabPrev => screen.switch_tab_prev(),
ScreenInstruction::CloseTab => screen.close_tab(), ScreenInstruction::CloseTab => screen.close_tab(),
ScreenInstruction::ApplyLayout((layout, new_pane_pids)) => { ScreenInstruction::ApplyLayout((layout, new_pane_pids)) => {
screen.apply_layout(layout, new_pane_pids) screen.apply_layout(layout, new_pane_pids);
command_is_executing.done_opening_new_pane();
} }
ScreenInstruction::Quit => { ScreenInstruction::Quit => {
break; break;
@ -441,13 +441,11 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
let mut send_screen_instructions = send_screen_instructions.clone(); let mut send_screen_instructions = send_screen_instructions.clone();
let mut send_app_instructions = send_app_instructions.clone(); let mut send_app_instructions = send_app_instructions.clone();
move || {
let store = Store::default(); let store = Store::default();
let mut plugin_id = 0; let mut plugin_id = 0;
let mut plugin_map = HashMap::new(); let mut plugin_map = HashMap::new();
loop { move || loop {
let (event, mut err_ctx) = receive_plugin_instructions let (event, mut err_ctx) = receive_plugin_instructions
.recv() .recv()
.expect("failed to receive event on channel"); .expect("failed to receive event on channel");
@ -457,8 +455,20 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
send_app_instructions.update(err_ctx); send_app_instructions.update(err_ctx);
match event { match event {
PluginInstruction::Load(pid_tx, path) => { PluginInstruction::Load(pid_tx, path) => {
let project_dirs =
ProjectDirs::from("org", "Mosaic Contributors", "Mosaic").unwrap();
let plugin_dir = project_dirs.data_dir().join("plugins/");
let wasm_bytes = fs::read(&path)
.or_else(|_| fs::read(&path.with_extension("wasm")))
.or_else(|_| {
fs::read(&plugin_dir.join(&path).with_extension("wasm"))
})
.unwrap_or_else(|_| {
panic!("cannot find plugin {}", &path.display())
});
// FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that // FIXME: Cache this compiled module on disk. I could use `(de)serialize_to_file()` for that
let module = Module::from_file(&store, &path).unwrap(); let module = Module::new(&store, &wasm_bytes).unwrap();
let output = Pipe::new(); let output = Pipe::new();
let input = Pipe::new(); let input = Pipe::new();
@ -514,8 +524,7 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
PluginInstruction::Input(pid, input_bytes) => { PluginInstruction::Input(pid, input_bytes) => {
let (instance, plugin_env) = plugin_map.get(&pid).unwrap(); let (instance, plugin_env) = plugin_map.get(&pid).unwrap();
let handle_key = let handle_key = instance.exports.get_function("handle_key").unwrap();
instance.exports.get_function("handle_key").unwrap();
for key in input_bytes.keys() { for key in input_bytes.keys() {
if let Ok(key) = key { if let Ok(key) = key {
wasi_write_string( wasi_write_string(
@ -550,7 +559,6 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: CliArgs) {
PluginInstruction::Quit => break, PluginInstruction::Quit => break,
} }
} }
}
}) })
.unwrap(), .unwrap(),
); );