void clear_messages(void) { cursor(0, 0); clear_to_eol(); mbuffer_full = FALSE; mbuffer_x = 0; }
static void input_refresh(void) { move_cursor(ne_lines - 1, start_x); for(int i = start_x, j = offset; j < len; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)) { if (i + get_char_width(&input_buffer[j], encoding) >= ne_columns) break; output_char(get_char(&input_buffer[j], encoding), 0, encoding); } clear_to_eol(); fflush(stdout); }
static void print_strings() { const int dx = rl.max_entry_len + 1 + (rl.suffix ? 1 : 0); set_attr(0); for(int row = 0; row < max_names_per_col; row++) { move_cursor(row, 0); clear_to_eol(); if (row < NAMES_PER_COL(page)) { for(int col = 0; col < NAMES_PER_LINE(page); col++) { if (PXY2N(page,col,row) < rl.cur_entries) { move_cursor(row, col * dx); const char * const p = rl.entries[PXY2N(page,col,row)]; if (rl.suffix) set_attr(p[strlen(p) - 1] == rl.suffix ? BOLD : 0); output_string(p, io_utf8); } } } } }
static void print_strings() { int row,col; const char *p; set_attr(0); for(row = 0; row < max_names_per_col; row++) { move_cursor(row, 0); clear_to_eol(); if (row < NAMES_PER_COL(page)) { for(col = 0; col < NAMES_PER_LINE(page); col++) { if (PXY2N(page,col,row) < num_entries) { move_cursor(row, col * max_name_len); p = entries[PXY2N(page,col,row)]; if (mark_char) set_attr(p[strlen(p) - 1] == mark_char ? BOLD : 0); output_string(p, io_utf8); } } } } }
static unsigned int print_prompt(const char * const prompt) { static const char *prior_prompt; assert(prompt != NULL || prior_prompt); if (prompt) prior_prompt = prompt; move_cursor(ne_lines - 1, 0); clear_to_eol(); standout_on(); output_string(prior_prompt, false); output_string(":", false); standout_off(); output_string(" ", false); reset_status_bar(); return strlen(prior_prompt) + 2; }
void special_reading_ansi(struct virtscreen *cur, unsigned char ch) { if ((ch>='0') && (ch<='9')) { cur->cur_ansi_number = (cur->cur_ansi_number * 10) + (ch - '0'); cur->ansi_reading_number = 1; return; } if ((cur->ansi_reading_number) || (ch == ';')) { if (cur->ansi_elements<MAX_ANSI_ELEMENTS) cur->ansi_element[cur->ansi_elements++] = cur->cur_ansi_number; cur->ansi_reading_number = 0; } cur->cur_ansi_number = 0; switch (ch) { case '?': case ';': return; case 'D': position_console(cur,0,(cur->ansi_elements) ? -cur->ansi_element[0] : -1,1); break; case 'a': case 'C': position_console(cur,0,(cur->ansi_elements) ? cur->ansi_element[0] : 1,1); break; case 'A': position_console(cur,(cur->ansi_elements) ? -cur->ansi_element[0] : -1,0,1); break; case 'e': case 'B': position_console(cur,(cur->ansi_elements) ? cur->ansi_element[0] : 1,0,1); break; case '`': case 'G': { int temp = cur->ansi_elements ? cur->ansi_element[0] : 1; if (temp) temp--; position_console(cur,cur->ypos,temp,0); } break; case 'E': position_console(cur,cur->ypos + ((cur->ansi_elements) ? cur->ansi_element[0] : 1), 0,0); break; case 'F': position_console(cur,cur->ypos - ((cur->ansi_elements) ? cur->ansi_element[0] : 1), 0,0); break; case 'd': { int temp = cur->ansi_elements ? cur->ansi_element[0] : 1; if (temp) temp--; position_console(cur,temp,cur->xpos,0); } break; case 'f': case 'H': { int row = (cur->ansi_elements > 0) ? cur->ansi_element[0] : 1; int col = (cur->ansi_elements > 1) ? cur->ansi_element[1] : 1; if (row) row--; if (col) col--; position_console(cur,row,col,0); } break; case 'J': clear_virtscreen(cur,(cur->ansi_elements) ? cur->ansi_element[0]: 0); break; case 'L': { int lines = (cur->ansi_elements) ? cur->ansi_element[0] : 1; while (lines>0) { scroll_virt_up_at_cursor(cur,0); lines--; } } break; case 'M': { int lines = (cur->ansi_elements) ? cur->ansi_element[0] : 1; while (lines>0) { scroll_virt_up_at_cursor(cur,1); lines--; } } break; case 'P': delete_chars_in_line(cur,(cur->ansi_elements) ? cur->ansi_element[0] : 1); break; case 'K': clear_to_eol(cur,cur->ansi_elements ? cur->ansi_element[0] : 0); break; case 's': cur->old_xpos = cur->xpos; cur->old_ypos = cur->ypos; break; case 'u': position_console(cur,cur->old_ypos,cur->old_xpos,0); break; case 'r': { int low = (cur->ansi_elements > 0) ? cur->ansi_element[0] : 1; int high = (cur->ansi_elements > 1) ? cur->ansi_element[1] : cur->rows; if (low<=high) set_scroll_region(cur,low,high); } break; case 'm': { int count = 0; int cthing; if (!cur->ansi_elements) change_attribute(cur,0x07); while (count < cur->ansi_elements) { cthing = cur->ansi_element[count]; switch (cthing) { case 0: case 27: change_attribute(cur,0x07); break; case 1: change_attribute(cur,cur->attrib | 0x08); break; case 5: change_attribute(cur,cur->attrib | 0x80); break; case 7: change_attribute(cur,0x70); break; case 21: case 22: change_attribute(cur,cur->attrib & 0xF7); break; case 25: change_attribute(cur,cur->attrib & 0x7F); break; default: if ((cthing>=30) && (cthing<=37)) { change_attribute(cur,(cur->attrib & 0xF8) | (cthing-30)); } if ((cthing>=40) && (cthing<=47)) { change_attribute(cur,(cur->attrib & 0x8F) | ((cthing-40) << 4)); } break; } count++; } } break; } cur->next_char_send = std_interpret_char; }
char *request(const char *prompt, const char * const default_string, const bool alpha_allowed, const int completion_type, const bool prefer_utf8) { set_attr(0); input_buffer[pos = len = offset = 0] = 0; encoding = ENC_ASCII; x = start_x = print_prompt(prompt); init_history(); if (default_string) { strncpy(input_buffer, default_string, MAX_INPUT_LINE_LEN); len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); input_refresh(); } bool first_char_typed = true, last_char_completion = false, selection = false; while(true) { assert(input_buffer[len] == 0); move_cursor(ne_lines - 1, x); int c; input_class ic; do c = get_key_code(); while((ic = CHAR_CLASS(c)) == IGNORE); /* ISO 10646 characters *above 256* can be added only to UTF-8 lines, or ASCII lines (making them, of course, UTF-8). */ if (ic == ALPHA && c > 0xFF && encoding != ENC_ASCII && encoding != ENC_UTF8) ic = INVALID; if (ic != TAB) last_char_completion = false; if (ic == TAB && !completion_type) ic = ALPHA; switch(ic) { case INVALID: alert(); break; case ALPHA: if (first_char_typed) { input_buffer[len = 0] = 0; clear_to_eol(); } if (encoding == ENC_ASCII && c > 0x7F) encoding = prefer_utf8 || c > 0xFF ? ENC_UTF8 : ENC_8_BIT; int c_len = encoding == ENC_UTF8 ? utf8seqlen(c) : 1; int c_width = output_width(c); assert(c_len > 0); if (len <= MAX_INPUT_LINE_LEN - c_len && (alpha_allowed || (c < 0x100 && isxdigit(c)) || c=='X' || c=='x')) { memmove(&input_buffer[pos + c_len], &input_buffer[pos], len - pos + 1); if (c_len == 1) input_buffer[pos] = c; else utf8str(c, &input_buffer[pos]); len += c_len; move_cursor(ne_lines - 1, x); if (x < ne_columns - c_width) { if (pos == len - c_len) output_char(c, 0, encoding); else if (char_ins_del_ok) insert_char(c, 0, encoding); else input_refresh(); } input_move_right(true); } break; case RETURN: selection = true; break; case TAB: if (completion_type == COMPLETE_FILE || completion_type == COMPLETE_SYNTAX) { bool quoted = false; char *prefix, *completion, *p; if (len && input_buffer[len - 1] == '"') { input_buffer[len - 1] = 0; if (prefix = strrchr(input_buffer, '"')) { quoted = true; prefix++; } else input_buffer[len - 1] = '"'; } if (!quoted) { prefix = strrchr(input_buffer, ' '); if (prefix) prefix++; else prefix = input_buffer; } if (last_char_completion || completion_type == COMPLETE_SYNTAX) { if (completion_type == COMPLETE_FILE ) completion = p = request_files(prefix, true); else completion = p = request_syntax(prefix, true); reset_window(); if (completion) { if (*completion) selection = true; else completion++; } } else { if (completion_type == COMPLETE_FILE ) completion = p = complete_filename(prefix); else completion = p = request_syntax(prefix, true); last_char_completion = true; if (!completion) alert(); } if (completion && (prefix - input_buffer) + strlen(completion) + 1 < MAX_INPUT_LINE_LEN) { const encoding_type completion_encoding = detect_encoding(completion, strlen(completion)); if (encoding == ENC_ASCII || completion_encoding == ENC_ASCII || encoding == completion_encoding) { strcpy(prefix, completion); if (quoted) strcat(prefix, "\""); len = strlen(input_buffer); pos = offset = 0; x = start_x; if (encoding == ENC_ASCII) encoding = completion_encoding; input_move_to_eol(); if (quoted) input_move_left(false); input_refresh(); } else alert(); } else if (quoted) strcat(prefix, "\""); free(p); } break; case COMMAND: if (c < 0) c = -c - 1; const int a = parse_command_line(key_binding[c], NULL, NULL, false); if (a >= 0) { switch(a) { case LINEUP_A: case LINEDOWN_A: case MOVESOF_A: case MOVEEOF_A: case PAGEUP_A: case PAGEDOWN_A: case NEXTPAGE_A: case PREVPAGE_A: if (history_buff) { switch(a) { case LINEUP_A: line_up(history_buff); break; case LINEDOWN_A: line_down(history_buff); break; case MOVESOF_A: move_to_sof(history_buff); break; case MOVEEOF_A: move_to_bof(history_buff); break; case PAGEUP_A: case PREVPAGE_A: prev_page(history_buff); break; case PAGEDOWN_A: case NEXTPAGE_A: next_page(history_buff); break; } /* In some cases, the default displayed on the command line will be the same as the first history item. In that case we skip it. */ if (first_char_typed == true && a == LINEUP_A && history_buff->cur_line_desc->line && !strncmp(history_buff->cur_line_desc->line, input_buffer, history_buff->cur_line_desc->line_len)) line_up(history_buff); if (history_buff->cur_line_desc->line) { strncpy(input_buffer, history_buff->cur_line_desc->line, min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)); input_buffer[min(history_buff->cur_line_desc->line_len,MAX_INPUT_LINE_LEN)] = 0; len = strlen(input_buffer); encoding = detect_encoding(input_buffer, len); } else { input_buffer[len = 0] = 0; encoding = ENC_ASCII; } x = start_x; pos = 0; offset = 0; input_refresh(); } break; case MOVELEFT_A: input_move_left(true); break; case MOVERIGHT_A: input_move_right(true); break; case BACKSPACE_A: if (pos == 0) break; input_move_left(true); case DELETECHAR_A: if (len > 0 && pos < len) { int c_len = encoding == ENC_UTF8 ? utf8len(input_buffer[pos]) : 1; int c_width = get_char_width(&input_buffer[pos], encoding); memmove(&input_buffer[pos], &input_buffer[pos + c_len], len - pos - c_len + 1); len -= c_len; if (input_buffer_is_ascii()) encoding = ENC_ASCII; if (char_ins_del_ok) { int i, j; move_cursor(ne_lines - 1, x); delete_chars(c_width); for(i = x, j = pos; j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns - c_width; i += get_char_width(&input_buffer[j], encoding), j = next_pos(input_buffer, j, encoding)); if (j < len) { move_cursor(ne_lines - 1, i); while(j < len && i + get_char_width(&input_buffer[j], encoding) < ne_columns) { output_char(get_char(&input_buffer[j], encoding), 0, encoding); i += get_char_width(&input_buffer[j], encoding); j = next_pos(input_buffer, j, encoding); } } } else input_refresh(); } break; case DELETELINE_A: move_cursor(ne_lines - 1, start_x); clear_to_eol(); input_buffer[len = pos = offset = 0] = 0; encoding = ENC_ASCII; x = start_x; break; case DELETEEOL_A: input_buffer[len = pos] = 0; clear_to_eol(); if (input_buffer_is_ascii()) encoding = ENC_ASCII; break; case MOVEINCUP_A: if (x != start_x) { pos = offset; x = start_x; break; } case MOVESOL_A: input_move_to_sol(); break; case MOVEINCDOWN_A: { int i, j; for(i = x, j = pos; 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 != pos && j < len) { pos = j; x = i; break; } } case MOVEEOL_A: input_move_to_eol(); break; case TOGGLESEOL_A: case TOGGLESEOF_A: if (pos != 0) input_move_to_sol(); else input_move_to_eol(); break; case PREVWORD_A: input_prev_word(); break; case NEXTWORD_A: input_next_word(); break; case REFRESH_A: input_refresh(); break; case PASTE_A: input_paste(); break; case AUTOCOMPLETE_A: input_autocomplete(); break; case ESCAPE_A: return NULL; default: break; } } break; default: break; } if (selection) { const line_desc * const last = (line_desc *)history_buff->line_desc_list.tail_pred->prev; assert(input_buffer[len] == 0); if (history_buff->num_lines == 0 || len != last->line_len || strncmp(input_buffer, last->line, last->line_len)) add_to_history(input_buffer); return input_buffer; } first_char_typed = false; } }