Skip to content

Commit d7feea8

Browse files
[update] <components>:finsh/shell.c
添加以下功能(需要kconfig使能FINSH_USING_WORD_OPERATION) 1 ctrl+back 按单词删除 2 ctrl+左右箭头 按单词切换光标 Signed-off-by: Yucai Liu <[email protected]>
1 parent 169d84d commit d7feea8

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

components/finsh/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ if RT_USING_MSH
3535
default 5
3636
endif
3737

38+
config FINSH_USING_WORD_OPERATION
39+
bool "Enable word-based cursor operations"
40+
default n
41+
help
42+
Enable Ctrl+Backspace to delete words and Ctrl+Arrow to move cursor by word
43+
3844
config FINSH_USING_SYMTAB
3945
bool "Using symbol table for commands"
4046
default y

components/finsh/shell.c

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

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

@@ -609,6 +640,40 @@ static void finsh_thread_entry(void *parameter)
609640

610641
continue;
611642
}
643+
#if defined(FINSH_USING_WORD_OPERATION)
644+
/* Add Ctrl+Left/Right handling */
645+
else if (ch == '1')
646+
{
647+
/* Read modifier sequence [1;5D/C] */
648+
int next_ch = finsh_getchar();
649+
if (next_ch == ';')
650+
{
651+
next_ch = finsh_getchar();
652+
if (next_ch == '5')
653+
{
654+
next_ch = finsh_getchar();
655+
if (next_ch == 'D')
656+
{ /* Ctrl+Left */
657+
int new_pos = find_prev_word_start(shell->line, shell->line_curpos);
658+
if (new_pos != shell->line_curpos) {
659+
rt_kprintf("\033[%dD", shell->line_curpos - new_pos);
660+
shell->line_curpos = new_pos;
661+
}
662+
continue;
663+
}
664+
else if (next_ch == 'C')
665+
{ /* Ctrl+Right */
666+
int new_pos = find_next_word_end(shell->line, shell->line_curpos, shell->line_position);
667+
if (new_pos != shell->line_curpos) {
668+
rt_kprintf("\033[%dC", new_pos - shell->line_curpos);
669+
shell->line_curpos = new_pos;
670+
}
671+
continue;
672+
}
673+
}
674+
}
675+
}
676+
#endif //defined(FINSH_USING_WORD_OPERATION)
612677
}
613678

614679
/* received null or error */
@@ -661,7 +726,40 @@ static void finsh_thread_entry(void *parameter)
661726

662727
continue;
663728
}
729+
#if defined(FINSH_USING_WORD_OPERATION)
730+
/* Add Ctrl+Backspace handling */
731+
else if (ch == 0x17) /* Ctrl+Backspace (typically ^W) */
732+
{
733+
if (shell->line_curpos == 0) continue;
734+
735+
int start = find_prev_word_start(shell->line, shell->line_curpos);
736+
int del_count = shell->line_curpos - start;
737+
int new_len = shell->line_position - del_count;
738+
739+
/* Delete characters with proper RT_null termination */
740+
rt_memmove(&shell->line[start],
741+
&shell->line[start + del_count],
742+
new_len - start + 1); // +1 包含 RT_null 终止符
743+
744+
/* Clear residual data */
745+
rt_memset(&shell->line[new_len], 0, shell->line_position - new_len);
664746

747+
/* Update positions */
748+
shell->line_position = new_len;
749+
shell->line_curpos = start;
750+
751+
/* Full redraw for affected area */
752+
rt_kprintf("\033[%dD", del_count); // 左移删除长度
753+
rt_kprintf("%.*s", shell->line_position - start, &shell->line[start]); // 重写剩余内容
754+
rt_kprintf("\033[K"); // 清除行尾残留
755+
if (shell->line_position > start)
756+
{
757+
rt_kprintf("\033[%dD", shell->line_position - start); // 复位光标
758+
}
759+
760+
continue;
761+
}
762+
#endif //defined(FINSH_USING_WORD_OPERATION)
665763
/* handle end of line, break */
666764
if (ch == '\r' || ch == '\n')
667765
{

0 commit comments

Comments
 (0)