@@ -43,6 +43,7 @@ namespace {
4343namespace action_names {
4444
4545char const INSERT_CHARACTER [] = " insert_character" ;
46+ char const NEW_LINE [] = " new_line" ;
4647char const MOVE_CURSOR_TO_BEGINING_OF_LINE [] = " move_cursor_to_begining_of_line" ;
4748char const MOVE_CURSOR_TO_END_OF_LINE [] = " move_cursor_to_end_of_line" ;
4849char const MOVE_CURSOR_LEFT [] = " move_cursor_left" ;
@@ -142,11 +143,11 @@ class IOModeGuard {
142143Replxx::ReplxxImpl::ReplxxImpl ( FILE *, FILE *, FILE * )
143144 : _utf8Buffer()
144145 , _data()
146+ , _pos( 0 )
145147 , _charWidths()
146148 , _display()
147149 , _displayInputLength( 0 )
148150 , _hint()
149- , _pos( 0 )
150151 , _prefix( 0 )
151152 , _hintSelection( -1 )
152153 , _history()
@@ -190,6 +191,7 @@ Replxx::ReplxxImpl::ReplxxImpl( FILE*, FILE*, FILE* )
190191 , _mutex() {
191192 using namespace std ::placeholders;
192193 _namedActions[action_names::INSERT_CHARACTER ] = std::bind ( &ReplxxImpl::invoke, this , Replxx::ACTION ::INSERT_CHARACTER , _1 );
194+ _namedActions[action_names::NEW_LINE ] = std::bind ( &ReplxxImpl::invoke, this , Replxx::ACTION ::NEW_LINE , _1 );
193195 _namedActions[action_names::MOVE_CURSOR_TO_BEGINING_OF_LINE ] = std::bind ( &ReplxxImpl::invoke, this , Replxx::ACTION ::MOVE_CURSOR_TO_BEGINING_OF_LINE , _1 );
194196 _namedActions[action_names::MOVE_CURSOR_TO_END_OF_LINE ] = std::bind ( &ReplxxImpl::invoke, this , Replxx::ACTION ::MOVE_CURSOR_TO_END_OF_LINE , _1 );
195197 _namedActions[action_names::MOVE_CURSOR_LEFT ] = std::bind ( &ReplxxImpl::invoke, this , Replxx::ACTION ::MOVE_CURSOR_LEFT , _1 );
@@ -280,7 +282,7 @@ Replxx::ReplxxImpl::ReplxxImpl( FILE*, FILE*, FILE* )
280282 bind_key ( 127 , _namedActions.at ( action_names::DELETE_CHARACTER_UNDER_CURSOR ) );
281283 bind_key ( Replxx::KEY ::DELETE + 0 , _namedActions.at ( action_names::DELETE_CHARACTER_UNDER_CURSOR ) );
282284 bind_key ( Replxx::KEY ::BACKSPACE + 0 , _namedActions.at ( action_names::DELETE_CHARACTER_LEFT_OF_CURSOR ) );
283- bind_key ( Replxx::KEY::control ( ' J' ), _namedActions.at ( action_names::COMMIT_LINE ) );
285+ bind_key ( Replxx::KEY::control ( ' J' ), _namedActions.at ( action_names::NEW_LINE ) );
284286 bind_key ( Replxx::KEY ::ENTER + 0 , _namedActions.at ( action_names::COMMIT_LINE ) );
285287 bind_key ( Replxx::KEY::control ( ' L' ), _namedActions.at ( action_names::CLEAR_SCREEN ) );
286288 bind_key ( Replxx::KEY::control ( ' N' ), _namedActions.at ( action_names::COMPLETE_NEXT ) );
@@ -314,14 +316,15 @@ Replxx::ReplxxImpl::~ReplxxImpl( void ) {
314316Replxx::ACTION_RESULT Replxx::ReplxxImpl::invoke ( Replxx::ACTION action_, char32_t code ) {
315317 switch ( action_ ) {
316318 case ( Replxx::ACTION ::INSERT_CHARACTER ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::insert_character, code ) );
319+ case ( Replxx::ACTION ::NEW_LINE ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::new_line, code ) );
317320 case ( Replxx::ACTION ::DELETE_CHARACTER_UNDER_CURSOR ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::delete_character, code ) );
318321 case ( Replxx::ACTION ::DELETE_CHARACTER_LEFT_OF_CURSOR ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::backspace_character, code ) );
319322 case ( Replxx::ACTION ::KILL_TO_END_OF_LINE ): return ( action ( WANT_REFRESH | SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_to_end_of_line, code ) );
320323 case ( Replxx::ACTION ::KILL_TO_BEGINING_OF_LINE ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_to_begining_of_line, code ) );
321324 case ( Replxx::ACTION ::KILL_TO_END_OF_WORD ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_word_to_right<false >, code ) );
322325 case ( Replxx::ACTION ::KILL_TO_BEGINING_OF_WORD ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_word_to_left<false >, code ) );
323- case ( Replxx::ACTION ::KILL_TO_END_OF_SUBWORD ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_word_to_right<true >, code ) );
324- case ( Replxx::ACTION ::KILL_TO_BEGINING_OF_SUBWORD ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_word_to_left<true >, code ) );
326+ case ( Replxx::ACTION ::KILL_TO_END_OF_SUBWORD ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_word_to_right<true >, code ) );
327+ case ( Replxx::ACTION ::KILL_TO_BEGINING_OF_SUBWORD ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_word_to_left<true >, code ) );
325328 case ( Replxx::ACTION ::KILL_TO_WHITESPACE_ON_LEFT ): return ( action ( SET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::kill_to_whitespace_to_left, code ) );
326329 case ( Replxx::ACTION ::YANK ): return ( action ( HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::yank, code ) );
327330 case ( Replxx::ACTION ::YANK_CYCLE ): return ( action ( HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::yank_cycle, code ) );
@@ -330,8 +333,8 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::invoke( Replxx::ACTION action_, char32
330333 case ( Replxx::ACTION ::MOVE_CURSOR_TO_END_OF_LINE ): return ( action ( WANT_REFRESH , &Replxx::ReplxxImpl::go_to_end_of_line, code ) );
331334 case ( Replxx::ACTION ::MOVE_CURSOR_ONE_WORD_LEFT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_word_left<false >, code ) );
332335 case ( Replxx::ACTION ::MOVE_CURSOR_ONE_WORD_RIGHT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_word_right<false >, code ) );
333- case ( Replxx::ACTION ::MOVE_CURSOR_ONE_SUBWORD_LEFT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_word_left<true >, code ) );
334- case ( Replxx::ACTION ::MOVE_CURSOR_ONE_SUBWORD_RIGHT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_word_right<true >, code ) );
336+ case ( Replxx::ACTION ::MOVE_CURSOR_ONE_SUBWORD_LEFT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_word_left<true >, code ) );
337+ case ( Replxx::ACTION ::MOVE_CURSOR_ONE_SUBWORD_RIGHT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_word_right<true >, code ) );
335338 case ( Replxx::ACTION ::MOVE_CURSOR_LEFT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_char_left, code ) );
336339 case ( Replxx::ACTION ::MOVE_CURSOR_RIGHT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::move_one_char_right, code ) );
337340 case ( Replxx::ACTION ::HISTORY_NEXT ): return ( action ( RESET_KILL_ACTION , &Replxx::ReplxxImpl::history_next, code ) );
@@ -345,9 +348,9 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::invoke( Replxx::ACTION action_, char32
345348 case ( Replxx::ACTION ::CAPITALIZE_WORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::capitalize_word<false >, code ) );
346349 case ( Replxx::ACTION ::LOWERCASE_WORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::lowercase_word<false >, code ) );
347350 case ( Replxx::ACTION ::UPPERCASE_WORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::uppercase_word<false >, code ) );
348- case ( Replxx::ACTION ::CAPITALIZE_SUBWORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::capitalize_word<true >, code ) );
349- case ( Replxx::ACTION ::LOWERCASE_SUBWORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::lowercase_word<true >, code ) );
350- case ( Replxx::ACTION ::UPPERCASE_SUBWORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::uppercase_word<true >, code ) );
351+ case ( Replxx::ACTION ::CAPITALIZE_SUBWORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::capitalize_word<true >, code ) );
352+ case ( Replxx::ACTION ::LOWERCASE_SUBWORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::lowercase_word<true >, code ) );
353+ case ( Replxx::ACTION ::UPPERCASE_SUBWORD ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::uppercase_word<true >, code ) );
351354 case ( Replxx::ACTION ::TRANSPOSE_CHARACTERS ): return ( action ( RESET_KILL_ACTION | HISTORY_RECALL_MOST_RECENT , &Replxx::ReplxxImpl::transpose_characters, code ) );
352355 case ( Replxx::ACTION ::TOGGLE_OVERWRITE_MODE ): return ( action ( NOOP , &Replxx::ReplxxImpl::toggle_overwrite_mode, code ) );
353356#ifndef _WIN32
@@ -674,7 +677,7 @@ void Replxx::ReplxxImpl::render( char32_t ch ) {
674677 if ( ch == Replxx::KEY ::ESCAPE ) {
675678 _display.push_back ( ' ^' );
676679 _display.push_back ( ' [' );
677- } else if ( is_control_code ( ch ) ) {
680+ } else if ( is_control_code ( ch ) && ( ch != ' \n ' ) ) {
678681 _display.push_back ( ' ^' );
679682 _display.push_back ( control_to_human ( ch ) );
680683 } else {
@@ -1306,7 +1309,7 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::insert_character( char32_t c ) {
13061309 * beep on unknown Ctrl and/or Meta keys
13071310 * don't insert control characters
13081311 */
1309- if ( ( c >= static_cast <int >( Replxx::KEY ::BASE ) ) || is_control_code ( c ) ) {
1312+ if ( ( c >= static_cast <int >( Replxx::KEY ::BASE ) ) || ( is_control_code ( c ) && ( c != ' \n ' ) ) ) {
13101313 beep ();
13111314 return ( Replxx::ACTION_RESULT ::CONTINUE );
13121315 }
@@ -1346,6 +1349,11 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::insert_character( char32_t c ) {
13461349 return ( Replxx::ACTION_RESULT ::CONTINUE );
13471350}
13481351
1352+ // ctrl-J/linefeed/newline
1353+ Replxx::ACTION_RESULT Replxx::ReplxxImpl::new_line ( char32_t ) {
1354+ return ( insert_character ( ' \n ' ) );
1355+ }
1356+
13491357// ctrl-A, HOME: move cursor to start of line
13501358Replxx::ACTION_RESULT Replxx::ReplxxImpl::go_to_begining_of_line ( char32_t ) {
13511359 _pos = 0 ;
@@ -1654,8 +1662,7 @@ Replxx::ACTION_RESULT Replxx::ReplxxImpl::backspace_character( char32_t ) {
16541662 return ( Replxx::ACTION_RESULT ::CONTINUE );
16551663}
16561664
1657- // ctrl-J/linefeed/newline, accept line
1658- // ctrl-M/return/enter
1665+ // ctrl-M/return/enter, accept line
16591666Replxx::ACTION_RESULT Replxx::ReplxxImpl::commit_line ( char32_t ) {
16601667 // we need one last refresh with the cursor at the end of the line
16611668 // so we don't display the next prompt over the previous input line
0 commit comments