mirror of
https://github.com/chylex/Bark-Browser.git
synced 2025-05-19 09:34:07 +02:00
Refactor construction of filesystem action map
This commit is contained in:
parent
63b56de63f
commit
aef1a0011b
14
src/app.rs
14
src/app.rs
@ -1,4 +1,4 @@
|
|||||||
use std::path::Path;
|
use std::io;
|
||||||
|
|
||||||
use crossterm::event::{Event, KeyEventKind};
|
use crossterm::event::{Event, KeyEventKind};
|
||||||
|
|
||||||
@ -6,14 +6,12 @@ use crate::input::keymap::KeyBinding;
|
|||||||
use crate::state::{Environment, State};
|
use crate::state::{Environment, State};
|
||||||
use crate::state::action::ActionResult;
|
use crate::state::action::ActionResult;
|
||||||
use crate::state::event::EventResult;
|
use crate::state::event::EventResult;
|
||||||
|
use crate::state::init::StateInitializer;
|
||||||
use crate::state::view::View;
|
use crate::state::view::View;
|
||||||
|
|
||||||
pub fn run(start_path: &Path) -> std::io::Result<()> {
|
pub fn run(state_initializer: &StateInitializer, view: &mut View) -> io::Result<()> {
|
||||||
View::restore_terminal_on_panic();
|
let environment = Environment::try_from(&*view)?;
|
||||||
let mut view = View::stdout()?;
|
let mut state = State::new(state_initializer, environment);
|
||||||
|
|
||||||
let environment = Environment::try_from(&view)?;
|
|
||||||
let mut state = State::with_root_path(start_path, environment);
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match state.handle_events() {
|
match state.handle_events() {
|
||||||
@ -69,7 +67,7 @@ pub fn run(start_path: &Path) -> std::io::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view.close()
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
|
@ -1,104 +1,5 @@
|
|||||||
use lazy_static::lazy_static;
|
pub mod application;
|
||||||
|
pub mod count;
|
||||||
use crate::component::filesystem::action::application::{Quit, RedrawScreen};
|
pub mod file;
|
||||||
use crate::component::filesystem::action::count::PushCountDigit;
|
pub mod movement;
|
||||||
use crate::component::filesystem::action::file::{CreateDirectoryInParentOfSelectedEntry, CreateDirectoryInSelectedDirectory, CreateFileInParentOfSelectedEntry, CreateFileInSelectedDirectory, DeleteSelectedEntry, EditSelectedEntry, RenameSelectedEntry};
|
pub mod tree;
|
||||||
use crate::component::filesystem::action::movement::{CollapseSelectedOr, ExpandSelectedOr, MoveBetweenFirstAndLastSibling, MoveDown, MovementWithCountFactory, MovementWithFallbackFactory, MoveOrTraverseUpParent, MoveToFirst, MoveToLast, MoveToLineOr, MoveToNextSibling, MoveToParent, MoveToPreviousSibling, MoveUp, ScreenHeightRatio};
|
|
||||||
use crate::component::filesystem::action::tree::{ExpandCollapse, RefreshChildrenOfSelected};
|
|
||||||
use crate::component::filesystem::FsLayer;
|
|
||||||
use crate::input::keymap::KeyMap;
|
|
||||||
use crate::state::action::Action;
|
|
||||||
|
|
||||||
mod application;
|
|
||||||
mod count;
|
|
||||||
mod file;
|
|
||||||
mod movement;
|
|
||||||
mod tree;
|
|
||||||
|
|
||||||
type ActionKeyMap = KeyMap<Box<dyn Action<FsLayer> + Sync>>;
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref ACTION_MAP: ActionKeyMap = create_action_map();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_action_map() -> ActionKeyMap {
|
|
||||||
let mut me = ActionKeyMap::new();
|
|
||||||
|
|
||||||
map(&mut me, "0", PushCountDigit(0));
|
|
||||||
map(&mut me, "1", PushCountDigit(1));
|
|
||||||
map(&mut me, "2", PushCountDigit(2));
|
|
||||||
map(&mut me, "3", PushCountDigit(3));
|
|
||||||
map(&mut me, "4", PushCountDigit(4));
|
|
||||||
map(&mut me, "5", PushCountDigit(5));
|
|
||||||
map(&mut me, "6", PushCountDigit(6));
|
|
||||||
map(&mut me, "7", PushCountDigit(7));
|
|
||||||
map(&mut me, "8", PushCountDigit(8));
|
|
||||||
map(&mut me, "9", PushCountDigit(9));
|
|
||||||
|
|
||||||
map(&mut me, "af", CreateFileInSelectedDirectory);
|
|
||||||
map(&mut me, "ad", CreateDirectoryInSelectedDirectory);
|
|
||||||
map(&mut me, "e", EditSelectedEntry);
|
|
||||||
map(&mut me, "d", DeleteSelectedEntry);
|
|
||||||
map(&mut me, "gg", MoveToLineOr(MoveToFirst));
|
|
||||||
map(&mut me, "G", MoveToLineOr(MoveToLast));
|
|
||||||
map(&mut me, "h", CollapseSelectedOr(MoveToParent));
|
|
||||||
map(&mut me, "H", MoveOrTraverseUpParent);
|
|
||||||
map(&mut me, "if", CreateFileInSelectedDirectory);
|
|
||||||
map(&mut me, "id", CreateDirectoryInSelectedDirectory);
|
|
||||||
map(&mut me, "j", MoveDown);
|
|
||||||
map(&mut me, "J", MoveToNextSibling.with_fallback(MoveDown));
|
|
||||||
map(&mut me, "k", MoveUp);
|
|
||||||
map(&mut me, "K", MoveToPreviousSibling.with_fallback(MoveUp));
|
|
||||||
map(&mut me, "l", ExpandSelectedOr(MoveDown));
|
|
||||||
map(&mut me, "of", CreateFileInParentOfSelectedEntry);
|
|
||||||
map(&mut me, "od", CreateDirectoryInParentOfSelectedEntry);
|
|
||||||
map(&mut me, "q", Quit);
|
|
||||||
map(&mut me, "r", RenameSelectedEntry { prefill: true });
|
|
||||||
map(&mut me, "R", RenameSelectedEntry { prefill: false });
|
|
||||||
|
|
||||||
map(&mut me, "%", MoveBetweenFirstAndLastSibling);
|
|
||||||
|
|
||||||
map(&mut me, "<Ctrl-B>", MoveUp.with_custom_count(ScreenHeightRatio(1)));
|
|
||||||
map(&mut me, "<Ctrl-C>", Quit);
|
|
||||||
map(&mut me, "<Ctrl-D>", MoveDown.with_default_count(ScreenHeightRatio(2)));
|
|
||||||
map(&mut me, "<Ctrl-F>", MoveDown.with_custom_count(ScreenHeightRatio(1)));
|
|
||||||
map(&mut me, "<Ctrl-L>", RedrawScreen);
|
|
||||||
map(&mut me, "<Ctrl-N>", MoveDown);
|
|
||||||
map(&mut me, "<Ctrl-P>", MoveUp);
|
|
||||||
map(&mut me, "<Ctrl-U>", MoveUp.with_default_count(ScreenHeightRatio(2)));
|
|
||||||
|
|
||||||
map(&mut me, "<Space>", ExpandCollapse { default_depth: 1 });
|
|
||||||
map(&mut me, "<Ctrl-Space>", ExpandCollapse { default_depth: 1000 });
|
|
||||||
|
|
||||||
map(&mut me, "<Down>", MoveDown);
|
|
||||||
map(&mut me, "<Shift-Down>", MoveDown.with_custom_count(ScreenHeightRatio(1)));
|
|
||||||
map(&mut me, "<Alt-Down>", MoveToNextSibling.with_fallback(MoveDown));
|
|
||||||
|
|
||||||
map(&mut me, "<Up>", MoveUp);
|
|
||||||
map(&mut me, "<Shift-Up>", MoveUp.with_custom_count(ScreenHeightRatio(1)));
|
|
||||||
map(&mut me, "<Alt-Up>", MoveToPreviousSibling.with_fallback(MoveUp));
|
|
||||||
|
|
||||||
map(&mut me, "<Left>", CollapseSelectedOr(MoveToParent));
|
|
||||||
map(&mut me, "<Alt-Left>", MoveOrTraverseUpParent);
|
|
||||||
|
|
||||||
map(&mut me, "<Right>", ExpandSelectedOr(MoveDown));
|
|
||||||
|
|
||||||
map(&mut me, "<Del>", DeleteSelectedEntry);
|
|
||||||
|
|
||||||
map(&mut me, "<PageDown>", MoveDown.with_custom_count(ScreenHeightRatio(1)));
|
|
||||||
map(&mut me, "<PageUp>", MoveUp.with_custom_count(ScreenHeightRatio(1)));
|
|
||||||
|
|
||||||
map(&mut me, "<F2>", RenameSelectedEntry { prefill: true });
|
|
||||||
map(&mut me, "<Shift-F2>", RenameSelectedEntry { prefill: false });
|
|
||||||
|
|
||||||
map(&mut me, "<F5>", RefreshChildrenOfSelected);
|
|
||||||
|
|
||||||
me
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map(map: &mut ActionKeyMap, key_binding_str: &str, action: impl Action<FsLayer> + Sync + 'static) {
|
|
||||||
// Panic on error, since we are hard-coding the key bindings.
|
|
||||||
if let Err(err) = map.insert(key_binding_str, Box::new(action)) {
|
|
||||||
panic!("Failed to insert key binding '{}'. {}", err.sequence(), err.error());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
98
src/component/filesystem/defaults.rs
Normal file
98
src/component/filesystem/defaults.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
use crate::component::filesystem::{ActionKeyMap, FsLayer};
|
||||||
|
use crate::component::filesystem::action::application::{EnterCommandMode, Quit, RedrawScreen};
|
||||||
|
use crate::component::filesystem::action::count::PushCountDigit;
|
||||||
|
use crate::component::filesystem::action::file::{CreateDirectoryInParentOfSelectedEntry, CreateDirectoryInSelectedDirectory, CreateFileInParentOfSelectedEntry, CreateFileInSelectedDirectory, DeleteSelectedEntry, EditSelectedEntry, RenameSelectedEntry};
|
||||||
|
use crate::component::filesystem::action::movement::{CollapseSelectedOr, ExpandSelectedOr, MoveBetweenFirstAndLastSibling, MoveDown, MovementWithCountFactory, MovementWithFallbackFactory, MoveOrTraverseUpParent, MoveToFirst, MoveToLast, MoveToLineOr, MoveToNextSibling, MoveToParent, MoveToPreviousSibling, MoveUp, ScreenHeightRatio};
|
||||||
|
use crate::component::filesystem::action::tree::{ExpandCollapse, RefreshChildrenOfSelected};
|
||||||
|
use crate::input::keymap::KeyMapInsertError;
|
||||||
|
use crate::state::action::Action;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref ACTION_MAP: Result<ActionKeyMap, KeyMapInsertError> = create_action_map();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_action_map() -> Result<&'static ActionKeyMap, &'static KeyMapInsertError> {
|
||||||
|
return ACTION_MAP.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_action_map() -> Result<ActionKeyMap, KeyMapInsertError> {
|
||||||
|
let mut me = ActionKeyMap::new();
|
||||||
|
|
||||||
|
map(&mut me, "0", PushCountDigit(0))?;
|
||||||
|
map(&mut me, "1", PushCountDigit(1))?;
|
||||||
|
map(&mut me, "2", PushCountDigit(2))?;
|
||||||
|
map(&mut me, "3", PushCountDigit(3))?;
|
||||||
|
map(&mut me, "4", PushCountDigit(4))?;
|
||||||
|
map(&mut me, "5", PushCountDigit(5))?;
|
||||||
|
map(&mut me, "6", PushCountDigit(6))?;
|
||||||
|
map(&mut me, "7", PushCountDigit(7))?;
|
||||||
|
map(&mut me, "8", PushCountDigit(8))?;
|
||||||
|
map(&mut me, "9", PushCountDigit(9))?;
|
||||||
|
|
||||||
|
map(&mut me, "af", CreateFileInSelectedDirectory)?;
|
||||||
|
map(&mut me, "ad", CreateDirectoryInSelectedDirectory)?;
|
||||||
|
map(&mut me, "e", EditSelectedEntry)?;
|
||||||
|
map(&mut me, "d", DeleteSelectedEntry)?;
|
||||||
|
map(&mut me, "gg", MoveToLineOr(MoveToFirst))?;
|
||||||
|
map(&mut me, "G", MoveToLineOr(MoveToLast))?;
|
||||||
|
map(&mut me, "h", CollapseSelectedOr(MoveToParent))?;
|
||||||
|
map(&mut me, "H", MoveOrTraverseUpParent)?;
|
||||||
|
map(&mut me, "if", CreateFileInSelectedDirectory)?;
|
||||||
|
map(&mut me, "id", CreateDirectoryInSelectedDirectory)?;
|
||||||
|
map(&mut me, "j", MoveDown)?;
|
||||||
|
map(&mut me, "J", MoveToNextSibling.with_fallback(MoveDown))?;
|
||||||
|
map(&mut me, "k", MoveUp)?;
|
||||||
|
map(&mut me, "K", MoveToPreviousSibling.with_fallback(MoveUp))?;
|
||||||
|
map(&mut me, "l", ExpandSelectedOr(MoveDown))?;
|
||||||
|
map(&mut me, "of", CreateFileInParentOfSelectedEntry)?;
|
||||||
|
map(&mut me, "od", CreateDirectoryInParentOfSelectedEntry)?;
|
||||||
|
map(&mut me, "q", Quit)?;
|
||||||
|
map(&mut me, "r", RenameSelectedEntry { prefill: true })?;
|
||||||
|
map(&mut me, "R", RenameSelectedEntry { prefill: false })?;
|
||||||
|
|
||||||
|
map(&mut me, "%", MoveBetweenFirstAndLastSibling)?;
|
||||||
|
map(&mut me, ":", EnterCommandMode)?;
|
||||||
|
|
||||||
|
map(&mut me, "<Ctrl-B>", MoveUp.with_custom_count(ScreenHeightRatio(1)))?;
|
||||||
|
map(&mut me, "<Ctrl-C>", Quit)?;
|
||||||
|
map(&mut me, "<Ctrl-D>", MoveDown.with_default_count(ScreenHeightRatio(2)))?;
|
||||||
|
map(&mut me, "<Ctrl-F>", MoveDown.with_custom_count(ScreenHeightRatio(1)))?;
|
||||||
|
map(&mut me, "<Ctrl-L>", RedrawScreen)?;
|
||||||
|
map(&mut me, "<Ctrl-N>", MoveDown)?;
|
||||||
|
map(&mut me, "<Ctrl-P>", MoveUp)?;
|
||||||
|
map(&mut me, "<Ctrl-U>", MoveUp.with_default_count(ScreenHeightRatio(2)))?;
|
||||||
|
|
||||||
|
map(&mut me, "<Space>", ExpandCollapse { default_depth: 1 })?;
|
||||||
|
map(&mut me, "<Ctrl-Space>", ExpandCollapse { default_depth: 1000 })?;
|
||||||
|
|
||||||
|
map(&mut me, "<Down>", MoveDown)?;
|
||||||
|
map(&mut me, "<Shift-Down>", MoveDown.with_custom_count(ScreenHeightRatio(1)))?;
|
||||||
|
map(&mut me, "<Alt-Down>", MoveToNextSibling.with_fallback(MoveDown))?;
|
||||||
|
|
||||||
|
map(&mut me, "<Up>", MoveUp)?;
|
||||||
|
map(&mut me, "<Shift-Up>", MoveUp.with_custom_count(ScreenHeightRatio(1)))?;
|
||||||
|
map(&mut me, "<Alt-Up>", MoveToPreviousSibling.with_fallback(MoveUp))?;
|
||||||
|
|
||||||
|
map(&mut me, "<Left>", CollapseSelectedOr(MoveToParent))?;
|
||||||
|
map(&mut me, "<Alt-Left>", MoveOrTraverseUpParent)?;
|
||||||
|
|
||||||
|
map(&mut me, "<Right>", ExpandSelectedOr(MoveDown))?;
|
||||||
|
|
||||||
|
map(&mut me, "<Del>", DeleteSelectedEntry)?;
|
||||||
|
|
||||||
|
map(&mut me, "<PageDown>", MoveDown.with_custom_count(ScreenHeightRatio(1)))?;
|
||||||
|
map(&mut me, "<PageUp>", MoveUp.with_custom_count(ScreenHeightRatio(1)))?;
|
||||||
|
|
||||||
|
map(&mut me, "<F2>", RenameSelectedEntry { prefill: true })?;
|
||||||
|
map(&mut me, "<Shift-F2>", RenameSelectedEntry { prefill: false })?;
|
||||||
|
|
||||||
|
map(&mut me, "<F5>", RefreshChildrenOfSelected)?;
|
||||||
|
|
||||||
|
Ok(me)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map(map: &mut ActionKeyMap, key_binding_str: &str, action: impl Action<FsLayer> + Sync + 'static) -> Result<(), KeyMapInsertError> {
|
||||||
|
map.insert(key_binding_str, Box::new(action))
|
||||||
|
}
|
@ -3,23 +3,28 @@ use std::path::Path;
|
|||||||
use crate::component::filesystem::registers::FsTreeRegisters;
|
use crate::component::filesystem::registers::FsTreeRegisters;
|
||||||
use crate::component::filesystem::tree::FsTree;
|
use crate::component::filesystem::tree::FsTree;
|
||||||
use crate::file::FileOwnerNameCache;
|
use crate::file::FileOwnerNameCache;
|
||||||
use crate::input::keymap::{KeyBinding, KeyMapLookupResult};
|
use crate::input::keymap::{KeyBinding, KeyMap, KeyMapLookupResult};
|
||||||
use crate::state::action::ActionResult;
|
use crate::state::action::{Action, ActionResult};
|
||||||
use crate::state::Environment;
|
use crate::state::Environment;
|
||||||
use crate::state::event::{EventQueue, EventResult};
|
use crate::state::event::{EventQueue, EventResult};
|
||||||
use crate::state::layer::Layer;
|
use crate::state::layer::Layer;
|
||||||
use crate::state::view::Frame;
|
use crate::state::view::Frame;
|
||||||
|
|
||||||
mod action;
|
mod action;
|
||||||
|
mod command;
|
||||||
|
mod registers;
|
||||||
mod render;
|
mod render;
|
||||||
mod tree;
|
mod tree;
|
||||||
mod registers;
|
pub mod defaults;
|
||||||
|
|
||||||
|
pub type ActionKeyMap = KeyMap<Box<dyn Action<FsLayer> + Sync>>;
|
||||||
|
|
||||||
pub struct FsLayer {
|
pub struct FsLayer {
|
||||||
|
action_map: &'static ActionKeyMap,
|
||||||
pub tree: FsTree,
|
pub tree: FsTree,
|
||||||
tree_structure_version: u32,
|
tree_structure_version: u32,
|
||||||
pub registers: FsTreeRegisters,
|
|
||||||
cursor_y: u16,
|
cursor_y: u16,
|
||||||
|
pub registers: FsTreeRegisters,
|
||||||
pending_keys: Vec<KeyBinding>,
|
pending_keys: Vec<KeyBinding>,
|
||||||
event_queue: EventQueue<FsLayer>,
|
event_queue: EventQueue<FsLayer>,
|
||||||
file_owner_name_cache: FileOwnerNameCache,
|
file_owner_name_cache: FileOwnerNameCache,
|
||||||
@ -27,11 +32,9 @@ pub struct FsLayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FsLayer {
|
impl FsLayer {
|
||||||
pub fn with_root_path(root_path: &Path) -> Self {
|
pub fn new(root_path: &Path, action_map: &'static ActionKeyMap) -> Self {
|
||||||
// Initialize action map early in case it errors.
|
|
||||||
let _ = *action::ACTION_MAP;
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
action_map,
|
||||||
tree: FsTree::with_root_path(root_path),
|
tree: FsTree::with_root_path(root_path),
|
||||||
tree_structure_version: 0,
|
tree_structure_version: 0,
|
||||||
cursor_y: 0,
|
cursor_y: 0,
|
||||||
@ -56,7 +59,7 @@ impl Layer for FsLayer {
|
|||||||
fn handle_input(&mut self, environment: &Environment, key_binding: KeyBinding) -> ActionResult {
|
fn handle_input(&mut self, environment: &Environment, key_binding: KeyBinding) -> ActionResult {
|
||||||
self.pending_keys.push(key_binding);
|
self.pending_keys.push(key_binding);
|
||||||
|
|
||||||
match action::ACTION_MAP.lookup(&self.pending_keys) {
|
match self.action_map.lookup(&self.pending_keys) {
|
||||||
KeyMapLookupResult::Prefix => {
|
KeyMapLookupResult::Prefix => {
|
||||||
ActionResult::Nothing
|
ActionResult::Nothing
|
||||||
}
|
}
|
||||||
|
57
src/main.rs
57
src/main.rs
@ -50,11 +50,13 @@
|
|||||||
#![allow(clippy::redundant_else)]
|
#![allow(clippy::redundant_else)]
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::error::Error;
|
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process::ExitCode;
|
use std::process::ExitCode;
|
||||||
|
|
||||||
|
use crate::state::init::StateInitializer;
|
||||||
|
use crate::state::view::View;
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod component;
|
mod component;
|
||||||
mod file;
|
mod file;
|
||||||
@ -65,11 +67,11 @@ mod util;
|
|||||||
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
const VERSION: Option<&str> = option_env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
#[allow(clippy::print_stdout)]
|
#[allow(clippy::print_stdout)]
|
||||||
fn main() -> Result<ExitCode, Box<dyn Error>> {
|
fn main() -> ExitCode {
|
||||||
let args = env::args_os().skip(1).collect::<Vec<_>>();
|
let args = env::args_os().skip(1).collect::<Vec<_>>();
|
||||||
if args.len() == 1 && args.get(0).is_some_and(|arg| arg == "-v" || arg == "--version") {
|
if args.len() == 1 && args.get(0).is_some_and(|arg| arg == "-v" || arg == "--version") {
|
||||||
println!("{}", VERSION.unwrap_or("unknown"));
|
println!("{}", VERSION.unwrap_or("unknown"));
|
||||||
return Ok(ExitCode::SUCCESS);
|
return ExitCode::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::indexing_slicing)] // Guarded by condition.
|
#[allow(clippy::indexing_slicing)] // Guarded by condition.
|
||||||
@ -81,21 +83,20 @@ fn main() -> Result<ExitCode, Box<dyn Error>> {
|
|||||||
|
|
||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
println!("Too many arguments!");
|
println!("Too many arguments!");
|
||||||
return Ok(ExitCode::SUCCESS);
|
return ExitCode::FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
match get_start_path(args.get(0)) {
|
match get_start_path(args.get(0)) {
|
||||||
StartPathResult::Ok(path) => {
|
StartPathResult::Ok(path) => {
|
||||||
app::run(&path)?;
|
prepare_and_run_app(&path)
|
||||||
Ok(ExitCode::SUCCESS)
|
|
||||||
},
|
},
|
||||||
StartPathResult::InvalidPathArgument(path) => {
|
StartPathResult::InvalidPathArgument(path) => {
|
||||||
println!("Invalid path: {}", path.to_string_lossy());
|
println!("Invalid path: {}", path.to_string_lossy());
|
||||||
Ok(ExitCode::FAILURE)
|
ExitCode::FAILURE
|
||||||
},
|
},
|
||||||
StartPathResult::InvalidWorkingDirectory => {
|
StartPathResult::InvalidWorkingDirectory => {
|
||||||
println!("Invalid working directory!");
|
println!("Invalid working directory!");
|
||||||
Ok(ExitCode::FAILURE)
|
ExitCode::FAILURE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,3 +120,43 @@ fn get_start_path(path_arg: Option<&OsString>) -> StartPathResult {
|
|||||||
StartPathResult::InvalidWorkingDirectory
|
StartPathResult::InvalidWorkingDirectory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
|
fn prepare_and_run_app(start_path: &Path) -> ExitCode {
|
||||||
|
match component::filesystem::defaults::get_action_map() {
|
||||||
|
Ok(action_map) => {
|
||||||
|
run_app(&StateInitializer {
|
||||||
|
filesystem_start_path: start_path,
|
||||||
|
filesystem_action_map: action_map,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
println!("Failed to initialize action map, could not insert key sequence: '{}'\nReason: {}", e.sequence(), e.error());
|
||||||
|
ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::print_stdout)]
|
||||||
|
fn run_app(state_initializer: &StateInitializer) -> ExitCode {
|
||||||
|
View::restore_terminal_on_panic();
|
||||||
|
|
||||||
|
match View::stdout() {
|
||||||
|
Err(e) => {
|
||||||
|
View::restore_terminal();
|
||||||
|
println!("Failed to initialize terminal: {e}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
}
|
||||||
|
Ok(mut view) => {
|
||||||
|
let result = app::run(state_initializer, &mut view);
|
||||||
|
let _ = view.close();
|
||||||
|
|
||||||
|
if let Err(e) = result {
|
||||||
|
println!("Runtime error: {e}");
|
||||||
|
ExitCode::FAILURE
|
||||||
|
} else {
|
||||||
|
ExitCode::SUCCESS
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
8
src/state/init.rs
Normal file
8
src/state/init.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use crate::component::filesystem::ActionKeyMap;
|
||||||
|
|
||||||
|
pub struct StateInitializer<'a> {
|
||||||
|
pub filesystem_start_path: &'a Path,
|
||||||
|
pub filesystem_action_map: &'static ActionKeyMap,
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use crate::component::filesystem::FsLayer;
|
use crate::component::filesystem::FsLayer;
|
||||||
use crate::input::keymap::KeyBinding;
|
use crate::input::keymap::KeyBinding;
|
||||||
use crate::state::action::ActionResult;
|
use crate::state::action::ActionResult;
|
||||||
use crate::state::event::EventResult;
|
use crate::state::event::EventResult;
|
||||||
|
use crate::state::init::StateInitializer;
|
||||||
use crate::state::layer::Layer;
|
use crate::state::layer::Layer;
|
||||||
use crate::state::view::Frame;
|
use crate::state::view::Frame;
|
||||||
|
|
||||||
@ -12,6 +11,7 @@ pub use self::environment::Environment;
|
|||||||
mod environment;
|
mod environment;
|
||||||
pub mod action;
|
pub mod action;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
|
pub mod init;
|
||||||
pub mod layer;
|
pub mod layer;
|
||||||
pub mod view;
|
pub mod view;
|
||||||
|
|
||||||
@ -21,9 +21,9 @@ pub struct State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn with_root_path(root_path: &Path, environment: Environment) -> Self {
|
pub fn new(initializer: &StateInitializer, environment: Environment) -> Self {
|
||||||
Self {
|
Self {
|
||||||
layers: vec![Box::new(FsLayer::with_root_path(root_path))],
|
layers: vec![Box::new(FsLayer::new(initializer.filesystem_start_path, initializer.filesystem_action_map))],
|
||||||
environment
|
environment
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,15 @@ impl View {
|
|||||||
let prev_hook = panic::take_hook();
|
let prev_hook = panic::take_hook();
|
||||||
|
|
||||||
panic::set_hook(Box::new(move |panic_info| {
|
panic::set_hook(Box::new(move |panic_info| {
|
||||||
let _ = terminal::disable_raw_mode();
|
Self::restore_terminal();
|
||||||
prev_hook(panic_info);
|
prev_hook(panic_info);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn restore_terminal() {
|
||||||
|
let _ = terminal::disable_raw_mode();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close(mut self) -> io::Result<()> {
|
pub fn close(mut self) -> io::Result<()> {
|
||||||
self.term.show_cursor()?;
|
self.term.show_cursor()?;
|
||||||
self.term.backend_mut().execute(terminal::LeaveAlternateScreen)?;
|
self.term.backend_mut().execute(terminal::LeaveAlternateScreen)?;
|
||||||
|
Loading…
Reference in New Issue
Block a user