@@ -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:
@@ -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
~~~~~~~~~~~~~~~~~~~~~~~
@@ -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
@@ -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);