aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.rs
diff options
context:
space:
mode:
authorDenis Maximov <denismaximov98@gmail.com>2020-11-14 19:59:37 +0200
committerGitHub <noreply@github.com>2020-11-14 18:59:37 +0100
commita2914066bf0e2e2bf5caee263d2378b7d77f477f (patch)
tree2a87397c32e2d9f512ad0c886107aa5c2e57d68e /src/main.rs
parentHOTFIX: do not get os input unless we're starting the app (diff)
downloadsl0ppij-a2914066bf0e2e2bf5caee263d2378b7d77f477f.tar.gz
sl0ppij-a2914066bf0e2e2bf5caee263d2378b7d77f477f.tar.xz
sl0ppij-a2914066bf0e2e2bf5caee263d2378b7d77f477f.zip
feat: add rustfmt, update action workflow to check for formatting (#45)
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs355
1 files changed, 222 insertions, 133 deletions
diff --git a/src/main.rs b/src/main.rs
index d996df1b..b964efa7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,23 +1,23 @@
#[cfg(test)]
mod tests;
+mod boundaries;
mod os_input_output;
-mod terminal_pane;
mod pty_bus;
mod screen;
-mod boundaries;
+mod terminal_pane;
use std::io::{Read, Write};
-use std::thread;
use std::os::unix::net::UnixStream;
use std::path::PathBuf;
-use std::sync::mpsc::{channel, Sender, Receiver};
+use std::sync::mpsc::{channel, Receiver, Sender};
+use std::thread;
-use serde::{Serialize, Deserialize};
+use serde::{Deserialize, Serialize};
use structopt::StructOpt;
use crate::os_input_output::{get_os_input, OsApi};
-use crate::pty_bus::{VteEvent, PtyBus, PtyInstruction};
+use crate::pty_bus::{PtyBus, PtyInstruction, VteEvent};
use crate::screen::{Screen, ScreenInstruction};
#[derive(Serialize, Deserialize, Debug)]
@@ -45,13 +45,17 @@ pub struct Opt {
max_panes: Option<usize>,
#[structopt(short, long)]
- debug: bool
+ debug: bool,
}
-fn _debug_log_to_file (message: String) {
+fn _debug_log_to_file(message: String) {
use std::fs::OpenOptions;
use std::io::prelude::*;
- let mut file = OpenOptions::new().append(true).create(true).open("/tmp/mosaic-log.txt").unwrap();
+ let mut file = OpenOptions::new()
+ .append(true)
+ .create(true)
+ .open("/tmp/mosaic-log.txt")
+ .unwrap();
file.write_all(message.as_bytes()).unwrap();
file.write_all("\n".as_bytes()).unwrap();
}
@@ -70,12 +74,12 @@ pub fn main() {
let mut stream = UnixStream::connect("/tmp/mosaic").unwrap();
let api_command = bincode::serialize(&ApiCommand::SplitHorizontally).unwrap();
stream.write_all(&api_command).unwrap();
- },
+ }
Some('v') => {
let mut stream = UnixStream::connect("/tmp/mosaic").unwrap();
let api_command = bincode::serialize(&ApiCommand::SplitVertically).unwrap();
stream.write_all(&api_command).unwrap();
- },
+ }
_ => {}
};
} else if opts.move_focus {
@@ -94,7 +98,7 @@ pub fn main() {
}
pub enum AppInstruction {
- Exit
+ Exit,
}
pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
@@ -104,11 +108,32 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
let full_screen_ws = os_input.get_terminal_size_using_fd(0);
os_input.into_raw_mode(0);
- let (send_screen_instructions, receive_screen_instructions): (Sender<ScreenInstruction>, Receiver<ScreenInstruction>) = channel();
- let (send_pty_instructions, receive_pty_instructions): (Sender<PtyInstruction>, Receiver<PtyInstruction>) = channel();
- let (send_app_instructions, receive_app_instructions): (Sender<AppInstruction>, Receiver<AppInstruction>) = channel();
- let mut screen = Screen::new(receive_screen_instructions, send_pty_instructions.clone(), send_app_instructions.clone(), &full_screen_ws, os_input.clone(), opts.max_panes);
- let mut pty_bus = PtyBus::new(receive_pty_instructions, send_screen_instructions.clone(), os_input.clone(), opts.debug);
+ let (send_screen_instructions, receive_screen_instructions): (
+ Sender<ScreenInstruction>,
+ Receiver<ScreenInstruction>,
+ ) = channel();
+ let (send_pty_instructions, receive_pty_instructions): (
+ Sender<PtyInstruction>,
+ Receiver<PtyInstruction>,
+ ) = channel();
+ let (send_app_instructions, receive_app_instructions): (
+ Sender<AppInstruction>,
+ Receiver<AppInstruction>,
+ ) = channel();
+ let mut screen = Screen::new(
+ receive_screen_instructions,
+ send_pty_instructions.clone(),
+ send_app_instructions.clone(),
+ &full_screen_ws,
+ os_input.clone(),
+ opts.max_panes,
+ );
+ let mut pty_bus = PtyBus::new(
+ receive_pty_instructions,
+ send_screen_instructions.clone(),
+ os_input.clone(),
+ opts.debug,
+ );
active_threads.push(
thread::Builder::new()
@@ -117,7 +142,8 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
move || {
pty_bus.spawn_terminal_vertically(None);
loop {
- let event = pty_bus.receive_pty_instructions
+ let event = pty_bus
+ .receive_pty_instructions
.recv()
.expect("failed to receive event on channel");
match event {
@@ -139,77 +165,78 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
}
}
}
- }).unwrap()
+ })
+ .unwrap(),
);
active_threads.push(
thread::Builder::new()
.name("screen".to_string())
.spawn({
- move || {
- loop {
- let event = screen.receiver
- .recv()
- .expect("failed to receive event on channel");
- match event {
- ScreenInstruction::Pty(pid, vte_event) => {
- screen.handle_pty_event(pid, vte_event);
- },
- ScreenInstruction::Render => {
- screen.render();
- },
- ScreenInstruction::NewPane(pid) => {
- screen.new_pane(pid);
- }
- ScreenInstruction::HorizontalSplit(pid) => {
- screen.horizontal_split(pid);
- }
- ScreenInstruction::VerticalSplit(pid) => {
- screen.vertical_split(pid);
- }
- ScreenInstruction::WriteCharacter(bytes) => {
- screen.write_to_active_terminal(bytes);
- }
- ScreenInstruction::ResizeLeft => {
- screen.resize_left();
- }
- ScreenInstruction::ResizeRight => {
- screen.resize_right();
- }
- ScreenInstruction::ResizeDown => {
- screen.resize_down();
- }
- ScreenInstruction::ResizeUp => {
- screen.resize_up();
- }
- ScreenInstruction::MoveFocus => {
- screen.move_focus();
- }
- ScreenInstruction::ScrollUp => {
- screen.scroll_active_terminal_up();
- }
- ScreenInstruction::ScrollDown => {
- screen.scroll_active_terminal_down();
- }
- ScreenInstruction::ClearScroll => {
- screen.clear_active_terminal_scroll();
- }
- ScreenInstruction::CloseFocusedPane => {
- screen.close_focused_pane();
- }
- ScreenInstruction::ClosePane(id) => {
- screen.close_pane(id);
- }
- ScreenInstruction::ToggleActiveTerminalFullscreen => {
- screen.toggle_active_terminal_fullscreen();
- }
- ScreenInstruction::Quit => {
- break;
- }
+ move || loop {
+ let event = screen
+ .receiver
+ .recv()
+ .expect("failed to receive event on channel");
+ match event {
+ ScreenInstruction::Pty(pid, vte_event) => {
+ screen.handle_pty_event(pid, vte_event);
+ }
+ ScreenInstruction::Render => {
+ screen.render();
+ }
+ ScreenInstruction::NewPane(pid) => {
+ screen.new_pane(pid);
+ }
+ ScreenInstruction::HorizontalSplit(pid) => {
+ screen.horizontal_split(pid);
+ }
+ ScreenInstruction::VerticalSplit(pid) => {
+ screen.vertical_split(pid);
+ }
+ ScreenInstruction::WriteCharacter(bytes) => {
+ screen.write_to_active_terminal(bytes);
+ }
+ ScreenInstruction::ResizeLeft => {
+ screen.resize_left();
+ }
+ ScreenInstruction::ResizeRight => {
+ screen.resize_right();
+ }
+ ScreenInstruction::ResizeDown => {
+ screen.resize_down();
+ }
+ ScreenInstruction::ResizeUp => {
+ screen.resize_up();
+ }
+ ScreenInstruction::MoveFocus => {
+ screen.move_focus();
+ }
+ ScreenInstruction::ScrollUp => {
+ screen.scroll_active_terminal_up();
+ }
+ ScreenInstruction::ScrollDown => {
+ screen.scroll_active_terminal_down();
+ }
+ ScreenInstruction::ClearScroll => {
+ screen.clear_active_terminal_scroll();
+ }
+ ScreenInstruction::CloseFocusedPane => {
+ screen.close_focused_pane();
+ }
+ ScreenInstruction::ClosePane(id) => {
+ screen.close_pane(id);
+ }
+ ScreenInstruction::ToggleActiveTerminalFullscreen => {
+ screen.toggle_active_terminal_fullscreen();
+ }
+ ScreenInstruction::Quit => {
+ break;
}
}
}
- }).unwrap()
+ })
+ .unwrap(),
);
// TODO: currently we don't push this into active_threads
@@ -223,27 +250,39 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
let send_screen_instructions = send_screen_instructions.clone();
move || {
::std::fs::remove_file("/tmp/mosaic").ok();
- let listener = ::std::os::unix::net::UnixListener::bind("/tmp/mosaic").expect("could not listen on ipc socket");
+ let listener = ::std::os::unix::net::UnixListener::bind("/tmp/mosaic")
+ .expect("could not listen on ipc socket");
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
let mut buffer = [0; 65535]; // TODO: more accurate
- stream.read(&mut buffer).expect("failed to parse ipc message");
- let decoded: ApiCommand = bincode::deserialize(&buffer).expect("failed to deserialize ipc message");
+ stream
+ .read(&mut buffer)
+ .expect("failed to parse ipc message");
+ let decoded: ApiCommand = bincode::deserialize(&buffer)
+ .expect("failed to deserialize ipc message");
match &decoded {
ApiCommand::OpenFile(file_name) => {
let path = PathBuf::from(file_name);
- send_pty_instructions.send(PtyInstruction::SpawnTerminal(Some(path))).unwrap();
+ send_pty_instructions
+ .send(PtyInstruction::SpawnTerminal(Some(path)))
+ .unwrap();
}
ApiCommand::SplitHorizontally => {
- send_pty_instructions.send(PtyInstruction::SpawnTerminalHorizontally(None)).unwrap();
+ send_pty_instructions
+ .send(PtyInstruction::SpawnTerminalHorizontally(None))
+ .unwrap();
}
ApiCommand::SplitVertically => {
- send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap();
+ send_pty_instructions
+ .send(PtyInstruction::SpawnTerminalVertically(None))
+ .unwrap();
}
ApiCommand::MoveFocus => {
- send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap();
+ send_screen_instructions
+ .send(ScreenInstruction::MoveFocus)
+ .unwrap();
}
}
}
@@ -253,7 +292,8 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
}
}
}
- }).unwrap();
+ })
+ .unwrap();
let _stdin_thread = thread::Builder::new()
.name("ipc_server".to_string())
@@ -270,66 +310,109 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
// uncomment this to print the entered character to a log file (/tmp/mosaic-log.txt) for debugging
// _debug_log_to_file(format!("buffer {:?}", buffer));
match buffer {
- [10, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-j
- send_screen_instructions.send(ScreenInstruction::ResizeDown).unwrap();
- },
- [11, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-k
- send_screen_instructions.send(ScreenInstruction::ResizeUp).unwrap();
- },
- [16, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-p
- send_screen_instructions.send(ScreenInstruction::MoveFocus).unwrap();
- },
- [8, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-h
- send_screen_instructions.send(ScreenInstruction::ResizeLeft).unwrap();
- },
- [12, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-l
- send_screen_instructions.send(ScreenInstruction::ResizeRight).unwrap();
- },
- [26, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-z
- send_pty_instructions.send(PtyInstruction::SpawnTerminal(None)).unwrap();
- },
- [14, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-n
- send_pty_instructions.send(PtyInstruction::SpawnTerminalVertically(None)).unwrap();
- },
- [2, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-b
- send_pty_instructions.send(PtyInstruction::SpawnTerminalHorizontally(None)).unwrap();
- },
- [17, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-q
+ [10, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-j
+ send_screen_instructions
+ .send(ScreenInstruction::ResizeDown)
+ .unwrap();
+ }
+ [11, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-k
+ send_screen_instructions
+ .send(ScreenInstruction::ResizeUp)
+ .unwrap();
+ }
+ [16, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-p
+ send_screen_instructions
+ .send(ScreenInstruction::MoveFocus)
+ .unwrap();
+ }
+ [8, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-h
+ send_screen_instructions
+ .send(ScreenInstruction::ResizeLeft)
+ .unwrap();
+ }
+ [12, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-l
+ send_screen_instructions
+ .send(ScreenInstruction::ResizeRight)
+ .unwrap();
+ }
+ [26, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-z
+ send_pty_instructions
+ .send(PtyInstruction::SpawnTerminal(None))
+ .unwrap();
+ }
+ [14, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-n
+ send_pty_instructions
+ .send(PtyInstruction::SpawnTerminalVertically(None))
+ .unwrap();
+ }
+ [2, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-b
+ send_pty_instructions
+ .send(PtyInstruction::SpawnTerminalHorizontally(None))
+ .unwrap();
+ }
+ [17, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-q
let _ = send_screen_instructions.send(ScreenInstruction::Quit);
let _ = send_pty_instructions.send(PtyInstruction::Quit);
let _ = send_app_instructions.send(AppInstruction::Exit);
break;
- },
- [27, 91, 53, 94, 0, 0, 0, 0, 0, 0] => { // ctrl-PgUp
- send_screen_instructions.send(ScreenInstruction::ScrollUp).unwrap();
- },
- [27, 91, 54, 94, 0, 0, 0, 0, 0, 0] => { // ctrl-PgDown
- send_screen_instructions.send(ScreenInstruction::ScrollDown).unwrap();
- },
- [24, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-x
- send_screen_instructions.send(ScreenInstruction::CloseFocusedPane).unwrap();
+ }
+ [27, 91, 53, 94, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-PgUp
+ send_screen_instructions
+ .send(ScreenInstruction::ScrollUp)
+ .unwrap();
+ }
+ [27, 91, 54, 94, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-PgDown
+ send_screen_instructions
+ .send(ScreenInstruction::ScrollDown)
+ .unwrap();
+ }
+ [24, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-x
+ send_screen_instructions
+ .send(ScreenInstruction::CloseFocusedPane)
+ .unwrap();
// ::std::thread::sleep(::std::time::Duration::from_millis(10));
- },
- [5, 0, 0, 0, 0, 0, 0, 0, 0, 0] => { // ctrl-e
- send_screen_instructions.send(ScreenInstruction::ToggleActiveTerminalFullscreen).unwrap();
- },
+ }
+ [5, 0, 0, 0, 0, 0, 0, 0, 0, 0] => {
+ // ctrl-e
+ send_screen_instructions
+ .send(ScreenInstruction::ToggleActiveTerminalFullscreen)
+ .unwrap();
+ }
_ => {
- send_screen_instructions.send(ScreenInstruction::ClearScroll).unwrap();
- send_screen_instructions.send(ScreenInstruction::WriteCharacter(buffer)).unwrap();
+ send_screen_instructions
+ .send(ScreenInstruction::ClearScroll)
+ .unwrap();
+ send_screen_instructions
+ .send(ScreenInstruction::WriteCharacter(buffer))
+ .unwrap();
}
}
- };
+ }
}
});
loop {
- let app_instruction = receive_app_instructions.recv().expect("failed to receive app instruction on channel");
+ let app_instruction = receive_app_instructions
+ .recv()
+ .expect("failed to receive app instruction on channel");
match app_instruction {
AppInstruction::Exit => {
let _ = send_screen_instructions.send(ScreenInstruction::Quit);
let _ = send_pty_instructions.send(PtyInstruction::Quit);
break;
- },
+ }
}
}
@@ -339,9 +422,15 @@ pub fn start(mut os_input: Box<dyn OsApi>, opts: Opt) {
// cleanup();
let reset_style = "\u{1b}[m";
let goto_start_of_last_line = format!("\u{1b}[{};{}H", full_screen_ws.ws_row, 1);
- let goodbye_message = format!("{}\n{}Bye from Mosaic!", goto_start_of_last_line, reset_style);
+ let goodbye_message = format!(
+ "{}\n{}Bye from Mosaic!",
+ goto_start_of_last_line, reset_style
+ );
os_input.unset_raw_mode(0);
- os_input.get_stdout_writer().write(goodbye_message.as_bytes()).unwrap();
+ os_input
+ .get_stdout_writer()
+ .write(goodbye_message.as_bytes())
+ .unwrap();
os_input.get_stdout_writer().flush().unwrap();
}