diff --git a/components/finsh/shell.c b/components/finsh/shell.c index 61c91954154..b76e504a1c5 100644 --- a/components/finsh/shell.c +++ b/components/finsh/shell.c @@ -558,6 +558,10 @@ static void finsh_thread_entry(void *parameter) * down key: 0x1b 0x5b 0x42 * right key:0x1b 0x5b 0x43 * left key: 0x1b 0x5b 0x44 + * home : 0x1b 0x5b 0x31 0x7E + * insert : 0x1b 0x5b 0x32 0x7E + * del : 0x1b 0x5b 0x33 0x7E + * end : 0x1b 0x5b 0x34 0x7E */ if (ch == 0x1b) { @@ -676,6 +680,66 @@ static void finsh_thread_entry(void *parameter) } } #endif /*defined(FINSH_USING_WORD_OPERATION) */ + else if (ch >= 0x31 && ch <= 0x34) /* home(0x31), insert(0x32), del(0x33), end(0x34) */ + { + shell->stat = WAIT_EXT_KEY; + shell->line[shell->line_position + 1] = ch; /* store the key code */ + continue; + } + } + else if (shell->stat == WAIT_EXT_KEY) + { + shell->stat = WAIT_NORMAL; + + if (ch == 0x7E) /* extended key terminator */ + { + rt_uint8_t key_code = shell->line[shell->line_position + 1]; + + if (key_code == 0x31) /* home key */ + { + /* move cursor to beginning of line */ + while (shell->line_curpos > 0) + { + rt_kprintf("\b"); + shell->line_curpos--; + } + } + else if (key_code == 0x32) /* insert key */ + { + /* toggle insert mode */ + shell->overwrite_mode = !shell->overwrite_mode; + } + else if (key_code == 0x33) /* del key */ + { + /* delete character at current cursor position */ + if (shell->line_curpos < shell->line_position) + { + int i; + + rt_memmove(&shell->line[shell->line_curpos], + &shell->line[shell->line_curpos + 1], + shell->line_position - shell->line_curpos); + shell->line_position--; + shell->line[shell->line_position] = 0; + + rt_kprintf("%s ", &shell->line[shell->line_curpos]); + + /* move cursor back to original position */ + for (i = shell->line_curpos; i <= shell->line_position; i++) + rt_kprintf("\b"); + } + } + else if (key_code == 0x34) /* end key */ + { + /* move cursor to end of line */ + while (shell->line_curpos < shell->line_position) + { + rt_kprintf("%c", shell->line[shell->line_curpos]); + shell->line_curpos++; + } + } + continue; + } } /* received null or error */ @@ -790,27 +854,44 @@ static void finsh_thread_entry(void *parameter) { int i; - rt_memmove(&shell->line[shell->line_curpos + 1], - &shell->line[shell->line_curpos], - shell->line_position - shell->line_curpos); - shell->line[shell->line_curpos] = ch; - if (shell->echo_mode) - rt_kprintf("%s", &shell->line[shell->line_curpos]); + if (shell->overwrite_mode) /* overwrite mode */ + { + /* directly overwrite the character */ + shell->line[shell->line_curpos] = ch; + if (shell->echo_mode) + rt_kprintf("%c", ch); + shell->line_curpos++; + } + else /* insert mode */ + { + shell->line_position++; + /* move existing characters to the right */ + rt_memmove(&shell->line[shell->line_curpos + 1], + &shell->line[shell->line_curpos], + shell->line_position - shell->line_curpos); + shell->line[shell->line_curpos] = ch; - /* move the cursor to new position */ - for (i = shell->line_curpos; i < shell->line_position; i++) - rt_kprintf("\b"); + if (shell->echo_mode) + { + rt_kprintf("%s", &shell->line[shell->line_curpos]); + /* move cursor back to correct position */ + for (i = shell->line_curpos + 1; i < shell->line_position; i++) + rt_kprintf("\b"); + } + shell->line_curpos++; + } } else { + /* append character at end of line */ shell->line[shell->line_position] = ch; if (shell->echo_mode) rt_kprintf("%c", ch); + shell->line_position++; + shell->line_curpos++; } ch = 0; - shell->line_position ++; - shell->line_curpos++; if (shell->line_position >= FINSH_CMD_SIZE) { /* clear command line */ diff --git a/components/finsh/shell.h b/components/finsh/shell.h index db4a77d5566..422c17e165a 100644 --- a/components/finsh/shell.h +++ b/components/finsh/shell.h @@ -57,6 +57,7 @@ enum input_stat WAIT_NORMAL, WAIT_SPEC_KEY, WAIT_FUNC_KEY, + WAIT_EXT_KEY, }; struct finsh_shell { @@ -66,7 +67,7 @@ struct finsh_shell rt_uint8_t echo_mode: 1; rt_uint8_t prompt_mode: 1; - + rt_uint8_t overwrite_mode: 1; #ifdef FINSH_USING_HISTORY rt_uint16_t current_history; rt_uint16_t history_count;