@@ -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
461490static 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