Skip to content

Commit 3e14af6

Browse files
[update] <components>:finsh/shell.c
添加以下功能 1 ctrl+back 按单词删除 2 ctrl+左右箭头 按单词切换光标 Signed-off-by: Yucai Liu <1486344514@qq.com>
1 parent 169d84d commit 3e14af6

File tree

1 file changed

+89
-2
lines changed

1 file changed

+89
-2
lines changed

components/finsh/shell.c

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,35 @@ static void shell_push_history(struct finsh_shell *shell)
457457
}
458458
#endif
459459

460+
static int find_prev_word_start(const char *line, int curpos)
461+
{
462+
if (curpos <= 0) return 0;
463+
464+
// Skip whitespace
465+
while (--curpos > 0 && (line[curpos] == ' ' || line[curpos] == '\t'));
466+
467+
// Find word start
468+
while (curpos > 0 && !(line[curpos] == ' ' || line[curpos] == '\t'))
469+
curpos--;
470+
471+
return (curpos <= 0) ? 0 : curpos + 1;
472+
}
473+
474+
static int find_next_word_end(const char *line, int curpos, int max)
475+
{
476+
if (curpos >= max) return max;
477+
478+
// Skip to next word
479+
while (curpos < max && (line[curpos] == ' ' || line[curpos] == '\t'))
480+
curpos++;
481+
482+
// Find word end
483+
while (curpos < max && !(line[curpos] == ' ' || line[curpos] == '\t'))
484+
curpos++;
485+
486+
return curpos;
487+
}
488+
460489
#ifdef RT_USING_HOOK
461490
static void (*_finsh_thread_entry_hook)(void);
462491

@@ -546,8 +575,35 @@ static void finsh_thread_entry(void *parameter)
546575
else if (shell->stat == WAIT_FUNC_KEY)
547576
{
548577
shell->stat = WAIT_NORMAL;
549-
550-
if (ch == 0x41) /* up key */
578+
/* Add Ctrl+Left/Right handling */
579+
if (ch == '1')
580+
{
581+
/* Read modifier sequence [1;5D/C] */
582+
int next_ch = finsh_getchar();
583+
if (next_ch == ';')
584+
{
585+
next_ch = finsh_getchar();
586+
if (next_ch == '5')
587+
{
588+
next_ch = finsh_getchar();
589+
if (next_ch == 'D')
590+
{ /* Ctrl+Left */
591+
int new_pos = find_prev_word_start(shell->line, shell->line_curpos);
592+
rt_kprintf("\033[%dD", shell->line_curpos - new_pos);
593+
shell->line_curpos = new_pos;
594+
continue;
595+
}
596+
else if (next_ch == 'C')
597+
{ /* Ctrl+Right */
598+
int new_pos = find_next_word_end(shell->line, shell->line_curpos, shell->line_position);
599+
rt_kprintf("\033[%dC", new_pos - shell->line_curpos);
600+
shell->line_curpos = new_pos;
601+
continue;
602+
}
603+
}
604+
}
605+
}
606+
else if (ch == 0x41) /* up key */
551607
{
552608
#ifdef FINSH_USING_HISTORY
553609
/* prev history */
@@ -661,7 +717,38 @@ static void finsh_thread_entry(void *parameter)
661717

662718
continue;
663719
}
720+
/* Add Ctrl+Backspace handling */
721+
else if (ch == 0x17) /* Ctrl+Backspace (typically ^W) */
722+
{
723+
if (shell->line_curpos == 0) continue;
724+
725+
int start = find_prev_word_start(shell->line, shell->line_curpos);
726+
int del_count = shell->line_curpos - start;
727+
int new_len = shell->line_position - del_count;
728+
729+
/* Delete characters with proper RT_null termination */
730+
rt_memmove(&shell->line[start],
731+
&shell->line[start + del_count],
732+
new_len - start + 1); // +1 包含 RT_null 终止符
733+
734+
/* Clear residual data */
735+
rt_memset(&shell->line[new_len], 0, shell->line_position - new_len);
664736

737+
/* Update positions */
738+
shell->line_position = new_len;
739+
shell->line_curpos = start;
740+
741+
/* Full redraw for affected area */
742+
rt_kprintf("\033[%dD", del_count); // 左移删除长度
743+
rt_kprintf("%.*s", shell->line_position - start, &shell->line[start]); // 重写剩余内容
744+
rt_kprintf("\033[K"); // 清除行尾残留
745+
if (shell->line_position > start)
746+
{
747+
rt_kprintf("\033[%dD", shell->line_position - start); // 复位光标
748+
}
749+
750+
continue;
751+
}
665752
/* handle end of line, break */
666753
if (ch == '\r' || ch == '\n')
667754
{

0 commit comments

Comments
 (0)