/* A convenience function for displaying a list of strings in columnar format on readline's output stream. MATCHES is the list of strings, in argv format, LEN is the number of strings in MATCHES, and MAX is the length of the longest string in MATCHES. Comes from readline/complete.c and modified to write in the TUI command window using tui_putc/tui_puts. */ static void tui_rl_display_match_list(char **matches, int len, int max) { typedef int QSFUNC(const void *, const void *); int count, limit, printed_len; int i, j, k, l; char *temp; /* Screen dimension correspond to the TUI command window: */ int screenwidth = TUI_CMD_WIN->generic.width; /* If there are many items, then ask the user if she really wants to see them all. */ if (len >= rl_completion_query_items) { char msg[256]; snprintf(msg, sizeof(msg), "\nDisplay all %d possibilities? (y or n)", len); tui_puts(msg); if (get_y_or_n() == 0) { tui_puts("\n"); return; } } /* How many items of MAX length can we fit in the screen window? */ max += 2; limit = (screenwidth / max); if ((limit != 1) && ((limit * max) == screenwidth)) limit--; /* Avoid a possible floating exception. If max > screenwidth, limit will be 0 and a divide-by-zero fault will result. */ if (limit == 0) limit = 1; /* How many iterations of the printing loop? */ count = ((len + (limit - 1)) / limit); /* FIXME: sanity-check result */ /* Watch out for special case. If LEN is less than LIMIT, then just do the inner printing loop. 0 < len <= limit implies count = 1. */ /* Sort the items if they are not already sorted. */ if (rl_ignore_completion_duplicates == 0) qsort(matches + 1, len, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); tui_putc('\n'); if (_rl_print_completions_horizontally == 0) { /* Print the sorted items, up-and-down alphabetically, like ls. */ for (i = 1; i <= count; i++) { for (j = 0, l = i; j < limit; j++) { if ((l > len) || (matches[l] == 0)) break; else { temp = printable_part(matches[l]); printed_len = print_filename(temp, matches[l]); if ((j + 1) < limit) for (k = 0; k < (max - printed_len); k++) tui_putc(' '); } l += count; } tui_putc('\n'); } } else { /* Print the sorted items, across alphabetically, like ls -x. */ for (i = 1; matches[i]; i++) { temp = printable_part(matches[i]); printed_len = print_filename(temp, matches[i]); /* Have we reached the end of this line? */ if (matches[i + 1]) { if (i && (limit > 1) && ((i % limit) == 0)) tui_putc('\n'); else for (k = 0; k < max - printed_len; k++) tui_putc(' '); } } tui_putc('\n'); } }
static void tui_mld_putch (const struct match_list_displayer *displayer, int ch) { tui_putc (ch); }
/* Get a character from the command window. This is called from the readline package. */ int tui_getc (FILE *fp) { int ch; WINDOW *w; w = TUI_CMD_WIN->generic.handle; #ifdef TUI_USE_PIPE_FOR_READLINE /* Flush readline output. */ tui_readline_output (0, 0); #endif ch = wgetch (w); /* The \n must be echoed because it will not be printed by readline. */ if (ch == '\n') { /* When hitting return with an empty input, gdb executes the last command. If we emit a newline, this fills up the command window with empty lines with gdb prompt at beginning. Instead of that, stay on the same line but provide a visual effect to show the user we recognized the command. */ if (rl_end == 0 && !gdb_in_secondary_prompt_p (current_ui)) { wmove (w, getcury (w), 0); /* Clear the line. This will blink the gdb prompt since it will be redrawn at the same line. */ wclrtoeol (w); wrefresh (w); napms (20); } else { /* Move cursor to the end of the command line before emitting the newline. We need to do so because when ncurses outputs a newline it truncates any text that appears past the end of the cursor. */ int px, py; getyx (w, py, px); px += rl_end - rl_point; py += px / TUI_CMD_WIN->generic.width; px %= TUI_CMD_WIN->generic.width; wmove (w, py, px); tui_putc ('\n'); } } /* Handle prev/next/up/down here. */ ch = tui_dispatch_ctrl_char (ch); if (ch == KEY_BACKSPACE) return '\b'; if (current_ui->command_editing && key_is_start_sequence (ch)) { int ch_pending; nodelay (w, TRUE); ch_pending = wgetch (w); nodelay (w, FALSE); /* If we have pending input following a start sequence, call the stdin event handler again because ncurses may have already read and stored the input into its internal buffer, meaning that we won't get an stdin event for it. If we don't compensate for this missed stdin event, key sequences as Alt_F (^[f) will not behave promptly. (We only compensates for the missed 2nd byte of a key sequence because 2-byte sequences are by far the most commonly used. ncurses may have buffered a larger, 3+-byte key sequence though it remains to be seen whether it is useful to compensate for all the bytes of such sequences.) */ if (ch_pending != ERR) { ungetch (ch_pending); call_stdin_event_handler_again_p = 1; } } return ch; }
static void tui_mld_crlf (const struct match_list_displayer *displayer) { tui_putc ('\n'); }