From af0f39c5664b46421e68b64216f7512deb7a3461 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 19 Nov 2021 16:18:28 +0300 Subject: [PATCH] Add history_move_{next/prevoius} Right now there is UP/DOWN arrows, that is binded to history_prevous/history_next accordingly. But in case of multiline history entry it will navigate through the lines in the current history itemfirst, and this may not be the requird behavior. So now replxx will have history_move_*, that will always navigate through history, regardless of new lines in query. New history_move_{next/prev} binded to C-n/C-p (like in readline). --- examples/cxx-api.cxx | 2 ++ include/replxx.h | 2 ++ include/replxx.hxx | 2 ++ src/replxx_impl.cxx | 16 ++++++++++++++++ src/replxx_impl.hxx | 2 ++ 5 files changed, 24 insertions(+) diff --git a/examples/cxx-api.cxx b/examples/cxx-api.cxx index 8104b32..d06340a 100644 --- a/examples/cxx-api.cxx +++ b/examples/cxx-api.cxx @@ -446,6 +446,8 @@ int main( int argc_, char** argv_ ) { rx.bind_key_internal( Replxx::KEY::RIGHT, "move_cursor_right" ); rx.bind_key_internal( Replxx::KEY::UP, "history_previous" ); rx.bind_key_internal( Replxx::KEY::DOWN, "history_next" ); + rx.bind_key_internal( Replxx::KEY::control( 'P' ), "history_move_previous" ); + rx.bind_key_internal( Replxx::KEY::control( 'N' ), "history_move_next" ); rx.bind_key_internal( Replxx::KEY::PAGE_UP, "history_first" ); rx.bind_key_internal( Replxx::KEY::PAGE_DOWN, "history_last" ); rx.bind_key_internal( Replxx::KEY::HOME, "move_cursor_to_begining_of_line" ); diff --git a/include/replxx.h b/include/replxx.h index 1dcfddc..29d01e7 100644 --- a/include/replxx.h +++ b/include/replxx.h @@ -163,6 +163,8 @@ typedef enum { REPLXX_ACTION_MOVE_CURSOR_RIGHT, REPLXX_ACTION_HISTORY_NEXT, REPLXX_ACTION_HISTORY_PREVIOUS, + REPLXX_ACTION_HISTORY_MOVE_NEXT, + REPLXX_ACTION_HISTORY_MOVE_PREVIOUS, REPLXX_ACTION_HISTORY_FIRST, REPLXX_ACTION_HISTORY_LAST, REPLXX_ACTION_HISTORY_RESTORE, diff --git a/include/replxx.hxx b/include/replxx.hxx index ce48139..6205c0b 100644 --- a/include/replxx.hxx +++ b/include/replxx.hxx @@ -178,6 +178,8 @@ public: MOVE_CURSOR_RIGHT, HISTORY_NEXT, HISTORY_PREVIOUS, + HISTORY_MOVE_NEXT, + HISTORY_MOVE_PREVIOUS, HISTORY_FIRST, HISTORY_LAST, HISTORY_RESTORE, diff --git a/src/replxx_impl.cxx b/src/replxx_impl.cxx index 9e326d5..1f8b5c4 100644 --- a/src/replxx_impl.cxx +++ b/src/replxx_impl.cxx @@ -80,6 +80,8 @@ char const COMMIT_LINE[] = "commit_line"; char const CLEAR_SCREEN[] = "clear_screen"; char const COMPLETE_NEXT[] = "complete_next"; char const COMPLETE_PREVIOUS[] = "complete_previous"; +char const HISTORY_MOVE_NEXT[] = "history_move_next"; +char const HISTORY_MOVE_PREVIOUS[] = "history_move_previous"; char const HISTORY_NEXT[] = "history_next"; char const HISTORY_PREVIOUS[] = "history_previous"; char const HISTORY_LAST[] = "history_last"; @@ -237,6 +239,8 @@ Replxx::ReplxxImpl::ReplxxImpl( FILE*, FILE*, FILE* ) _namedActions[action_names::COMPLETE_PREVIOUS] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::COMPLETE_PREVIOUS, _1 ); _namedActions[action_names::HISTORY_NEXT] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_NEXT, _1 ); _namedActions[action_names::HISTORY_PREVIOUS] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_PREVIOUS, _1 ); + _namedActions[action_names::HISTORY_MOVE_NEXT] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_MOVE_NEXT, _1 ); + _namedActions[action_names::HISTORY_MOVE_PREVIOUS] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_MOVE_PREVIOUS, _1 ); _namedActions[action_names::HISTORY_LAST] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_LAST, _1 ); _namedActions[action_names::HISTORY_FIRST] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_FIRST, _1 ); _namedActions[action_names::HISTORY_RESTORE] = std::bind( &ReplxxImpl::invoke, this, Replxx::ACTION::HISTORY_RESTORE, _1 ); @@ -300,6 +304,8 @@ Replxx::ReplxxImpl::ReplxxImpl( FILE*, FILE*, FILE* ) bind_key( Replxx::KEY::control( 'L' ), _namedActions.at( action_names::CLEAR_SCREEN ) ); bind_key( Replxx::KEY::DOWN + 0, _namedActions.at( action_names::HISTORY_NEXT ) ); bind_key( Replxx::KEY::UP + 0, _namedActions.at( action_names::HISTORY_PREVIOUS ) ); + bind_key( Replxx::KEY::control( 'N' ), _namedActions.at( action_names::HISTORY_MOVE_NEXT ) ); + bind_key( Replxx::KEY::control( 'P' ), _namedActions.at( action_names::HISTORY_MOVE_PREVIOUS ) ); bind_key( Replxx::KEY::meta( '<' ), _namedActions.at( action_names::HISTORY_FIRST ) ); bind_key( Replxx::KEY::PAGE_UP + 0, _namedActions.at( action_names::HISTORY_FIRST ) ); bind_key( Replxx::KEY::meta( '>' ), _namedActions.at( action_names::HISTORY_LAST ) ); @@ -352,6 +358,8 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::invoke( Replxx::ACTION action_, char32 case ( Replxx::ACTION::MOVE_CURSOR_RIGHT ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::move_one_char_right, code ) ); case ( Replxx::ACTION::HISTORY_NEXT ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_next, code ) ); case ( Replxx::ACTION::HISTORY_PREVIOUS ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_previous, code ) ); + case ( Replxx::ACTION::HISTORY_MOVE_NEXT ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_move_next, code ) ); + case ( Replxx::ACTION::HISTORY_MOVE_PREVIOUS ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_move_previous, code ) ); case ( Replxx::ACTION::HISTORY_FIRST ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_first, code ) ); case ( Replxx::ACTION::HISTORY_LAST ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_last, code ) ); case ( Replxx::ACTION::HISTORY_RESTORE_CURRENT ): return ( action( MOVE_CURSOR | RESET_KILL_ACTION, &Replxx::ReplxxImpl::history_restore_current, code ) ); @@ -1917,6 +1925,14 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::history_next( char32_t ) { return ( history_move( false ) ); } +Replxx::ACTION_RESULT Replxx::ReplxxImpl::history_move_next( char32_t ) { + return ( history_move( false ) ); +} + +Replxx::ACTION_RESULT Replxx::ReplxxImpl::history_move_previous( char32_t ) { + return ( history_move( true ) ); +} + Replxx::ACTION_RESULT Replxx::ReplxxImpl::history_move( bool previous_ ) { // if not already recalling, add the current line to the history list so // we don't have to special case it diff --git a/src/replxx_impl.hxx b/src/replxx_impl.hxx index a5e3f15..537e35c 100644 --- a/src/replxx_impl.hxx +++ b/src/replxx_impl.hxx @@ -243,6 +243,8 @@ private: Replxx::ACTION_RESULT commit_line( char32_t ); Replxx::ACTION_RESULT history_next( char32_t ); Replxx::ACTION_RESULT history_previous( char32_t ); + Replxx::ACTION_RESULT history_move_next( char32_t ); + Replxx::ACTION_RESULT history_move_previous( char32_t ); Replxx::ACTION_RESULT history_move( bool ); Replxx::ACTION_RESULT history_first( char32_t ); Replxx::ACTION_RESULT history_last( char32_t );