diff --git a/examples/run.rs b/examples/run.rs new file mode 100644 index 0000000..8cef95e --- /dev/null +++ b/examples/run.rs @@ -0,0 +1,14 @@ +fn main() { + let pwd = std::path::PathBuf::from("/"); + match xplr::run(pwd, None) { + Ok(Some(out)) => print!("{}", out), + Ok(None) => {} + Err(err) => { + if !err.to_string().is_empty() { + eprintln!("error: {}", err); + }; + + std::process::exit(1); + } + } +} diff --git a/src/app.rs b/src/app.rs index b836ad2..b76209c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -4,6 +4,7 @@ use crate::explorer; use crate::input::Key; use crate::lua; use crate::permissions::Permissions; +use crate::runner; use crate::ui::Layout; use anyhow::{bail, Result}; use chrono::{DateTime, Local}; @@ -1765,8 +1766,8 @@ impl App { pub fn explore_pwd(self) -> Result { let dir = explorer::explore_sync( self.explorer_config().clone(), - self.pwd().clone(), - self.focused_node().map(|n| n.absolute_path().clone()), + self.pwd().into(), + self.focused_node().map(|n| n.absolute_path().into()), )?; self.add_directory(dir.parent().clone(), dir) } @@ -2794,4 +2795,15 @@ impl App { last_modes: self.last_modes.clone(), } } + + pub fn run(self, focused_path: Option, lua: &mlua::Lua) -> Result> { + runner::run(self, focused_path, lua) + } +} + +/// Run xplr TUI +pub fn run(pwd: PathBuf, focused_path: Option) -> Result> { + let lua = mlua::Lua::new(); + let app = App::create(pwd, &lua)?; + app.run(focused_path, &lua) } diff --git a/src/explorer.rs b/src/explorer.rs index 10892d4..b48d40f 100644 --- a/src/explorer.rs +++ b/src/explorer.rs @@ -5,14 +5,12 @@ use std::path::PathBuf; use std::sync::mpsc::Sender; use std::thread; -pub fn explore_sync( +pub(crate) fn explore_sync( config: ExplorerConfig, - parent: String, - focused_path: Option, + parent: PathBuf, + focused_path: Option, ) -> Result { - let path = PathBuf::from(&parent); - - let dirs = fs::read_dir(&path)?; + let dirs = fs::read_dir(&parent)?; let mut nodes = dirs .filter_map(|d| { d.ok().map(|e| { @@ -22,30 +20,35 @@ pub fn explore_sync( .unwrap_or_default() }) }) - .map(|name| Node::new(parent.clone(), name)) + .map(|name| Node::new(parent.to_string_lossy().to_string(), name)) .filter(|n| config.filter(n)) .collect::>(); nodes.sort_by(|a, b| config.sort(a, b)); let focus_index = if let Some(focus) = focused_path { + let focus_str = focus.to_string_lossy().to_string(); nodes .iter() .enumerate() - .find(|(_, n)| n.relative_path() == &focus) + .find(|(_, n)| n.relative_path() == &focus_str) .map(|(i, _)| i) .unwrap_or(0) } else { 0 }; - Ok(DirectoryBuffer::new(parent, nodes, focus_index)) + Ok(DirectoryBuffer::new( + parent.to_string_lossy().to_string(), + nodes, + focus_index, + )) } -pub fn explore_async( +pub(crate) fn explore_async( config: ExplorerConfig, - parent: String, - focused_path: Option, + parent: PathBuf, + focused_path: Option, tx_msg_in: Sender, ) { thread::spawn(move || { @@ -53,7 +56,10 @@ pub fn explore_async( .map(|buf| { tx_msg_in .send(Task::new( - MsgIn::Internal(InternalMsg::AddDirectory(parent.clone(), buf)), + MsgIn::Internal(InternalMsg::AddDirectory( + parent.to_string_lossy().to_string(), + buf, + )), None, )) .unwrap_or_default(); @@ -69,19 +75,23 @@ pub fn explore_async( }); } -pub fn explore_recursive_async( +pub(crate) fn explore_recursive_async( config: ExplorerConfig, - parent: String, - focused_path: Option, + parent: PathBuf, + focused_path: Option, tx_msg_in: Sender, ) { - let path = PathBuf::from(&parent); - explore_async(config.clone(), parent, focused_path, tx_msg_in.clone()); - if let Some(grand_parent) = path.parent() { + explore_async( + config.clone(), + parent.clone(), + focused_path, + tx_msg_in.clone(), + ); + if let Some(grand_parent) = parent.parent() { explore_recursive_async( config, - grand_parent.to_string_lossy().to_string(), - path.file_name().map(|f| f.to_string_lossy().to_string()), + grand_parent.into(), + parent.file_name().map(|p| p.into()), tx_msg_in, ); } diff --git a/src/lib.rs b/src/lib.rs index bf407fd..2237f5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,3 +14,5 @@ pub mod pipe_reader; pub mod pwd_watcher; pub mod runner; pub mod ui; + +pub use app::run; diff --git a/src/main.rs b/src/main.rs index 07fef2e..985e7ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ use std::env; use std::path::PathBuf; use xplr::app; -use xplr::runner; fn main() { let mut pwd = PathBuf::from(env::args().nth(1).unwrap_or_else(|| ".".into())) @@ -12,23 +11,11 @@ fn main() { let mut focused_path = None; if pwd.is_file() { - focused_path = Some( - pwd.file_name() - .unwrap_or_default() - .to_string_lossy() - .to_string(), - ); - pwd = pwd.parent().map(|p| p.into()).unwrap_or_default(); + focused_path = pwd.file_name().map(|p| p.into()); + pwd = pwd.parent().map(|p| p.into()).unwrap_or_else(|| ".".into()); } - let lua = mlua::Lua::new(); - - let app = app::App::create(pwd, &lua).unwrap_or_else(|e| { - eprintln!("error: {}", e); - std::process::exit(1); - }); - - match runner::run(app, focused_path, lua) { + match app::run(pwd, focused_path) { Ok(Some(out)) => print!("{}", out), Ok(None) => {} Err(err) => { diff --git a/src/runner.rs b/src/runner.rs index a7b0c6d..578b7b4 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -16,6 +16,7 @@ use mlua::LuaSerdeExt; use std::fs; use std::io; use std::io::prelude::*; +use std::path::PathBuf; use std::process::{Command, ExitStatus, Stdio}; use std::sync::mpsc; use termion::get_tty; @@ -86,10 +87,10 @@ fn call(app: &app::App, cmd: app::Command, silent: bool) -> io::Result, - lua: mlua::Lua, + focused_path: Option, + lua: &mlua::Lua, ) -> Result> { fs::create_dir_all(app.session_path())?; @@ -99,7 +100,10 @@ pub fn run( app = app.explore_pwd()?; - app = if let Some(f) = focused_path.clone() { + app = if let Some(f) = focused_path + .clone() + .map(|f| f.to_string_lossy().to_string()) + { app.focus_by_file_name(&f, true)? } else { app.focus_first(true)? @@ -107,7 +111,7 @@ pub fn run( explorer::explore_recursive_async( app.explorer_config().clone(), - app.pwd().clone(), + app.pwd().into(), focused_path, tx_msg_in.clone(), ); @@ -170,8 +174,8 @@ pub fn run( app::MsgOut::ExplorePwdAsync => { explorer::explore_async( app.explorer_config().clone(), - app.pwd().clone(), - app.focused_node().map(|n| n.relative_path().clone()), + app.pwd().into(), + app.focused_node().map(|n| n.relative_path().into()), tx_msg_in.clone(), ); tx_pwd_watcher.send(app.pwd().clone())?; @@ -180,8 +184,8 @@ pub fn run( app::MsgOut::ExploreParentsAsync => { explorer::explore_recursive_async( app.explorer_config().clone(), - app.pwd().clone(), - app.focused_node().map(|n| n.relative_path().clone()), + app.pwd().into(), + app.focused_node().map(|n| n.relative_path().into()), tx_msg_in.clone(), ); tx_pwd_watcher.send(app.pwd().clone())?;