diff --git a/src/lib.rs b/src/lib.rs index 97b6f30..c264586 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,6 +44,7 @@ pub fn run(buffer: String, opt: &CliOpt) -> Option<(String, bool)> { let mut viewbox = view::View::new( &mut model, opt.unique_hint, + opt.focus_wrap_around, &opt.hint_alignment, &opt.colors, hint_style, @@ -95,6 +96,10 @@ pub struct CliOpt { #[clap(short = "a", long, arg_enum, default_value = "leading")] hint_alignment: view::HintAlignment, + /// Move focus back to first/last match. + #[clap(long)] + focus_wrap_around: bool, + /// Optional hint styling. /// /// Underline or surround the hint for increased visibility. diff --git a/src/view.rs b/src/view.rs index eee90de..4568312 100644 --- a/src/view.rs +++ b/src/view.rs @@ -14,6 +14,7 @@ pub struct View<'a> { matches: Vec>, lookup_trie: SequenceTrie, focus_index: usize, + focus_wrap_around: bool, hint_alignment: &'a HintAlignment, rendering_colors: &'a ViewColors, hint_style: Option, @@ -115,6 +116,7 @@ impl<'a> View<'a> { pub fn new( model: &'a mut model::Model<'a>, unique_hint: bool, + focus_wrap_around: bool, hint_alignment: &'a HintAlignment, rendering_colors: &'a ViewColors, hint_style: Option, @@ -128,6 +130,7 @@ impl<'a> View<'a> { matches, lookup_trie, focus_index, + focus_wrap_around, hint_alignment, rendering_colors, hint_style, @@ -136,15 +139,31 @@ impl<'a> View<'a> { /// Move focus onto the previous hint. pub fn prev(&mut self) { - if self.focus_index > 0 { - self.focus_index -= 1; + if self.focus_wrap_around { + if self.focus_index == 0 { + self.focus_index = self.matches.len() - 1; + } else { + self.focus_index -= 1; + } + } else { + if self.focus_index > 0 { + self.focus_index -= 1; + } } } /// Move focus onto the next hint. pub fn next(&mut self) { - if self.focus_index < self.matches.len() - 1 { - self.focus_index += 1; + if self.focus_wrap_around { + if self.focus_index == self.matches.len() - 1 { + self.focus_index = 0; + } else { + self.focus_index += 1; + } + } else { + if self.focus_index < self.matches.len() - 1 { + self.focus_index += 1; + } } } @@ -380,7 +399,6 @@ impl<'a> View<'a> { /// # Panics /// /// - This function panics if termion cannot read the entered keys on stdin. - /// - This function also panics if the user types Insert on a line without hints. fn listen(&mut self, reader: &mut dyn io::Read, writer: &mut dyn io::Write) -> Event { use termion::input::TermRead; // Trait for `reader.keys().next()`. @@ -783,6 +801,7 @@ Barcelona https://en.wikipedia.org/wiki/Barcelona - "; matches: vec![], // no matches lookup_trie: SequenceTrie::new(), focus_index: 0, + focus_wrap_around: false, hint_alignment: &hint_alignment, rendering_colors: &rendering_colors, hint_style: None, @@ -829,6 +848,7 @@ Barcelona https://en.wikipedia.org/wiki/Barcelona - "; let reverse = true; let mut model = model::Model::new(&lines, &alphabet, &named_pat, &custom_regexes, reverse); let unique_hint = false; + let wrap_around = false; let rendering_colors = ViewColors { text_fg: Box::new(color::Black), @@ -846,6 +866,7 @@ Barcelona https://en.wikipedia.org/wiki/Barcelona - "; let view = View::new( &mut model, unique_hint, + wrap_around, &hint_alignment, &rendering_colors, hint_style,