
From: Simon Glass <sjg@chromium.org> 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> --- common/pager.c | 36 +++++++++++++++++++++++++----------- doc/usage/console.rst | 3 +++ include/pager.h | 4 ++++ test/common/pager.c | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/common/pager.c b/common/pager.c index a16937768b6..c0a55b738b9 100644 --- a/common/pager.c +++ b/common/pager.c @@ -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; - - /* skip the newline, since our prompt has one */ - p++; - break; + 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; + } } + } 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: diff --git a/doc/usage/console.rst b/doc/usage/console.rst index 4a28ea95906..880a5b7b605 100644 --- a/doc/usage/console.rst +++ b/doc/usage/console.rst @@ -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 ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/pager.h b/include/pager.h index b43b332a83c..887f5d1f639 100644 --- a/include/pager.h +++ b/include/pager.h @@ -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 diff --git a/test/common/pager.c b/test/common/pager.c index 53902ab29a3..636069d5b37 100644 --- a/test/common/pager.c +++ b/test/common/pager.c @@ -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); -- 2.43.0