From b2043135ed956ead0d3b5d5df49ea9d929dc7120 Mon Sep 17 00:00:00 2001 From: Maxim Zhiburt Date: Wed, 12 Jul 2023 22:13:35 +0300 Subject: [PATCH] nu-explore/ Add handlers for HOME/END keys (#9666) close #9665 It could be good to run it though and see if it does what indented. (I did but cause there's no test coverage for it it's better to recheck) PS: Surely... this cursor logic much more complex then it shall be ... the method names .... cc: @fdncred --------- Signed-off-by: Maxim Zhiburt --- crates/nu-explore/src/views/configuration.rs | 69 +++++++++---------- crates/nu-explore/src/views/cursor/mod.rs | 2 +- .../nu-explore/src/views/cursor/xycursor.rs | 9 +++ crates/nu-explore/src/views/preview.rs | 56 ++++++++------- crates/nu-explore/src/views/record/mod.rs | 20 ++++++ 5 files changed, 95 insertions(+), 61 deletions(-) diff --git a/crates/nu-explore/src/views/configuration.rs b/crates/nu-explore/src/views/configuration.rs index d9e3046ce..b1c8212d4 100644 --- a/crates/nu-explore/src/views/configuration.rs +++ b/crates/nu-explore/src/views/configuration.rs @@ -118,6 +118,10 @@ impl ConfigurationView { Some(&mut self.options[i].options[j]) } + + fn get_cursor_mut(&mut self) -> &mut WindowCursor { + self.peeked_cursor.as_mut().unwrap_or(&mut self.cursor) + } } #[derive(Debug, Default)] @@ -245,52 +249,40 @@ impl View for ConfigurationView { } } KeyCode::Up => { - match &mut self.peeked_cursor { - Some(cursor) => cursor.prev(1), - None => self.cursor.prev(1), - }; + let cursor = self.get_cursor_mut(); + cursor.prev(1); - if let Some((group, opt)) = self.peek_current() { - return Some(Transition::Cmd(build_tweak_cmd(group, opt))); - } - - Some(Transition::Ok) + Some(transition_tweak_if(self)) } KeyCode::Down => { - match &mut self.peeked_cursor { - Some(cursor) => cursor.next(1), - None => self.cursor.next(1), - }; + let cursor = self.get_cursor_mut(); + cursor.next(1); - if let Some((group, opt)) = self.peek_current() { - return Some(Transition::Cmd(build_tweak_cmd(group, opt))); - } - - Some(Transition::Ok) + Some(transition_tweak_if(self)) } KeyCode::PageUp => { - match &mut self.peeked_cursor { - Some(cursor) => cursor.prev_window(), - None => self.cursor.prev_window(), - }; + let cursor = self.get_cursor_mut(); + cursor.prev_window(); - if let Some((group, opt)) = self.peek_current() { - return Some(Transition::Cmd(build_tweak_cmd(group, opt))); - } - - Some(Transition::Ok) + Some(transition_tweak_if(self)) } KeyCode::PageDown => { - match &mut self.peeked_cursor { - Some(cursor) => cursor.next_window(), - None => self.cursor.next_window(), - }; + let cursor = self.get_cursor_mut(); + cursor.next_window(); - if let Some((group, opt)) = self.peek_current() { - return Some(Transition::Cmd(build_tweak_cmd(group, opt))); - } + Some(transition_tweak_if(self)) + } + KeyCode::Home => { + let cursor = self.get_cursor_mut(); + cursor.prev(cursor.index()); - Some(Transition::Ok) + Some(transition_tweak_if(self)) + } + KeyCode::End => { + let cursor = self.get_cursor_mut(); + cursor.next(cursor.cap()); + + Some(transition_tweak_if(self)) } KeyCode::Enter => { if self.peeked_cursor.is_some() { @@ -299,7 +291,6 @@ impl View for ConfigurationView { self.peeked_cursor = Some(WindowCursor::default()); let length = self.peek_current().expect("...").0.options.len(); - self.peeked_cursor = WindowCursor::new(length, length); let (group, opt) = self.peek_current().expect("..."); @@ -428,3 +419,9 @@ fn render_list( layout.push(&name, area.x, area.y, area.width, 1); } } + +fn transition_tweak_if(view: &ConfigurationView) -> Transition { + view.peek_current().map_or(Transition::Ok, |(group, opt)| { + Transition::Cmd(build_tweak_cmd(group, opt)) + }) +} diff --git a/crates/nu-explore/src/views/cursor/mod.rs b/crates/nu-explore/src/views/cursor/mod.rs index 4e96b3e85..bb2aed5f1 100644 --- a/crates/nu-explore/src/views/cursor/mod.rs +++ b/crates/nu-explore/src/views/cursor/mod.rs @@ -16,7 +16,7 @@ impl Cursor { } #[allow(dead_code)] - pub fn index(&self) -> usize { + pub fn get_index(&self) -> usize { self.index } diff --git a/crates/nu-explore/src/views/cursor/xycursor.rs b/crates/nu-explore/src/views/cursor/xycursor.rs index 1a8be79f7..3332ded7c 100644 --- a/crates/nu-explore/src/views/cursor/xycursor.rs +++ b/crates/nu-explore/src/views/cursor/xycursor.rs @@ -67,6 +67,7 @@ impl XYCursor { self.x.offset() } + #[allow(dead_code)] pub fn row_window_size(&self) -> usize { self.y.window() } @@ -88,6 +89,14 @@ impl XYCursor { self.y.next_window() } + pub fn row_move_to_end(&mut self) -> bool { + self.y.next(self.y.cap()) + } + + pub fn row_move_to_start(&mut self) -> bool { + self.y.prev(self.y.index()) + } + pub fn prev_row(&mut self) -> bool { self.y.prev(1) } diff --git a/crates/nu-explore/src/views/preview.rs b/crates/nu-explore/src/views/preview.rs index 14711571e..cfff9ee5f 100644 --- a/crates/nu-explore/src/views/preview.rs +++ b/crates/nu-explore/src/views/preview.rs @@ -83,45 +83,37 @@ impl View for Preview { } KeyCode::Up => { self.cursor.prev_row_i(); - - if self.cursor.row_starts_at() == 0 { - info.status = Some(Report::info("TOP")); - } else { - info.status = Some(Report::default()); - } + set_status_top(self, info); Some(Transition::Ok) } KeyCode::Down => { - if self.cursor.row() + self.cursor.row_window_size() < self.cursor.row_limit() { - self.cursor.next_row_i(); - - info.status = Some(Report::info("END")); - } else { - info.status = Some(Report::default()); - } + self.cursor.next_row_i(); + set_status_end(self, info); Some(Transition::Ok) } KeyCode::PageUp => { self.cursor.prev_row_page(); - - if self.cursor.row_starts_at() == 0 { - info.status = Some(Report::info("TOP")); - } else { - info.status = Some(Report::default()); - } + set_status_top(self, info); Some(Transition::Ok) } KeyCode::PageDown => { self.cursor.next_row_page(); + set_status_end(self, info); - if self.cursor.row() + 1 == self.cursor.row_limit() { - info.status = Some(Report::info("END")); - } else { - info.status = Some(Report::default()); - } + Some(Transition::Ok) + } + KeyCode::Home => { + self.cursor.row_move_to_start(); + set_status_top(self, info); + + Some(Transition::Ok) + } + KeyCode::End => { + self.cursor.row_move_to_end(); + set_status_end(self, info); Some(Transition::Ok) } @@ -156,3 +148,19 @@ impl View for Preview { } } } + +fn set_status_end(view: &Preview, info: &mut ViewInfo) { + if view.cursor.row() + 1 == view.cursor.row_limit() { + info.status = Some(Report::info("END")); + } else { + info.status = Some(Report::default()); + } +} + +fn set_status_top(view: &Preview, info: &mut ViewInfo) { + if view.cursor.row_starts_at() == 0 { + info.status = Some(Report::info("TOP")); + } else { + info.status = Some(Report::default()); + } +} diff --git a/crates/nu-explore/src/views/record/mod.rs b/crates/nu-explore/src/views/record/mod.rs index 8f5bbc35e..8b6457388 100644 --- a/crates/nu-explore/src/views/record/mod.rs +++ b/crates/nu-explore/src/views/record/mod.rs @@ -503,6 +503,16 @@ fn handle_key_event_view_mode(view: &mut RecordView, key: &KeyEvent) -> Option { + view.get_layer_last_mut().cursor.row_move_to_start(); + + Some(Transition::Ok) + } + KeyCode::End => { + view.get_layer_last_mut().cursor.row_move_to_end(); + + Some(Transition::Ok) + } _ => None, } } @@ -544,6 +554,16 @@ fn handle_key_event_cursor_mode(view: &mut RecordView, key: &KeyEvent) -> Option Some(Transition::Ok) } + KeyCode::Home => { + view.get_layer_last_mut().cursor.row_move_to_start(); + + Some(Transition::Ok) + } + KeyCode::End => { + view.get_layer_last_mut().cursor.row_move_to_end(); + + Some(Transition::Ok) + } KeyCode::Enter => { let value = view.get_current_value(); let is_record = matches!(value, Value::Record { .. });