console: Add a way to quit pager with no further output
Add support for pressing 'q' to throw away any further output until the prompt is reached. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
@@ -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);
|
||||
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user