@ -24,6 +24,7 @@ use anyhow::{bail, Result};
use chrono ::{ DateTime , Local } ;
use chrono ::{ DateTime , Local } ;
use gethostname ::gethostname ;
use gethostname ::gethostname ;
use indexmap ::set ::IndexSet ;
use indexmap ::set ::IndexSet ;
use path_absolutize ::* ;
use serde ::{ Deserialize , Serialize } ;
use serde ::{ Deserialize , Serialize } ;
use std ::collections ::HashMap ;
use std ::collections ::HashMap ;
use std ::collections ::VecDeque ;
use std ::collections ::VecDeque ;
@ -166,6 +167,7 @@ pub struct App {
pub version : String ,
pub version : String ,
pub config : Config ,
pub config : Config ,
pub hooks : Hooks ,
pub hooks : Hooks ,
pub vroot : String ,
pub pwd : String ,
pub pwd : String ,
pub directory_buffer : Option < DirectoryBuffer > ,
pub directory_buffer : Option < DirectoryBuffer > ,
pub last_focus : HashMap < String , Option < String > > ,
pub last_focus : HashMap < String , Option < String > > ,
@ -188,6 +190,7 @@ pub struct App {
impl App {
impl App {
pub fn create (
pub fn create (
bin : String ,
bin : String ,
vroot : PathBuf ,
pwd : PathBuf ,
pwd : PathBuf ,
lua : & mlua ::Lua ,
lua : & mlua ::Lua ,
config_file : Option < PathBuf > ,
config_file : Option < PathBuf > ,
@ -199,14 +202,14 @@ impl App {
let config_file = if let Some ( path ) = config_file {
let config_file = if let Some ( path ) = config_file {
Some ( path )
Some ( path )
} else if let Some ( dir ) = dirs ::home_dir ( ) {
} else if let Some ( dir ) = dirs ::home_dir ( ) {
let path = dir . join ( ".config ") . join ( "xplr" ) . join ( " init.lua") ;
let path = dir . join ( ".config /xplr/ init.lua") ;
if path . exists ( ) {
if path . exists ( ) {
Some ( path )
Some ( path )
} else {
} else {
None
None
}
}
} else {
} else {
let path = PathBuf ::from ( "/ ") . join ( "etc" ) . join ( "xplr" ) . join ( " init.lua") ;
let path = PathBuf ::from ( "/ etc/xplr/ init.lua") ;
if path . exists ( ) {
if path . exists ( ) {
Some ( path )
Some ( path )
} else {
} else {
@ -294,7 +297,16 @@ impl App {
} ;
} ;
let hostname = gethostname ( ) . to_string_lossy ( ) . to_string ( ) ;
let hostname = gethostname ( ) . to_string_lossy ( ) . to_string ( ) ;
if ! pwd . starts_with ( & vroot ) {
bail ! (
"{:?} is outside of virtual root {:?}" ,
pwd . to_string_lossy ( ) ,
vroot . to_string_lossy ( )
)
}
let pwd = pwd . to_string_lossy ( ) . to_string ( ) ;
let pwd = pwd . to_string_lossy ( ) . to_string ( ) ;
let vroot = vroot . to_string_lossy ( ) . to_string ( ) ;
env ::set_current_dir ( & pwd ) ? ;
env ::set_current_dir ( & pwd ) ? ;
let input = InputBuffer {
let input = InputBuffer {
@ -306,6 +318,7 @@ impl App {
bin ,
bin ,
version : VERSION . to_string ( ) ,
version : VERSION . to_string ( ) ,
config ,
config ,
vroot ,
pwd ,
pwd ,
directory_buffer : Default ::default ( ) ,
directory_buffer : Default ::default ( ) ,
last_focus : Default ::default ( ) ,
last_focus : Default ::default ( ) ,
@ -743,9 +756,15 @@ impl App {
}
}
fn change_directory ( mut self , dir : & str , save_history : bool ) -> Result < Self > {
fn change_directory ( mut self , dir : & str , save_history : bool ) -> Result < Self > {
let mut dir = PathBuf ::from ( dir ) ;
let dir = PathBuf ::from ( dir ) . absolutize ( ) ? . to_path_buf ( ) ;
if dir . is_relative ( ) {
dir = PathBuf ::from ( self . pwd . clone ( ) ) . join ( dir ) ;
let vroot = & self . vroot . clone ( ) ;
if ! dir . starts_with ( & self . vroot ) {
return self . log_error ( format! (
"{:?} is outside of virtual root {:?}" ,
dir . to_string_lossy ( ) ,
vroot ,
) ) ;
}
}
match env ::set_current_dir ( & dir ) {
match env ::set_current_dir ( & dir ) {
@ -971,10 +990,7 @@ impl App {
}
}
pub fn focus_path ( self , path : & str , save_history : bool ) -> Result < Self > {
pub fn focus_path ( self , path : & str , save_history : bool ) -> Result < Self > {
let mut pathbuf = PathBuf ::from ( path ) ;
let pathbuf = PathBuf ::from ( path ) . absolutize ( ) ? . to_path_buf ( ) ;
if pathbuf . is_relative ( ) {
pathbuf = PathBuf ::from ( self . pwd . clone ( ) ) . join ( pathbuf ) ;
}
if let Some ( parent ) = pathbuf . parent ( ) {
if let Some ( parent ) = pathbuf . parent ( ) {
if let Some ( filename ) = pathbuf . file_name ( ) {
if let Some ( filename ) = pathbuf . file_name ( ) {
self . change_directory ( & parent . to_string_lossy ( ) , false ) ?
self . change_directory ( & parent . to_string_lossy ( ) , false ) ?
@ -1216,10 +1232,7 @@ impl App {
}
}
pub fn select_path ( mut self , path : String ) -> Result < Self > {
pub fn select_path ( mut self , path : String ) -> Result < Self > {
let mut path = PathBuf ::from ( path ) ;
let path = PathBuf ::from ( path ) . absolutize ( ) ? . to_path_buf ( ) ;
if path . is_relative ( ) {
path = PathBuf ::from ( self . pwd . clone ( ) ) . join ( path ) ;
}
let parent = path . parent ( ) . map ( | p | p . to_string_lossy ( ) . to_string ( ) ) ;
let parent = path . parent ( ) . map ( | p | p . to_string_lossy ( ) . to_string ( ) ) ;
let filename = path . file_name ( ) . map ( | p | p . to_string_lossy ( ) . to_string ( ) ) ;
let filename = path . file_name ( ) . map ( | p | p . to_string_lossy ( ) . to_string ( ) ) ;
if let ( Some ( p ) , Some ( n ) ) = ( parent , filename ) {
if let ( Some ( p ) , Some ( n ) ) = ( parent , filename ) {
@ -1246,10 +1259,7 @@ impl App {
}
}
pub fn un_select_path ( mut self , path : String ) -> Result < Self > {
pub fn un_select_path ( mut self , path : String ) -> Result < Self > {
let mut pathbuf = PathBuf ::from ( path ) ;
let pathbuf = PathBuf ::from ( path ) . absolutize ( ) ? . to_path_buf ( ) ;
if pathbuf . is_relative ( ) {
pathbuf = PathBuf ::from ( self . pwd . clone ( ) ) . join ( pathbuf ) ;
}
self . selection
self . selection
. retain ( | n | PathBuf ::from ( & n . absolute_path ) ! = pathbuf ) ;
. retain ( | n | PathBuf ::from ( & n . absolute_path ) ! = pathbuf ) ;
Ok ( self )
Ok ( self )
@ -1286,10 +1296,7 @@ impl App {
}
}
fn toggle_selection_by_path ( self , path : String ) -> Result < Self > {
fn toggle_selection_by_path ( self , path : String ) -> Result < Self > {
let mut pathbuf = PathBuf ::from ( & path ) ;
let pathbuf = PathBuf ::from ( & path ) . absolutize ( ) ? . to_path_buf ( ) ;
if pathbuf . is_relative ( ) {
pathbuf = PathBuf ::from ( self . pwd . clone ( ) ) . join ( pathbuf ) ;
}
if self
if self
. selection
. selection
. iter ( )
. iter ( )