@@ -1395,6 +1395,121 @@ typedef enum {
13951395 __FILTER_SUCCESS_DROP_ALL_PEEKED
13961396} FilterReturn ;
13971397
1398+ typedef struct {
1399+ int count ;
1400+ char * * completions ;
1401+ } CompletionList ;
1402+
1403+ typedef struct {
1404+ char lineBuff [PIKA_LINE_BUFF_SIZE ];
1405+ size_t line_position ;
1406+ size_t line_curpos ;
1407+ char prefix [32 ];
1408+ } Shell ;
1409+
1410+ const char * dictionary [] = {
1411+ "import" , "PikaStdLib" , "from" , "high" , "low" , "Pin" , "value" , "def" ,
1412+ "PikaStdDevice" , "setPin" , "enable" , "print" , "sleep_ms" , "read" ,
1413+ "setMode" , "setCallBack" , "setPull" , "as" , "MemChecker" , "max" , "min" ,
1414+ "float" , "int" , "str" , "list" , "dict" , "tuple" , "if" , "else" ,
1415+ "elif" , "for" , "while" , "break" , "continue" , "return" , "try" , "except" ,
1416+ "finally" , "with" , "open" , "write" , "append" , "close" , "True" , "False" ,
1417+ "None" , "self" , "class" , "init" , "len" , "range" , "input" , "output" ,
1418+ "config" , "setup" , "loop" , "GPIO" , "UART" , "I2C" , "SPI" , "ADC" , "PWM" ,
1419+ "digitalRead" , "digitalWrite" , "analogRead" , "analogWrite" , "time" , "datetime" ,
1420+ "random" , "OS" , "sys" , "math" , "json" , "readFile" , "writeFile" ,
1421+ ""
1422+ };
1423+
1424+ int dictSize = sizeof (dictionary ) / sizeof (dictionary [0 ]);
1425+
1426+ static CompletionList filtered_complete = {0 , NULL };
1427+
1428+ void shCompletePrint (CompletionList * completeList , const char * prefix ) {
1429+ for (int i = 0 ; i < completeList -> count ; i ++ ) {
1430+ printf ("%s " , completeList -> completions [i ]);
1431+ }
1432+ }
1433+
1434+ void getFilteredCompletions (const char * prefix , const char * * dictionary , int dictSize , CompletionList * result ) {
1435+ printf ("\n" );
1436+ if (result -> completions != NULL ) {
1437+ for (int i = 0 ; i < result -> count ; i ++ ) {
1438+ free (result -> completions [i ]);
1439+ }
1440+ free (result -> completions );
1441+ result -> completions = NULL ;
1442+ }
1443+ result -> count = 0 ;
1444+ result -> completions = (char * * )malloc (dictSize * sizeof (char * ));
1445+ if (result -> completions == NULL ) {
1446+ printf ("Memory allocation failed\n" );
1447+ return ;
1448+ }
1449+
1450+ for (int i = 0 ; i < dictSize ; i ++ ) {
1451+ if (strncmp (dictionary [i ], prefix , strlen (prefix )) == 0 ) {
1452+ result -> completions [result -> count ] = strdup (dictionary [i ]);
1453+ if (result -> completions [result -> count ] == NULL ) {
1454+ printf ("Memory allocation failed for completion\n" );
1455+ continue ;
1456+ }
1457+ result -> count ++ ;
1458+ }
1459+ }
1460+
1461+ if (result -> count == 0 ) {
1462+ printf ("Warning: No matches found for '%s'\n" , prefix );
1463+ }
1464+ }
1465+
1466+ /*free CompletionList*/
1467+ void freeCompletionList (CompletionList * list ) {
1468+ for (int i = 0 ; i < list -> count ; ++ i ) {
1469+ free (list -> completions [i ]);
1470+ }
1471+ free (list -> completions );
1472+ list -> completions = NULL ;
1473+ list -> count = 0 ;
1474+ }
1475+
1476+ void handleTabCompletion (ShellConfig * shell , char * prefix ) {
1477+ #if PIKA_TAB_ENABLE
1478+ if (shell -> line_position > 0 ) {
1479+ if (prefix == NULL ) {
1480+ printf ("Memory allocation failed for prefix\n" );
1481+ return ;
1482+ }
1483+
1484+ // printf("\n================[fetch : %s ]=====================\n", prefix);
1485+ getFilteredCompletions (prefix , dictionary , dictSize , & filtered_complete );
1486+
1487+ if (filtered_complete .count == 1 ) {
1488+ char * last_space = strrchr (shell -> lineBuff , ' ' );
1489+ size_t start_pos = 0 ;
1490+
1491+ if (last_space != NULL ) {
1492+ /*保留空格以前的内容*/
1493+ start_pos = last_space - shell -> lineBuff + 1 ;
1494+ }
1495+
1496+ memset (shell -> lineBuff + start_pos , 0 , sizeof (shell -> lineBuff ) - start_pos );
1497+ strncpy (shell -> lineBuff + start_pos , filtered_complete .completions [0 ], sizeof (shell -> lineBuff ) - start_pos - 1 );
1498+ shell -> lineBuff [sizeof (shell -> lineBuff ) - 1 ] = '\0' ;
1499+ shell -> line_position = strlen (shell -> lineBuff );
1500+ shell -> line_curpos = shell -> line_position ;
1501+
1502+ printf (">>> %s" , shell -> lineBuff );
1503+ } else {
1504+ shCompletePrint (& filtered_complete , prefix );
1505+ printf ("\n>>> %s" , shell -> lineBuff );
1506+ }
1507+ free (prefix );
1508+ }
1509+ #endif
1510+ freeCompletionList (& filtered_complete );
1511+ }
1512+
13981513pika_bool _filter_msg_hi_pika_handler (FilterItem * msg ,
13991514 PikaObj * self ,
14001515 ShellConfig * shell ) {
@@ -1668,6 +1783,14 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
16681783 ShellConfig * shell ) {
16691784 char * input_line = NULL ;
16701785 enum shellCTRL ctrl = SHELL_CTRL_CONTINUE ;
1786+ static uint64_t tick_start_block_input = 0 ;
1787+ if (tick_start_block_input != 0 ) {
1788+ if (pika_platform_get_tick () - tick_start_block_input < 5000 ) {
1789+ return SHELL_CTRL_CONTINUE ;
1790+ } else {
1791+ tick_start_block_input = 0 ;
1792+ }
1793+ }
16711794 if (inputChar == 0x7F ) {
16721795 inputChar = '\b' ;
16731796 }
@@ -1682,6 +1805,33 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
16821805 ctrl = SHELL_CTRL_CONTINUE ;
16831806 goto __exit ;
16841807 }
1808+ if (inputChar == 0x09 ) {
1809+ #if PIKA_TAB_ENABLE
1810+ if (shell -> line_position > 0 ) {
1811+ // printf("Current cursor position: %zu, Line position: %zu\n", shell->line_curpos, shell->line_position);
1812+ char * shell_content = NULL ;
1813+ char * last_space = strrchr (shell -> lineBuff , ' ' );
1814+
1815+ if (last_space == NULL ) {
1816+ shell_content = strndup (shell -> lineBuff , shell -> line_position );
1817+ } else {
1818+ shell_content = strdup (last_space + 1 );
1819+ }
1820+
1821+ if (shell_content == NULL ) {
1822+ printf ("Memory allocation failed for shell_content\n" );
1823+ // return;
1824+ }
1825+
1826+ handleTabCompletion (shell , shell_content );
1827+ ctrl = SHELL_CTRL_CONTINUE ;
1828+ // __clearBuff(shell);
1829+ goto __exit ;
1830+ }
1831+ #endif
1832+ ctrl = SHELL_CTRL_CONTINUE ;
1833+ goto __exit ;
1834+ }
16851835 if (inputChar == 0x1b ) {
16861836 shell -> stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY ;
16871837 ctrl = SHELL_CTRL_CONTINUE ;
@@ -1762,7 +1912,12 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
17621912 pika_platform_printf (
17631913 "\r\nError: line buff overflow, please use bigger "
17641914 "'PIKA_LINE_BUFF_SIZE'\r\n" );
1765- ctrl = SHELL_CTRL_EXIT ;
1915+ ctrl = SHELL_CTRL_CONTINUE ;
1916+ pika_platform_printf (
1917+ "Input is blocked for 5 seconds to protect the "
1918+ "kernel...\r\n" );
1919+ tick_start_block_input = pika_platform_get_tick ();
1920+ pika_platform_printf (">>> " );
17661921 __clearBuff (shell );
17671922 goto __exit ;
17681923 }
@@ -1981,6 +2136,12 @@ void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg) {
19812136 while (1 ) {
19822137 inputChar [1 ] = inputChar [0 ];
19832138 inputChar [0 ] = _await_getchar (cfg -> fn_getchar );
2139+ #ifdef __linux
2140+ if (inputChar [0 ] == EOF ) {
2141+ pika_platform_printf ("\r\n" );
2142+ return ;
2143+ }
2144+ #endif
19842145#if !PIKA_NANO_ENABLE
19852146 /* run python script */
19862147 if (inputChar [0 ] == '!' && inputChar [1 ] == '#' ) {
0 commit comments