microrl.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. Author: Samoylov Eugene aka Helius (ghelius@gmail.com)
  3. BUGS and TODO:
  4. -- add echo_off feature
  5. -- rewrite history for use more than 256 byte buffer
  6. */
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10. #include "microrl.h"
  11. #ifdef _USE_LIBC_STDIO
  12. #include <stdio.h>
  13. #endif
  14. //#define DBG(...) fprintf(stderr, "\033[33m");fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\033[0m");
  15. char * prompt_default = _PROMPT_DEFAULT;
  16. #ifdef _USE_HISTORY
  17. #ifdef _HISTORY_DEBUG
  18. //*****************************************************************************
  19. // print buffer content on screen
  20. static void print_hist (ring_history_t * pThis)
  21. {
  22. printf ("\n");
  23. for (int i = 0; i < _RING_HISTORY_LEN; i++) {
  24. if (i == pThis->begin)
  25. printf ("b");
  26. else
  27. printf (" ");
  28. }
  29. printf ("\n");
  30. for (int i = 0; i < _RING_HISTORY_LEN; i++) {
  31. if (isalpha(pThis->ring_buf[i]))
  32. printf ("%c", pThis->ring_buf[i]);
  33. else
  34. printf ("%d", pThis->ring_buf[i]);
  35. }
  36. printf ("\n");
  37. for (int i = 0; i < _RING_HISTORY_LEN; i++) {
  38. if (i == pThis->end)
  39. printf ("e");
  40. else
  41. printf (" ");
  42. }
  43. printf ("\n");
  44. }
  45. #endif
  46. //*****************************************************************************
  47. // remove older message from ring buffer
  48. static void hist_erase_older (ring_history_t * pThis)
  49. {
  50. int new_pos = pThis->begin + pThis->ring_buf [pThis->begin] + 1;
  51. if (new_pos >= _RING_HISTORY_LEN)
  52. new_pos = new_pos - _RING_HISTORY_LEN;
  53. pThis->begin = new_pos;
  54. }
  55. //*****************************************************************************
  56. // check space for new line, remove older while not space
  57. static int hist_is_space_for_new (ring_history_t * pThis, int len)
  58. {
  59. if (pThis->ring_buf [pThis->begin] == 0)
  60. return true;
  61. if (pThis->end >= pThis->begin) {
  62. if (_RING_HISTORY_LEN - pThis->end + pThis->begin - 1 > len)
  63. return true;
  64. } else {
  65. if (pThis->begin - pThis->end - 1> len)
  66. return true;
  67. }
  68. return false;
  69. }
  70. //*****************************************************************************
  71. // put line to ring buffer
  72. static void hist_save_line (ring_history_t * pThis, char * line, int len)
  73. {
  74. if (len > _RING_HISTORY_LEN - 2)
  75. return;
  76. while (!hist_is_space_for_new (pThis, len)) {
  77. hist_erase_older (pThis);
  78. }
  79. // if it's first line
  80. if (pThis->ring_buf [pThis->begin] == 0)
  81. pThis->ring_buf [pThis->begin] = len;
  82. // store line
  83. if (len < _RING_HISTORY_LEN-pThis->end-1)
  84. memcpy (pThis->ring_buf + pThis->end + 1, line, len);
  85. else {
  86. int part_len = _RING_HISTORY_LEN-pThis->end-1;
  87. memcpy (pThis->ring_buf + pThis->end + 1, line, part_len);
  88. memcpy (pThis->ring_buf, line + part_len, len - part_len);
  89. }
  90. pThis->ring_buf [pThis->end] = len;
  91. pThis->end = pThis->end + len + 1;
  92. if (pThis->end >= _RING_HISTORY_LEN)
  93. pThis->end -= _RING_HISTORY_LEN;
  94. pThis->ring_buf [pThis->end] = 0;
  95. pThis->cur = 0;
  96. #ifdef _HISTORY_DEBUG
  97. print_hist (pThis);
  98. #endif
  99. }
  100. //*****************************************************************************
  101. // copy saved line to 'line' and return size of line
  102. static int hist_restore_line (ring_history_t * pThis, char * line, int dir)
  103. {
  104. int cnt = 0;
  105. // count history record
  106. int header = pThis->begin;
  107. while (pThis->ring_buf [header] != 0) {
  108. header += pThis->ring_buf [header] + 1;
  109. if (header >= _RING_HISTORY_LEN)
  110. header -= _RING_HISTORY_LEN;
  111. cnt++;
  112. }
  113. if (dir == _HIST_UP) {
  114. if (cnt >= pThis->cur) {
  115. int header = pThis->begin;
  116. int j = 0;
  117. // found record for 'pThis->cur' index
  118. while ((pThis->ring_buf [header] != 0) && (cnt - j -1 != pThis->cur)) {
  119. header += pThis->ring_buf [header] + 1;
  120. if (header >= _RING_HISTORY_LEN)
  121. header -= _RING_HISTORY_LEN;
  122. j++;
  123. }
  124. if (pThis->ring_buf[header]) {
  125. pThis->cur++;
  126. // obtain saved line
  127. if (pThis->ring_buf [header] + header + 1< _RING_HISTORY_LEN) {
  128. memset (line, 0, _COMMAND_LINE_LEN);
  129. memcpy (line, pThis->ring_buf + header + 1, pThis->ring_buf[header]);
  130. } else {
  131. int part0 = _RING_HISTORY_LEN - header - 1;
  132. memset (line, 0, _COMMAND_LINE_LEN);
  133. memcpy (line, pThis->ring_buf + header + 1, part0);
  134. memcpy (line + part0, pThis->ring_buf, pThis->ring_buf[header] - part0);
  135. }
  136. return pThis->ring_buf[header];
  137. }
  138. }
  139. } else {
  140. if (pThis->cur > 0) {
  141. pThis->cur--;
  142. int header = pThis->begin;
  143. int j = 0;
  144. while ((pThis->ring_buf [header] != 0) && (cnt - j != pThis->cur)) {
  145. header += pThis->ring_buf [header] + 1;
  146. if (header >= _RING_HISTORY_LEN)
  147. header -= _RING_HISTORY_LEN;
  148. j++;
  149. }
  150. if (pThis->ring_buf [header] + header < _RING_HISTORY_LEN) {
  151. memcpy (line, pThis->ring_buf + header + 1, pThis->ring_buf[header]);
  152. } else {
  153. int part0 = _RING_HISTORY_LEN - header - 1;
  154. memcpy (line, pThis->ring_buf + header + 1, part0);
  155. memcpy (line + part0, pThis->ring_buf, pThis->ring_buf[header] - part0);
  156. }
  157. return pThis->ring_buf[header];
  158. } else {
  159. /* empty line */
  160. return 0;
  161. }
  162. }
  163. return -1;
  164. }
  165. #endif
  166. //*****************************************************************************
  167. // split cmdline to tkn array and return nmb of token
  168. static int split (microrl_t * pThis, int limit, char const ** tkn_arr)
  169. {
  170. int i = 0;
  171. int ind = 0;
  172. while (1) {
  173. // go to the first whitespace (zerro for us)
  174. while ((pThis->cmdline [ind] == '\0') && (ind < limit)) {
  175. ind++;
  176. }
  177. if (!(ind < limit)) return i;
  178. tkn_arr[i++] = pThis->cmdline + ind;
  179. if (i >= _COMMAND_TOKEN_NMB) {
  180. return -1;
  181. }
  182. // go to the first NOT whitespace (not zerro for us)
  183. while ((pThis->cmdline [ind] != '\0') && (ind < limit)) {
  184. ind++;
  185. }
  186. if (!(ind < limit)) return i;
  187. }
  188. //return i;
  189. }
  190. //*****************************************************************************
  191. inline static void print_prompt (microrl_t * pThis)
  192. {
  193. pThis->print (pThis->prompt_str);
  194. }
  195. //*****************************************************************************
  196. inline static void terminal_backspace (microrl_t * pThis)
  197. {
  198. pThis->print ("\033[D \033[D");
  199. }
  200. //*****************************************************************************
  201. inline static void terminal_newline (microrl_t * pThis)
  202. {
  203. pThis->print (ENDL);
  204. }
  205. #ifndef _USE_LIBC_STDIO
  206. //*****************************************************************************
  207. // convert 16 bit value to string
  208. // 0 value not supported!!! just make empty string
  209. // Returns pointer to a buffer tail
  210. static char *u16bit_to_str (unsigned int nmb, char * buf)
  211. {
  212. char tmp_str [6] = {0,};
  213. int i = 0, j;
  214. if (nmb <= 0xFFFF) {
  215. while (nmb > 0) {
  216. tmp_str[i++] = (nmb % 10) + '0';
  217. nmb /=10;
  218. }
  219. for (j = 0; j < i; ++j)
  220. *(buf++) = tmp_str [i-j-1];
  221. }
  222. *buf = '\0';
  223. return buf;
  224. }
  225. #endif
  226. //*****************************************************************************
  227. // set cursor at position from begin cmdline (after prompt) + offset
  228. static void terminal_move_cursor (microrl_t * pThis, int offset)
  229. {
  230. char str[16];
  231. #ifdef _USE_LIBC_STDIO
  232. if (offset > 0) {
  233. snprintf (str, 16, "\033[%dC", offset);
  234. } else if (offset < 0) {
  235. snprintf (str, 16, "\033[%dD", -(offset));
  236. }
  237. #else
  238. char *endstr;
  239. strcpy (str, "\033[");
  240. if (offset > 0) {
  241. endstr = u16bit_to_str (offset, str+2);
  242. strcpy (endstr, "C");
  243. } else if (offset < 0) {
  244. endstr = u16bit_to_str (-(offset), str+2);
  245. strcpy (endstr, "D");
  246. } else
  247. return;
  248. #endif
  249. pThis->print (str);
  250. }
  251. //*****************************************************************************
  252. static void terminal_reset_cursor (microrl_t * pThis)
  253. {
  254. char str[16];
  255. #ifdef _USE_LIBC_STDIO
  256. snprintf (str, 16, "\033[%dD\033[%dC", \
  257. _COMMAND_LINE_LEN + _PROMPT_LEN + 2, _PROMPT_LEN);
  258. #else
  259. char *endstr;
  260. strcpy (str, "\033[");
  261. endstr = u16bit_to_str ( _COMMAND_LINE_LEN + _PROMPT_LEN + 2,str+2);
  262. strcpy (endstr, "D\033["); endstr += 3;
  263. endstr = u16bit_to_str (_PROMPT_LEN, endstr);
  264. strcpy (endstr, "C");
  265. #endif
  266. pThis->print (str);
  267. }
  268. //*****************************************************************************
  269. // print cmdline to screen, replace '\0' to wihitespace
  270. static void terminal_print_line (microrl_t * pThis, int pos, int cursor)
  271. {
  272. pThis->print ("\033[K"); // delete all from cursor to end
  273. char nch [] = {0,0};
  274. int i;
  275. for (i = pos; i < pThis->cmdlen; i++) {
  276. nch [0] = pThis->cmdline [i];
  277. if (nch[0] == '\0')
  278. nch[0] = ' ';
  279. pThis->print (nch);
  280. }
  281. terminal_reset_cursor (pThis);
  282. terminal_move_cursor (pThis, cursor);
  283. }
  284. //*****************************************************************************
  285. void microrl_init (microrl_t * pThis, void (*print) (const char *))
  286. {
  287. memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
  288. #ifdef _USE_HISTORY
  289. memset(pThis->ring_hist.ring_buf, 0, _RING_HISTORY_LEN);
  290. pThis->ring_hist.begin = 0;
  291. pThis->ring_hist.end = 0;
  292. pThis->ring_hist.cur = 0;
  293. #endif
  294. pThis->cmdlen =0;
  295. pThis->cursor = 0;
  296. pThis->execute = NULL;
  297. pThis->get_completion = NULL;
  298. #ifdef _USE_CTLR_C
  299. pThis->sigint = NULL;
  300. #endif
  301. pThis->prompt_str = prompt_default;
  302. pThis->print = print;
  303. #ifdef _ENABLE_INIT_PROMPT
  304. print_prompt (pThis);
  305. #endif
  306. }
  307. //*****************************************************************************
  308. void microrl_set_complete_callback (microrl_t * pThis, char ** (*get_completion)(int, const char* const*))
  309. {
  310. pThis->get_completion = get_completion;
  311. }
  312. //*****************************************************************************
  313. void microrl_set_execute_callback (microrl_t * pThis, int (*execute)(int, const char* const*))
  314. {
  315. pThis->execute = execute;
  316. }
  317. #ifdef _USE_CTLR_C
  318. //*****************************************************************************
  319. void microrl_set_sigint_callback (microrl_t * pThis, void (*sigintf)(void))
  320. {
  321. pThis->sigint = sigintf;
  322. }
  323. #endif
  324. #ifdef _USE_ESC_SEQ
  325. static void hist_search (microrl_t * pThis, int dir)
  326. {
  327. int len = hist_restore_line (&pThis->ring_hist, pThis->cmdline, dir);
  328. if (len >= 0) {
  329. pThis->cursor = pThis->cmdlen = len;
  330. terminal_reset_cursor (pThis);
  331. terminal_print_line (pThis, 0, pThis->cursor);
  332. }
  333. }
  334. //*****************************************************************************
  335. // handling escape sequences
  336. static int escape_process (microrl_t * pThis, char ch)
  337. {
  338. if (ch == '[') {
  339. pThis->escape_seq = _ESC_BRACKET;
  340. return 0;
  341. } else if (pThis->escape_seq == _ESC_BRACKET) {
  342. if (ch == 'A') {
  343. #ifdef _USE_HISTORY
  344. hist_search (pThis, _HIST_UP);
  345. #endif
  346. return 1;
  347. } else if (ch == 'B') {
  348. #ifdef _USE_HISTORY
  349. hist_search (pThis, _HIST_DOWN);
  350. #endif
  351. return 1;
  352. } else if (ch == 'C') {
  353. if (pThis->cursor < pThis->cmdlen) {
  354. terminal_move_cursor (pThis, 1);
  355. pThis->cursor++;
  356. }
  357. return 1;
  358. } else if (ch == 'D') {
  359. if (pThis->cursor > 0) {
  360. terminal_move_cursor (pThis, -1);
  361. pThis->cursor--;
  362. }
  363. return 1;
  364. } else if (ch == '7') {
  365. pThis->escape_seq = _ESC_HOME;
  366. return 0;
  367. } else if (ch == '8') {
  368. pThis->escape_seq = _ESC_END;
  369. return 0;
  370. }
  371. } else if (ch == '~') {
  372. if (pThis->escape_seq == _ESC_HOME) {
  373. terminal_reset_cursor (pThis);
  374. pThis->cursor = 0;
  375. return 1;
  376. } else if (pThis->escape_seq == _ESC_END) {
  377. terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
  378. pThis->cursor = pThis->cmdlen;
  379. return 1;
  380. }
  381. }
  382. /* unknown escape sequence, stop */
  383. return 1;
  384. }
  385. #endif
  386. //*****************************************************************************
  387. // insert len char of text at cursor position
  388. static int microrl_insert_text (microrl_t * pThis, char * text, int len)
  389. {
  390. int i;
  391. if (pThis->cmdlen + len < _COMMAND_LINE_LEN) {
  392. memmove (pThis->cmdline + pThis->cursor + len,
  393. pThis->cmdline + pThis->cursor,
  394. pThis->cmdlen - pThis->cursor);
  395. for (i = 0; i < len; i++) {
  396. pThis->cmdline [pThis->cursor + i] = text [i];
  397. if (pThis->cmdline [pThis->cursor + i] == ' ') {
  398. pThis->cmdline [pThis->cursor + i] = 0;
  399. }
  400. }
  401. pThis->cursor += len;
  402. pThis->cmdlen += len;
  403. pThis->cmdline [pThis->cmdlen] = '\0';
  404. return true;
  405. }
  406. return false;
  407. }
  408. //*****************************************************************************
  409. // remove one char at cursor
  410. static void microrl_backspace (microrl_t * pThis)
  411. {
  412. if (pThis->cursor > 0) {
  413. terminal_backspace (pThis);
  414. memmove (pThis->cmdline + pThis->cursor-1,
  415. pThis->cmdline + pThis->cursor,
  416. pThis->cmdlen-pThis->cursor+1);
  417. pThis->cursor--;
  418. pThis->cmdline [pThis->cmdlen] = '\0';
  419. pThis->cmdlen--;
  420. }
  421. }
  422. #ifdef _USE_COMPLETE
  423. //*****************************************************************************
  424. static int common_len (char ** arr)
  425. {
  426. int i;
  427. int j;
  428. char *shortest = arr[0];
  429. int shortlen = strlen(shortest);
  430. for (i = 0; arr[i] != NULL; ++i)
  431. if (strlen(arr[i]) < shortlen) {
  432. shortest = arr[i];
  433. shortlen = strlen(shortest);
  434. }
  435. for (i = 0; i < shortlen; ++i)
  436. for (j = 0; arr[j] != 0; ++j)
  437. if (shortest[i] != arr[j][i])
  438. return i;
  439. return i;
  440. }
  441. //*****************************************************************************
  442. static void microrl_get_complite (microrl_t * pThis)
  443. {
  444. char const * tkn_arr[_COMMAND_TOKEN_NMB];
  445. char ** compl_token;
  446. if (pThis->get_completion == NULL) // callback was not set
  447. return;
  448. int status = split (pThis, pThis->cursor, tkn_arr);
  449. if (pThis->cmdline[pThis->cursor-1] == '\0')
  450. tkn_arr[status++] = "";
  451. compl_token = pThis->get_completion (status, tkn_arr);
  452. if (compl_token[0] != NULL) {
  453. int i = 0;
  454. int len;
  455. if (compl_token[1] == NULL) {
  456. len = strlen (compl_token[0]);
  457. } else {
  458. len = common_len (compl_token);
  459. terminal_newline (pThis);
  460. while (compl_token [i] != NULL) {
  461. pThis->print (compl_token[i]);
  462. pThis->print (" ");
  463. i++;
  464. }
  465. terminal_newline (pThis);
  466. print_prompt (pThis);
  467. }
  468. if (len) {
  469. microrl_insert_text (pThis, compl_token[0] + strlen(tkn_arr[status-1]),
  470. len - strlen(tkn_arr[status-1]));
  471. if (compl_token[1] == NULL)
  472. microrl_insert_text (pThis, " ", 1);
  473. }
  474. terminal_reset_cursor (pThis);
  475. terminal_print_line (pThis, 0, pThis->cursor);
  476. }
  477. }
  478. #endif
  479. //*****************************************************************************
  480. void new_line_handler(microrl_t * pThis){
  481. char const * tkn_arr [_COMMAND_TOKEN_NMB];
  482. int status;
  483. terminal_newline (pThis);
  484. #ifdef _USE_HISTORY
  485. if (pThis->cmdlen > 0)
  486. hist_save_line (&pThis->ring_hist, pThis->cmdline, pThis->cmdlen);
  487. #endif
  488. status = split (pThis, pThis->cmdlen, tkn_arr);
  489. if (status == -1){
  490. // pThis->print ("ERROR: Max token amount exseed\n");
  491. pThis->print ("ERROR:too many tokens");
  492. pThis->print (ENDL);
  493. }
  494. if ((status > 0) && (pThis->execute != NULL))
  495. pThis->execute (status, tkn_arr);
  496. print_prompt (pThis);
  497. pThis->cmdlen = 0;
  498. pThis->cursor = 0;
  499. memset(pThis->cmdline, 0, _COMMAND_LINE_LEN);
  500. #ifdef _USE_HISTORY
  501. pThis->ring_hist.cur = 0;
  502. #endif
  503. }
  504. //*****************************************************************************
  505. void microrl_insert_char (microrl_t * pThis, int ch)
  506. {
  507. #ifdef _USE_ESC_SEQ
  508. if (pThis->escape) {
  509. if (escape_process(pThis, ch))
  510. pThis->escape = 0;
  511. } else {
  512. #endif
  513. switch (ch) {
  514. //-----------------------------------------------------
  515. #ifdef _ENDL_CR
  516. case KEY_CR:
  517. new_line_handler(pThis);
  518. break;
  519. case KEY_LF:
  520. break;
  521. #elif defined(_ENDL_CRLF)
  522. case KEY_CR:
  523. pThis->tmpch = KEY_CR;
  524. break;
  525. case KEY_LF:
  526. if (pThis->tmpch == KEY_CR)
  527. new_line_handler(pThis);
  528. break;
  529. #elif defined(_ENDL_LFCR)
  530. case KEY_LF:
  531. pThis->tmpch = KEY_LF;
  532. break;
  533. case KEY_CR:
  534. if (pThis->tmpch == KEY_LF)
  535. new_line_handler(pThis);
  536. break;
  537. #else
  538. case KEY_CR:
  539. break;
  540. case KEY_LF:
  541. new_line_handler(pThis);
  542. break;
  543. #endif
  544. //-----------------------------------------------------
  545. #ifdef _USE_COMPLETE
  546. case KEY_HT:
  547. microrl_get_complite (pThis);
  548. break;
  549. #endif
  550. //-----------------------------------------------------
  551. case KEY_ESC:
  552. #ifdef _USE_ESC_SEQ
  553. pThis->escape = 1;
  554. #endif
  555. break;
  556. //-----------------------------------------------------
  557. case KEY_NAK: // ^U
  558. while (pThis->cursor > 0) {
  559. microrl_backspace (pThis);
  560. }
  561. terminal_print_line (pThis, 0, pThis->cursor);
  562. break;
  563. //-----------------------------------------------------
  564. case KEY_VT: // ^K
  565. pThis->print ("\033[K");
  566. pThis->cmdlen = pThis->cursor;
  567. break;
  568. //-----------------------------------------------------
  569. case KEY_ENQ: // ^E
  570. terminal_move_cursor (pThis, pThis->cmdlen-pThis->cursor);
  571. pThis->cursor = pThis->cmdlen;
  572. break;
  573. //-----------------------------------------------------
  574. case KEY_SOH: // ^A
  575. terminal_reset_cursor (pThis);
  576. pThis->cursor = 0;
  577. break;
  578. //-----------------------------------------------------
  579. case KEY_ACK: // ^F
  580. if (pThis->cursor < pThis->cmdlen) {
  581. terminal_move_cursor (pThis, 1);
  582. pThis->cursor++;
  583. }
  584. break;
  585. //-----------------------------------------------------
  586. case KEY_STX: // ^B
  587. if (pThis->cursor) {
  588. terminal_move_cursor (pThis, -1);
  589. pThis->cursor--;
  590. }
  591. break;
  592. //-----------------------------------------------------
  593. case KEY_DLE: //^P
  594. #ifdef _USE_HISTORY
  595. hist_search (pThis, _HIST_UP);
  596. #endif
  597. break;
  598. //-----------------------------------------------------
  599. case KEY_SO: //^N
  600. #ifdef _USE_HISTORY
  601. hist_search (pThis, _HIST_DOWN);
  602. #endif
  603. break;
  604. //-----------------------------------------------------
  605. case KEY_DEL: // Backspace
  606. case KEY_BS: // ^U
  607. microrl_backspace (pThis);
  608. terminal_print_line (pThis, pThis->cursor, pThis->cursor);
  609. break;
  610. #ifdef _USE_CTLR_C
  611. case KEY_ETX:
  612. if (pThis->sigint != NULL)
  613. pThis->sigint();
  614. break;
  615. #endif
  616. //-----------------------------------------------------
  617. default:
  618. if (((ch == ' ') && (pThis->cmdlen == 0)) || IS_CONTROL_CHAR(ch))
  619. break;
  620. if (microrl_insert_text (pThis, (char*)&ch, 1))
  621. terminal_print_line (pThis, pThis->cursor-1, pThis->cursor);
  622. break;
  623. }
  624. #ifdef _USE_ESC_SEQ
  625. }
  626. #endif
  627. }