]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Adding basic Tab completion.
authorJacob Alexander <haata@kiibohd.com>
Fri, 24 Jan 2014 11:01:09 +0000 (03:01 -0800)
committerJacob Alexander <haata@kiibohd.com>
Sat, 22 Mar 2014 21:13:45 +0000 (14:13 -0700)
Debug/cli/cli.c
Debug/cli/cli.h
Debug/print/print.c
Debug/print/print.h

index f4415aff4a434a36bc9d250393a38d15d7740b29..e44d613bd33f0b33da20faef5b587c97c9473752 100644 (file)
@@ -53,8 +53,8 @@ CLIDictItem basicCLIDict[] = {
 
 inline void prompt()
 {
-       print("\033[2K"); // Erases the current line
-       print("\033[1;34m:\033[0m ");
+       print("\033[2K\r"); // Erases the current line and resets cursor to beginning of line
+       print("\033[1;34m:\033[0m "); // Blue bold prompt
 }
 
 // Initialize the CLI
@@ -155,7 +155,12 @@ void process_cli()
 
                case 0x09: // Tab
                        // Tab completion for the current command
-                       // TODO
+                       tabCompletion_cli();
+
+                       CLILineBufferCurrent--; // Remove the Tab
+
+                       // XXX There is a potential bug here when resetting the buffer (losing valid keypresses)
+                       //     Doesn't look like it will happen *that* often, so not handling it for now -HaaTa
                        return;
 
                case 0x1B: // Esc
@@ -242,7 +247,7 @@ void commandLookup_cli()
                for ( uint8_t cmd = 0; CLIDict[dict][cmd].name != 0; cmd++ )
                {
                        // Compare the first argument and each command entry
-                       if ( eqStr( cmdPtr, CLIDict[dict][cmd].name ) )
+                       if ( eqStr( cmdPtr, CLIDict[dict][cmd].name ) == -1 )
                        {
                                // Run the specified command function pointer
                                //   argPtr is already pointing at the first character of the arguments
@@ -273,6 +278,64 @@ inline void registerDictionary_cli( CLIDictItem *cmdDict, char* dictName )
        CLIDict[CLIDictionariesUsed++] = cmdDict;
 }
 
+inline void tabCompletion_cli()
+{
+       // Ignore command if buffer is 0 length
+       if ( CLILineBufferCurrent == 0 )
+               return;
+
+       // Set the last+1 character of the buffer to NULL for string processing
+       CLILineBuffer[CLILineBufferCurrent] = '\0';
+
+       // Retrieve pointers to command and beginning of arguments
+       // Places a NULL at the first space after the command
+       char* cmdPtr;
+       char* argPtr;
+       argumentIsolation_cli( CLILineBuffer, &cmdPtr, &argPtr );
+
+       // Tab match pointer
+       char* tabMatch = 0;
+       uint8_t matches = 0;
+
+       // Scan array of dictionaries for a valid command match
+       for ( uint8_t dict = 0; dict < CLIDictionariesUsed; dict++ )
+       {
+               // Parse each cmd until a null command entry is found, or an argument match
+               for ( uint8_t cmd = 0; CLIDict[dict][cmd].name != 0; cmd++ )
+               {
+                       // Compare the first argument piece to each command entry to see if it is "like"
+                       // NOTE: To save on processing, we only care about the commands and ignore the arguments
+                       //       If there are arguments, and a valid tab match is found, buffer is cleared (args lost)
+                       //       Also ignores full matches
+                       if ( eqStr( cmdPtr, CLIDict[dict][cmd].name ) == 0 )
+                       {
+                               // TODO Make list of commands if multiple matches
+                               matches++;
+                               tabMatch = CLIDict[dict][cmd].name;
+                       }
+               }
+       }
+
+       // Only tab complete if there was 1 match
+       if ( matches == 1 )
+       {
+               // Reset the buffer
+               CLILineBufferCurrent = 0;
+
+               // Reprint the prompt (automatically clears the line)
+               prompt();
+
+               // Display the command
+               dPrint( tabMatch );
+
+               // There are no index counts, so just copy the whole string to the input buffer
+               while ( *tabMatch != '\0' )
+               {
+                       CLILineBuffer[CLILineBufferCurrent++] = *tabMatch++;
+               }
+       }
+}
+
 
 
 // ----- CLI Command Functions -----
index 0a2080308ebbc1962a06b47301b123755bcb4cc5..e7529b18578b861cbf06c762755366552ad87c5e 100644 (file)
@@ -72,6 +72,7 @@ void registerDictionary_cli( CLIDictItem *cmdDict, char* dictName );
 void argumentIsolation_cli( char* string, char** first, char** second );
 
 void commandLookup_cli();
+void tabCompletion_cli();
 
 // CLI Command Functions
 void cliFunc_arch    ( char* args );
index 27ecf4becb6170edb5e2662f18480b61b850b624..147bd97635b9305776d56254e41804280b600bfe 100644 (file)
@@ -241,12 +241,13 @@ uint16_t lenStr( char* in )
 }
 
 
-uint8_t eqStr( char* str1, char* str2 )
+int16_t eqStr( char* str1, char* str2 )
 {
        // Scan each string for NULLs and whether they are the same
        while( *str1 != '\0' && *str1++ == *str2++ );
 
-       // If the strings are still identical (i.e. both NULL), then return 1, otherwise 0
-       return *--str1 == *--str2 ? 1 : 0;
+       // If the strings are still identical (i.e. both NULL), then return -1, otherwise current *str1
+       // If *str1 is 0, then str1 ended (and str1 is "like" str2), otherwise strings are different
+       return *--str1 == *--str2 ? -1 : *++str1;
 }
 
index 924d101030f7e2c53a5569fe49cfa84d0a2f017f..c4d909237ff2bd094526fe9d129124a6a6d616d0 100644 (file)
@@ -109,7 +109,7 @@ void int16ToStr ( uint16_t in, char*  out );
 void hexToStr_op( uint16_t in, char*  out, uint8_t op );
 void revsStr    ( char*  in );
 uint16_t lenStr ( char*  in );
-uint8_t eqStr   ( char*  str1, char* str2 ); // Returns 1 if identical, 0 otherwise
+int16_t eqStr   ( char*  str1, char* str2 ); // Returns -1 if identical, last character of str1 comparison (0 if str1 is like str2)
 
 #endif