mirror of https://github.com/bobwen-dev/hunter
some bugs fixed
This commit is contained in:
parent
4658b2fcf0
commit
ed6abefc3c
|
@ -174,6 +174,7 @@ impl Tabbable for TabView<FileBrowser> {
|
|||
|
||||
impl FileBrowser {
|
||||
pub fn new(core: &WidgetCore, cache: Option<FsCache>) -> HResult<FileBrowser> {
|
||||
let startup = cache.is_none();
|
||||
let fs_cache = cache.unwrap_or_else(|| FsCache::new(core.get_sender()));
|
||||
|
||||
let cwd = std::env::current_dir().unwrap();
|
||||
|
@ -210,7 +211,13 @@ impl FileBrowser {
|
|||
if let Some(file) = selection {
|
||||
list.select_file(&file);
|
||||
}
|
||||
list.animate_slide_up().log();
|
||||
|
||||
list.refresh().log();
|
||||
|
||||
if startup {
|
||||
list.animate_slide_up().log();
|
||||
}
|
||||
|
||||
list.content.meta_all();
|
||||
Ok(list)
|
||||
}));
|
||||
|
@ -230,7 +237,13 @@ impl FileBrowser {
|
|||
if let Some(file) = selection {
|
||||
list.select_file(&file);
|
||||
}
|
||||
list.animate_slide_up().log();
|
||||
|
||||
list.refresh().log();
|
||||
|
||||
if startup {
|
||||
list.animate_slide_up().log();
|
||||
}
|
||||
|
||||
Ok(list)
|
||||
}));
|
||||
let left_widget = FileBrowserWidgets::FileList(left_widget);
|
||||
|
@ -341,6 +354,7 @@ impl FileBrowser {
|
|||
let mut list = ListView::new(&core, files);
|
||||
|
||||
list.content.meta_set_fresh().log();
|
||||
list.content.meta_all();
|
||||
|
||||
if let Some(file) = selected_file {
|
||||
list.select_file(&file);
|
||||
|
@ -351,9 +365,9 @@ impl FileBrowser {
|
|||
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
|
||||
self.left_widget_goto(&grand_parent).log();
|
||||
} else {
|
||||
self.left_async_widget_mut()?.clear().log();
|
||||
Ok(self.screen()?.flush()?).log();
|
||||
self.left_async_widget_mut()?.set_stale().log();
|
||||
self.left_async_widget_mut()?.change_to(Box::new(move |_,_| {
|
||||
HError::stale()?
|
||||
})).log();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -455,34 +469,26 @@ impl FileBrowser {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_files(&self) -> HResult<Files> {
|
||||
Ok(self.main_widget()?.content.clone())
|
||||
pub fn get_files(&self) -> HResult<&Files> {
|
||||
Ok(&self.main_widget()?.content)
|
||||
}
|
||||
|
||||
pub fn get_left_files(&self) -> HResult<Files> {
|
||||
Ok(self.left_widget()?.content.clone())
|
||||
pub fn get_left_files(&self) -> HResult<&Files> {
|
||||
Ok(&self.left_widget()?.content)
|
||||
}
|
||||
|
||||
pub fn cache_files(&self) -> HResult<()> {
|
||||
if !self.fs_cache.is_cached(&self.cwd)? {
|
||||
let files = self.get_files()?;
|
||||
let selected_file = self.selected_file().ok();
|
||||
self.fs_cache.put_files(files, selected_file).log();
|
||||
} else {
|
||||
let files = &self.main_widget()?.content;
|
||||
let selected_file = self.selected_file().ok();
|
||||
self.fs_cache.save_settings(&files, selected_file).log();
|
||||
}
|
||||
pub fn cache_files(&mut self) -> HResult<()> {
|
||||
let files = self.get_files()?;
|
||||
let selected_file = self.selected_file().ok();
|
||||
self.fs_cache.put_files(files, selected_file).log();
|
||||
self.main_widget_mut()?.content.meta_updated = false;
|
||||
|
||||
|
||||
let left_selection = self.left_widget()?.clone_selected_file();
|
||||
let left_files = self.get_left_files()?;
|
||||
self.fs_cache.put_files(left_files, Some(left_selection)).log();
|
||||
self.left_widget_mut()?.content.meta_updated = false;
|
||||
|
||||
if !self.fs_cache.is_cached(&self.left_widget()?.content.directory)? {
|
||||
let left_selection = self.left_widget()?.clone_selected_file();
|
||||
let left_files = self.get_left_files()?;
|
||||
self.fs_cache.put_files(left_files, Some(left_selection)).log();
|
||||
} else {
|
||||
let files = &self.left_widget()?.content;
|
||||
let selected_file = self.left_widget()?.clone_selected_file();
|
||||
self.fs_cache.save_settings(&files, Some(selected_file)).log();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -729,17 +735,23 @@ impl FileBrowser {
|
|||
let count_xpos = xsize - file_count.len() as u16;
|
||||
let count_ypos = ypos + self.get_coordinates()?.ysize();
|
||||
|
||||
let status = format!("{} {}:{} {}{} {}{}{} {}{}",
|
||||
let status = format!("{} {}:{} {}{} {}{}",
|
||||
permissions,
|
||||
user,
|
||||
group,
|
||||
crate::term::header_color(),
|
||||
mtime,
|
||||
crate::term::color_yellow(),
|
||||
target,
|
||||
target
|
||||
);
|
||||
let status = crate::term::sized_string_u(&status, (xsize-1) as usize);
|
||||
|
||||
let status = format!("{}{}{}{}",
|
||||
status,
|
||||
crate::term::header_color(),
|
||||
crate::term::goto_xy(count_xpos, count_ypos),
|
||||
file_count);
|
||||
|
||||
Ok(status)
|
||||
}
|
||||
}
|
||||
|
@ -783,8 +795,9 @@ impl Widget for FileBrowser {
|
|||
Ok(sized_path)
|
||||
}
|
||||
fn render_footer(&self) -> HResult<String> {
|
||||
let xsize = term::xsize_u();
|
||||
match self.get_core()?.status_bar_content.lock()?.as_mut().take() {
|
||||
Some(status) => Ok(status.clone()),
|
||||
Some(status) => Ok(term::sized_string_u(&status, xsize)),
|
||||
_ => { self.get_footer() },
|
||||
}
|
||||
}
|
||||
|
|
22
src/files.rs
22
src/files.rs
|
@ -79,6 +79,7 @@ pub struct Files {
|
|||
pub directory: File,
|
||||
pub files: Vec<File>,
|
||||
pub meta_upto: Option<usize>,
|
||||
pub meta_updated: bool,
|
||||
pub sort: SortBy,
|
||||
pub dirs_first: bool,
|
||||
pub reverse: bool,
|
||||
|
@ -133,6 +134,7 @@ impl Files {
|
|||
directory: File::new_from_path(&path, None)?,
|
||||
files: files,
|
||||
meta_upto: None,
|
||||
meta_updated: false,
|
||||
sort: SortBy::Name,
|
||||
dirs_first: true,
|
||||
reverse: false,
|
||||
|
@ -189,6 +191,7 @@ impl Files {
|
|||
directory: File::new_from_path(&path, None)?,
|
||||
files: files,
|
||||
meta_upto: None,
|
||||
meta_updated: false,
|
||||
sort: SortBy::Name,
|
||||
dirs_first: true,
|
||||
reverse: false,
|
||||
|
@ -358,6 +361,7 @@ impl Files {
|
|||
}
|
||||
}
|
||||
self.set_dirty();
|
||||
self.meta_updated = true;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -386,10 +390,10 @@ impl Files {
|
|||
|
||||
for file in self.files.iter_mut().take(meta_files) {
|
||||
if !file.meta_processed {
|
||||
file.take_meta(&meta_pool).ok();
|
||||
file.take_meta(&meta_pool, &mut self.meta_updated).ok();
|
||||
}
|
||||
if file.is_dir() && file.meta_processed {
|
||||
file.take_dirsize(&meta_pool).ok();
|
||||
if file.is_dir() {
|
||||
file.take_dirsize(&meta_pool, &mut self.meta_updated).ok();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -618,12 +622,14 @@ impl File {
|
|||
self.meta.get()
|
||||
}
|
||||
|
||||
fn take_dirsize(&mut self, pool: &ThreadPool) -> HResult<()> {
|
||||
fn take_dirsize(&mut self,
|
||||
pool: &ThreadPool,
|
||||
meta_updated: &mut bool) -> HResult<()> {
|
||||
let dirsize = self.dirsize.as_mut()?;
|
||||
if let Ok(_) = dirsize.value { return Ok(()) }
|
||||
|
||||
match dirsize.take_async() {
|
||||
Ok(_) => {},
|
||||
Ok(_) => { *meta_updated = true; },
|
||||
Err(HError::AsyncNotReadyError) => { dirsize.run_pooled(&*pool).ok(); },
|
||||
Err(HError::AsyncAlreadyTakenError) => {},
|
||||
Err(HError::NoneError) => {},
|
||||
|
@ -632,11 +638,13 @@ impl File {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn take_meta(&mut self, pool: &ThreadPool) -> HResult<()> {
|
||||
pub fn take_meta(&mut self,
|
||||
pool: &ThreadPool,
|
||||
meta_updated: &mut bool) -> HResult<()> {
|
||||
if self.meta_processed { return Ok(()) }
|
||||
|
||||
match self.meta.take_async() {
|
||||
Ok(_) => {},
|
||||
Ok(_) => { *meta_updated = true; },
|
||||
Err(HError::AsyncNotReadyError) => { self.meta.run_pooled(&*pool).ok(); },
|
||||
Err(HError::AsyncAlreadyTakenError) => {},
|
||||
Err(HError::NoneError) => {},
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::path::PathBuf;
|
|||
|
||||
use crate::preview::{Async, Stale};
|
||||
use crate::files::{Files, File, SortBy};
|
||||
use crate::dirty::*;
|
||||
use crate::widget::Events;
|
||||
use crate::fail::{HResult, HError, ErrorLog};
|
||||
|
||||
|
@ -115,7 +114,6 @@ impl FsCache {
|
|||
} else {
|
||||
self.add_watch(&dir).log();
|
||||
let dir = dir.clone();
|
||||
let cache = self.files.clone();
|
||||
let files = Async::new(Box::new(move |_| {
|
||||
let files = Files::new_from_path_cancellable(&dir.path, stale)?;
|
||||
Ok(files)
|
||||
|
@ -125,7 +123,7 @@ impl FsCache {
|
|||
}
|
||||
|
||||
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
|
||||
let mut files = self.get_files(&dir, Stale::new())?.1;
|
||||
let files = self.get_files(&dir, Stale::new())?.1;
|
||||
files.wait()
|
||||
}
|
||||
|
||||
|
@ -140,7 +138,7 @@ impl FsCache {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn put_files(&self, files: Files, selection: Option<File>) -> HResult<()> {
|
||||
pub fn put_files(&self, files: &Files, selection: Option<File>) -> HResult<()> {
|
||||
let dir = files.directory.clone();
|
||||
|
||||
let tab_settings = FsCache::extract_tab_settings(&files, selection);
|
||||
|
@ -149,8 +147,14 @@ impl FsCache {
|
|||
|
||||
let mut file_cache = self.files.write()?;
|
||||
|
||||
if !file_cache.contains_key(&files.directory) {
|
||||
file_cache.insert(dir, files);
|
||||
if file_cache.contains_key(&files.directory) {
|
||||
if files.meta_updated {
|
||||
let mut files = files.clone();
|
||||
files.meta_updated = false;
|
||||
file_cache.insert(dir, files);
|
||||
}
|
||||
} else {
|
||||
file_cache.insert(dir, files.clone());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -551,7 +551,7 @@ impl Previewer {
|
|||
|
||||
if is_stale(&stale)? { return Previewer::preview_failed(&file) }
|
||||
|
||||
let output = process.wait_with_output()?;
|
||||
let output = dbg!(process.wait_with_output())?;
|
||||
|
||||
if is_stale(&stale)? { return Previewer::preview_failed(&file) }
|
||||
{
|
||||
|
@ -559,10 +559,9 @@ impl Previewer {
|
|||
*pid_ = None;
|
||||
}
|
||||
|
||||
let status = output.status.code()
|
||||
.ok_or(HError::preview_failed(file)?);
|
||||
let status = output.status.code()?;
|
||||
|
||||
if status == Ok(0) || status == Ok(5) && !is_stale(&stale)? {
|
||||
if !is_stale(&stale)? {
|
||||
let output = std::str::from_utf8(&output.stdout)
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
|
28
src/term.rs
28
src/term.rs
|
@ -15,7 +15,8 @@ pub type TermMode = AlternateScreen<MouseTerminal<RawTerminal<BufWriter<Stdout>>
|
|||
#[derive(Clone)]
|
||||
pub struct Screen {
|
||||
screen: Arc<Mutex<Option<TermMode>>>,
|
||||
size: Arc<RwLock<Option<(usize, usize)>>>
|
||||
size: Arc<RwLock<Option<(usize, usize)>>>,
|
||||
terminal: String
|
||||
}
|
||||
|
||||
impl Screen {
|
||||
|
@ -23,11 +24,13 @@ impl Screen {
|
|||
let screen = BufWriter::new(std::io::stdout()).into_raw_mode()?;
|
||||
let mut screen = MouseTerminal::from(screen);
|
||||
let mut screen = AlternateScreen::from(screen);
|
||||
let terminal = std::env::var("TERM").unwrap_or("xterm".into());
|
||||
|
||||
screen.cursor_hide()?;
|
||||
Ok(Screen {
|
||||
screen: Arc::new(Mutex::new(Some(screen))),
|
||||
size: Arc::new(RwLock::new(None))
|
||||
size: Arc::new(RwLock::new(None)),
|
||||
terminal: terminal
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -58,6 +61,16 @@ impl Screen {
|
|||
pub fn take_size(&self) -> HResult<(usize, usize)> {
|
||||
Ok(self.size.write()?.take()?)
|
||||
}
|
||||
|
||||
pub fn set_title(&mut self, title: &str) -> HResult<()> {
|
||||
if !self.terminal.starts_with("rxvt") {
|
||||
write!(self, "\x1b]2;hunter: {}", title)?;
|
||||
}
|
||||
if self.terminal.starts_with("tmux") {
|
||||
write!(self, "\x1bkhunter: {}\x1b\\", title)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Screen {
|
||||
|
@ -112,11 +125,6 @@ pub trait ScreenExt: Write {
|
|||
let (_, ysize) = termion::terminal_size()?;
|
||||
Ok((ysize - 1) as usize)
|
||||
}
|
||||
fn set_title(&mut self, title: &str) -> HResult<()> {
|
||||
write!(self, "\x1b]2;hunter: {}", title)?;
|
||||
write!(self, "\x1bkhunter: {}\x1b\\", title)?;
|
||||
Ok(())
|
||||
}
|
||||
fn to_main_screen(&mut self) -> HResult<()> {
|
||||
write!(self, "{}", termion::screen::ToMainScreen)?;
|
||||
self.flush()?;
|
||||
|
@ -132,6 +140,11 @@ pub fn xsize() -> u16 {
|
|||
xsize
|
||||
}
|
||||
|
||||
pub fn xsize_u() -> usize {
|
||||
let (xsize, _) = termion::terminal_size().unwrap();
|
||||
xsize as usize - 1
|
||||
}
|
||||
|
||||
pub fn ysize() -> u16 {
|
||||
let (_, ysize) = termion::terminal_size().unwrap();
|
||||
ysize
|
||||
|
@ -195,6 +208,7 @@ pub fn sized_string_u(string: &str, xsize: usize) -> String {
|
|||
padded
|
||||
}
|
||||
|
||||
|
||||
// Do these as constants
|
||||
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ pub trait Widget {
|
|||
}
|
||||
|
||||
fn bad(&mut self, event: Event) -> HResult<()> {
|
||||
self.show_status(&format!("Stop the nasty stuff!! {:?} does nothing!", event))
|
||||
self.show_status(&format!("Stop it!! {:?} does nothing!", event))
|
||||
}
|
||||
|
||||
fn get_header_drawlist(&mut self) -> HResult<String> {
|
||||
|
@ -356,33 +356,29 @@ pub trait Widget {
|
|||
}
|
||||
|
||||
fn draw_status(&self) -> HResult<()> {
|
||||
let xsize = term::xsize() as u16;
|
||||
let xsize = term::xsize_u();
|
||||
let status = match self.get_core()?.status_bar_content.lock()?.as_ref() {
|
||||
Some(status) => status.to_string(),
|
||||
None => "".to_string(),
|
||||
};
|
||||
let sized_status = term::sized_string_u(&status, xsize);
|
||||
|
||||
self.write_to_screen(
|
||||
&format!(
|
||||
"{}{}{:xsize$}{}{}",
|
||||
"{}{}{}",
|
||||
term::move_bottom(),
|
||||
term::status_bg(),
|
||||
" ",
|
||||
term::move_bottom(),
|
||||
status,
|
||||
xsize = xsize as usize
|
||||
sized_status
|
||||
)).log();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn show_status(&self, status: &str) -> HResult<()> {
|
||||
let xsize = self.get_core()?.coordinates.xsize_u();
|
||||
let sized_status = term::sized_string_u(status, xsize);
|
||||
HError::log::<()>(status.to_string()).log();
|
||||
{
|
||||
let mut status_content = self.get_core()?.status_bar_content.lock()?;
|
||||
*status_content = Some(sized_status);
|
||||
*status_content = Some(status.to_string());
|
||||
}
|
||||
self.draw_status()?;
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in New Issue