diff options
author | Canop <cano.petrole@gmail.com> | 2021-08-03 20:49:25 +0200 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2021-08-04 13:25:29 +0200 |
commit | c68e7f3bd12ad14214e074d90c1640d8b2536801 (patch) | |
tree | 797741ea2fae240960a9aa03ce3dadb79cb29856 /src | |
parent | 3123abc98b2f2e8e52da3ecce96c690341e75c11 (diff) |
improve scrolling behaviors
Especially move the selection when you're at one end and you
try to scroll the blocked way. Fix #419
Diffstat (limited to 'src')
32 files changed, 167 insertions, 120 deletions
diff --git a/src/app/app.rs b/src/app/app.rs index efd5045..31d4c16 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -617,7 +617,7 @@ impl App { con, }; self.mut_panel().refresh_input_status(app_state, &app_cmd_context); - self.display_panels(w, &skin, app_state, con)?; + self.display_panels(w, skin, app_state, con)?; } else { warn!("unexpected lack of update on do_pending_task"); return Ok(()); @@ -688,7 +688,7 @@ impl App { .map(|server_name| { let shared_root = Arc::new(Mutex::new(app_state.root.clone())); let server = crate::net::Server::new( - &server_name, + server_name, self.tx_seqs.clone(), Arc::clone(&shared_root), ); diff --git a/src/app/panel.rs b/src/app/panel.rs index 6a2f97c..f4a6d30 100644 --- a/src/app/panel.rs +++ b/src/app/panel.rs @@ -128,7 +128,7 @@ impl Panel { app_state: &AppState, con: &AppContext, ) -> Result<Command, ProgramError> { - let sel_info = self.states[self.states.len() - 1].sel_info(&app_state); + let sel_info = self.states[self.states.len() - 1].sel_info(app_state); self.input.on_event(w, event, con, sel_info, app_state, self.state().get_mode()) } @@ -195,21 +195,21 @@ impl Panel { ) -> Result<(), ProgramError> { self.mut_state().display(w, disc)?; if disc.active || !WIDE_STATUS { - self.write_status(w, &disc.panel_skin, disc.screen)?; + self.write_status(w, disc.panel_skin, disc.screen)?; } let mut input_area = self.areas.input.clone(); if disc.active { - self.write_purpose(w, &disc.panel_skin, disc.screen, &disc.con)?; + self.write_purpose(w, disc.panel_skin, disc.screen, disc.con)?; let flags = self.state().get_flags(); let input_content_len = self.input.get_content().len() as u16; let flags_len = flags_display::visible_width(&flags); if input_area.width > input_content_len + 1 + flags_len { input_area.width -= flags_len + 1; disc.screen.goto(w, input_area.left + input_area.width, input_area.top)?; - flags_display::write(w, &flags, &disc.panel_skin)?; + flags_display::write(w, &flags, disc.panel_skin)?; } } - self.input.display(w, disc.active, self.state().get_mode(), input_area, &disc.panel_skin)?; + self.input.display(w, disc.active, self.state().get_mode(), input_area, disc.panel_skin)?; Ok(()) } diff --git a/src/app/panel_state.rs b/src/app/panel_state.rs index bae620f..83a0138 100644 --- a/src/app/panel_state.rs +++ b/src/app/panel_state.rs @@ -463,7 +463,7 @@ pub trait PanelState { ) -> Result<CmdResult, ProgramError> { let sel_info = self.sel_info(app_state); if let Some(invocation) = &invocation { - if let Some(error) = verb.check_args(&sel_info, &invocation, &app_state.other_panel_path) { + if let Some(error) = verb.check_args(&sel_info, invocation, &app_state.other_panel_path) { debug!("verb.check_args prevented execution: {:?}", &error); return Ok(CmdResult::error(error)); } @@ -478,7 +478,7 @@ pub trait PanelState { &None }, ); - external_execution.to_cmd_result(w, exec_builder, &cc.app.con) + external_execution.to_cmd_result(w, exec_builder, cc.app.con) } fn execute_sequence( @@ -614,7 +614,7 @@ pub trait PanelState { InputPattern::none(), prefered_mode, self.tree_options(), - &cc.app.con, + cc.app.con, )), purpose: PanelPurpose::Preview, direction: HDir::Right, diff --git a/src/app/standard_status.rs b/src/app/standard_status.rs index 3b8f256..5a4c123 100644 --- a/src/app/standard_status.rs +++ b/src/app/standard_status.rs @@ -73,7 +73,7 @@ impl StandardStatus { state_type: PanelStateType, selection: Selection<'s>, ) -> StandardStatusBuilder<'s> { - StandardStatusBuilder::new(&self, state_type, selection) + StandardStatusBuilder::new(self, state_type, selection) } } diff --git a/src/browser/browser_state.rs b/src/browser/browser_state.rs index 4c56b61..dccb3b5 100644 --- a/src/browser/browser_state.rs +++ b/src/browser/browser_state.rs @@ -207,7 +207,7 @@ impl PanelState for BrowserState { let tree = self.displayed_tree(); let mut selection = tree.selected_line().as_selection(); selection.line = tree.options.pattern.pattern - .get_match_line_count(&selection.path) + .get_match_line_count(selection.path) .unwrap_or(0); Some(selection) } @@ -373,15 +373,15 @@ impl PanelState for BrowserState { } Internal::page_down => { let tree = self.displayed_tree_mut(); - if page_height < tree.lines.len() as i32 { - tree.try_scroll(page_height, page_height); + if !tree.try_scroll(page_height, page_height) { + tree.try_select_last(page_height); } CmdResult::Keep } Internal::page_up => { let tree = self.displayed_tree_mut(); - if page_height < tree.lines.len() as i32 { - tree.try_scroll(-page_height, page_height); + if !tree.try_scroll(-page_height, page_height) { + tree.try_select_first(); } CmdResult::Keep } @@ -428,7 +428,7 @@ impl PanelState for BrowserState { } Internal::parent => self.go_to_parent(screen, con, bang), Internal::print_tree => { - print::print_tree(&self.displayed_tree(), cc.app.screen, &cc.app.panel_skin, con)? + print::print_tree(self.displayed_tree(), cc.app.screen, cc.app.panel_skin, con)? } Internal::root_up => { let tree = self.displayed_tree(); @@ -587,8 +587,8 @@ impl PanelState for BrowserState { disc: &DisplayContext, ) -> Result<(), ProgramError> { let dp = DisplayableTree { - app_state: Some(&disc.app_state), - tree: &self.displayed_tree(), + app_state: Some(disc.app_state), + tree: self.displayed_tree(), skin: &disc.panel_skin.styles, ext_colors: &disc.con.ext_colors, area: disc.state_area.clone(), diff --git a/src/command/completion.rs b/src/command/completion.rs index 0e7090d..3964a92 100644 --- a/src/command/completion.rs +++ b/src/command/completion.rs @@ -46,7 +46,7 @@ impl Completions { } let mut iter = completions.iter(); let mut common: &str = match iter.next() { - Some(s) => &s, + Some(s) => s, _ => { return Self::None; } }; for c in iter { diff --git a/src/command/scroll.rs b/src/command/scroll.rs index 73928bf..5734c25 100644 --- a/src/command/scroll.rs +++ b/src/command/scroll.rs @@ -12,6 +12,12 @@ impl ScrollCommand { Self::Pages(n) => n * page_height as i32, } } + pub fn is_up(self) -> bool { + match self { + Self::Lines(n) => n < 0, + Self::Pages(n) => n < 0, + } + } /// compute the new scroll value pub fn apply( self, diff --git a/src/conf/format.rs b/src/conf/format.rs index 65a9e87..4c57c95 100644 --- a/src/conf/format.rs +++ b/src/conf/format.rs @@ -48,8 +48,8 @@ impl SerdeFormat { pub fn read_file<T>(path: &Path) -> Result<T, ProgramError> where T: DeserializeOwned { - let format = Self::from_path(&path)?; - let file_content = fs::read_to_string(&path)?; + let format = Self::from_path(path)?; + let file_content = fs::read_to_string(path)?; match format { Self::Hjson => { deser_hjson::from_str::<T>(&file_content) diff --git a/src/conf/verb_conf.rs b/src/conf/verb_conf.rs index dc269e1..022425a 100644 --- a/src/conf/verb_conf.rs +++ b/src/conf/verb_conf.rs @@ -93,7 +93,7 @@ impl TryFrom<&VerbConf> for Verb { VerbExecution::Internal(if s.starts_with(':') || s.starts_with(' ') { InternalExecution::try_from(&s[1..])? } else { - InternalExecution::try_from(&s)? + InternalExecution::try_from(s)? }) } // "external": it can be about any form diff --git a/src/content_search/mod.rs b/src/content_search/mod.rs index 362672b..522cf0f 100644 --- a/src/content_search/mod.rs +++ b/src/content_search/mod.rs @@ -33,7 +33,7 @@ pub fn get_mmap<P: AsRef<Path>>(hay_path: P) -> io::Result<Mmap> { /// that the file is binary (from its extension, size, or first bytes) pub fn get_mmap_if_not_binary<P: AsRef<Path>>(hay_path: P) -> io::Result<Option<Mmap>> { if let Some(ext) = hay_path.as_ref().extension().and_then(|s| s.to_str()) { - if extensions::is_known_binary(&ext) { + if extensions::is_known_binary(ext) { return Ok(None); } } diff --git a/src/content_search/needle.rs b/src/content_search/needle.rs index 8dc5523..c1912e4 100644 --- a/src/content_search/needle.rs +++ b/src/content_search/needle.rs @@ -142,7 +142,7 @@ impl Needle { fn find_naive(&self, mut pos: usize, hay: &Mmap) -> Option<usize> { let max_pos = hay.len() - self.bytes.len(); while pos <= max_pos { - if self.is_at_pos(&hay, pos) { + if self.is_at_pos(hay, pos) { return Some(pos); } pos += 1; @@ -183,12 +183,12 @@ impl Needle { } let pos = match self.bytes.len() { - 1 => self.find_naive_1(&hay), - 2 => self.find_naive_2(0, &hay), - 3 => self.find_naive_3(0, &hay), - 4 => self.find_naive_4(0, &hay), - 6 => self.find_naive_6(0, &hay), - _ => self.find_naive(0, &hay), + 1 => self.find_naive_1(hay), + 2 => self.find_naive_2(0, hay), + 3 => self.find_naive_3(0, hay), + 4 => self.find_naive_4(0, hay), + 6 => self.find_naive_6(0, hay), + _ => self.find_naive(0, hay), }; pos.map_or( ContentSearchResult::NotFound, diff --git a/src/display/displayable_tree.rs b/src/display/displayable_tree.rs index fcec623..7e5fd35 100644 --- a/src/display/displayable_tree.rs +++ b/src/display/displayable_tree.rs @@ -106,7 +106,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { ) -> Result<usize, termimad::Error> { Ok(if let Some(s) = line.sum { cond_bg!(count_style, self, selected, self.skin.count); - cw.queue_g_string(&count_style, format!("{:>width$}", s.to_count(), width=count_len))?; + cw.queue_g_string(count_style, format!("{:>width$}", s.to_count(), width=count_len))?; 1 } else { count_len + 1 @@ -122,11 +122,11 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { ) -> Result<usize, termimad::Error> { let device_id = line.device_id(); cond_bg!(style, self, selected, self.skin.device_id_major); - cw.queue_g_string(&style, format!("{:>3}", device_id.major))?; + cw.queue_g_string(style, format!("{:>3}", device_id.major))?; cond_bg!(style, self, selected, self.skin.device_id_sep); - cw.queue_char(&style, ':')?; + cw.queue_char(style, ':')?; cond_bg!(style, self, selected, self.skin.device_id_minor); - cw.queue_g_string(&style, format!("{:<3}", device_id.minor))?; + cw.queue_g_string(style, format!("{:<3}", device_id.minor))?; Ok(0) } @@ -137,7 +137,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { selected: bool, ) -> Result<usize, termimad::Error> { Ok(if selected { - cw.queue_char(&style, '▶')?; + cw.queue_char(style, '▶')?; 0 } else { 1 @@ -180,7 +180,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { format!("{:>4}", file_size::fit_4(s.to_size())), )?; cw.queue_char( - &sparse_style, + sparse_style, if s.is_sparse() && line.is_file() { 's' } else { ' ' }, )?; cw.queue_g_string(label_style, format!("{:<10}", pb))?; @@ -268,7 +268,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { ); } if !branch.is_empty() { - cw.queue_g_string(&branch_style, branch)?; + cw.queue_g_string(branch_style, branch)?; } Ok(0) } @@ -281,7 +281,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { staged: bool, ) -> Result<usize, termimad::Error> { Ok(if staged { - cw.queue_char(&style, '◍')?; // ▣ + cw.queue_char(style, '◍')?; // ▣ 0 } else { 1 @@ -309,13 +309,13 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { let mut path_ms = MatchedString::new( name_match, &line.subpath, - &style, - &char_match_style, + style, + char_match_style, ); let name_ms = path_ms.split_on_last('/'); cond_bg!(parent_style, self, selected, self.skin.parent); if name_ms.is_some() { - path_ms.base_style = &parent_style; + path_ms.base_style = parent_style; } path_ms.queue_on(cw)?; if let Some(name_ms) = name_ms { @@ -327,8 +327,8 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { let matched_string = MatchedString::new( name_match, &line.name, - &style, - &char_match_style, + style, + char_match_style, ); matched_string.queue_on(cw)?; } @@ -341,7 +341,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { TreeLineType::BrokenSymLink(direct_path) => { cw.queue_str(style, " -> ")?; cond_bg!(error_style, self, selected, self.skin.file_error); - cw.queue_str(error_style, &direct_path)?; + cw.queue_str(error_style, direct_path)?; } TreeLineType::SymLink { final_is_dir, @@ -355,7 +355,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { &self.skin.file }; cond_bg!(target_style, self, selected, target_style); - cw.queue_str(target_style, &direct_target)?; + cw.queue_str(target_style, direct_target)?; } _ => {} } @@ -370,16 +370,16 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { ) -> Result<(), ProgramError> { cond_bg!(extract_style, self, selected, self.skin.content_extract); cond_bg!(match_style, self, selected, self.skin.content_match); - cw.queue_str(&extract_style, " ")?; + cw.queue_str(extract_style, " ")?; if extract.needle_start > 0 { - cw.queue_str(&extract_style, &extract.extract[0..extract.needle_start])?; + cw.queue_str(extract_style, &extract.extract[0..extract.needle_start])?; } cw.queue_str( - &match_style, + match_style, &extract.extract[extract.needle_start..extract.needle_end], )?; if extract.needle_end < extract.extract.len() { - cw.queue_str(&extract_style, &extract.extract[extract.needle_end..])?; + cw.queue_str(extract_style, &extract.extract[extract.needle_end..])?; } Ok(()) } @@ -400,12 +400,12 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { } } let title = line.path.to_string_lossy(); - cw.queue_str(&style, &title)?; + cw.queue_str(style, &title)?; if self.in_app && !cw.is_full() { if let ComputationResult::Done(git_status) = &self.tree.git_status { let git_status_display = GitStatusDisplay::from( git_status, - &self.skin, + self.skin, cw.allowed, ); git_status_display.write(cw, selected)?; @@ -415,7 +415,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { if let Some(mount) = line.mount() { let fs_space_display = crate::filesystems::MountSpaceDisplay::from( &mount, - &self.skin, + self.skin, cw.allowed, ); fs_space_display.write(cw, selected)?; @@ -446,7 +446,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { /// write the whole tree on the given `W` pub fn write_on<W: Write>(&self, f: &mut W) -> Result<(), ProgramError> { #[cfg(not(any(target_family = "windows", target_os = "android")))] - let perm_writer = super::PermWriter::for_tree(&self.skin, &self.tree); + let perm_writer = super::PermWriter::for_tree(self.skin, self.tree); let tree = self.tree; let total_size = tree.total_sum(); @@ -467,7 +467,7 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { .options .cols_order .iter() - .filter(|col| col.is_visible(&tree, self.app_state)) + .filter(|col| col.is_visible(tree, self.app_state)) .cloned() .collect(); @@ -584,10 +584,10 @@ impl<'a, 's, 't> DisplayableTree<'a, 's, 't> { }; // void: intercol & replacing missing cells if in_branch && void_len > 2 { - cond_bg!(void_style, self, selected, &self.skin.tree); + cond_bg!(void_style, self, selected, self.skin.tree); cw.repeat(void_style, &BRANCH_FILLING, void_len)?; } else { - cond_bg!(void_style, self, selected, &self.skin.default); + cond_bg!(void_style, self, selected, self.skin.default); cw.repeat(void_style, &SPACE_FILLING, void_len)?; } } diff --git a/src/display/git_status_display.rs b/src/display/git_status_display.rs index b443fc3..77c287f 100644 --- a/src/display/git_status_display.rs +++ b/src/display/git_status_display.rs @@ -61,19 +61,19 @@ impl<'a, 's> GitStatusDisplay<'a, 's> { cond_bg!(branch_style, self, selected, self.skin.git_branch); if let Some(name) = &self.status.current_branch_name { if self.show_wide { - cw.queue_str(&branch_style, " ᚜ ")?; + cw.queue_str(branch_style, " ᚜ ")?; } else { - cw.queue_char(&branch_style, ' ')?; + cw.queue_char(branch_style, ' ')?; } - cw.queue_str(&branch_style, name)?; - cw.queue_char(&branch_style, ' ')?; + cw.queue_str(branch_style, name)?; + cw.queue_char(branch_style, ' ')?; } } if self.show_stats { cond_bg!(insertions_style, self, selected, self.skin.git_insertions); - cw.queue_g_string(&insertions_style, format!("+{}", self.status.insertions))?; + cw.queue_g_string(insertions_style, format!("+{}", self.status.insertions))?; cond_bg!(deletions_style, self, selected, self.skin.git_deletions); - cw.queue_g_string(&deletions_style, format!("-{}", self.status.deletions))?; + cw.queue_g_string(deletions_style, format!("-{}", self.status.deletions))?; } Ok(()) } diff --git a/src/display/matched_string.rs b/src/display/matched_string.rs index 45becfb..d37b366 100644 --- a/src/display/matched_string.rs +++ b/src/display/matched_string.rs @@ -81,11 +81,11 @@ impl<'a, 'w> MatchedString<'a> { } else if w < dw { match self.align { Alignment::Right => { - cw.repeat(&self.base_style, &SPACE_FILLING, dw - w)?; + cw.repeat(self.base_style, &SPACE_FILLING, dw - w)?; } Alignment::Center => { right_filling = (dw - w) / 2; - cw.repeat(&self.base_style, &SPACE_FILLING, dw - w - right_filling)?; + cw.repeat(self.base_style, &SPACE_FILLING, dw - w - right_filling)?; } _ => { right_filling = dw - w; @@ -100,26 +100,26 @@ impl<'a, 'w> MatchedString<'a> { cw.queue_char(&combined_style, cand_char)?; pos_idx += 1; } else { - cw.queue_char(&self.base_style, cand_char)?; + cw.queue_char(self.base_style, cand_char)?; } } if right_filling > 0 { - cw.repeat(&self.base_style, &SPACE_FILLING, right_filling)?; + cw.repeat(self.base_style, &SPACE_FILLING, right_filling)?; } } else if let Some(w) = self.display_width { match self.align { Alignment::Center => { - cw.queue_str(&self.base_style, &format!("{:^w$}", self.string, w = w))?; + cw.queue_str(self.base_style, &format!("{:^w$}", self.string, w = w))?; } Alignment::Right => { - cw.queue_str(&self.base_style, &format!("{:>w$}", self.string, w = w))?; + cw.queue_str(self.base_style, &format!("{:>w$}", self.string, w = w))?; } _ => { - cw.queue_str(&self.base_style, &format!("{:<w$}", self.string, w = w))?; + cw.queue_str(self.base_style, &format!("{:<w$}", self.string, w = w))?; } } } else { - cw.queue_str(&self.base_style, self.string)?; + cw.queue_str(self.base_style, self.string)?; } Ok(()) } diff --git a/src/display/permissions.rs b/src/display/permissions.rs index 56b8240..b4c0ccc 100644 --- a/src/display/permissions.rs +++ b/src/display/permissions.rs @@ -113,13 +113,13 @@ impl<'s> PermWriter<'s> { let owner = permissions::user_name(line.metadata.uid()); cond_bg!(owner_style, self, selected, self.skin.owner); cw.queue_g_string( - &owner_style, + owner_style, format!(" {:w$}", &owner, w = self.max_user_len), )?; let group = permissions::group_name(line.metadata.gid()); cond_bg!(group_style, self, selected, self.skin.group); cw.queue_g_string( - &group_style, + group_style, format!(" {:w$}", &group, w = self.max_group_len), )?; 1 diff --git a/src/file_sum/sum_computation.rs b/src/file_sum/sum_computation.rs index 3bb32f2..d6a05a8 100644 --- a/src/file_sum/sum_computation.rs +++ b/src/file_sum/sum_computation.rs @@ -317,6 +317,6 @@ fn md_sum(md: &fs::Metadata) -> FileSum { #[cfg(not(unix))] let size = md.len(); - let seconds = extract_seconds(&md); + let seconds = extract_seconds(md); FileSum::new(size, false, 1, seconds) } diff --git a/src/filesystems/filesystems_state.rs b/src/filesystems/filesystems_state.rs index 707a064..fdd201c 100644 --- a/src/filesystems/filesystems_state.rs +++ b/src/filesystems/filesystems_state.rs @@ -106,9 +106,15 @@ impl FilesystemState { ) -> bool { let old_scroll = self.scroll; self.scroll = cmd.apply(self.scroll, self.count(), self.page_height); + if self.selection_idx < self.scroll { + self.selection_idx = self.scroll; + } else if self.selection_idx >= self.scroll + self.page_height { + self.selection_idx = self.scroll + self.page_height - 1; + } self.scroll != old_scroll } + /// change the selection fn move_line( &mut self, internal_exec: &InternalExecution, @@ -123,6 +129,11 @@ impl FilesystemState { } else { self.selection_idx = move_sel(self.selection_idx, self.mounts.len().get(), dir, cycle); } + if self.selection_idx < self.scroll { + self.scroll = self.selection_idx; + } else if self.selection_idx >= self.scroll + self.page_height { + self.scroll = self.selection_idx + 1 - self.page_height; + } CmdResult::Keep } @@ -220,7 +231,7 @@ impl PanelState for FilesystemState { ) -> Result<(), ProgramError> { let area = &disc.state_area; let con = &disc.con; - self.page_height = area.height as usize; + self.page_height = area.height as usize - 2; let (mounts, selection_idx) = if let Some(filtered) = &self.filtered { (filtered.mounts.as_slice(), filtered.selection_idx) } else { @@ -350,7 +361,7 @@ impl PanelState for FilesystemState { let match_style = if selected { &selected_match_style } else { &match_style }; let border_style = if selected { &selected_border_style } else { &border_style }; if con.show_selection_mark { - |