void readline_update(t_readline *readline, char *c) { int i; i = -1; while (c[++i]) { if (c[i] == '\x7f') readline_delete_char(readline); else readline_insert_char(readline, c[i]); } }
/* return true if command handled */ void readline_handle_byte(ReadLineState *rs, int ch) { switch(rs->esc_state) { case IS_NORM: switch(ch) { case 1: readline_bol(rs); break; case 4: readline_delete_char(rs); break; case 5: readline_eol(rs); break; case 9: readline_completion(rs); break; case 10: case 13: rs->cmd_buf[rs->cmd_buf_size] = '\0'; if (!rs->read_password) readline_hist_add(rs, rs->cmd_buf); monitor_printf(rs->mon, "\n"); rs->cmd_buf_index = 0; rs->cmd_buf_size = 0; rs->last_cmd_buf_index = 0; rs->last_cmd_buf_size = 0; rs->readline_func(rs->mon, rs->cmd_buf, rs->readline_opaque); break; case 23: /* ^W */ readline_backword(rs); break; case 27: rs->esc_state = IS_ESC; break; case 127: case 8: readline_backspace(rs); break; case 155: rs->esc_state = IS_CSI; break; default: if (ch >= 32) { readline_insert_char(rs, ch); } break; } break; case IS_ESC: if (ch == '[') { rs->esc_state = IS_CSI; rs->esc_param = 0; } else { rs->esc_state = IS_NORM; } break; case IS_CSI: switch(ch) { case 'A': case 'F': readline_up_char(rs); break; case 'B': case 'E': readline_down_char(rs); break; case 'D': readline_backward_char(rs); break; case 'C': readline_forward_char(rs); break; case '0' ... '9': rs->esc_param = rs->esc_param * 10 + (ch - '0'); goto the_end; case '~': switch(rs->esc_param) { case 1: readline_bol(rs); break; case 3: readline_delete_char(rs); break; case 4: readline_eol(rs); break; } break; default: break; } rs->esc_state = IS_NORM; the_end: break; } readline_update(rs); }
static void readline_completion(ReadLineState *rs) { Monitor *mon = cur_mon; int len, i, j, max_width, nb_cols, max_prefix; char *cmdline; rs->nb_completions = 0; cmdline = g_malloc(rs->cmd_buf_index + 1); memcpy(cmdline, rs->cmd_buf, rs->cmd_buf_index); cmdline[rs->cmd_buf_index] = '\0'; rs->completion_finder(cmdline); g_free(cmdline); /* no completion found */ if (rs->nb_completions <= 0) return; if (rs->nb_completions == 1) { len = strlen(rs->completions[0]); for(i = rs->completion_index; i < len; i++) { readline_insert_char(rs, rs->completions[0][i]); } /* extra space for next argument. XXX: make it more generic */ if (len > 0 && rs->completions[0][len - 1] != '/') readline_insert_char(rs, ' '); } else { monitor_printf(mon, "\n"); max_width = 0; max_prefix = 0; for(i = 0; i < rs->nb_completions; i++) { len = strlen(rs->completions[i]); if (i==0) { max_prefix = len; } else { if (len < max_prefix) max_prefix = len; for(j=0; j<max_prefix; j++) { if (rs->completions[i][j] != rs->completions[0][j]) max_prefix = j; } } if (len > max_width) max_width = len; } if (max_prefix > 0) for(i = rs->completion_index; i < max_prefix; i++) { readline_insert_char(rs, rs->completions[0][i]); } max_width += 2; if (max_width < 10) max_width = 10; else if (max_width > 80) max_width = 80; nb_cols = 80 / max_width; j = 0; for(i = 0; i < rs->nb_completions; i++) { monitor_printf(rs->mon, "%-*s", max_width, rs->completions[i]); if (++j == nb_cols || i == (rs->nb_completions - 1)) { monitor_printf(rs->mon, "\n"); j = 0; } } readline_show_prompt(rs); } for (i = 0; i < rs->nb_completions; i++) { g_free(rs->completions[i]); } }