commit ceb7cae5806c7f63ca458115a470fe81d08d38ff Author: Simon Kirby Date: Sat Mar 17 00:55:15 2012 -0700 Implement cli tab completion. diff --git a/baseflight/src/cli.c b/baseflight/src/cli.c index 06bbed0..cf6e4f6 100644 --- a/baseflight/src/cli.c +++ b/baseflight/src/cli.c @@ -30,8 +30,6 @@ const cliCmd cmdTable[] = { static void cliPrompt(void) { uartPrint("\r\n# "); - memset(cliBuffer, 0, sizeof(cliBuffer)); - bufferIndex = 0; } static int cliCompare(const void *a, const void *b) @@ -42,7 +40,7 @@ static int cliCompare(const void *a, const void *b) static void cliExit(char *cmdline) { - uartPrint("Leaving CLI mode...\r\n"); + uartPrint("\r\nLeaving CLI mode...\r\n"); memset(cliBuffer, 0, sizeof(cliBuffer)); bufferIndex = 0; cliMode = 0; @@ -72,6 +70,7 @@ static void cliRMode(char *cmdline) featureSet(FEATURE_PPM); } + cliExit(cmdline); writeParams(); systemReset(false); } @@ -83,20 +82,56 @@ static void cliVersion(char *cmdline) void cliProcess(void) { + if (!cliMode) { + cliMode = 1; + uartPrint("\r\nEntering CLI Mode, type 'exit' to return\r\n"); + cliPrompt(); + } while (uartAvailable()) { uint8_t c = uartRead(); - cliBuffer[bufferIndex++] = c; - if (bufferIndex == sizeof(cliBuffer)) { - bufferIndex--; - c = '\n'; - } - - if (bufferIndex && (c == '\n' || c == '\r')) { + if (c == '\t' || c == '?') { + const cliCmd *cmd, *pstart = NULL, *pend = NULL; + int i = bufferIndex; + for (cmd = cmdTable;cmd < cmdTable + CMD_COUNT;cmd++) { + if (bufferIndex && (strncasecmp(cliBuffer, cmd->name, bufferIndex) != 0)) + continue; + if (!pstart) + pstart = cmd; + pend = cmd; + } + if (pstart) { /* Buffer matches one or more commands */ + for (;;bufferIndex++) { + if (pstart->name[bufferIndex] != pend->name[bufferIndex]) + break; + if (!pstart->name[bufferIndex]) { + /* Unambiguous -- append a space */ + cliBuffer[bufferIndex++] = ' '; + break; + } + cliBuffer[bufferIndex] = pstart->name[bufferIndex]; + } + } + if (!bufferIndex || pstart != pend) { + /* Print list of ambiguous matches */ + uartPrint("\r\033[K"); + for (cmd = pstart;cmd <= pend;cmd++) { + uartPrint(cmd->name); + uartWrite('\t'); + } + cliPrompt(); + i = 0; /* Redraw prompt */ + } + for (;i < bufferIndex;i++) + uartWrite(cliBuffer[i]); + } else if (!bufferIndex && c == 4) { + cliExit(cliBuffer); + return; + } else if (bufferIndex && (c == '\n' || c == '\r')) { // enter pressed cliCmd *cmd = NULL; cliCmd target; - uartPrint("\r\n"); + uartPrint("\r\n"); cliBuffer[bufferIndex] = 0; // null terminate target.name = cliBuffer; @@ -108,25 +143,23 @@ void cliProcess(void) else uartPrint("ERR: Unknown command, try 'HELP'"); - // 'exit' will reset this flag, so we don't need to print prompt again - if (cliMode) - cliPrompt(); + memset(cliBuffer, 0, sizeof(cliBuffer)); + bufferIndex = 0; - } else if (c == 127) { + // 'exit' will reset this flag, so we don't need to print prompt again + if (!cliMode) + return; + cliPrompt(); + } else if (c == 8 || c == 127) { // backspace - if (bufferIndex > 1) { - cliBuffer[bufferIndex - 2] = 0; - uartPrint("\r# "); - uartPrint(cliBuffer); - uartWrite(' '); - uartPrint("\r# "); - uartPrint(cliBuffer); - bufferIndex -= 2; + if (bufferIndex) { + cliBuffer[--bufferIndex] = 0; + uartPrint("\010 \010"); } - } else if (c < 32 || c > 126) { - // non-printable ascii - bufferIndex--; - } else { + } else if (bufferIndex < sizeof(cliBuffer) && c >= 32 && c <= 126) { + if (!bufferIndex && c == 32) + continue; + cliBuffer[bufferIndex++] = c; uartWrite(c); } } diff --git a/baseflight/src/serial.c b/baseflight/src/serial.c index 088f42b..fb540f8 100755 --- a/baseflight/src/serial.c +++ b/baseflight/src/serial.c @@ -33,8 +33,7 @@ void serialCom(void) if (uartAvailable()) { switch (uartRead()) { case '#': - uartPrint("\r\nEntering CLI Mode, type 'exit' to return\r\n"); - cliMode = 1; + cliProcess(); break; #ifdef BTSERIAL