@@ -1395,6 +1395,135 @@ 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" ,
1412+ "low" , "Pin" , "value" , "def" ,
1413+ "PikaStdDevice" , "setPin" , "enable" , "print" ,
1414+ "sleep_ms" , "read" , "setMode" , "setCallBack" ,
1415+ "setPull" , "as" , "MemChecker" , "max" ,
1416+ "min" , "float" , "int" , "str" ,
1417+ "list" , "dict" , "tuple" , "if" ,
1418+ "else" , "elif" , "for" , "while" ,
1419+ "break" , "continue" , "return" , "try" ,
1420+ "except" , "finally" , "with" , "open" ,
1421+ "write" , "append" , "close" , "True" ,
1422+ "False" , "None" , "self" , "class" ,
1423+ "init" , "len" , "range" , "input" ,
1424+ "output" , "config" , "setup" , "loop" ,
1425+ "GPIO" , "UART" , "I2C" , "SPI" ,
1426+ "ADC" , "PWM" , "digitalRead" , "digitalWrite" ,
1427+ "analogRead" , "analogWrite" , "time" , "datetime" ,
1428+ "random" , "OS" , "sys" , "math" ,
1429+ "json" , "readFile" , "writeFile" , "" };
1430+
1431+ int dictSize = sizeof (dictionary ) / sizeof (dictionary [0 ]);
1432+
1433+ static CompletionList filtered_complete = {0 , NULL };
1434+
1435+ void shCompletePrint (CompletionList * completeList , const char * prefix ) {
1436+ for (int i = 0 ; i < completeList -> count ; i ++ ) {
1437+ printf ("%s " , completeList -> completions [i ]);
1438+ }
1439+ }
1440+
1441+ void getFilteredCompletions (const char * prefix ,
1442+ const char * * dictionary ,
1443+ int dictSize ,
1444+ CompletionList * result ) {
1445+ printf ("\n" );
1446+ if (result -> completions != NULL ) {
1447+ for (int i = 0 ; i < result -> count ; i ++ ) {
1448+ free (result -> completions [i ]);
1449+ }
1450+ free (result -> completions );
1451+ result -> completions = NULL ;
1452+ }
1453+ result -> count = 0 ;
1454+ result -> completions = (char * * )malloc (dictSize * sizeof (char * ));
1455+ if (result -> completions == NULL ) {
1456+ printf ("Memory allocation failed\n" );
1457+ return ;
1458+ }
1459+
1460+ for (int i = 0 ; i < dictSize ; i ++ ) {
1461+ if (strncmp (dictionary [i ], prefix , strlen (prefix )) == 0 ) {
1462+ result -> completions [result -> count ] = strdup (dictionary [i ]);
1463+ if (result -> completions [result -> count ] == NULL ) {
1464+ printf ("Memory allocation failed for completion\n" );
1465+ continue ;
1466+ }
1467+ result -> count ++ ;
1468+ }
1469+ }
1470+
1471+ if (result -> count == 0 ) {
1472+ printf ("Warning: No matches found for '%s'\n" , prefix );
1473+ }
1474+ }
1475+
1476+ /*free CompletionList*/
1477+ void freeCompletionList (CompletionList * list ) {
1478+ for (int i = 0 ; i < list -> count ; ++ i ) {
1479+ free (list -> completions [i ]);
1480+ }
1481+ free (list -> completions );
1482+ list -> completions = NULL ;
1483+ list -> count = 0 ;
1484+ }
1485+
1486+ void handleTabCompletion (ShellConfig * shell , char * prefix ) {
1487+ #if PIKA_TAB_ENABLE
1488+ if (shell -> line_position > 0 ) {
1489+ if (prefix == NULL ) {
1490+ printf ("Memory allocation failed for prefix\n" );
1491+ return ;
1492+ }
1493+
1494+ // printf("\n================[fetch : %s ]=====================\n",
1495+ // prefix);
1496+ getFilteredCompletions (prefix , dictionary , dictSize ,
1497+ & filtered_complete );
1498+
1499+ if (filtered_complete .count == 1 ) {
1500+ char * last_space = strrchr (shell -> lineBuff , ' ' );
1501+ size_t start_pos = 0 ;
1502+
1503+ if (last_space != NULL ) {
1504+ start_pos = last_space - shell -> lineBuff + 1 ;
1505+ }
1506+
1507+ memset (shell -> lineBuff + start_pos , 0 ,
1508+ sizeof (shell -> lineBuff ) - start_pos );
1509+ strncpy (shell -> lineBuff + start_pos ,
1510+ filtered_complete .completions [0 ],
1511+ sizeof (shell -> lineBuff ) - start_pos - 1 );
1512+ shell -> lineBuff [sizeof (shell -> lineBuff ) - 1 ] = '\0' ;
1513+ shell -> line_position = strlen (shell -> lineBuff );
1514+ shell -> line_curpos = shell -> line_position ;
1515+
1516+ printf (">>> %s" , shell -> lineBuff );
1517+ } else {
1518+ shCompletePrint (& filtered_complete , prefix );
1519+ printf ("\n>>> %s" , shell -> lineBuff );
1520+ }
1521+ free (prefix );
1522+ }
1523+ #endif
1524+ freeCompletionList (& filtered_complete );
1525+ }
1526+
13981527pika_bool _filter_msg_hi_pika_handler (FilterItem * msg ,
13991528 PikaObj * self ,
14001529 ShellConfig * shell ) {
@@ -1668,6 +1797,14 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
16681797 ShellConfig * shell ) {
16691798 char * input_line = NULL ;
16701799 enum shellCTRL ctrl = SHELL_CTRL_CONTINUE ;
1800+ static uint64_t tick_start_block_input = 0 ;
1801+ if (tick_start_block_input != 0 ) {
1802+ if (pika_platform_get_tick () - tick_start_block_input < 5000 ) {
1803+ return SHELL_CTRL_CONTINUE ;
1804+ } else {
1805+ tick_start_block_input = 0 ;
1806+ }
1807+ }
16711808 if (inputChar == 0x7F ) {
16721809 inputChar = '\b' ;
16731810 }
@@ -1682,6 +1819,34 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
16821819 ctrl = SHELL_CTRL_CONTINUE ;
16831820 goto __exit ;
16841821 }
1822+ if (inputChar == 0x09 ) {
1823+ #if PIKA_TAB_ENABLE
1824+ if (shell -> line_position > 0 ) {
1825+ // printf("Current cursor position: %zu, Line position: %zu\n",
1826+ // shell->line_curpos, shell->line_position);
1827+ char * shell_content = NULL ;
1828+ char * last_space = strrchr (shell -> lineBuff , ' ' );
1829+
1830+ if (last_space == NULL ) {
1831+ shell_content = strndup (shell -> lineBuff , shell -> line_position );
1832+ } else {
1833+ shell_content = strdup (last_space + 1 );
1834+ }
1835+
1836+ if (shell_content == NULL ) {
1837+ printf ("Memory allocation failed for shell_content\n" );
1838+ // return;
1839+ }
1840+
1841+ handleTabCompletion (shell , shell_content );
1842+ ctrl = SHELL_CTRL_CONTINUE ;
1843+ // __clearBuff(shell);
1844+ goto __exit ;
1845+ }
1846+ #endif
1847+ ctrl = SHELL_CTRL_CONTINUE ;
1848+ goto __exit ;
1849+ }
16851850 if (inputChar == 0x1b ) {
16861851 shell -> stat = PIKA_SHELL_STATE_WAIT_SPEC_KEY ;
16871852 ctrl = SHELL_CTRL_CONTINUE ;
@@ -1762,7 +1927,12 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
17621927 pika_platform_printf (
17631928 "\r\nError: line buff overflow, please use bigger "
17641929 "'PIKA_LINE_BUFF_SIZE'\r\n" );
1765- ctrl = SHELL_CTRL_EXIT ;
1930+ ctrl = SHELL_CTRL_CONTINUE ;
1931+ pika_platform_printf (
1932+ "Input is blocked for 5 seconds to protect the "
1933+ "kernel...\r\n" );
1934+ tick_start_block_input = pika_platform_get_tick ();
1935+ pika_platform_printf (">>> " );
17661936 __clearBuff (shell );
17671937 goto __exit ;
17681938 }
@@ -1981,6 +2151,12 @@ void _do_pikaScriptShell(PikaObj* self, ShellConfig* cfg) {
19812151 while (1 ) {
19822152 inputChar [1 ] = inputChar [0 ];
19832153 inputChar [0 ] = _await_getchar (cfg -> fn_getchar );
2154+ #ifdef __linux
2155+ if (inputChar [0 ] == EOF ) {
2156+ pika_platform_printf ("\r\n" );
2157+ return ;
2158+ }
2159+ #endif
19842160#if !PIKA_NANO_ENABLE
19852161 /* run python script */
19862162 if (inputChar [0 ] == '!' && inputChar [1 ] == '#' ) {
0 commit comments