# HG changeset patch # User Jacob Alexander # Date 1428044151 25200 # Node ID 64f43aad73af65098fc85affb93bad2169fac11a # Parent 7d21e5b97be4ab7912352d2bc871eb72dc7b2c99# Parent 3994a5a6879365ad63cecaa44bd1180535371ed2 Merge pull request #33 from smasher816/devel Add CLI History diff -r 7d21e5b97be4 -r 64f43aad73af Debug/cli/cli.c --- a/Debug/cli/cli.c Thu Apr 02 19:07:21 2015 -0700 +++ b/Debug/cli/cli.c Thu Apr 02 23:55:51 2015 -0700 @@ -72,6 +72,11 @@ // Reset the Line Buffer CLILineBufferCurrent = 0; + // History starts empty + CLIHistoryHead = 0; + CLIHistoryCurrent = 0; + CLIHistoryTail = 0; + // Set prompt prompt(); @@ -154,6 +159,22 @@ // Process the current line buffer CLI_commandLookup(); + // Add the command to the history + cli_saveHistory( CLILineBuffer ); + + // Keep the array circular, discarding the older entries + if ( CLIHistoryTail < CLIHistoryHead ) + CLIHistoryHead = ( CLIHistoryHead + 1 ) % CLIMaxHistorySize; + CLIHistoryTail++; + if ( CLIHistoryTail == CLIMaxHistorySize ) + { + CLIHistoryTail = 0; + CLIHistoryHead = 1; + } + + CLIHistoryCurrent = CLIHistoryTail; // 'Up' starts at the last item + cli_saveHistory( NULL ); // delete the old temp buffer + // Reset the buffer CLILineBufferCurrent = 0; @@ -175,9 +196,38 @@ // Doesn't look like it will happen *that* often, so not handling it for now -HaaTa return; - case 0x1B: // Esc - // Check for escape sequence - // TODO + case 0x1B: // Esc / Escape codes + // Check for other escape sequence + + // \e[ is an escape code in vt100 compatable terminals + if ( CLILineBufferCurrent >= prev_buf_pos + 3 + && CLILineBuffer[ prev_buf_pos ] == 0x1B + && CLILineBuffer[ prev_buf_pos + 1] == 0x5B ) + { + // Arrow Keys: A (0x41) = Up, B (0x42) = Down, C (0x43) = Right, D (0x44) = Left + + if ( CLILineBuffer[ prev_buf_pos + 2 ] == 0x41 ) // Hist prev + { + if ( CLIHistoryCurrent == CLIHistoryTail ) + { + // Is first time pressing arrow. Save the current buffer + CLILineBuffer[ prev_buf_pos ] = '\0'; + cli_saveHistory( CLILineBuffer ); + } + + // Grab the previus item from the history if there is one + if ( RING_PREV( CLIHistoryCurrent ) != RING_PREV( CLIHistoryHead ) ) + CLIHistoryCurrent = RING_PREV( CLIHistoryCurrent ); + cli_retreiveHistory( CLIHistoryCurrent ); + } + if ( CLILineBuffer[ prev_buf_pos + 2 ] == 0x42 ) // Hist next + { + // Grab the next item from the history if it exists + if ( RING_NEXT( CLIHistoryCurrent ) != RING_NEXT( CLIHistoryTail ) ) + CLIHistoryCurrent = RING_NEXT( CLIHistoryCurrent ); + cli_retreiveHistory( CLIHistoryCurrent ); + } + } return; case 0x08: @@ -348,6 +398,54 @@ } } +inline int CLI_wrap( int kX, int const kLowerBound, int const kUpperBound ) +{ + int range_size = kUpperBound - kLowerBound + 1; + + if ( kX < kLowerBound ) + kX += range_size * ((kLowerBound - kX) / range_size + 1); + + return kLowerBound + (kX - kLowerBound) % range_size; +} + +inline void CLI_saveHistory( char *buff ) +{ + if ( buff == NULL ) + { + //clear the item + CLIHistoryBuffer[ CLIHistoryTail ][ 0 ] = '\0'; + return; + } + + // Copy the line to the history + int i; + for (i = 0; i < CLILineBufferCurrent; i++) + { + CLIHistoryBuffer[ CLIHistoryTail ][ i ] = CLILineBuffer[ i ]; + } +} + +void CLI_retreiveHistory( int index ) +{ + char *histMatch = CLIHistoryBuffer[ index ]; + + // Reset the buffer + CLILineBufferCurrent = 0; + + // Reprint the prompt (automatically clears the line) + prompt(); + + // Display the command + dPrint( histMatch ); + + // There are no index counts, so just copy the whole string to the input buffe + CLILineBufferCurrent = 0; + while ( *histMatch != '\0' ) + { + CLILineBuffer[ CLILineBufferCurrent++ ] = *histMatch++; + } +} + // ----- CLI Command Functions ----- diff -r 7d21e5b97be4 -r 64f43aad73af Debug/cli/cli.h --- a/Debug/cli/cli.h Thu Apr 02 19:07:21 2015 -0700 +++ b/Debug/cli/cli.h Thu Apr 02 23:55:51 2015 -0700 @@ -36,7 +36,7 @@ #define CLILineBufferMaxSize 100 #define CLIMaxDictionaries 10 #define CLIEntryTabAlign 13 - +#define CLIMaxHistorySize 10 // ----- Macros ----- @@ -67,6 +67,8 @@ const char name##CLIDict_DescEntry[] = description; #endif +#define RING_PREV(i) wrap(i-1,0,CLIMaxHistorySize-1) +#define RING_NEXT(i) wrap(i+1,0,CLIMaxHistorySize-1) // ----- Structs ----- @@ -90,6 +92,13 @@ char* CLIDictNames[CLIMaxDictionaries]; uint8_t CLIDictionariesUsed; +// History +char CLIHistoryBuffer[CLIMaxHistorySize][CLILineBufferMaxSize]; +uint8_t CLIHistoryHead; +uint8_t CLIHistoryTail; +int8_t CLIHistoryCurrent; + +// Debug uint8_t CLILEDState; uint8_t CLIHexDebugMode; @@ -102,8 +111,11 @@ void CLI_registerDictionary( const CLIDictItem *cmdDict, const char* dictName ); void CLI_argumentIsolation( char* string, char** first, char** second ); +int CLI_wrap( int x, int low, int high ); void CLI_commandLookup(); void CLI_tabCompletion(); +void CLI_saveHistory( char *buff ); +void CLI_retreiveHistory( int index ); // CLI Command Functions void cliFunc_arch ( char* args );