summaryrefslogtreecommitdiffstats
path: root/src/run.rs
diff options
context:
space:
mode:
authorCaleb Bassi <calebjbassi@gmail.com>2019-02-15 04:43:09 -0800
committerCaleb Bassi <calebjbassi@gmail.com>2019-02-15 05:56:09 -0800
commit29b3922f9efb9f277641a63f8f1719a15cbb8d16 (patch)
treed919ba11fa5c754565c64c43cb1614f7ae4d2546 /src/run.rs
parent3853eef2d052460982903038daac7abd2b71d12e (diff)
refactor: project layout
Diffstat (limited to 'src/run.rs')
-rw-r--r--src/run.rs197
1 files changed, 197 insertions, 0 deletions
diff --git a/src/run.rs b/src/run.rs
new file mode 100644
index 0000000..6f81c40
--- /dev/null
+++ b/src/run.rs
@@ -0,0 +1,197 @@
+extern crate ncurses;
+
+use std::collections::HashMap;
+use std::time;
+
+use commands;
+use commands::{CommandKeybind, JoshutoCommand};
+use config;
+use context::JoshutoContext;
+use preview;
+use ui;
+use window::JoshutoPanel;
+
+fn recurse_get_keycommand<'a>(
+ keymap: &'a HashMap<i32, CommandKeybind>,
+) -> Option<&Box<dyn JoshutoCommand>> {
+ let (term_rows, term_cols) = ui::getmaxyx();
+ ncurses::timeout(-1);
+
+ let ch: i32;
+ {
+ let keymap_len = keymap.len();
+ let win = JoshutoPanel::new(
+ keymap_len as i32 + 1,
+ term_cols,
+ ((term_rows - keymap_len as i32 - 2) as usize, 0),
+ );
+
+ let mut display_vec: Vec<String> = Vec::with_capacity(keymap_len);
+ for (key, val) in keymap {
+ display_vec.push(format!(" {}\t{}", *key as u8 as char, val));
+ }
+ display_vec.sort();
+
+ win.move_to_top();
+ ui::display_options(&win, &display_vec);
+ ncurses::doupdate();
+
+ ch = ncurses::wgetch(win.win);
+ }
+ ncurses::doupdate();
+
+ if ch == config::keymap::ESCAPE {
+ return None;
+ }
+
+ match keymap.get(&ch) {
+ Some(CommandKeybind::CompositeKeybind(m)) => recurse_get_keycommand(&m),
+ Some(CommandKeybind::SimpleKeybind(s)) => Some(s),
+ _ => None,
+ }
+}
+
+fn process_threads(context: &mut JoshutoContext) {
+ let thread_wait_duration: time::Duration = time::Duration::from_millis(100);
+
+ let mut i: usize = 0;
+ while i < context.threads.len() {
+ match &context.threads[i].recv_timeout(&thread_wait_duration) {
+ Ok(progress_info) => {
+ if progress_info.bytes_finished == progress_info.total_bytes {
+ ncurses::werase(context.views.bot_win.win);
+ let thread = context.threads.swap_remove(i);
+ thread.handle.join().unwrap();
+ let (tab_src, tab_dest) = (thread.tab_src, thread.tab_dest);
+ if tab_src < context.tabs.len() {
+ context.tabs[tab_src].reload_contents(&context.config_t.sort_type);
+ if tab_src == context.curr_tab_index {
+ context.tabs[tab_src].refresh(
+ &context.views,
+ &context.config_t,
+ &context.username,
+ &context.hostname,
+ );
+ }
+ }
+ if tab_dest != tab_src && tab_dest < context.tabs.len() {
+ context.tabs[tab_dest].reload_contents(&context.config_t.sort_type);
+ if tab_dest == context.curr_tab_index {
+ context.tabs[tab_dest].refresh(
+ &context.views,
+ &context.config_t,
+ &context.username,
+ &context.hostname,
+ );
+ }
+ }
+ } else {
+ let percent = (progress_info.bytes_finished as f64
+ / progress_info.total_bytes as f64)
+ as f32;
+ ui::draw_progress_bar(&context.views.bot_win, percent);
+ ncurses::wnoutrefresh(context.views.bot_win.win);
+ i = i + 1;
+ }
+ ncurses::doupdate();
+ }
+ Err(std::sync::mpsc::RecvTimeoutError::Disconnected) => {
+ ncurses::werase(context.views.bot_win.win);
+ let thread = context.threads.swap_remove(i);
+ let (tab_src, tab_dest) = (thread.tab_src, thread.tab_dest);
+ thread.handle.join().unwrap();
+ if tab_src < context.tabs.len() {
+ context.tabs[tab_src].reload_contents(&context.config_t.sort_type);
+ if tab_src == context.curr_tab_index {
+ context.tabs[tab_src].refresh(
+ &context.views,
+ &context.config_t,
+ &context.username,
+ &context.hostname,
+ );
+ }
+ }
+ if tab_dest != tab_src && tab_dest < context.tabs.len() {
+ context.tabs[tab_dest].reload_contents(&context.config_t.sort_type);
+ if tab_dest == context.curr_tab_index {
+ context.tabs[tab_dest].refresh(
+ &context.views,
+ &context.config_t,
+ &context.username,
+ &context.hostname,
+ );
+ }
+ }
+ ncurses::doupdate();
+ }
+ Err(std::sync::mpsc::RecvTimeoutError::Timeout) => {
+ i = i + 1;
+ }
+ }
+ }
+}
+
+fn resize_handler(context: &mut JoshutoContext) {
+ ui::redraw_tab_view(&context.views.tab_win, &context);
+ {
+ let curr_tab = &mut context.tabs[context.curr_tab_index];
+ curr_tab.refresh(
+ &context.views,
+ &context.config_t,
+ &context.username,
+ &context.hostname,
+ );
+ }
+ preview::preview_file(context);
+ ncurses::doupdate();
+}
+
+#[allow(unreachable_code)]
+pub fn run(config_t: config::JoshutoConfig, keymap_t: config::JoshutoKeymap) {
+ ui::init_ncurses();
+
+ let mut context = JoshutoContext::new(config_t);
+ commands::NewTab::new_tab(&mut context);
+ ncurses::doupdate();
+
+ loop {
+ if context.threads.len() > 0 {
+ ncurses::timeout(0);
+ process_threads(&mut context);
+ } else {
+ ncurses::timeout(-1);
+ }
+
+ if let Some(ch) = ncurses::get_wch() {
+ let ch = match ch {
+ ncurses::WchResult::Char(s) => s as i32,
+ ncurses::WchResult::KeyCode(s) => s,
+ };
+
+ if ch == ncurses::KEY_RESIZE {
+ context.views.resize_views();
+ resize_handler(&mut context);
+ continue;
+ }
+
+ let keycommand: &std::boxed::Box<dyn JoshutoCommand>;
+
+ match keymap_t.keymaps.get(&ch) {
+ Some(CommandKeybind::CompositeKeybind(m)) => match recurse_get_keycommand(&m) {
+ Some(s) => {
+ keycommand = s;
+ }
+ None => continue,
+ },
+ Some(CommandKeybind::SimpleKeybind(s)) => {
+ keycommand = s;
+ }
+ None => {
+ continue;
+ }
+ }
+ keycommand.execute(&mut context);
+ }
+ }
+ ncurses::endwin();
+}