mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-06 09:02:20 +08:00
[update] <components>:finsh/shell.c
添加以下功能(需要kconfig使能FINSH_USING_WORD_OPERATION) 1 ctrl+back 按单词删除 2 ctrl+左右箭头 按单词切换光标 Signed-off-by: Yucai Liu <1486344514@qq.com>
This commit is contained in:
@@ -35,6 +35,12 @@ if RT_USING_MSH
|
||||
default 5
|
||||
endif
|
||||
|
||||
config FINSH_USING_WORD_OPERATION
|
||||
bool "Enable word-based cursor operations"
|
||||
default n
|
||||
help
|
||||
Enable Ctrl+Backspace to delete words and Ctrl+Arrow to move cursor by word
|
||||
|
||||
config FINSH_USING_SYMTAB
|
||||
bool "Using symbol table for commands"
|
||||
default y
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2025, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -457,6 +457,37 @@ static void shell_push_history(struct finsh_shell *shell)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FINSH_USING_WORD_OPERATION)
|
||||
static int find_prev_word_start(const char *line, int curpos)
|
||||
{
|
||||
if (curpos <= 0) return 0;
|
||||
|
||||
/* Skip whitespace */
|
||||
while (--curpos > 0 && (line[curpos] == ' ' || line[curpos] == '\t'));
|
||||
|
||||
/* Find word start */
|
||||
while (curpos > 0 && !(line[curpos] == ' ' || line[curpos] == '\t'))
|
||||
curpos--;
|
||||
|
||||
return (curpos <= 0) ? 0 : curpos + 1;
|
||||
}
|
||||
|
||||
static int find_next_word_end(const char *line, int curpos, int max)
|
||||
{
|
||||
if (curpos >= max) return max;
|
||||
|
||||
/* Skip to next word */
|
||||
while (curpos < max && (line[curpos] == ' ' || line[curpos] == '\t'))
|
||||
curpos++;
|
||||
|
||||
/* Find word end */
|
||||
while (curpos < max && !(line[curpos] == ' ' || line[curpos] == '\t'))
|
||||
curpos++;
|
||||
|
||||
return curpos;
|
||||
}
|
||||
#endif /* defined(FINSH_USING_WORD_OPERATION) */
|
||||
|
||||
#ifdef RT_USING_HOOK
|
||||
static void (*_finsh_thread_entry_hook)(void);
|
||||
|
||||
@@ -609,6 +640,42 @@ static void finsh_thread_entry(void *parameter)
|
||||
|
||||
continue;
|
||||
}
|
||||
#if defined(FINSH_USING_WORD_OPERATION)
|
||||
/* Add Ctrl+Left/Right handling */
|
||||
else if (ch == '1')
|
||||
{
|
||||
/* Read modifier sequence [1;5D/C] */
|
||||
int next_ch = finsh_getchar();
|
||||
if (next_ch == ';')
|
||||
{
|
||||
next_ch = finsh_getchar();
|
||||
if (next_ch == '5')
|
||||
{
|
||||
next_ch = finsh_getchar();
|
||||
if (next_ch == 'D') /* Ctrl+Left */
|
||||
{
|
||||
int new_pos = find_prev_word_start(shell->line, shell->line_curpos);
|
||||
if (new_pos != shell->line_curpos)
|
||||
{
|
||||
rt_kprintf("\033[%dD", shell->line_curpos - new_pos);
|
||||
shell->line_curpos = new_pos;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (next_ch == 'C') /* Ctrl+Right */
|
||||
{
|
||||
int new_pos = find_next_word_end(shell->line, shell->line_curpos, shell->line_position);
|
||||
if (new_pos != shell->line_curpos)
|
||||
{
|
||||
rt_kprintf("\033[%dC", new_pos - shell->line_curpos);
|
||||
shell->line_curpos = new_pos;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /*defined(FINSH_USING_WORD_OPERATION) */
|
||||
}
|
||||
|
||||
/* received null or error */
|
||||
@@ -661,7 +728,43 @@ static void finsh_thread_entry(void *parameter)
|
||||
|
||||
continue;
|
||||
}
|
||||
#if defined(FINSH_USING_WORD_OPERATION)
|
||||
/* Add Ctrl+Backspace handling */
|
||||
else if (ch == 0x17) /* Ctrl+Backspace (typically ^W) */
|
||||
{
|
||||
if (shell->line_curpos == 0) continue;
|
||||
|
||||
int start = find_prev_word_start(shell->line, shell->line_curpos);
|
||||
int del_count = shell->line_curpos - start;
|
||||
int new_len = shell->line_position - del_count;
|
||||
|
||||
/* Delete characters and properly add RT_NULL termination */
|
||||
rt_memmove(&shell->line[start],
|
||||
&shell->line[start + del_count],
|
||||
new_len - start + 1);
|
||||
|
||||
/* Clear residual data */
|
||||
rt_memset(&shell->line[new_len], 0, shell->line_position - new_len);
|
||||
|
||||
/* Update positions */
|
||||
shell->line_position = new_len;
|
||||
shell->line_curpos = start;
|
||||
|
||||
/* Redraw the affected line section */
|
||||
rt_kprintf("\033[%dD", del_count);
|
||||
/* Rewrite the remaining content */
|
||||
rt_kprintf("%.*s", shell->line_position - start, &shell->line[start]);
|
||||
/* Clear trailing artifacts */
|
||||
rt_kprintf("\033[K");
|
||||
if (shell->line_position > start)
|
||||
{
|
||||
/* Reset cursor */
|
||||
rt_kprintf("\033[%dD", shell->line_position - start);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
#endif /*defined(FINSH_USING_WORD_OPERATION) */
|
||||
/* handle end of line, break */
|
||||
if (ch == '\r' || ch == '\n')
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user