Refactored parts of `runner::Runner` to take a Cli struct, instead of putting everything manually in `Runner`.

pull/325/head
Tom van Dijk 3 years ago committed by Arijit Basu
parent a6dcd476aa
commit 671d1b11fd

@ -1,5 +1,5 @@
fn main() {
match xplr::runner(None).and_then(|a| a.run()) {
match xplr::runner::Runner::new(xplr::cli::Cli::default()).and_then(|a| a.run()) {
Ok(Some(out)) => print!("{}", out),
Ok(None) => {}
Err(err) => {

@ -1,3 +1,4 @@
use crate::cli;
use crate::config::Config;
use crate::config::Mode;
use crate::explorer;
@ -2342,10 +2343,8 @@ impl App {
fn select(mut self) -> Result<Self> {
if let Some(n) = self.focused_node().map(|n| n.to_owned()) {
self.selection.insert(n);
Ok(self)
} else {
Ok(self)
}
Ok(self)
}
fn select_path(mut self, path: String) -> Result<Self> {
@ -2357,10 +2356,8 @@ impl App {
let filename = path.file_name().map(|p| p.to_string_lossy().to_string());
if let (Some(p), Some(n)) = (parent, filename) {
self.selection.insert(Node::new(p, n));
Ok(self)
} else {
Ok(self)
}
Ok(self)
}
fn select_all(mut self) -> Result<Self> {
@ -2903,6 +2900,6 @@ impl App {
}
}
pub fn runner(path: Option<PathBuf>) -> Result<Runner> {
Runner::new(path)
pub fn runner(cli: cli::Cli) -> Result<Runner> {
Runner::new(cli)
}

@ -1,92 +1,8 @@
#![allow(clippy::too_many_arguments)]
use anyhow::Result;
use std::collections::VecDeque;
use std::env;
use std::io;
use std::path::PathBuf;
use xplr::app;
#[derive(Debug, Clone, Default)]
struct Cli {
version: bool,
help: bool,
read_only: bool,
path: Option<PathBuf>,
config: Option<PathBuf>,
extra_config: Vec<PathBuf>,
on_load: Vec<app::ExternalMsg>,
}
impl Cli {
fn parse(args: env::Args) -> Result<Self> {
let mut args: VecDeque<String> = args.skip(1).collect();
let mut cli = Self::default();
while let Some(arg) = args.pop_front() {
match arg.as_str() {
// Flags
"-" => {
let mut path = String::new();
if io::stdin().read_line(&mut path).is_ok() {
cli.path =
Some(path.trim_end_matches("\r\n").trim_end_matches('\n').into());
};
}
"-h" | "--help" => {
cli.help = true;
}
"-V" | "--version" => {
cli.version = true;
}
"--" => {
if cli.path.is_none() {
cli.path = args.pop_front().map(PathBuf::from);
}
return Ok(cli);
}
// Options
"-c" | "--config" => cli.config = args.pop_front().map(PathBuf::from),
"-C" | "--extra-config" => {
while let Some(path) = args.pop_front() {
if path.starts_with('-') {
args.push_front(path);
break;
} else {
cli.extra_config.push(PathBuf::from(path));
}
}
}
"--read-only" => cli.read_only = true,
"--on-load" => {
while let Some(msg) = args.pop_front() {
if msg.starts_with('-') {
args.push_front(msg);
break;
} else {
cli.on_load.push(serde_yaml::from_str(&msg)?);
}
}
}
// path
path => {
if cli.path.is_none() {
cli.path = Some(path.into());
}
}
}
}
Ok(cli)
}
}
use xplr::{cli::Cli, runner::Runner};
fn main() {
let cli = Cli::parse(env::args()).unwrap_or_else(|e| {
@ -130,13 +46,7 @@ fn main() {
} else if cli.version {
println!("xplr {}", xplr::app::VERSION);
} else {
match app::runner(cli.path.clone())
.map(|a| a.with_on_load(cli.on_load.clone()))
.map(|a| a.with_config(cli.config.clone()))
.map(|a| a.with_extra_config(cli.extra_config.clone()))
.map(|a| a.with_read_only(cli.read_only))
.and_then(|a| a.run())
{
match Runner::new(cli).and_then(|a| a.run()) {
Ok(Some(out)) => print!("{}", out),
Ok(None) => {}
Err(err) => {

@ -0,0 +1,87 @@
use anyhow::Result;
use std::collections::VecDeque;
use std::path::PathBuf;
use std::{env, io};
use crate::app;
#[derive(Debug, Clone, Default)]
pub struct Cli {
pub version: bool,
pub help: bool,
pub read_only: bool,
pub path: Option<PathBuf>,
pub config: Option<PathBuf>,
pub extra_config: Vec<PathBuf>,
pub on_load: Vec<app::ExternalMsg>,
}
impl Cli {
pub fn parse(args: env::Args) -> Result<Self> {
let mut args: VecDeque<String> = args.skip(1).collect();
let mut cli = Self::default();
while let Some(arg) = args.pop_front() {
match arg.as_str() {
// Flags
"-" => {
let mut path = String::new();
if io::stdin().read_line(&mut path).is_ok() {
cli.path =
Some(path.trim_end_matches("\r\n").trim_end_matches('\n').into());
};
}
"-h" | "--help" => {
cli.help = true;
}
"-V" | "--version" => {
cli.version = true;
}
"--" => {
if cli.path.is_none() {
cli.path = args.pop_front().map(PathBuf::from);
}
return Ok(cli);
}
// Options
"-c" | "--config" => cli.config = args.pop_front().map(PathBuf::from),
"-C" | "--extra-config" => {
while let Some(path) = args.pop_front() {
if path.starts_with('-') {
args.push_front(path);
break;
} else {
cli.extra_config.push(PathBuf::from(path));
}
}
}
"--read-only" => cli.read_only = true,
"--on-load" => {
while let Some(msg) = args.pop_front() {
if msg.starts_with('-') {
args.push_front(msg);
break;
} else {
cli.on_load.push(serde_yaml::from_str(&msg)?);
}
}
}
// path
path => {
if cli.path.is_none() {
cli.path = Some(path.into());
}
}
}
}
Ok(cli)
}
}

@ -3,6 +3,7 @@
#![allow(clippy::unnecessary_wraps)]
pub mod app;
pub mod cli;
pub mod config;
pub mod event_reader;
pub mod explorer;
@ -13,5 +14,3 @@ pub mod pipe_reader;
pub mod pwd_watcher;
pub mod runner;
pub mod ui;
pub use app::runner;

@ -106,9 +106,10 @@ pub struct Runner {
}
impl Runner {
pub(crate) fn new(path: Option<PathBuf>) -> Result<Self> {
pub fn new(cli: crate::cli::Cli) -> Result<Self> {
let basedir = std::env::current_dir()?;
let mut pwd = path
let mut pwd = cli
.path
.map(|p| if p.is_relative() { basedir.join(p) } else { p })
.unwrap_or_else(|| basedir.clone());
let mut focused_path = None;
@ -121,33 +122,13 @@ impl Runner {
Ok(Self {
pwd,
focused_path,
config_file: Default::default(),
extra_config_files: Default::default(),
on_load: Default::default(),
read_only: Default::default(),
config_file: cli.config,
extra_config_files: cli.extra_config,
on_load: cli.on_load,
read_only: cli.read_only,
})
}
pub fn with_on_load(mut self, on_load: Vec<app::ExternalMsg>) -> Self {
self.on_load = on_load;
self
}
pub fn with_config(mut self, config_file: Option<PathBuf>) -> Self {
self.config_file = config_file;
self
}
pub fn with_extra_config(mut self, config_files: Vec<PathBuf>) -> Self {
self.extra_config_files = config_files;
self
}
pub fn with_read_only(mut self, read_only: bool) -> Self {
self.read_only = read_only;
self
}
pub fn run(self) -> Result<Option<String>> {
// Why unsafe? See https://github.com/sayanarijit/xplr/issues/309
let lua = unsafe { mlua::Lua::unsafe_new() };
@ -231,55 +212,56 @@ impl Runner {
Ok(a) => {
app = a;
while let Some(msg) = app.pop_msg_out() {
use app::MsgOut::*;
match msg {
// NOTE: Do not schedule critical tasks via tx_msg_in in this loop.
// Try handling them immediately.
app::MsgOut::Enque(task) => {
Enque(task) => {
tx_msg_in.send(task)?;
}
app::MsgOut::Quit => {
Quit => {
result = Ok(None);
break 'outer;
}
app::MsgOut::PrintPwdAndQuit => {
PrintPwdAndQuit => {
result = Ok(Some(format!("{}\n", app.pwd())));
break 'outer;
}
app::MsgOut::PrintFocusPathAndQuit => {
PrintFocusPathAndQuit => {
result = Ok(app
.focused_node()
.map(|n| format!("{}\n", n.absolute_path())));
break 'outer;
}
app::MsgOut::PrintSelectionAndQuit => {
PrintSelectionAndQuit => {
result = Ok(Some(app.selection_str()));
break 'outer;
}
app::MsgOut::PrintResultAndQuit => {
PrintResultAndQuit => {
result = Ok(Some(app.result_str()));
break 'outer;
}
app::MsgOut::PrintAppStateAndQuit => {
PrintAppStateAndQuit => {
let out = serde_yaml::to_string(&app)?;
result = Ok(Some(out));
break 'outer;
}
app::MsgOut::Debug(path) => {
Debug(path) => {
fs::write(&path, serde_yaml::to_string(&app)?)?;
}
app::MsgOut::ClearScreen => {
ClearScreen => {
terminal.clear()?;
}
app::MsgOut::ExplorePwdAsync => {
ExplorePwdAsync => {
explorer::explore_async(
app.explorer_config().clone(),
app.pwd().into(),
@ -290,7 +272,7 @@ impl Runner {
tx_pwd_watcher.send(app.pwd().clone())?;
}
app::MsgOut::ExploreParentsAsync => {
ExploreParentsAsync => {
explorer::explore_recursive_async(
app.explorer_config().clone(),
app.pwd().into(),
@ -301,7 +283,7 @@ impl Runner {
tx_pwd_watcher.send(app.pwd().clone())?;
}
app::MsgOut::Refresh => {
Refresh => {
// $PWD watcher
tx_pwd_watcher.send(app.pwd().clone())?;
// UI
@ -316,7 +298,7 @@ impl Runner {
}
}
app::MsgOut::EnableMouse => {
EnableMouse => {
if !mouse_enabled {
match execute!(
terminal.backend_mut(),
@ -332,7 +314,7 @@ impl Runner {
}
}
app::MsgOut::ToggleMouse => {
ToggleMouse => {
let msg = if mouse_enabled {
app::ExternalMsg::DisableMouse
} else {
@ -342,7 +324,7 @@ impl Runner {
.handle_task(app::Task::new(app::MsgIn::External(msg), None))?;
}
app::MsgOut::DisableMouse => {
DisableMouse => {
if mouse_enabled {
match execute!(
terminal.backend_mut(),
@ -358,7 +340,7 @@ impl Runner {
}
}
app::MsgOut::StartFifo(path) => {
StartFifo(path) => {
fifo = match start_fifo(&path, &app.focused_node_str()) {
Ok(file) => Some(file),
Err(e) => {
@ -368,14 +350,14 @@ impl Runner {
}
}
app::MsgOut::StopFifo => {
StopFifo => {
if let Some(file) = fifo {
fifo = None;
std::mem::drop(file);
}
}
app::MsgOut::ToggleFifo(path) => {
ToggleFifo(path) => {
if let Some(file) = fifo {
fifo = None;
std::mem::drop(file);
@ -390,7 +372,7 @@ impl Runner {
}
}
app::MsgOut::CallLuaSilently(func) => {
CallLuaSilently(func) => {
tx_event_reader.send(true)?;
match call_lua(&app, &lua, &func, false) {
@ -411,7 +393,7 @@ impl Runner {
tx_event_reader.send(false)?;
}
app::MsgOut::CallSilently(cmd) => {
CallSilently(cmd) => {
tx_event_reader.send(true)?;
app.write_pipes()?;
@ -448,7 +430,7 @@ impl Runner {
tx_event_reader.send(false)?;
}
app::MsgOut::CallLua(func) => {
CallLua(func) => {
execute!(terminal.backend_mut(), event::DisableMouseCapture)
.unwrap_or_default();
@ -494,7 +476,7 @@ impl Runner {
}
}
app::MsgOut::Call(cmd) => {
Call(cmd) => {
execute!(terminal.backend_mut(), event::DisableMouseCapture)
.unwrap_or_default();

Loading…
Cancel
Save