void J_Text_Box::standard_text_box_input_parser(int i_key, int , int i_action, int ){ if((J_PRESS != i_action) && (J_REPEAT != i_action)){ return; } if(read_only_status()){ return; } switch(i_key){ case J_KEY_BACKSPACE: backspace(); break; case J_KEY_TAB: insert_char('\t'); break; case J_KEY_ENTER: insert_char('\n'); break; case J_KEY_LEFT: move_cursor(-1); break; case J_KEY_RIGHT: move_cursor(1); break; case J_KEY_DELETE: delete_char(); break; default: ; } }
static el_status_t emacs(int c) { el_status_t s; el_keymap_t *kp; /* Save point before interpreting input character 'c'. */ old_point = rl_point; if (rl_meta_chars && ISMETA(c)) { tty_push(UNMETA(c)); return meta(); } for (kp = Map; kp->Function; kp++) { if (kp->Key == c) break; } if (kp->Function) { s = kp->Function(); if (s == CSdispatch) /* If Function is inhibited. */ s = insert_char(c); } else { s = insert_char(c); } if (!el_pushed) { /* No pushback means no repeat count; hacky, but true. */ Repeat = NO_ARG; } return s; }
/** * Handle input on the line editor. * * @param editor Line editor state. * @param key Key that was pressed. */ void line_editor_input(line_editor_t *editor, uint16_t key) { switch (key) { case CONSOLE_KEY_LEFT: if (editor->offset) { console_putc(editor->console, '\b'); editor->offset--; } break; case CONSOLE_KEY_RIGHT: if (editor->offset != editor->len) { console_putc(editor->console, editor->buf[editor->offset]); editor->offset++; } break; case CONSOLE_KEY_HOME: while (editor->offset) { console_putc(editor->console, '\b'); editor->offset--; } break; case CONSOLE_KEY_END: while (editor->offset < editor->len) { console_putc(editor->console, editor->buf[editor->offset]); editor->offset++; } break; case '\b': erase_char(editor, false); break; case 0x7f: erase_char(editor, true); break; case '\n': /* The shell code sends \n to place it at the end of the buffer. */ editor->offset = editor->len; insert_char(editor, key); break; default: if (isprint(key)) insert_char(editor, key); break; } }
void ttext_::signal_handler_sdl_text_input(const event::tevent event , bool& handled , const char* text) { // for windows, ascii char will send WM_KEYDOWN and WM_CHAR, // WM_KEYDOWN result to call signal_handler_sdl_key_down, // WM_CHAR result to call signal_handler_sdl_text_input, // so ascii will generate two input. const std::string str = text; bool inserted = false; utils::utf8_iterator ch(str); for (utils::utf8_iterator end = utils::utf8_iterator::end(str); ch != end; ++ch) { if (*ch <= 0x7f) { // ASCII char, don't insert. continue; } insert_char(*ch); fire(event::NOTIFY_MODIFIED, *this, NULL); inserted = true; } if (inserted && text_changed_callback_) { text_changed_callback_(this, this->text()); } handled = true; }
static void input_move_left(const bool do_refresh) { if (pos > 0) { const int x_delta = get_char_width(&input_buffer[pos = prev_pos(input_buffer, pos, encoding)], encoding); assert(pos >= 0); if (x == start_x) { offset = pos; if (char_ins_del_ok) { int i, j; for(i = start_x, j = offset; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j < len) { move_cursor(ne_lines - 1, i); delete_chars(get_char_width(&input_buffer[j], encoding)); } move_cursor(ne_lines - 1, start_x); insert_char(get_char(&input_buffer[pos], encoding), 0, encoding); move_cursor(ne_lines - 1, start_x); } else if (do_refresh) input_refresh(); } else x -= x_delta; } }
INLINE void csi_at(ldat nr) { if (nr > (ldat)SizeX - X) nr = (ldat)SizeX - X; else if (!nr) nr = 1; insert_char(nr); }
void insert(buffer_t *buf, int ch) { /* Skriv in tecknet i strukturen ... mycket jox... */ if (13 == (char)ch) { insert_char(buf, (int)10); buf->scr.y++; buf->scr.x = 0; } else { if (isprint(ch)) { insert_char(buf, ch); buf->scr.x++; } else { // beep(); /* Finns bara i curses!! */ } } }
void get_raw_input(t_raw *raw, t_hist *hist, int *enter, int *move) { int err; while (!*enter) { *move = 0; raw->rd = raw_alloc(sizeof(char) * 10); raw->line->oldcursor = raw->line->cursor; if (read(0, raw->rd, 10) < 0) continue ; if (raw->rd[0] > 31 && raw->rd[0] < 127) { err = insert_char(raw, raw->rd[0]); raw->complete = 0; raw->beg = NULL; } else err = get_std_escape(raw, raw->rd, enter, move); (err != SUCCESS) ? (input_error(err)) : (0); if (err == ERROR && raw->line->input->buffer[0] == 0) return ; redraw(raw, *move, *enter); free(raw->rd); } free_hist(raw->history); }
void ttext_::handle_key_default( bool& handled, SDLKey /*key*/, SDLMod /*modifier*/, Uint16 unicode) { DBG_GUI_E << LOG_SCOPE_HEADER << '\n'; if(unicode >= 32 && unicode != 127) { handled = true; insert_char(unicode); } }
void insert_string(char *c, t_print *print) { int i; i = 0; while (c[i] != '\0') { insert_char(c[i], print); i++; } }
const struct dfont_rect * dfont_insert(struct dfont *df, int c, int font, int width, int height) { if (width > df->width) return NULL; assert(dfont_lookup(df,c,font) == NULL); for (;;) { struct font_line *line = find_line(df, width, height); if (line == NULL) break; struct hash_rect * hr = find_space(df, line, width); if (hr) { return insert_char(df,c,font,hr); } } struct hash_rect * hr = release_space(df, width, height); if (hr) { return insert_char(df,c,font,hr); } return NULL; }
/** Handle key without modifier. */ static void key_handle_unmod(kbd_event_t const *ev) { switch (ev->key) { case KC_ENTER: selection_delete(); insert_char('\n'); caret_update(); break; case KC_LEFT: case KC_RIGHT: case KC_UP: case KC_DOWN: case KC_HOME: case KC_END: case KC_PAGE_UP: case KC_PAGE_DOWN: key_handle_movement(ev->key, false); break; case KC_BACKSPACE: if (selection_active()) selection_delete(); else delete_char_before(); caret_update(); break; case KC_DELETE: if (selection_active()) selection_delete(); else delete_char_after(); caret_update(); break; default: if (ev->c >= 32 || ev->c == '\t') { selection_delete(); insert_char(ev->c); caret_update(); } break; } }
int insert_tab(void) { if (warn_if_readonly_buffer()) return FALSE; if (!lookup_bool_variable("expand-tabs")) insert_char('\t'); else insert_expanded_tab(); return TRUE; }
void ttext_::handle_key_default(bool& handled, SDL_Keycode /*key*/, SDL_Keymod /*modifier*/, const utf8::string& unicode) { DBG_GUI_E << LOG_SCOPE_HEADER << '\n'; if(unicode.size() > 1 || unicode[0] != 0) { handled = true; insert_char(unicode); fire(event::NOTIFY_MODIFIED, *this, nullptr); } }
static bool insert_tab (void) { if (warn_if_readonly_buffer ()) return false; if (get_variable_bool ("indent-tabs-mode")) insert_char ('\t'); else insert_expanded_tab (); return true; }
/* * read text from file into editor buffer */ static void read_file(const char *filename) { register int fd; unsigned char ch; vedit_init(); if ((fd = open(filename, O_RDONLY)) < 0) { if ((fd = open(filename, O_WRONLY | O_CREAT, 0644)) > 0) { close(fd); return; } indigestion(4); abort_bbs(0); } while (read(fd, &ch, 1) > 0) { if (ch == '\t') { do { insert_char(' '); } while (currpnt & 0x7); } #if defined(BIT8) else if (isprint2(ch)) #else else if (isprint(ch)) #endif insert_char(ch); else if (ch == '\n') split(currline, currpnt); } close(fd); }
void replaceword( unsigned int *p_xCursorPos, unsigned int *y_CursorPos ) { int i; for ( i = strlen( source ); i != 0; i-- ) { backspace( p_xCursorPos ); } while ( replace[i] != '\0' ) { insert_char( replace[i], p_xCursorPos, y_CursorPos ); i++; } refreshline( 0, *y_CursorPos ); }
static void insert_expanded_tab(void) { int col = 0, t = cur_bp->tab_width; char *sp = cur_wp->pointp->text, *p = sp; while (p < sp + cur_wp->pointo) { if (*p == '\t') col |= t - 1; ++col, ++p; } for (col = t - col % t; col > 0; --col) insert_char(' '); }
/** * Inserts the characters (string) 'chars' at the cursor position 'pos'. * * Returns 0 if no chars were inserted or non-zero otherwise. */ static int insert_chars(struct current *current, int pos, const char *chars) { int inserted = 0; while (*chars) { int ch; int n = utf8_tounicode(chars, &ch); if (insert_char(current, pos, ch) == 0) { break; } inserted++; pos++; chars += n; } return inserted; }
int select_font( int *page, char *status ) { static int ch = 0; char tmp; int dum; extern int cur_char; unsigned maxx, maxy; int save = get_active_clock( ); static new_page = -1; char key, ch2; start_clock( SELECT_FONT ); maxx = 256 / char_per_col( ); maxy = char_per_col( ); cur_char = ch; while ( !( ( key = get_pos( &sel_x, &sel_y, maxx, maxy - 1, 1, 1 ) ) == RET || key == 3 ) ) { ch = sel_y + sel_x*char_per_col( ); if ( ch>255 ) { sel_x = maxx; sel_y = char_per_col( ) - ( ( char_per_col( )*( 1 + sel_x ) ) - 255 ); ch = 255; }; cur_char = ch; if ( new_page == -1 ) { switch ( tolower( key ) ) { case 'o': new_page = 0; ch2 = select_font( &dum, &tmp ); if ( *status == RET ) { or_char( ch, ch2 ); print_table( which_page( ch ) ); } new_page = -1; break; case '?': help_select( ); break; case 1: insert_char( ch ); break; case 2: delete_char( ch ); break; } } } start_clock( save ); *status = key; return ch; }
/* Insert a character at the current position in the insert mode * whetever the current insert mode is. */ int insert_char_in_insert_mode(int c) { int overwrite_mode_save, ret_value; /* save current mode */ overwrite_mode_save = cur_bp->flags & BFLAG_OVERWRITE; /* force insert mode */ cur_bp->flags &= ~BFLAG_OVERWRITE; ret_value = insert_char(c); /* restore previous mode */ cur_bp->flags |= overwrite_mode_save; return ret_value; }
void insert_pinyin (const char* pinyin, int pos, pinyin_trie* root) { int i = 0; int k = 0; int len = 0; pinyin_trie* cur_node = root; if ( !pinyin || !root ) { g_warning ("args error in insert trie!\n"); return ; } for (; pinyin[i] != '\0'; i++ ) { k = ch_to_num (pinyin[i]); insert_char (pinyin[i], pos, cur_node); cur_node = cur_node->next[k]; } }
/** Handle Shift-key combination. */ static void key_handle_shift(kbd_event_t const *ev) { switch (ev->key) { case KC_LEFT: case KC_RIGHT: case KC_UP: case KC_DOWN: case KC_HOME: case KC_END: case KC_PAGE_UP: case KC_PAGE_DOWN: key_handle_movement(ev->key, true); break; default: if (ev->c >= 32 || ev->c == '\t') { selection_delete(); insert_char(ev->c); caret_update(); } break; } }
static void insert_clipboard_data(void) { char *str; size_t off; wchar_t c; int rc; rc = clipboard_get_str(&str); if (rc != EOK || str == NULL) return; off = 0; while (true) { c = str_decode(str, &off, STR_NO_LIMIT); if (c == '\0') break; insert_char(c); } free(str); }
void screen_insert_char(struct te_buffer *buf, char c) { if (buf == NULL) return; if (buf->dirty < 1) buf->dirty = 1; insert_char(buf, c); if (c == '\n') { clrtoeol(); clear_nfirst_lines(buffer_win, max(buf->y - 1, 0)); scroll_down(buffer_win); paint_buffer_nlines(buf, buf->y + 1); paint_nthline(buf, buf->y + 2, buf->y + 1); screen_move_right(buf); } else { bstring s = current_line_as_bstring(buf->contents, buf->point); draw_line(s, buf->y); screen_move_right(buf); } }
/** Insert file at caret position. * * Reads in the contents of a file and inserts them at the current position * of the caret. */ static int file_insert(char *fname) { FILE *f; wchar_t c; char buf[BUF_SIZE]; int bcnt; int n_read; size_t off; f = fopen(fname, "rt"); if (f == NULL) return EINVAL; bcnt = 0; while (true) { if (bcnt < STR_BOUNDS(1)) { n_read = fread(buf + bcnt, 1, BUF_SIZE - bcnt, f); bcnt += n_read; } off = 0; c = str_decode(buf, &off, bcnt); if (c == '\0') break; bcnt -= off; memcpy(buf, buf + off, bcnt); insert_char(c); } fclose(f); return EOK; }
void uart_console_isr(struct device *unused) { ARG_UNUSED(unused); while (uart_irq_update(uart_console_dev) && uart_irq_is_pending(uart_console_dev)) { static struct uart_console_input *cmd; uint8_t byte; int rx; if (!uart_irq_rx_ready(uart_console_dev)) { continue; } /* Character(s) have been received */ rx = read_uart(uart_console_dev, &byte, 1); if (rx < 0) { return; } if (uart_irq_input_hook(uart_console_dev, byte) != 0) { /* * The input hook indicates that no further processing * should be done by this handler. */ return; } if (!cmd) { cmd = nano_isr_fifo_get(avail_queue, TICKS_NONE); if (!cmd) return; } /* Handle ANSI escape mode */ if (atomic_test_bit(&esc_state, ESC_ANSI)) { handle_ansi(byte); continue; } /* Handle escape mode */ if (atomic_test_and_clear_bit(&esc_state, ESC_ESC)) { switch (byte) { case ANSI_ESC: atomic_set_bit(&esc_state, ESC_ANSI); atomic_set_bit(&esc_state, ESC_ANSI_FIRST); break; default: break; } continue; } /* Handle special control characters */ if (!isprint(byte)) { switch (byte) { case DEL: if (cur > 0) { del_char(&cmd->line[--cur], end); } break; case ESC: atomic_set_bit(&esc_state, ESC_ESC); break; case '\r': cmd->line[cur + end] = '\0'; uart_poll_out(uart_console_dev, '\r'); uart_poll_out(uart_console_dev, '\n'); cur = 0; end = 0; nano_isr_fifo_put(lines_queue, cmd); cmd = NULL; break; case '\t': if (completion_cb && !end) { cur += completion_cb(cmd->line, cur); } break; default: break; } continue; } /* Ignore characters if there's no more buffer space */ if (cur + end < sizeof(cmd->line) - 1) { insert_char(&cmd->line[cur++], byte, end); } } }
void uart_console_isr(struct device *unused) { ARG_UNUSED(unused); while (uart_irq_update(uart_console_dev) && uart_irq_is_pending(uart_console_dev)) { static struct console_input *cmd; u8_t byte; int rx; if (!uart_irq_rx_ready(uart_console_dev)) { continue; } /* Character(s) have been received */ rx = read_uart(uart_console_dev, &byte, 1); if (rx < 0) { return; } #ifdef CONFIG_UART_CONSOLE_DEBUG_SERVER_HOOKS if (debug_hook_in != NULL && debug_hook_in(byte) != 0) { /* * The input hook indicates that no further processing * should be done by this handler. */ return; } #endif if (!cmd) { cmd = k_fifo_get(avail_queue, K_NO_WAIT); if (!cmd) { return; } } #ifdef CONFIG_UART_CONSOLE_MCUMGR /* Divert this byte from normal console handling if it is part * of an mcumgr frame. */ if (handle_mcumgr(cmd, byte)) { continue; } #endif /* CONFIG_UART_CONSOLE_MCUMGR */ /* Handle ANSI escape mode */ if (atomic_test_bit(&esc_state, ESC_ANSI)) { handle_ansi(byte, cmd->line); continue; } /* Handle escape mode */ if (atomic_test_and_clear_bit(&esc_state, ESC_ESC)) { if (byte == ANSI_ESC) { atomic_set_bit(&esc_state, ESC_ANSI); atomic_set_bit(&esc_state, ESC_ANSI_FIRST); } continue; } /* Handle special control characters */ if (!isprint(byte)) { switch (byte) { case DEL: if (cur > 0) { del_char(&cmd->line[--cur], end); } break; case ESC: atomic_set_bit(&esc_state, ESC_ESC); break; case '\r': cmd->line[cur + end] = '\0'; uart_poll_out(uart_console_dev, '\r'); uart_poll_out(uart_console_dev, '\n'); cur = 0; end = 0; k_fifo_put(lines_queue, cmd); cmd = NULL; break; case '\t': if (completion_cb && !end) { cur += completion_cb(cmd->line, cur); } break; default: break; } continue; } /* Ignore characters if there's no more buffer space */ if (cur + end < sizeof(cmd->line) - 1) { insert_char(&cmd->line[cur++], byte, end); } } }
static int glw_text_bitmap_event(glw_t *w, event_t *e) { glw_text_bitmap_t *gtb = (glw_text_bitmap_t *)w; if(event_is_action(e, ACTION_BS)) { del_char(gtb); gtb_notify(gtb); return 1; } else if(event_is_type(e, EVENT_UNICODE)) { event_int_t *eu = (event_int_t *)e; if(insert_char(gtb, eu->val)) gtb_notify(gtb); return 1; } else if(event_is_type(e, EVENT_INSERT_STRING)) { event_payload_t *ep = (event_payload_t *)e; const char *str = ep->payload; int uc; while((uc = utf8_get(&str)) != 0) { insert_char(gtb, uc); } gtb_notify(gtb); return 1; } else if(event_is_action(e, ACTION_LEFT)) { if(gtb->gtb_edit_ptr > 0) { gtb->gtb_edit_ptr--; gtb->gtb_update_cursor = 1; } return 1; } else if(event_is_action(e, ACTION_RIGHT)) { if(gtb->gtb_edit_ptr < gtb->gtb_uc_len) { gtb->gtb_edit_ptr++; gtb->gtb_update_cursor = 1; } return 1; } else if(event_is_action(e, ACTION_ACTIVATE) || event_is_action(e, ACTION_ITEMMENU)) { gtb_caption_refresh(gtb); if(gtb->gtb_flags & (GTB_FILE_REQUEST | GTB_DIR_REQUEST)) { if(gtb->gtb_p == NULL) { TRACE(TRACE_ERROR, "GLW", "File requests on unbound widgets is not supported"); } else { int flags = (gtb->gtb_flags & GTB_FILE_REQUEST ? FILEPICKER_FILES : 0) | (gtb->gtb_flags & GTB_DIR_REQUEST ? FILEPICKER_DIRECTORIES : 0); filepicker_pick_to_prop(gtb->gtb_description, gtb->gtb_p, gtb->gtb_caption, flags); } } else { if(event_is_action(e, ACTION_ACTIVATE) && e->e_flags & EVENT_MOUSE) return 1; w->glw_root->gr_open_osk(w->glw_root, gtb->gtb_description, gtb->gtb_caption, w, gtb->gtb_flags & GTB_PASSWORD); } return 1; } return 0; }
static int linenoiseEdit(struct current *current) { int history_index = 0; /* The latest history entry is always our current buffer, that * initially is just an empty string. */ linenoiseHistoryAdd(""); set_current(current, ""); refreshLine(current->prompt, current); while(1) { int dir = -1; int c = fd_read(current); #ifndef NO_COMPLETION /* Only autocomplete when the callback is set. It returns < 0 when * there was an error reading from fd. Otherwise it will return the * character that should be handled next. */ if (c == '\t' && current->pos == current->chars && completionCallback != NULL) { c = completeLine(current); /* Return on errors */ if (c < 0) return current->len; /* Read next character when 0 */ if (c == 0) continue; } #endif process_char: if (c == -1) return current->len; #ifdef USE_TERMIOS if (c == 27) { /* escape sequence */ c = check_special(current->fd); } #endif switch(c) { case '\r': /* enter */ history_len--; free(history[history_len]); return current->len; case ctrl('C'): /* ctrl-c */ errno = EAGAIN; return -1; case 127: /* backspace */ case ctrl('H'): if (remove_char(current, current->pos - 1) == 1) { refreshLine(current->prompt, current); } break; case ctrl('D'): /* ctrl-d */ if (current->len == 0) { /* Empty line, so EOF */ history_len--; free(history[history_len]); return -1; } /* Otherwise fall through to delete char to right of cursor */ case SPECIAL_DELETE: if (remove_char(current, current->pos) == 1) { refreshLine(current->prompt, current); } break; case SPECIAL_INSERT: /* Ignore. Expansion Hook. * Future possibility: Toggle Insert/Overwrite Modes */ break; case ctrl('W'): /* ctrl-w, delete word at left. save deleted chars */ /* eat any spaces on the left */ { int pos = current->pos; while (pos > 0 && get_char(current, pos - 1) == ' ') { pos--; } /* now eat any non-spaces on the left */ while (pos > 0 && get_char(current, pos - 1) != ' ') { pos--; } if (remove_chars(current, pos, current->pos - pos)) { refreshLine(current->prompt, current); } } break; case ctrl('R'): /* ctrl-r */ { /* Display the reverse-i-search prompt and process chars */ char rbuf[50]; char rprompt[80]; int rchars = 0; int rlen = 0; int searchpos = history_len - 1; rbuf[0] = 0; while (1) { int n = 0; const char *p = NULL; int skipsame = 0; int searchdir = -1; snprintf(rprompt, sizeof(rprompt), "(reverse-i-search)'%s': ", rbuf); refreshLine(rprompt, current); c = fd_read(current); if (c == ctrl('H') || c == 127) { if (rchars) { int p = utf8_index(rbuf, --rchars); rbuf[p] = 0; rlen = strlen(rbuf); } continue; } #ifdef USE_TERMIOS if (c == 27) { c = check_special(current->fd); } #endif if (c == ctrl('P') || c == SPECIAL_UP) { /* Search for the previous (earlier) match */ if (searchpos > 0) { searchpos--; } skipsame = 1; } else if (c == ctrl('N') || c == SPECIAL_DOWN) { /* Search for the next (later) match */ if (searchpos < history_len) { searchpos++; } searchdir = 1; skipsame = 1; } else if (c >= ' ') { if (rlen >= (int)sizeof(rbuf) + 3) { continue; } n = utf8_getchars(rbuf + rlen, c); rlen += n; rchars++; rbuf[rlen] = 0; /* Adding a new char resets the search location */ searchpos = history_len - 1; } else { /* Exit from incremental search mode */ break; } /* Now search through the history for a match */ for (; searchpos >= 0 && searchpos < history_len; searchpos += searchdir) { p = strstr(history[searchpos], rbuf); if (p) { /* Found a match */ if (skipsame && strcmp(history[searchpos], current->buf) == 0) { /* But it is identical, so skip it */ continue; } /* Copy the matching line and set the cursor position */ set_current(current,history[searchpos]); current->pos = utf8_strlen(history[searchpos], p - history[searchpos]); break; } } if (!p && n) { /* No match, so don't add it */ rchars--; rlen -= n; rbuf[rlen] = 0; } } if (c == ctrl('G') || c == ctrl('C')) { /* ctrl-g terminates the search with no effect */ set_current(current, ""); c = 0; } else if (c == ctrl('J')) { /* ctrl-j terminates the search leaving the buffer in place */ c = 0; } /* Go process the char normally */ refreshLine(current->prompt, current); goto process_char; } break; case ctrl('T'): /* ctrl-t */ if (current->pos > 0 && current->pos <= current->chars) { /* If cursor is at end, transpose the previous two chars */ int fixer = (current->pos == current->chars); c = get_char(current, current->pos - fixer); remove_char(current, current->pos - fixer); insert_char(current, current->pos - 1, c); refreshLine(current->prompt, current); } break; case ctrl('V'): /* ctrl-v */ if (has_room(current, 3)) { /* Insert the ^V first */ if (insert_char(current, current->pos, c)) { refreshLine(current->prompt, current); /* Now wait for the next char. Can insert anything except \0 */ c = fd_read(current); /* Remove the ^V first */ remove_char(current, current->pos - 1); if (c != -1) { /* Insert the actual char */ insert_char(current, current->pos, c); } refreshLine(current->prompt, current); } } break; case ctrl('B'): case SPECIAL_LEFT: if (current->pos > 0) { current->pos--; refreshLine(current->prompt, current); } break; case ctrl('F'): case SPECIAL_RIGHT: if (current->pos < current->chars) { current->pos++; refreshLine(current->prompt, current); } break; case SPECIAL_PAGE_UP: dir = history_len - history_index - 1; /* move to start of history */ goto history_navigation; case SPECIAL_PAGE_DOWN: dir = -history_index; /* move to 0 == end of history, i.e. current */ goto history_navigation; case ctrl('P'): case SPECIAL_UP: dir = 1; goto history_navigation; case ctrl('N'): case SPECIAL_DOWN: history_navigation: if (history_len > 1) { /* Update the current history entry before to * overwrite it with tne next one. */ free(history[history_len - 1 - history_index]); history[history_len - 1 - history_index] = strdup(current->buf); /* Show the new entry */ history_index += dir; if (history_index < 0) { history_index = 0; break; } else if (history_index >= history_len) { history_index = history_len - 1; break; } set_current(current, history[history_len - 1 - history_index]); refreshLine(current->prompt, current); } break; case ctrl('A'): /* Ctrl+a, go to the start of the line */ case SPECIAL_HOME: current->pos = 0; refreshLine(current->prompt, current); break; case ctrl('E'): /* ctrl+e, go to the end of the line */ case SPECIAL_END: current->pos = current->chars; refreshLine(current->prompt, current); break; case ctrl('U'): /* Ctrl+u, delete to beginning of line, save deleted chars. */ if (remove_chars(current, 0, current->pos)) { refreshLine(current->prompt, current); } break; case ctrl('K'): /* Ctrl+k, delete from current to end of line, save deleted chars. */ if (remove_chars(current, current->pos, current->chars - current->pos)) { refreshLine(current->prompt, current); } break; case ctrl('Y'): /* Ctrl+y, insert saved chars at current position */ if (current->capture && insert_chars(current, current->pos, current->capture)) { refreshLine(current->prompt, current); } break; case ctrl('L'): /* Ctrl+L, clear screen */ linenoiseClearScreen(); /* Force recalc of window size for serial terminals */ current->cols = 0; refreshLine(current->prompt, current); break; default: /* Only tab is allowed without ^V */ if (c == '\t' || c >= ' ') { if (insert_char(current, current->pos, c) == 1) { refreshLine(current->prompt, current); } } break; } } return current->len; }