changeset 320:64f43aad73af

Merge pull request #33 from smasher816/devel Add CLI History
author Jacob Alexander <haata@kiibohd.com>
date Thu, 02 Apr 2015 23:55:51 -0700
parents 7d21e5b97be4 (current diff) 3994a5a68793 (diff)
children 18c3c4924f20
files
diffstat 2 files changed, 114 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- 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 -----
--- 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 );