From e6cf18ea4351a5041ce5869bccd6b790237aee60 Mon Sep 17 00:00:00 2001 From: Maxim Zhiburt Date: Sat, 3 Dec 2022 01:12:33 +0300 Subject: [PATCH] nu-explore/ A few fixes. (#7334) close #7322 close #7323 Signed-off-by: Maxim Zhiburt --- crates/nu-explore/src/events.rs | 11 ++++ crates/nu-explore/src/nu_common/command.rs | 14 +++-- crates/nu-explore/src/pager.rs | 60 +++++++++++++++++++--- crates/nu-explore/src/views/preview.rs | 13 +++++ 4 files changed, 88 insertions(+), 10 deletions(-) diff --git a/crates/nu-explore/src/events.rs b/crates/nu-explore/src/events.rs index 002d61e422..7d8348c4ab 100644 --- a/crates/nu-explore/src/events.rs +++ b/crates/nu-explore/src/events.rs @@ -48,4 +48,15 @@ impl UIEvents { Err(err) => Err(err), } } + + pub fn try_next(&self) -> Result> { + match poll(Duration::default()) { + Ok(true) => match read()? { + Event::Key(event) => Ok(Some(event)), + _ => Ok(None), + }, + Ok(false) => Ok(None), + Err(err) => Err(err), + } + } } diff --git a/crates/nu-explore/src/nu_common/command.rs b/crates/nu-explore/src/nu_common/command.rs index 810d53eb00..9eccfeeb53 100644 --- a/crates/nu-explore/src/nu_common/command.rs +++ b/crates/nu-explore/src/nu_common/command.rs @@ -11,8 +11,8 @@ pub fn run_nu_command( cmd: &str, current: PipelineData, ) -> std::result::Result { - let engine_state = engine_state.clone(); - eval_source2(&engine_state, stack, cmd.as_bytes(), "", current) + let mut engine_state = engine_state.clone(); + eval_source2(&mut engine_state, stack, cmd.as_bytes(), "", current) } pub fn is_ignored_command(command: &str) -> bool { @@ -20,13 +20,13 @@ pub fn is_ignored_command(command: &str) -> bool { } fn eval_source2( - engine_state: &EngineState, + engine_state: &mut EngineState, stack: &mut Stack, source: &[u8], fname: &str, input: PipelineData, ) -> Result { - let (mut block, _) = { + let (mut block, delta) = { let mut working_set = StateWorkingSet::new(engine_state); let (output, err) = parse( &mut working_set, @@ -35,6 +35,7 @@ fn eval_source2( false, &[], ); + if let Some(err) = err { return Err(ShellError::IOError(err.to_string())); } @@ -42,6 +43,11 @@ fn eval_source2( (output, working_set.render()) }; + // We need to merge different info other wise things like PIPEs etc will not work. + if let Err(err) = engine_state.merge_delta(delta) { + return Err(ShellError::IOError(err.to_string())); + } + // eval_block outputs all expressions expept the last to STDOUT; // we don't wont that. // diff --git a/crates/nu-explore/src/pager.rs b/crates/nu-explore/src/pager.rs index 92b7224c53..2fd07dbd8b 100644 --- a/crates/nu-explore/src/pager.rs +++ b/crates/nu-explore/src/pager.rs @@ -432,7 +432,7 @@ fn highlight_search_results(f: &mut Frame, pager: &Pager, layout: &Layout, style } #[allow(clippy::too_many_arguments)] -fn handle_events( +fn handle_events( engine_state: &EngineState, stack: &mut Stack, events: &UIEvents, @@ -441,15 +441,64 @@ fn handle_events( search: &mut SearchBuf, command: &mut CommandBuf, mut view: Option<&mut V>, -) -> (bool, bool) -where - V: View, -{ +) -> (bool, bool) { let key = match events.next() { Ok(Some(key)) => key, _ => return (false, false), }; + let result = handle_event( + engine_state, + stack, + layout, + info, + search, + command, + view.as_deref_mut(), + key, + ); + + if let (true, _) = result { + return result; + } + + // Sometimes we get a BIG list of events; + // for example when someone scrolls via a mouse either UP or DOWN. + // This MIGHT causes freeses as we have a 400 delay for a next command read. + // + // To eliminate that we are trying ot read all possible commands which we should action upon. + + while let Ok(Some(key)) = events.try_next() { + let result = handle_event( + engine_state, + stack, + layout, + info, + search, + command, + view.as_deref_mut(), + key, + ); + + if let (true, _) = result { + return result; + } + } + + result +} + +#[allow(clippy::too_many_arguments)] +fn handle_event( + engine_state: &EngineState, + stack: &mut Stack, + layout: &Layout, + info: &mut ViewInfo, + search: &mut SearchBuf, + command: &mut CommandBuf, + mut view: Option<&mut V>, + key: KeyEvent, +) -> (bool, bool) { if handle_exit_key_event(&key) { return (true, true); } @@ -472,7 +521,6 @@ where } // was not handled so we must check our default controlls - handle_general_key_events2(&key, search, command, view, info); (false, false) diff --git a/crates/nu-explore/src/views/preview.rs b/crates/nu-explore/src/views/preview.rs index 960fd1971a..facfdd21bc 100644 --- a/crates/nu-explore/src/views/preview.rs +++ b/crates/nu-explore/src/views/preview.rs @@ -84,6 +84,12 @@ impl View for Preview { Some(Transition::Ok) } KeyCode::Up => { + let is_start = self.i_row == 0; + if is_start { + // noop + return Some(Transition::Ok); + } + let page_size = layout.data.len(); let max = self.lines.len().saturating_sub(page_size); let was_end = self.i_row == max; @@ -99,6 +105,13 @@ impl View for Preview { KeyCode::Down => { let page_size = layout.data.len(); let max = self.lines.len().saturating_sub(page_size); + + let is_end = self.i_row == max; + if is_end { + // noop + return Some(Transition::Ok); + } + self.i_row = min(self.i_row + 1, max); let is_end = self.i_row == max;