Commit 7655f4cc authored by Andrew Dunstan's avatar Andrew Dunstan

Add a pager_min_lines setting to psql

If set, the pager will not be used unless this many lines are to be
displayed, even if that is more than the screen depth. Default is zero,
meaning it's disabled.

There is probably more work to be done in giving the user control over
when the pager is used, particularly when wide output forces use of the
pager regardless of how many lines there are, but this is a start.
parent cfe12763
...@@ -2235,6 +2235,18 @@ lo_import 152801 ...@@ -2235,6 +2235,18 @@ lo_import 152801
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>pager_min_lines</literal></term>
<listitem>
<para>
If <literal>pager_min_lines</> is set to a number greater than the
page height, the pager program will not be called unless there are
at least this many lines of output to show. The default setting
is 0.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><literal>recordsep</literal></term> <term><literal>recordsep</literal></term>
<listitem> <listitem>
......
...@@ -1071,7 +1071,8 @@ exec_command(const char *cmd, ...@@ -1071,7 +1071,8 @@ exec_command(const char *cmd,
static const char *const my_list[] = { static const char *const my_list[] = {
"border", "columns", "expanded", "fieldsep", "fieldsep_zero", "border", "columns", "expanded", "fieldsep", "fieldsep_zero",
"footer", "format", "linestyle", "null", "footer", "format", "linestyle", "null",
"numericlocale", "pager", "recordsep", "recordsep_zero", "numericlocale", "pager", "pager_min_lines",
"recordsep", "recordsep_zero",
"tableattr", "title", "tuples_only", "tableattr", "title", "tuples_only",
"unicode_border_linestyle", "unicode_border_linestyle",
"unicode_column_linestyle", "unicode_column_linestyle",
...@@ -1265,7 +1266,7 @@ exec_command(const char *cmd, ...@@ -1265,7 +1266,7 @@ exec_command(const char *cmd,
lines++; lines++;
} }
output = PageOutput(lineno, pset.popt.topt.pager); output = PageOutput(lineno, &(pset.popt.topt));
is_pager = true; is_pager = true;
} }
else else
...@@ -2519,6 +2520,13 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) ...@@ -2519,6 +2520,13 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
popt->topt.pager = 1; popt->topt.pager = 1;
} }
/* set minimum lines for pager use */
else if (strcmp(param, "pager_min_lines") == 0)
{
if (value)
popt->topt.pager_min_lines = atoi(value);
}
/* disable "(x rows)" footer */ /* disable "(x rows)" footer */
else if (strcmp(param, "footer") == 0) else if (strcmp(param, "footer") == 0)
{ {
...@@ -2640,6 +2648,13 @@ printPsetInfo(const char *param, struct printQueryOpt *popt) ...@@ -2640,6 +2648,13 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
printf(_("Pager usage is off.\n")); printf(_("Pager usage is off.\n"));
} }
/* show minimum lines for pager use */
else if (strcmp(param, "pager_min_lines") == 0)
{
printf(_("Pager won't be used for less than %d lines\n"),
popt->topt.pager_min_lines);
}
/* show record separator for unaligned text */ /* show record separator for unaligned text */
else if (strcmp(param, "recordsep") == 0) else if (strcmp(param, "recordsep") == 0)
{ {
...@@ -2792,6 +2807,8 @@ pset_value_string(const char *param, struct printQueryOpt *popt) ...@@ -2792,6 +2807,8 @@ pset_value_string(const char *param, struct printQueryOpt *popt)
return pstrdup(pset_bool_string(popt->topt.numericLocale)); return pstrdup(pset_bool_string(popt->topt.numericLocale));
else if (strcmp(param, "pager") == 0) else if (strcmp(param, "pager") == 0)
return psprintf("%d", popt->topt.pager); return psprintf("%d", popt->topt.pager);
else if (strcmp(param, "pager_min_lines") == 0)
return psprintf("%d", popt->topt.pager_min_lines);
else if (strcmp(param, "recordsep") == 0) else if (strcmp(param, "recordsep") == 0)
return pset_quoted_string(popt->topt.recordSep.separator return pset_quoted_string(popt->topt.recordSep.separator
? popt->topt.recordSep.separator ? popt->topt.recordSep.separator
......
...@@ -1337,7 +1337,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) ...@@ -1337,7 +1337,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
* If query requires multiple result sets, hack to ensure that * If query requires multiple result sets, hack to ensure that
* only one pager instance is used for the whole mess * only one pager instance is used for the whole mess
*/ */
pset.queryFout = PageOutput(100000, my_popt.topt.pager); pset.queryFout = PageOutput(100000, &(my_popt.topt));
did_pager = true; did_pager = true;
} }
......
...@@ -65,7 +65,7 @@ usage(unsigned short int pager) ...@@ -65,7 +65,7 @@ usage(unsigned short int pager)
} }
} }
output = PageOutput(59, pager); output = PageOutput(59, pager ? &(pset.popt.topt) : NULL);
fprintf(output, _("psql is the PostgreSQL interactive terminal.\n\n")); fprintf(output, _("psql is the PostgreSQL interactive terminal.\n\n"));
fprintf(output, _("Usage:\n")); fprintf(output, _("Usage:\n"));
...@@ -158,7 +158,7 @@ slashUsage(unsigned short int pager) ...@@ -158,7 +158,7 @@ slashUsage(unsigned short int pager)
currdb = PQdb(pset.db); currdb = PQdb(pset.db);
output = PageOutput(103, pager); output = PageOutput(103, pager ? &(pset.popt.topt) : NULL);
/* if you add/remove a line here, change the row count above */ /* if you add/remove a line here, change the row count above */
...@@ -305,7 +305,7 @@ helpVariables(unsigned short int pager) ...@@ -305,7 +305,7 @@ helpVariables(unsigned short int pager)
{ {
FILE *output; FILE *output;
output = PageOutput(85, pager); output = PageOutput(85, pager ? &(pset.popt.topt) : NULL);
fprintf(output, _("List of specially treated variables.\n")); fprintf(output, _("List of specially treated variables.\n"));
...@@ -435,7 +435,7 @@ helpSQL(const char *topic, unsigned short int pager) ...@@ -435,7 +435,7 @@ helpSQL(const char *topic, unsigned short int pager)
ncolumns = Max(ncolumns, 1); ncolumns = Max(ncolumns, 1);
nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns; nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns;
output = PageOutput(nrows + 1, pager); output = PageOutput(nrows + 1, pager ? &(pset.popt.topt) : NULL);
fputs(_("Available help:\n"), output); fputs(_("Available help:\n"), output);
...@@ -488,7 +488,7 @@ helpSQL(const char *topic, unsigned short int pager) ...@@ -488,7 +488,7 @@ helpSQL(const char *topic, unsigned short int pager)
if (wordlen >= len) /* Don't try again if the same word */ if (wordlen >= len) /* Don't try again if the same word */
{ {
if (!output) if (!output)
output = PageOutput(nl_count, pager); output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL);
break; break;
} }
len = wordlen; len = wordlen;
...@@ -509,7 +509,7 @@ helpSQL(const char *topic, unsigned short int pager) ...@@ -509,7 +509,7 @@ helpSQL(const char *topic, unsigned short int pager)
} }
if (!output) if (!output)
output = PageOutput(nl_count, pager); output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL);
for (i = 0; QL_HELP[i].cmd; i++) for (i = 0; QL_HELP[i].cmd; i++)
{ {
......
...@@ -474,7 +474,7 @@ printHistory(const char *fname, unsigned short int pager) ...@@ -474,7 +474,7 @@ printHistory(const char *fname, unsigned short int pager)
if (fname == NULL) if (fname == NULL)
{ {
/* use pager, if enabled, when printing to console */ /* use pager, if enabled, when printing to console */
output = PageOutput(INT_MAX, pager); output = PageOutput(INT_MAX, pager ? &(pset.popt.topt) : NULL);
is_pager = true; is_pager = true;
} }
else else
......
...@@ -811,7 +811,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) ...@@ -811,7 +811,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
if (!is_pager && fout == stdout && output_columns > 0 && if (!is_pager && fout == stdout && output_columns > 0 &&
(output_columns < total_header_width || output_columns < width_total)) (output_columns < total_header_width || output_columns < width_total))
{ {
fout = PageOutput(INT_MAX, cont->opt->pager); /* force pager */ fout = PageOutput(INT_MAX, cont->opt); /* force pager */
is_pager = true; is_pager = true;
} }
...@@ -2497,15 +2497,19 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout) ...@@ -2497,15 +2497,19 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
* PageOutput * PageOutput
* *
* Tests if pager is needed and returns appropriate FILE pointer. * Tests if pager is needed and returns appropriate FILE pointer.
*
* If the topt argument is NULL no pager is used.
*/ */
FILE * FILE *
PageOutput(int lines, unsigned short int pager) PageOutput(int lines, const printTableOpt *topt)
{ {
/* check whether we need / can / are supposed to use pager */ /* check whether we need / can / are supposed to use pager */
if (pager && isatty(fileno(stdin)) && isatty(fileno(stdout))) if (topt && topt->pager && isatty(fileno(stdin)) && isatty(fileno(stdout)))
{ {
const char *pagerprog; const char *pagerprog;
FILE *pagerpipe; FILE *pagerpipe;
unsigned short int pager = topt->pager;
int min_lines = topt->pager_min_lines;
#ifdef TIOCGWINSZ #ifdef TIOCGWINSZ
int result; int result;
...@@ -2514,7 +2518,9 @@ PageOutput(int lines, unsigned short int pager) ...@@ -2514,7 +2518,9 @@ PageOutput(int lines, unsigned short int pager)
result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size); result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
/* >= accounts for a one-line prompt */ /* >= accounts for a one-line prompt */
if (result == -1 || lines >= screen_size.ws_row || pager > 1) if (result == -1
|| (lines >= screen_size.ws_row && lines >= min_lines)
|| pager > 1)
{ {
#endif #endif
pagerprog = getenv("PAGER"); pagerprog = getenv("PAGER");
...@@ -2814,7 +2820,7 @@ IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expande ...@@ -2814,7 +2820,7 @@ IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expande
lines++; lines++;
} }
*fout = PageOutput(lines + extra_lines, cont->opt->pager); *fout = PageOutput(lines + extra_lines, cont->opt);
*is_pager = (*fout != stdout); *is_pager = (*fout != stdout);
} }
else else
......
...@@ -89,6 +89,8 @@ typedef struct printTableOpt ...@@ -89,6 +89,8 @@ typedef struct printTableOpt
* 1=dividing lines, 2=full */ * 1=dividing lines, 2=full */
unsigned short int pager; /* use pager for output (if to stdout and unsigned short int pager; /* use pager for output (if to stdout and
* stdout is a tty) 0=off 1=on 2=always */ * stdout is a tty) 0=off 1=on 2=always */
int pager_min_lines;/* don't use pager unless there are at least
* this many lines */
bool tuples_only; /* don't output headers, row counts, etc. */ bool tuples_only; /* don't output headers, row counts, etc. */
bool start_table; /* print start decoration, eg <table> */ bool start_table; /* print start decoration, eg <table> */
bool stop_table; /* print stop decoration, eg </table> */ bool stop_table; /* print stop decoration, eg </table> */
...@@ -164,7 +166,7 @@ extern const printTextFormat pg_asciiformat_old; ...@@ -164,7 +166,7 @@ extern const printTextFormat pg_asciiformat_old;
extern const printTextFormat pg_utf8format; extern const printTextFormat pg_utf8format;
extern FILE *PageOutput(int lines, unsigned short int pager); extern FILE *PageOutput(int lines, const printTableOpt *topt);
extern void ClosePager(FILE *pagerpipe); extern void ClosePager(FILE *pagerpipe);
extern void html_escaped_print(const char *in, FILE *fout); extern void html_escaped_print(const char *in, FILE *fout);
......
...@@ -129,6 +129,7 @@ main(int argc, char *argv[]) ...@@ -129,6 +129,7 @@ main(int argc, char *argv[])
pset.popt.topt.format = PRINT_ALIGNED; pset.popt.topt.format = PRINT_ALIGNED;
pset.popt.topt.border = 1; pset.popt.topt.border = 1;
pset.popt.topt.pager = 1; pset.popt.topt.pager = 1;
pset.popt.topt.pager_min_lines = 0;
pset.popt.topt.start_table = true; pset.popt.topt.start_table = true;
pset.popt.topt.stop_table = true; pset.popt.topt.stop_table = true;
pset.popt.topt.default_footer = true; pset.popt.topt.default_footer = true;
......
...@@ -65,6 +65,7 @@ linestyle ascii ...@@ -65,6 +65,7 @@ linestyle ascii
null '' null ''
numericlocale off numericlocale off
pager 1 pager 1
pager_min_lines 0
recordsep '\n' recordsep '\n'
recordsep_zero off recordsep_zero off
tableattr tableattr
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment