-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Reconstruct the shell, manage historical commands using list, and add the ctrl+z/y functions #10986
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
base: master
Are you sure you want to change the base?
Conversation
… the ctrl+z/y functions
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
📌 Code Review Assignment🏷️ Tag: componentsReviewers: Maihuanyi Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2025-12-02 13:42 CST)
📝 Review Instructions
|
…n up comments for consistency.
…e_t to rt_size_t.
wdfk-prog
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 改太多了,看不过来.
- 能分批提交么?
| struct finsh_shell *shell; | ||
| static char *finsh_prompt_custom = RT_NULL; | ||
| static struct finsh_shell *shell = RT_NULL; | ||
| static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = { 0 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 这个咋成静态的了?原来的动态分配不好吗?
- 只有在使用的时候才分配内存.而不是有没有使用都占用
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里以前也是一个静态数组,放在函数const char *finsh_get_prompt(void) static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};中,动态分配存没有使用heap的时候,不能自定义prompt提示词,因为现在使用的自定义提示词是动态内存分配出来的
components/finsh/shell.c
Outdated
| { | ||
| finsh_prompt[0] = '\0'; | ||
| return finsh_prompt; | ||
| finsh_prompt[RT_CONSOLEBUF_SIZE] = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 改成
\0是不是更好,虽然一样
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以
components/finsh/shell.c
Outdated
| finsh_prompt[rt_strlen(finsh_prompt)] = '>'; | ||
| finsh_prompt[rt_strlen(finsh_prompt) + 1] = '\0'; | ||
| finsh_prompt[len++] = '>'; | ||
| finsh_prompt[len++] = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 这里没必要再次++了吧
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是的,这里可以不用加了,写习惯了
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
但这里也不影响
| if (!finsh_prompt[0]) | ||
| finsh_set_prompt_word(FINSH_PROMPT_WORD_DEFAULT); | ||
|
|
||
| len = finsh_prompt_length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 这里依赖与
finsh_prompt_length = rt_strlen(finsh_prompt);这个逻辑
-没有执行finsh_set_prompt_word函数当获取的话,会有问题
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
如果没有调用了finsh_set_prompt_word这个函数就需要获取提示词的话。在finsh_get_prompt_word这个函数中,会首先判断是否需要提示词模式,如果不需要,则finsh_prompt提示词数组最后一个数据置零后返回。如果需要,因为之前没有调用过finsh_set_prompt_word这个函数,这时的finsh_prompt数组为一个空数组,就会设置默认的提示词同时设置提示词长度。在往后执行,就能获取到finsh_prompt_length变量的长度了。
| /* release semaphore to let finsh thread rx data */ | ||
| rt_sem_release(&shell->rx_sem); | ||
| if (size) | ||
| rt_sem_release(&shell->rx_notice); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 奇怪的写法
- 没有size就不释放合适吗
rx_notice为什么要改名字呢- 返回值为什么改成0了
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1、因为没有数据接收,就不要释放信号量做无效的处理
2、因为改的较多,就把一写变量也就改了,也没其他原因,我拷贝以前的其它代码所以就一并了
3、因为0就是无错误返回,这里等同于返回RT_EOK,这个是习惯问题
| struct rt_device *device; | ||
| rt_uint16_t oflag; | ||
| int ret; | ||
| #ifdef RT_USING_SERIAL_V2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- 这边还要用宏去依赖serial_v2不合适吧?
- serial_v2 还是 serial_v1 应该传入同一个参数都能处理来着.兼容的吧?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
是兼容,只是想在了解源码的时候,能够知道是适配了串口版本2的
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
便于后续了解源码的,便利理解
| return; | ||
|
|
||
| #ifdef RT_USING_SERIAL_V2 | ||
| oflag = RT_DEVICE_FLAG_RX_BLOCKING | RT_DEVICE_FLAG_TX_BLOCKING; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里阻塞跟中断没区别吧?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
没区别的
|
@youzuwei ci问题需要修正下 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR performs a major reconstruction of the FinSH shell component, transitioning from array-based to list-based command history management and introducing new snapshot functionality for undo/redo operations. The changes affect core shell behavior, memory management, and user interaction patterns.
Key Changes
- List-based history management: Replaces fixed array with dynamic linked list for command history, improving flexibility and memory efficiency
- Snapshot feature: Adds Ctrl+Z/Ctrl+Y undo/redo functionality with configurable depth, tracking command editing states
- Refactored input handling: State machine approach for processing keyboard inputs (normal, function keys, extended keys, Ctrl sequences)
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 21 comments.
| File | Description |
|---|---|
| components/finsh/shell.h | Restructured shell data structures with new enums for input states and snapshot states; changed from array-based to list-based history; updated API signatures to use rt_bool_t instead of bitfields; added new public APIs for prompt and device management |
| components/finsh/shell.c | Complete refactoring of shell implementation: new memory allocation/deallocation for history and snapshots; extracted key handling into separate state-based functions; added snapshot push/pop/rollback logic; improved error handling and documentation; introduced finsh_shell_init/deinit lifecycle management |
| components/finsh/Kconfig | Added FINSH_USING_SNAPSHOT feature with configurable depth; renamed FINSH_USING_FUNC_EXT to FINSH_USING_EXTEND_FEATURE (breaking change); increased default history lines from 5 to 10; added prompt configuration options; reorganized indentation for better readability |
| #ifndef RT_USING_HEAP | ||
| int i; | ||
| for (i = 0; i < FINSH_SNAPSHOT_DEPTH; i++) | ||
| { | ||
| if (shell->snapshot[i].list.next && shell->snapshot[i].list.prev) | ||
| continue; | ||
| snap = &shell->snapshot[i]; | ||
| break; | ||
| } | ||
| if (i >= FINSH_SNAPSHOT_DEPTH) | ||
| { | ||
| rt_kprintf("No available snapshot buffer zone!\n"); | ||
| return RT_NULL; | ||
| } |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Potential bug: Uninitialized variable / 潜在错误:未初始化变量
English: Similar to the history allocation, in the non-heap case, if none of the FINSH_SNAPSHOT_DEPTH slots are available, the variable snap remains uninitialized when reaching the check at line 524. This will cause undefined behavior.
Recommendation: Initialize snap = RT_NULL; before the loop.
中文: 与历史记录分配类似,在非堆情况下,如果所有 FINSH_SNAPSHOT_DEPTH 槽位都不可用,变量 snap 在第 524 行的检查处保持未初始化状态。这将导致未定义行为。
建议: 在循环前初始化 snap = RT_NULL;。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里不影响,因为如果没有可用的FINSH_SNAPSHOT_DEPTH 槽位,会直接返回RT_NULL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里也不用更改,因为槽位不可用的时候,将直接返回RT_NULL
components/finsh/shell.h
Outdated
| int finsh_set_prompt_word(const char *prompt); | ||
| const char *finsh_get_prompt_word(void); | ||
| #define FINSH_PROMPT finsh_get_prompt_word() | ||
|
|
||
| void finsh_set_prompt(rt_bool_t prompt); | ||
| rt_bool_t finsh_get_prompt(void); |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Inconsistent naming / 命名不一致
English: The function name finsh_set_prompt_word and finsh_get_prompt_word use "word" to indicate they work with the prompt text/string. However, the related functions finsh_set_prompt and finsh_get_prompt work with the prompt mode (boolean). This naming is confusing as "prompt" could refer to either the text or the mode.
Recommendation: Consider renaming to make the distinction clearer:
finsh_set_prompt_text/finsh_get_prompt_textfor the stringfinsh_set_prompt_enabled/finsh_get_prompt_enabledfor the boolean
or keep current naming but ensure it's well documented.
中文: 函数名 finsh_set_prompt_word 和 finsh_get_prompt_word 使用"word"表示它们处理提示文本/字符串。然而,相关函数 finsh_set_prompt 和 finsh_get_prompt 处理提示模式(布尔值)。这种命名令人困惑,因为"prompt"可以指文本或模式。
建议: 考虑重命名以使区别更清晰:
finsh_set_prompt_text/finsh_get_prompt_text用于字符串finsh_set_prompt_enabled/finsh_get_prompt_enabled用于布尔值
或保持当前命名但确保有良好的文档说明。
| int finsh_set_prompt_word(const char *prompt); | |
| const char *finsh_get_prompt_word(void); | |
| #define FINSH_PROMPT finsh_get_prompt_word() | |
| void finsh_set_prompt(rt_bool_t prompt); | |
| rt_bool_t finsh_get_prompt(void); | |
| int finsh_set_prompt_text(const char *prompt_text); | |
| const char *finsh_get_prompt_text(void); | |
| #define FINSH_PROMPT finsh_get_prompt_text() | |
| void finsh_set_prompt_enabled(rt_bool_t enabled); | |
| rt_bool_t finsh_get_prompt_enabled(void); |
| /* clang-format off */ | ||
| #define finsh_printf(fmt, ...) do { if (shell->is_echo) rt_kprintf(fmt, ##__VA_ARGS__); } while (0) | ||
| #define finsh_puts(str) do { if (shell->is_echo) rt_kputs(str); } while (0) | ||
| #define finsh_putc(ch) do { if (shell->is_echo) rt_kprintf("%c", ch); } while (0) | ||
| /* clang-format on */ |
Copilot
AI
Dec 2, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Documentation: Missing comment explanation / 文档:缺少注释说明
English: The macro uses "clang-format off/on" directives but doesn't explain why the macros need special formatting. A comment explaining that these macros use GNU statement expressions (do-while-0 pattern) and need to avoid auto-formatting would be helpful for maintainability.
中文: 宏使用了"clang-format off/on"指令,但没有解释为什么这些宏需要特殊格式化。添加注释说明这些宏使用 GNU 语句表达式(do-while-0 模式)并需要避免自动格式化,这对可维护性有帮助。
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
…r than or equal' condition
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
#10978
你的解决方案是什么 (what is your solution)
重构shell,拆分大函数。使用链表管理历史命令。增加ctrl+z/y功能,可使用宏(FINSH_USING_SNAPSHOT)开启和关闭
请提供验证的bsp和config (provide the config and bsp)
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up