console: Add bypass keypress to disable paging

Add support for pressing 'Q' to put the pager into bypass mode,disabling
further paging for the current session.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-08-22 16:28:10 -06:00
parent e617ccfc40
commit c7ba355d1f
4 changed files with 70 additions and 10 deletions

View File

@@ -71,6 +71,10 @@ const char *pager_next(struct pager *pag, bool use_pager, int key)
pag->state = PAGERST_WAIT_USER;
return PAGER_PROMPT;
case PAGERST_WAIT_USER:
if (key == 'Q') {
pag->state = PAGERST_BYPASS;
return PAGER_BLANK;
}
if (key != ' ')
return PAGER_WAITING;
pag->state = PAGERST_CLEAR_PROMPT;
@@ -79,7 +83,7 @@ const char *pager_next(struct pager *pag, bool use_pager, int key)
pag->state = PAGERST_OK;
break;
case PAGERST_BYPASS:
return NULL;
break;
}
ret = membuf_getraw(&pag->mb, pag->buf.size - 1, false, &str);
@@ -93,17 +97,26 @@ const char *pager_next(struct pager *pag, bool use_pager, int key)
return NULL;
}
/* return lines until we reach the limit */
for (p = str, end = str + ret; p < end; p++) {
if (*p == '\n' && ++pag->line_count == pag->page_len - 1) {
/* remember to display the pager message next time */
pag->state = PAGERST_AT_LIMIT;
pag->line_count = 0;
end = str + ret;
if (pag->state != PAGERST_BYPASS) {
/* return lines until we reach the limit */
for (p = str; p < end; p++) {
if (*p == '\n' &&
++pag->line_count == pag->page_len - 1) {
/*
* remember to display the pager message next
* time
*/
pag->state = PAGERST_AT_LIMIT;
pag->line_count = 0;
/* skip the newline, since our prompt has one */
p++;
break;
/* skip the newline, since our prompt has one */
p++;
break;
}
}
} else {
p = end;
}
/* remove the used bytes from the membuf */
@@ -178,6 +191,7 @@ static int on_pager(const char *name, const char *value, enum env_op op,
if (value) {
new_page_len = simple_strtoul(value, NULL, 16);
pager_set_page_len(pag, new_page_len);
pager_set_bypass(pag, false);
}
break;
case env_op_delete:

View File

@@ -72,6 +72,9 @@ When activated, the pager pauses at the end of each 'page' (screenful) of
output, shows a prompt ": Press SPACE to continue" and lets the user read the
output. To continue to the next page, press the SPACE key.
The pager can be bypassed by pressing 'Q' at the prompt. This disables the pager
until the 'pager' environment variable is given a new value.
Page Size Configuration
~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -110,6 +110,10 @@ const char *pager_post(struct pager *pag, bool use_pager, const char *s);
* busy-wait for a keypress, if desired, since pager_next() will only ever
* return PAGER_WAITING until @ch is non-zero.
*
* When the pager prompts for user input, pressing SPACE continues to the next
* page, while pressing capital 'Q' puts the pager into bypass mode and
* disables further paging.
*
* @pag: Pager to use
* @use_pager: Whether or not to use the pager functionality
* @ch: Key that the user has pressed, or 0 if none

View File

@@ -579,3 +579,42 @@ static int pager_test_console(struct unit_test_state *uts)
return 0;
}
COMMON_TEST(pager_test_console, UTF_CONSOLE);
/* Test bypass keypress ('Q') functionality */
static int pager_test_bypass_keypress(struct unit_test_state *uts)
{
struct pager *pag;
const char *out;
int ret;
ret = pager_init(&pag, 3, SZ_1K);
ut_assertok(ret);
/* Post text that will trigger paging */
out = pager_post(pag, true, "line1\nline2\nline3\nline4\n");
ut_assertnonnull(out);
ut_asserteq_str("line1\nline2", out);
/* Should be waiting for user input */
out = pager_next(pag, true, 0);
ut_asserteq_str(PAGER_PROMPT, out);
/* Press 'Q' to bypass */
out = pager_next(pag, true, 'Q');
ut_asserteq_str(PAGER_BLANK, out);
/* Verify pager is now in bypass mode */
ut_asserteq(PAGERST_BYPASS, pag->state);
/* Next call should return the remaining text without paging */
out = pager_next(pag, true, 0);
ut_asserteq_str("line3\nline4\n", out);
/* No more text should be available */
out = pager_next(pag, true, 0);
ut_asserteq_ptr(NULL, out);
pager_uninit(pag);
return 0;
}
COMMON_TEST(pager_test_bypass_keypress, 0);