1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
use crate::commands::{CommandKeybind, CursorMoveStub, JoshutoRunnable};
use crate::config::{JoshutoCommandMapping, JoshutoConfig};
use crate::context::JoshutoContext;
use crate::history::DirectoryHistory;
use crate::io::IOWorkerObserver;
use crate::tab::JoshutoTab;
use crate::ui;
use crate::ui::widgets::{TuiCommandMenu, TuiView};
use crate::util::event::Event;
pub fn run(config_t: JoshutoConfig, keymap_t: JoshutoCommandMapping) -> std::io::Result<()> {
let mut backend: ui::TuiBackend = ui::TuiBackend::new()?;
let mut context = JoshutoContext::new(config_t);
let curr_path = std::env::current_dir()?;
{
// Initialize an initial tab
let tab = JoshutoTab::new(curr_path, &context.config_t.sort_option)?;
context.push_tab(tab);
// move the cursor by 0 just to trigger a preview of child
CursorMoveStub::new().execute(&mut context, &mut backend);
// render our view
let mut view = TuiView::new(&context);
backend.render(&mut view);
}
let mut io_observer = None;
while !context.exit {
/* checking if there are workers that need to be run */
if !context.worker_queue.is_empty() {
if let None = io_observer.as_ref() {
let worker = context.worker_queue.pop_front().unwrap();
io_observer = {
let event_tx = context.events.event_tx.clone();
let observer = IOWorkerObserver::new(worker, event_tx);
Some(observer)
};
}
}
let event = match context.events.next() {
Ok(event) => event,
Err(e) => return Ok(()),
};
match event {
Event::IOWorkerProgress(p) => {
context.worker_msg = Some(format!("bytes copied {}", p));
}
Event::IOWorkerResult(res) => {
match io_observer {
Some(handle) => {
let src = handle.src.clone();
let dest = handle.dest.clone();
handle.join();
let msg = match res {
Ok(s) => {
format!("io_worker completed successfully: {} bytes processed", s)
}
Err(e) => format!("io_worker was not completed: {}", e.to_string()),
};
context.message_queue.push_back(msg);
let options = &context.config_t.sort_option;
for tab in context.tabs.iter_mut() {
tab.history.create_or_update(src.as_path(), options);
tab.history.create_or_update(dest.as_path(), options);
}
}
None => {}
}
io_observer = None;
context.worker_msg = None;
}
Event::Input(key) => {
/* Message handling */
if !context.message_queue.is_empty() {
let _ = context.message_queue.pop_front();
}
match keymap_t.get(&key) {
None => {
context
.message_queue
.push_back(format!("Unknown keycode: {:?}", key));
}
Some(CommandKeybind::SimpleKeybind(command)) => {
if let Err(e) = command.execute(&mut context, &mut backend) {
context.message_queue.push_back(e.to_string());
}
}
Some(CommandKeybind::CompositeKeybind(m)) => {
let cmd = {
let mut menu = TuiCommandMenu::new();
menu.get_input(&mut backend, &context, &m)
};
if let Some(command) = cmd {
if let Err(e) = command.execute(&mut context, &mut backend) {
context.message_queue.push_back(e.to_string());
}
}
}
}
context.events.flush();
}
}
let mut view = TuiView::new(&context);
backend.render(&mut view);
}
Ok(())
}
|