microrl.c 17 KB

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