diff options
-rw-r--r-- | vlib/vlib/unix/cli.c | 452 |
1 files changed, 364 insertions, 88 deletions
diff --git a/vlib/vlib/unix/cli.c b/vlib/vlib/unix/cli.c index 70ffdec74b9..c34ae219297 100644 --- a/vlib/vlib/unix/cli.c +++ b/vlib/vlib/unix/cli.c @@ -116,6 +116,18 @@ _("\n") }; #undef _ +/** Pager line index */ +typedef struct { + /** Index into pager_vector */ + u32 line; + + /** Offset of the string in the line */ + u32 offset; + + /** Length of the string in the line */ + u32 length; +} unix_cli_pager_index_t; + /** Unix CLI session. */ typedef struct { @@ -164,8 +176,8 @@ typedef struct { /** Pager buffer */ u8 ** pager_vector; - /** Lines currently displayed */ - u32 pager_lines; + /** Index of line fragments in the pager buffer */ + unix_cli_pager_index_t * pager_index; /** Line number of top of page */ u32 pager_start; @@ -188,12 +200,16 @@ unix_cli_pager_reset (unix_cli_file_t *f) { u8 ** p; - f->pager_lines = f->pager_start = 0; + f->pager_start = 0; + + vec_free (f->pager_index); + f->pager_index = 0; + vec_foreach (p, f->pager_vector) { - vec_free(*p); + vec_free (*p); } - vec_free(f->pager_vector); + vec_free (f->pager_vector); f->pager_vector = 0; } @@ -205,7 +221,7 @@ unix_cli_file_free (unix_cli_file_t * f) { vec_free (f->output_vector); vec_free (f->input_vector); - unix_cli_pager_reset(f); + unix_cli_pager_reset (f); } /** CLI actions */ @@ -240,6 +256,7 @@ typedef enum { UNIX_CLI_PARSE_ACTION_PAGER_BOTTOM, UNIX_CLI_PARSE_ACTION_PAGER_PGDN, UNIX_CLI_PARSE_ACTION_PAGER_PGUP, + UNIX_CLI_PARSE_ACTION_PAGER_REDRAW, UNIX_CLI_PARSE_ACTION_PAGER_SEARCH, UNIX_CLI_PARSE_ACTION_PARTIALMATCH, @@ -344,6 +361,8 @@ static unix_cli_parse_actions_t unix_cli_parse_pager[] = { /* Pager commands */ _( " ", UNIX_CLI_PARSE_ACTION_PAGER_NEXT ), _( "q", UNIX_CLI_PARSE_ACTION_PAGER_QUIT ), + _( CTL('L'), UNIX_CLI_PARSE_ACTION_PAGER_REDRAW ), + _( CTL('R'), UNIX_CLI_PARSE_ACTION_PAGER_REDRAW ), _( "/", UNIX_CLI_PARSE_ACTION_PAGER_SEARCH ), /* VT100 */ @@ -615,7 +634,7 @@ static void unix_cli_pager_prompt(unix_cli_file_t * cf, unix_file_t * uf) cf->ansi_capable ? ANSI_BOLD : "", cf->pager_start + 1, cf->pager_start + cf->height, - cf->pager_lines, + vec_len (cf->pager_index), cf->ansi_capable ? ANSI_RESET: ""); unix_vlib_cli_output_cooked(cf, uf, prompt, vec_len(prompt)); @@ -673,7 +692,205 @@ static void unix_cli_ansi_cursor(unix_cli_file_t * cf, unix_file_t * uf, vec_free(str); } -/** \brief VLIB CLI output function. */ +/** Redraw the currently displayed page of text. + * @param cf CLI session to redraw the pager buffer of. + * @param uf Unix file of the CLI session. + */ +static void unix_cli_pager_redraw(unix_cli_file_t * cf, unix_file_t * uf) +{ + unix_cli_pager_index_t * pi = NULL; + u8 * line = NULL; + word i; + + /* No active pager? Do nothing. */ + if (!vec_len (cf->pager_index)) + return; + + if (cf->ansi_capable) + { + /* If we have ANSI, send the clear screen sequence */ + unix_vlib_cli_output_cooked (cf, uf, + (u8 *)ANSI_CLEAR, sizeof(ANSI_CLEAR) - 1); + } + else + { + /* Otherwise make sure we're on a blank line */ + unix_cli_pager_prompt_erase (cf, uf); + } + + /* (Re-)send the current page of content */ + for (i = 0; i < cf->height - 1 && + i + cf->pager_start < vec_len (cf->pager_index); + i ++) + { + pi = &cf->pager_index[cf->pager_start + i]; + line = cf->pager_vector[pi->line] + pi->offset; + + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); + } + /* if the last line didn't end in newline, add a newline */ + if (pi && line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); + + unix_cli_pager_prompt (cf, uf); +} + +/** @brief Process and add a line to the pager index. + * In normal operation this function will take the given character string + * found in @c line and with length @c len_or_index and iterates the over the + * contents, adding each line of text discovered within it to the + * pager index. Lines are identified by newlines ("<code>\\n</code>") and by + * strings longer than the width of the terminal. + * + * If instead @c line is @c NULL then @c len_or_index is taken to mean the + * index of an existing line in the pager buffer; this simply means that the + * input line does not need to be cloned since we alreayd have it. This is + * typical if we are reindexing the pager buffer. + * + * @param cf The CLI session whose pager we are adding to. + * @param line The string of text to be indexed into the pager buffer. + * If @c line is @c NULL then the mode of operation + * changes slightly; see the description above. + * @param len_or_index If @c line is a pointer to a string then this parameter + * indicates the length of that string; Otherwise this + * value provides the index in the pager buffer of an + * existing string to be indexed. + */ +static void unix_cli_pager_add_line (unix_cli_file_t * cf, + u8 * line, + word len_or_index) +{ + u8 * p; + word i, j, k; + word line_index, len; + u32 width = cf->width; + unix_cli_pager_index_t * pi; + + if (line == NULL) + { + /* Use a line already in the pager buffer */ + line_index = len_or_index; + p = cf->pager_vector[line_index]; + len = vec_len (p); + } + else + { + len = len_or_index; + /* Add a copy of the raw string to the pager buffer */ + p = vec_new (u8, len); + clib_memcpy (p, line, len); + + /* store in pager buffer */ + line_index = vec_len (cf->pager_vector); + vec_add1 (cf->pager_vector, p); + } + + i = 0; + while (i < len) + { + /* Find the next line, or run to terminal width, or run to EOL */ + int l = len - i; + j = unix_vlib_findchr((u8)'\n', p, l < width ? l : width); + + if (j < l && p[j] == '\n') /* incl \n */ + j ++; + + /* Add the line to the index */ + k = vec_len (cf->pager_index); + vec_validate (cf->pager_index, k); + pi = &cf->pager_index[k]; + + pi->line = line_index; + pi->offset = i; + pi->length = j; + + i += j; + p += j; + } +} + +/** @brief Reindex entire pager buffer. + * Resets the current pager index and then re-adds the lines in the pager + * buffer to the index. + * + * Additionally this function attempts to retain the current page start + * line offset by searching for the same top-of-screen line in the new index. + * + * @param cf The CLI session whose pager buffer should be reindexed. + */ +static void unix_cli_pager_reindex (unix_cli_file_t * cf) +{ + word i, old_line, old_offset; + unix_cli_pager_index_t * pi; + + /* If there is nothing in the pager buffer then make sure the index + * is empty and move on. + */ + if (cf->pager_vector == 0) + { + vec_reset_length (cf->pager_index); + return; + } + + /* Retain a pointer to the current page start line so we can + * find it later + */ + pi = &cf->pager_index[cf->pager_start]; + old_line = pi->line; + old_offset = pi->offset; + + /* Re-add the buffered lines to the index */ + vec_reset_length (cf->pager_index); + vec_foreach_index(i, cf->pager_vector) + { + unix_cli_pager_add_line(cf, NULL, i); + } + + /* Attempt to re-locate the previously stored page start line */ + vec_foreach_index(i, cf->pager_index) + { + pi = &cf->pager_index[i]; + + if (pi->line == old_line && + (pi->offset <= old_offset || + pi->offset + pi->length > old_offset)) + { + /* Found it! */ + cf->pager_start = i; + break; + } + } + + /* In case the start line was not found (rare), ensure the pager start + * index is within bounds + */ + if (cf->pager_start >= vec_len (cf->pager_index)) + { + cf->pager_start = vec_len (cf->pager_index) - cf->height + 1; + + if (cf->pager_start < 0) + cf->pager_start = 0; + } +} + +/** VLIB CLI output function. + * + * If the terminal has a pager configured then this function takes care + * of collating output into the pager buffer; ensuring only the first page + * is displayed and any lines in excess of the first page are buffered. + * + * If the maximum number of index lines in the buffer is exceeded then the + * pager is cancelled and the contents of the current buffer are sent to the + * terminal. + * + * If there is no pager configured then the output is sent directly to the + * terminal. + * + * @param cli_file_index Index of the CLI session where this output is + * directed. + * @param buffer String of printabe bytes to be output. + * @param buffer_bytes The number of bytes in @c buffer to be output. + */ static void unix_vlib_cli_output (uword cli_file_index, u8 * buffer, uword buffer_bytes) @@ -688,75 +905,80 @@ static void unix_vlib_cli_output (uword cli_file_index, if (cf->no_pager || um->cli_pager_buffer_limit == 0 || cf->height == 0) { - unix_vlib_cli_output_cooked(cf, uf, buffer, buffer_bytes); + unix_vlib_cli_output_cooked (cf, uf, buffer, buffer_bytes); } else { - /* At each \n add the line to the pager buffer. - * If we've not yet displayed a whole page in this command then - * also output the line. - * If we have displayed a whole page then display a pager prompt - * and count the lines we've buffered. - */ - u8 * p = buffer; + word row = vec_len (cf->pager_index); u8 * line; - uword i, len = buffer_bytes; - - while (len) - { - i = unix_vlib_findchr('\n', p, len); - if (i < len) - i ++; /* include the '\n' */ - - /* make a vec out of this substring */ - line = vec_new(u8, i); - memcpy(line, p, i); + unix_cli_pager_index_t * pi; - /* store in pager buffer */ - vec_add1(cf->pager_vector, line); - cf->pager_lines ++; + /* Index and add the output lines to the pager buffer. */ + unix_cli_pager_add_line (cf, buffer, buffer_bytes); - if (cf->pager_lines < cf->height) + /* Now iterate what was added to display the lines. + * If we reach the bottom of the page, display a prompt. + */ + while (row < vec_len (cf->pager_index)) + { + if (row < cf->height - 1) { /* output this line */ - unix_vlib_cli_output_cooked(cf, uf, p, i); - /* TODO: stop if line longer than cf->width and would - * overflow cf->height */ + pi = &cf->pager_index[row]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); + + /* if the last line didn't end in newline, and we're at the + * bottom of the page, add a newline */ + if (line[pi->length - 1] != '\n' && row == cf->height - 2) + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); } else { /* Display the pager prompt every 10 lines */ - if (!(cf->pager_lines % 10)) + if (!(row % 10)) unix_cli_pager_prompt(cf, uf); } - - p += i; - len -= i; + row ++; } - /* Check if we went over the pager buffer limit */ - if (cf->pager_lines > um->cli_pager_buffer_limit) - { - /* Stop using the pager for the remainder of this CLI command */ - cf->no_pager = 2; + /* Check if we went over the pager buffer limit */ + if (vec_len (cf->pager_index) > um->cli_pager_buffer_limit) + { + /* Stop using the pager for the remainder of this CLI command */ + cf->no_pager = 2; - /* If we likely printed the prompt, erase it */ - if (cf->pager_lines > cf->height - 1) - unix_cli_pager_prompt_erase (cf, uf); + /* If we likely printed the prompt, erase it */ + if (vec_len (cf->pager_index) > cf->height - 1) + unix_cli_pager_prompt_erase (cf, uf); - /* Dump out the contents of the buffer */ - for (i = cf->pager_start + (cf->height - 1); - i < cf->pager_lines; i ++) - unix_vlib_cli_output_cooked (cf, uf, - cf->pager_vector[i], - vec_len(cf->pager_vector[i])); + /* Dump out the contents of the buffer */ + for (row = cf->pager_start + (cf->height - 1); + row < vec_len (cf->pager_index); row ++) + { + pi = &cf->pager_index[row]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); + } - unix_cli_pager_reset (cf); - } + unix_cli_pager_reset (cf); + } } } -/** \brief Identify whether a terminal type is ANSI capable. */ +/** Identify whether a terminal type is ANSI capable. + * + * Compares the string given in @term with a list of terminal types known + * to support ANSI escape sequences. + * + * This list contains, for example, @c xterm, @c screen and @c ansi. + * + * @param term A string with a terminal type in it. + * @param len The length of the string in @term. + * + * @return @c 1 if the terminal type is recognized as supporting ANSI + * terminal sequences; @c 0 otherwise. + */ static u8 unix_cli_terminal_type(u8 * term, uword len) { /* This may later be better done as a hash of some sort. */ @@ -906,6 +1128,10 @@ static i32 unix_cli_process_telnet(unix_main_t * um, break; cf->width = clib_net_to_host_u16(*((u16 *)(input_vector + 3))); cf->height = clib_net_to_host_u16(*((u16 *)(input_vector + 5))); + /* reindex pager buffer */ + unix_cli_pager_reindex (cf); + /* redraw page */ + unix_cli_pager_redraw (cf, uf); break; default: @@ -1308,18 +1534,24 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, case UNIX_CLI_PARSE_ACTION_PAGER_NEXT: case UNIX_CLI_PARSE_ACTION_PAGER_PGDN: /* show next page of the buffer */ - if (cf->height + cf->pager_start < cf->pager_lines) + if (cf->height + cf->pager_start < vec_len (cf->pager_index)) { - u8 * line; + u8 * line = NULL; + unix_cli_pager_index_t * pi = NULL; + int m = cf->pager_start + (cf->height - 1); unix_cli_pager_prompt_erase (cf, uf); for (j = m; - j < cf->pager_lines && cf->pager_start < m; + j < vec_len (cf->pager_index) && cf->pager_start < m; j ++, cf->pager_start ++) { - line = cf->pager_vector[j]; - unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line)); + pi = &cf->pager_index[j]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); } + /* if the last line didn't end in newline, add a newline */ + if (pi && line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); unix_cli_pager_prompt (cf, uf); } else @@ -1333,13 +1565,19 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, case UNIX_CLI_PARSE_ACTION_PAGER_DN: case UNIX_CLI_PARSE_ACTION_PAGER_CRLF: /* display the next line of the buffer */ - if (cf->pager_start < cf->pager_lines - (cf->height - 1)) + if (cf->pager_start < vec_len (cf->pager_index) - (cf->height - 1)) { u8 * line; + unix_cli_pager_index_t * pi; + unix_cli_pager_prompt_erase (cf, uf); - line = cf->pager_vector[cf->pager_start + (cf->height - 1)]; - unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line)); + pi = &cf->pager_index[cf->pager_start + (cf->height - 1)]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); cf->pager_start ++; + /* if the last line didn't end in newline, add a newline */ + if (line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); unix_cli_pager_prompt (cf, uf); } else @@ -1355,16 +1593,20 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, /* scroll the page back one line */ if (cf->pager_start > 0) { - u8 * line; + u8 * line = NULL; + unix_cli_pager_index_t * pi = NULL; + cf->pager_start --; if (cf->ansi_capable) { + pi = &cf->pager_index[cf->pager_start]; + line = cf->pager_vector[pi->line] + pi->offset; unix_cli_pager_prompt_erase (cf, uf); unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_SCROLLDN, sizeof(ANSI_SCROLLDN) - 1); unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_SAVECURSOR, sizeof(ANSI_SAVECURSOR) - 1); unix_cli_ansi_cursor(cf, uf, 1, 1); unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_CLEARLINE, sizeof(ANSI_CLEARLINE) - 1); - unix_vlib_cli_output_cooked (cf, uf, cf->pager_vector[cf->pager_start], vec_len(cf->pager_vector[cf->pager_start])); + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); unix_vlib_cli_output_cooked (cf, uf, (u8 *)ANSI_RESTCURSOR, sizeof(ANSI_RESTCURSOR) - 1); unix_cli_pager_prompt_erase (cf, uf); unix_cli_pager_prompt (cf, uf); @@ -1373,11 +1615,15 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, { int m = cf->pager_start + (cf->height - 1); unix_cli_pager_prompt_erase (cf, uf); - for (j = cf->pager_start; j < cf->pager_lines && j < m; j ++) + for (j = cf->pager_start; j < vec_len (cf->pager_index) && j < m; j ++) { - line = cf->pager_vector[j]; - unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line)); + pi = &cf->pager_index[j]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); } + /* if the last line didn't end in newline, add a newline */ + if (pi && line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); unix_cli_pager_prompt (cf, uf); } } @@ -1387,32 +1633,44 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, /* back to the first page of the buffer */ if (cf->pager_start > 0) { - u8 * line; + u8 * line = NULL; + unix_cli_pager_index_t * pi = NULL; + cf->pager_start = 0; int m = cf->pager_start + (cf->height - 1); unix_cli_pager_prompt_erase (cf, uf); - for (j = cf->pager_start; j < cf->pager_lines && j < m; j ++) + for (j = cf->pager_start; j < vec_len (cf->pager_index) && j < m; j ++) { - line = cf->pager_vector[j]; - unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line)); + pi = &cf->pager_index[j]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); } + /* if the last line didn't end in newline, add a newline */ + if (pi && line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); unix_cli_pager_prompt (cf, uf); } break; case UNIX_CLI_PARSE_ACTION_PAGER_BOTTOM: /* skip to the last page of the buffer */ - if (cf->pager_start < cf->pager_lines - (cf->height - 1)) + if (cf->pager_start < vec_len (cf->pager_index) - (cf->height - 1)) { - u8 * line; - cf->pager_start = cf->pager_lines - (cf->height - 1); + u8 * line = NULL; + unix_cli_pager_index_t * pi = NULL; + + cf->pager_start = vec_len (cf->pager_index) - (cf->height - 1); unix_cli_pager_prompt_erase (cf, uf); unix_cli_pager_message (cf, uf, "skipping", "\n"); - for (j = cf->pager_start; j < cf->pager_lines; j ++) + for (j = cf->pager_start; j < vec_len (cf->pager_index); j ++) { - line = cf->pager_vector[j]; - unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line)); + pi = &cf->pager_index[j]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); } + /* if the last line didn't end in newline, add a newline */ + if (pi && line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); unix_cli_pager_prompt (cf, uf); } break; @@ -1421,23 +1679,34 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, /* wander back one page in the buffer */ if (cf->pager_start > 0) { - u8 * line; + u8 * line = NULL; + unix_cli_pager_index_t * pi = NULL; int m; + if (cf->pager_start >= cf->height) cf->pager_start -= cf->height - 1; else - cf->pager_start = 1; + cf->pager_start = 0; m = cf->pager_start + cf->height - 1; unix_cli_pager_prompt_erase (cf, uf); - for (j = cf->pager_start; j < cf->pager_lines && j < m; j ++) + for (j = cf->pager_start; j < vec_len (cf->pager_index) && j < m; j ++) { - line = cf->pager_vector[j]; - unix_vlib_cli_output_cooked (cf, uf, line, vec_len(line)); + pi = &cf->pager_index[j]; + line = cf->pager_vector[pi->line] + pi->offset; + unix_vlib_cli_output_cooked (cf, uf, line, pi->length); } + /* if the last line didn't end in newline, add a newline */ + if (pi && line[pi->length - 1] != '\n') + unix_vlib_cli_output_cooked (cf, uf, (u8 *)"\n", 1); unix_cli_pager_prompt (cf, uf); } break; + case UNIX_CLI_PARSE_ACTION_PAGER_REDRAW: + /* Redraw the current pager screen */ + unix_cli_pager_redraw (cf, uf); + break; + case UNIX_CLI_PARSE_ACTION_PAGER_SEARCH: /* search forwards in the buffer */ break; @@ -1482,7 +1751,7 @@ static int unix_cli_line_process_one(unix_cli_main_t * cm, case UNIX_CLI_PARSE_ACTION_PARTIALMATCH: case UNIX_CLI_PARSE_ACTION_NOMATCH: - if (cf->pager_lines) + if (vec_len (cf->pager_index)) { /* no-op for now */ } @@ -1605,7 +1874,7 @@ static int unix_cli_line_edit (unix_cli_main_t * cm, unix_cli_parse_actions_t *a; /* If we're in the pager mode, search the pager actions */ - a = cf->pager_lines ? unix_cli_parse_pager : unix_cli_parse_strings; + a = vec_len (cf->pager_index) ? unix_cli_parse_pager : unix_cli_parse_strings; /* See if the input buffer is some sort of control code */ action = unix_cli_match_action(a, &cf->input_vector[i], @@ -1714,8 +1983,7 @@ more: (void) unformat (&input, ""); cm->current_input_file_index = cli_file_index; - cf->pager_lines = 0; /* start a new pager session */ - cf->pager_start = 0; + cf->pager_start = 0; /* start a new pager session */ if (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT) vlib_cli_input (um->vlib_main, &input, unix_vlib_cli_output, cli_file_index); @@ -1743,7 +2011,7 @@ done: cf->no_pager = um->cli_no_pager; } - if (cf->pager_lines == 0 || cf->pager_lines < cf->height) + if (vec_len (cf->pager_index) == 0 || vec_len (cf->pager_index) < cf->height) { /* There was no need for the pager */ unix_cli_pager_reset (cf); @@ -2034,9 +2302,11 @@ static clib_error_t * unix_cli_listen_read_ready (unix_file_t * uf) static void unix_cli_resize_interrupt (int signum) { + unix_main_t * um = &unix_main; unix_cli_main_t * cm = &unix_cli_main; unix_cli_file_t * cf = pool_elt_at_index (cm->cli_file_pool, cm->stdin_cli_file_index); + unix_file_t * uf = pool_elt_at_index (um->file_pool, cf->unix_file_index); struct winsize ws; (void)signum; @@ -2044,6 +2314,12 @@ unix_cli_resize_interrupt (int signum) ioctl(UNIX_CLI_STDIN_FD, TIOCGWINSZ, &ws); cf->width = ws.ws_col; cf->height = ws.ws_row; + + /* Reindex the pager buffer */ + unix_cli_pager_reindex (cf); + + /* Redraw the page */ + unix_cli_pager_redraw (cf, uf); } /** Handle configuration directives in the @em unix section. */ |