/* return true if command handled */ void readline_handle_byte(int ch) { switch(term_esc_state) { case IS_NORM: switch(ch) { case 1: term_bol(); break; case 4: term_delete_char(); break; case 5: term_eol(); break; case 9: term_completion(); break; case 10: case 13: term_cmd_buf[term_cmd_buf_size] = '\0'; if (!term_is_password) term_hist_add(term_cmd_buf); term_printf("\n"); term_cmd_buf_index = 0; term_cmd_buf_size = 0; term_last_cmd_buf_index = 0; term_last_cmd_buf_size = 0; /* NOTE: readline_start can be called here */ term_readline_func(term_readline_opaque, term_cmd_buf); break; case 23: /* ^W */ term_backword(); break; case 27: term_esc_state = IS_ESC; break; case 127: case 8: term_backspace(); break; case 155: term_esc_state = IS_CSI; break; default: if (ch >= 32) { term_insert_char(ch); } break; } break; case IS_ESC: if (ch == '[') { term_esc_state = IS_CSI; term_esc_param = 0; } else { term_esc_state = IS_NORM; } break; case IS_CSI: switch(ch) { case 'A': case 'F': term_up_char(); break; case 'B': case 'E': term_down_char(); break; case 'D': term_backward_char(); break; case 'C': term_forward_char(); break; case '0' ... '9': term_esc_param = term_esc_param * 10 + (ch - '0'); goto the_end; case '~': switch(term_esc_param) { case 1: term_bol(); break; case 3: term_delete_char(); break; case 4: term_eol(); break; } break; default: break; } term_esc_state = IS_NORM; the_end: break; } term_update(); }
/* ----------------------------------------------------------------------- */ int term_read(int fd, char *buf, unsigned int len) { char c; int ret; static unsigned long remain; if(remain) { check_remain: if(len > remain) len = remain; byte_copy(buf, len, &term_cmdline.s[term_cmdline.len - remain]); remain -= len; if(!remain) { tcsetattr(fd, TCSANOW, &term_tcattr); stralloc_zero(&term_cmdline); } return len; } /* tcsetattr(fd, TCSANOW, &term_tcattr);*/ term_attr(term_input.fd, 1); prompt_show(); while((ret = buffer_getc(&term_input, &c)) > 0) { switch(c) { /* control-c discards the current line */ case 3: stralloc_zero(&term_cmdline); /* newline */ case '\n': term_newline(); remain = term_cmdline.len; goto check_remain; /* control-a is HOME */ case 1: term_home(); break; /* control-e is END */ case 5: term_end(); break; /* control-d is EOF */ case 4: if(!term_cmdline.len) { buffer_puts(term_output, "EOF"); buffer_putnlflush(term_output); ret = 0; goto fail; } break; /* do the ANSI codes */ case '\033': term_ansi(); break; /* backspace */ case 127: case '\b': term_backspace(); break; /* printable chars */ case '\t': c = ' '; default: if(term_insert) term_insertc(c); else term_overwritec(c); break; } } fail: return ret; }