Skip to content

[update] <components>:finsh/shell.c 增加新功能 #10394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions components/finsh/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
98 changes: 98 additions & 0 deletions components/finsh/shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -609,6 +640,40 @@ 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 */
Expand Down Expand Up @@ -661,7 +726,40 @@ 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 with proper RT_null termination */
rt_memmove(&shell->line[start],
&shell->line[start + del_count],
new_len - start + 1); // +1 包含 RT_null 终止符

/* 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;

/* Full redraw for affected area */
rt_kprintf("\033[%dD", del_count); // 左移删除长度
rt_kprintf("%.*s", shell->line_position - start, &shell->line[start]); // 重写剩余内容
rt_kprintf("\033[K"); // 清除行尾残留
if (shell->line_position > start)
{
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')
{
Expand Down