
From: Simon Glass <sjg@chromium.org> Add support for pressing 'q' to throw away any further output until the prompt is reached. Signed-off-by: Simon Glass <sjg@chromium.org> --- common/cli_readline.c | 1 + common/pager.c | 19 +++++++++++++++++ doc/usage/console.rst | 3 ++- include/pager.h | 20 +++++++++++++++++- test/common/pager.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 2 deletions(-) diff --git a/common/cli_readline.c b/common/cli_readline.c index dc27a962e9d..244a287b435 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -654,6 +654,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, static int initted; bool old_bypass; + pager_clear_quit(gd_pager()); old_bypass = pager_set_bypass(gd_pager(), true); /* diff --git a/common/pager.c b/common/pager.c index c0a55b738b9..60b1adc8571 100644 --- a/common/pager.c +++ b/common/pager.c @@ -24,6 +24,9 @@ const char *pager_post(struct pager *pag, bool use_pager, const char *s) pag->state == PAGERST_BYPASS) return s; + if (pag->state == PAGERST_QUIT_SUPPRESS) + return NULL; + len = strlen(s); if (!len) return NULL; @@ -75,6 +78,10 @@ const char *pager_next(struct pager *pag, bool use_pager, int key) pag->state = PAGERST_BYPASS; return PAGER_BLANK; } + if (key == 'q') { + pag->state = PAGERST_QUIT_SUPPRESS; + return "\r \r"; + } if (key != ' ') return PAGER_WAITING; pag->state = PAGERST_CLEAR_PROMPT; @@ -84,6 +91,9 @@ const char *pager_next(struct pager *pag, bool use_pager, int key) break; case PAGERST_BYPASS: break; + case PAGERST_QUIT_SUPPRESS: + membuf_purge(&pag->mb); + return NULL; } ret = membuf_getraw(&pag->mb, pag->buf.size - 1, false, &str); @@ -176,6 +186,15 @@ void pager_reset(struct pager *pag) pag->line_count = 0; } +void pager_clear_quit(struct pager *pag) +{ + if (!pag) + return; + + if (pag->state == PAGERST_QUIT_SUPPRESS) + pag->state = PAGERST_OK; +} + static int on_pager(const char *name, const char *value, enum env_op op, int flags) { diff --git a/doc/usage/console.rst b/doc/usage/console.rst index 880a5b7b605..088760c6f86 100644 --- a/doc/usage/console.rst +++ b/doc/usage/console.rst @@ -70,7 +70,8 @@ only available if `CONFIG_CONSOLE_MUX` is also enabled. 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. +output. To continue to the next page, press the SPACE key. To quit paging +without seeing further output from the current command, press 'q'. 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. diff --git a/include/pager.h b/include/pager.h index 887f5d1f639..3f13f82885d 100644 --- a/include/pager.h +++ b/include/pager.h @@ -33,6 +33,7 @@ * @PAGERST_WAIT_USER: Waiting for the user to press a key * @PAGERST_CLEAR_PROMPT: Clearing the prompt ready for more output * @PAGERST_BYPASS: Pager is being bypassed + * @PAGERST_QUIT_SUPPRESS: Output is being suppressed after 'q' keypress */ enum pager_state { PAGERST_OK, @@ -40,6 +41,7 @@ enum pager_state { PAGERST_WAIT_USER, PAGERST_CLEAR_PROMPT, PAGERST_BYPASS, + PAGERST_QUIT_SUPPRESS, }; /** @@ -112,7 +114,8 @@ const char *pager_post(struct pager *pag, bool use_pager, const char *s); * * 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. + * disables further paging. Pressing 'q' quits and suppresses all output until + * the next command prompt. * * @pag: Pager to use * @use_pager: Whether or not to use the pager functionality @@ -157,6 +160,17 @@ bool pager_set_test_bypass(struct pager *pag, bool bypass); */ void pager_reset(struct pager *pag); +/** + * pager_clear_quit() - Clear quit suppression mode + * + * If the pager is in PAGERST_QUIT_SUPPRESS state, this resets it to normal + * operation (PAGERST_OK). This is typically called at the start of + * cli_readline_into_buffer() to allow new commands to display output normally. + * + * @pag: Pager to update, may be NULL in which case this function does nothing + */ +void pager_clear_quit(struct pager *pag); + /** * pager_uninit() - Uninit the pager * @@ -188,6 +202,10 @@ static inline bool pager_set_test_bypass(struct pager *pag, bool bypass) return true; } +static inline void pager_clear_quit(struct pager *pag) +{ +} + static inline void pager_reset(struct pager *pag) { } diff --git a/test/common/pager.c b/test/common/pager.c index 636069d5b37..ccd5230f3a4 100644 --- a/test/common/pager.c +++ b/test/common/pager.c @@ -618,3 +618,50 @@ static int pager_test_bypass_keypress(struct unit_test_state *uts) return 0; } COMMON_TEST(pager_test_bypass_keypress, 0); + +/* Test quit keypress ('q') functionality */ +static int pager_test_quit_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 quit and suppress */ + out = pager_next(pag, true, 'q'); + ut_asserteq_str("\r \r", out); + + /* Verify pager is now in quit suppress mode */ + ut_asserteq(PAGERST_QUIT_SUPPRESS, pag->state); + + /* Next call should return NULL (suppressed) */ + out = pager_next(pag, true, 0); + ut_asserteq_ptr(NULL, out); + + /* Posting new text should also return NULL (suppressed) */ + out = pager_post(pag, true, "new text\n"); + ut_asserteq_ptr(NULL, out); + + /* Test that pager_clear_quit() restores normal operation */ + pager_clear_quit(pag); + ut_asserteq(PAGERST_OK, pag->state); + + /* and that any new test appears */ + out = pager_post(pag, true, "more new text\n"); + ut_asserteq_str("more new text\n", out); + + pager_uninit(pag); + return 0; +} +COMMON_TEST(pager_test_quit_keypress, 0); -- 2.43.0