From 205e9dc4265b9a9d7fdcd836e646830bf8e0ce30 Mon Sep 17 00:00:00 2001 From: rabite Date: Wed, 13 Feb 2019 10:08:29 +0100 Subject: [PATCH] speed optimization --- src/file_browser.rs | 6 +- src/listview.rs | 19 +++-- src/preview.rs | 201 +++++++++----------------------------------- src/textview.rs | 15 ++++ 4 files changed, 71 insertions(+), 170 deletions(-) diff --git a/src/file_browser.rs b/src/file_browser.rs index a499c5b..3a178b0 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -115,12 +115,8 @@ impl FileBrowser { pub fn update_preview(&mut self) { if self.columns.get_main_widget().content.len() == 0 { return } let file = self.columns.get_main_widget().selected_file().clone(); - //let preview = &mut self.columns.preview; - let coords = self.columns.preview.get_coordinates(); - let mut preview = crate::preview::AsyncPreviewer::new(); - preview.set_coordinates(&coords); + let preview = &mut self.columns.preview; preview.set_file(&file); - self.columns.preview = preview; } pub fn fix_selection(&mut self) { diff --git a/src/listview.rs b/src/listview.rs index cec6630..b3ab73f 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -19,6 +19,7 @@ where T: Send, { pub content: T, + lines: usize, selection: usize, offset: usize, buffer: Vec, @@ -29,11 +30,12 @@ where impl ListView where ListView: Widget, - T: Send, + T: Send { pub fn new(content: T) -> ListView { let view = ListView:: { content: content, + lines: 0, selection: 0, offset: 0, buffer: Vec::new(), @@ -59,7 +61,7 @@ where self.seeking = false; } fn move_down(&mut self) { - let lines = self.buffer.len(); + let lines = self.lines; let y_size = self.coordinates.ysize() as usize; if self.selection == lines - 1 { @@ -340,9 +342,13 @@ where } fn render(&self) -> Vec { + let ysize = self.get_coordinates().ysize() as usize; + let offset = self.offset; self.content .files .par_iter() + .skip(offset) + .take(ysize) .map(|file| self.render_line(&file)) .collect() } @@ -360,6 +366,7 @@ impl Widget for ListView { self.refresh(); } fn refresh(&mut self) { + self.lines = self.content.len(); self.buffer = self.render(); } @@ -372,8 +379,8 @@ impl Widget for ListView { output += &self .buffer .par_iter() - .skip(self.offset) - .take(ysize as usize) + //.skip(self.offset) + //.take(ysize as usize) .enumerate() .map(|(i, item)| { let mut output = term::normal_color(); @@ -405,8 +412,8 @@ impl Widget for ListView { self.move_up(); self.refresh(); } - Key::Char('P') => for _ in 0..10 { self.move_up() } - Key::Char('N') => for _ in 0..10 { self.move_down() } + Key::Char('P') => { for _ in 0..10 { self.move_up() } self.refresh(); } + Key::Char('N') => { for _ in 0..10 { self.move_down() } self.refresh(); } Key::Down | Key::Char('n') => { self.move_down(); self.refresh(); diff --git a/src/preview.rs b/src/preview.rs index f6bad98..859c8eb 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -24,8 +24,10 @@ fn kill_procs() { } fn is_current(file: &File) -> bool { - true - //CURFILE.lock().unwrap().as_ref().unwrap() == file + match CURFILE.lock().unwrap().as_ref() { + Some(curfile) => curfile == file, + None => true + } } #[derive(PartialEq)] @@ -56,6 +58,8 @@ impl AsyncPreviewer { let coordinates = self.coordinates.clone(); let file = file.clone(); let redraw = crate::term::reset() + &self.get_redraw_empty_list(0); + let pids = PIDS.clone(); + kill_procs(); self.async_plug.replace_widget(Box::new(move || { kill_procs(); @@ -86,7 +90,10 @@ impl AsyncPreviewer { } _ => { if file.get_mime() == Some("text".to_string()) { - let mut textview = TextView::new_from_file(&file); + let lines = coordinates.ysize() as usize; + let mut textview + = TextView::new_from_file_limit_lines(&file, + lines); //if !is_current(&file) { return } textview.set_coordinates(&coordinates); textview.refresh(); @@ -106,173 +113,49 @@ impl AsyncPreviewer { .stderr(std::process::Stdio::null()) .spawn().unwrap(); - // let pid = process.id(); - // PIDS.lock().unwrap().push(pid); + let pid = process.id(); + PIDS.lock().unwrap().push(pid); //if !is_current(&file) { return } let output = process.wait_with_output(); - //if output.is_err() { return } - let output = output.unwrap(); - - let status = output.status.code(); - //if status.is_none() { return } - let status = status.unwrap(); - - if status == 0 || status == 5 && is_current(&file) { - let output = std::str::from_utf8(&output.stdout) - .unwrap() - .to_string(); - let mut textview = TextView { - lines: output.lines().map(|s| s.to_string()).collect(), - buffer: String::new(), - coordinates: Coordinates::new() }; - textview.set_coordinates(&coordinates); - textview.refresh(); - textview.animate_slide_up(); - return Box::new(textview); + match output { + Ok(output) => { + let status = output.status.code(); + match status { + Some(status) => { + if status == 0 || status == 5 && is_current(&file) { + let output = std::str::from_utf8(&output.stdout) + .unwrap() + .to_string(); + let mut textview = TextView { + lines: output.lines().map(|s| s.to_string()).collect(), + buffer: String::new(), + coordinates: Coordinates::new() }; + textview.set_coordinates(&coordinates); + textview.refresh(); + textview.animate_slide_up(); + return Box::new(textview); + } + }, None => {} + } + }, Err(_) => {} } - } - - write!(bufout, "{}", redraw).unwrap(); - //std::io::stdout().flush().unwrap(); - let textview = crate::textview::TextView { - lines: vec![], - buffer: "".to_string(), - coordinates: Coordinates::new(), - }; - return Box::new(textview); - } - } - })); - } -} - -#[derive(PartialEq)] -pub struct Previewer { - pub file: Option, - pub buffer: String, - pub coordinates: Coordinates, -} - -impl Previewer { - pub fn new() -> Previewer { - Previewer { - file: None, - buffer: String::new(), - coordinates: Coordinates::new(), - } - } - pub fn set_file(&mut self, file: &File) { - let coordinates = self.coordinates.clone(); - let file = file.clone(); - let redraw = crate::term::reset() + &self.get_redraw_empty_list(0); - - *CURFILE.lock().unwrap() = Some(file.clone()); - - std::thread::spawn(move || { - kill_procs(); - match &file.kind { - Kind::Directory => match Files::new_from_path(&file.path) { - Ok(files) => { - if !is_current(&file) { return } - let len = files.len(); - if len == 0 { return }; - let mut file_list = ListView::new(files); - file_list.set_coordinates(&coordinates); - file_list.refresh(); - if !is_current(&file) { return } - file_list.animate_slide_up(); - - } - Err(err) => { - crate::window::show_status(&format!("Can't preview because: {}", err)); - } - - }, - _ => { - if file.get_mime() == Some("text".to_string()) { - let mut textview = TextView::new_from_file(&file); - if !is_current(&file) { return } - textview.set_coordinates(&coordinates); - textview.refresh(); - if !is_current(&file) { return } - textview.animate_slide_up(); - } else { - let process = - std::process::Command::new("scope.sh") - .arg(&file.name) - .arg("10".to_string()) - .arg("10".to_string()) - .arg("".to_string()) - .arg("false".to_string()) - .stdin(std::process::Stdio::null()) - .stdout(std::process::Stdio::piped()) - .stderr(std::process::Stdio::null()) - .spawn().unwrap(); - - let pid = process.id(); - PIDS.lock().unwrap().push(pid); - - if !is_current(&file) { return } - - let output = process.wait_with_output(); - if output.is_err() { return } - let output = output.unwrap(); - - let status = output.status.code(); - if status.is_none() { return } - let status = status.unwrap(); - - if status == 0 || status == 5 && is_current(&file) { - let output = std::str::from_utf8(&output.stdout) - .unwrap() - .to_string(); - let mut textview = TextView { - lines: output.lines().map(|s| s.to_string()).collect(), - buffer: String::new(), - coordinates: Coordinates::new() }; - textview.set_coordinates(&coordinates); - textview.refresh(); - textview.animate_slide_up(); - - } else - { - write!(std::io::stdout(), "{}", redraw).unwrap(); - } - PIDS.lock().unwrap().remove_item(&pid); + write!(bufout, "{}", redraw).unwrap(); + //std::io::stdout().flush().unwrap(); + let textview = crate::textview::TextView { + lines: vec![], + buffer: "".to_string(), + coordinates: Coordinates::new(), + }; + return Box::new(textview); } } - } - }); + }})) } } -impl Widget for Previewer { - fn get_coordinates(&self) -> &Coordinates { - &self.coordinates - } - fn set_coordinates(&mut self, coordinates: &Coordinates) { - if self.coordinates == *coordinates { - return; - } - self.coordinates = coordinates.clone(); - self.refresh(); - } - fn render_header(&self) -> String { - "".to_string() - } - fn refresh(&mut self) { - let file = self.file.clone(); - if let Some(file) = file { - self.set_file(&file); - } - } - fn get_drawlist(&self) -> String { - self.buffer.clone() - } -} impl Widget for AsyncPreviewer { diff --git a/src/textview.rs b/src/textview.rs index 04e0fbf..73b7741 100644 --- a/src/textview.rs +++ b/src/textview.rs @@ -28,6 +28,21 @@ impl TextView { coordinates: Coordinates::new(), } } + pub fn new_from_file_limit_lines(file: &File, num: usize) -> TextView { + let file = std::fs::File::open(&file.path).unwrap(); + let file = std::io::BufReader::new(file); + let lines = file.lines() + .take(num) + .map(|line| + line.unwrap() + .replace("\t", " ")).collect(); + + TextView { + lines: lines, + buffer: String::new(), + coordinates: Coordinates::new(), + } + } } impl Widget for TextView {