]> granicus.if.org Git - postgresql/commitdiff
Add a pager_min_lines setting to psql
authorAndrew Dunstan <andrew@dunslane.net>
Sat, 28 Mar 2015 15:07:41 +0000 (11:07 -0400)
committerAndrew Dunstan <andrew@dunslane.net>
Sat, 28 Mar 2015 15:07:41 +0000 (11:07 -0400)
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.

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/common.c
src/bin/psql/help.c
src/bin/psql/input.c
src/bin/psql/print.c
src/bin/psql/print.h
src/bin/psql/startup.c
src/test/regress/expected/psql.out

index a6370014987d5d69f4cfda862b93cd182d705c15..a33e460bca08dc00d0e34140924545baf3faaf0c 100644 (file)
@@ -2235,6 +2235,18 @@ lo_import 152801
           </listitem>
           </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>
           <term><literal>recordsep</literal></term>
           <listitem>
index 7c9f28dee067efb992612f3e6f4758eefa999d00..e64c033bf8c474e48ef4e71f3a186f7529cb2710 100644 (file)
@@ -1071,7 +1071,8 @@ exec_command(const char *cmd,
                        static const char *const my_list[] = {
                                "border", "columns", "expanded", "fieldsep", "fieldsep_zero",
                                "footer", "format", "linestyle", "null",
-                               "numericlocale", "pager", "recordsep", "recordsep_zero",
+                               "numericlocale", "pager", "pager_min_lines",
+                               "recordsep", "recordsep_zero",
                                "tableattr", "title", "tuples_only",
                                "unicode_border_linestyle",
                                "unicode_column_linestyle",
@@ -1265,7 +1266,7 @@ exec_command(const char *cmd,
                                        lines++;
                                }
 
-                               output = PageOutput(lineno, pset.popt.topt.pager);
+                               output = PageOutput(lineno, &(pset.popt.topt));
                                is_pager = true;
                        }
                        else
@@ -2519,6 +2520,13 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
                        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 */
        else if (strcmp(param, "footer") == 0)
        {
@@ -2640,6 +2648,13 @@ printPsetInfo(const char *param, struct printQueryOpt *popt)
                        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 */
        else if (strcmp(param, "recordsep") == 0)
        {
@@ -2792,6 +2807,8 @@ pset_value_string(const char *param, struct printQueryOpt *popt)
                return pstrdup(pset_bool_string(popt->topt.numericLocale));
        else if (strcmp(param, "pager") == 0)
                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)
                return pset_quoted_string(popt->topt.recordSep.separator
                                                                  ? popt->topt.recordSep.separator
index 15488ff035726951148523e20d539ed33885447e..2e7d9a45cb388de2efb8429cf0b593f11f187d68 100644 (file)
@@ -1337,7 +1337,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec)
                         * If query requires multiple result sets, hack to ensure that
                         * 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;
                }
 
index ac0dc279078af910818e5062f904a39b49789ccd..2da444b6d594b41b0a050cfbf271af3822f0d9f7 100644 (file)
@@ -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, _("Usage:\n"));
@@ -158,7 +158,7 @@ slashUsage(unsigned short int pager)
 
        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 */
 
@@ -305,7 +305,7 @@ helpVariables(unsigned short int pager)
 {
        FILE       *output;
 
-       output = PageOutput(85, pager);
+       output = PageOutput(85, pager ? &(pset.popt.topt) : NULL);
 
        fprintf(output, _("List of specially treated variables.\n"));
 
@@ -435,7 +435,7 @@ helpSQL(const char *topic, unsigned short int pager)
                ncolumns = Max(ncolumns, 1);
                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);
 
@@ -488,7 +488,7 @@ helpSQL(const char *topic, unsigned short int pager)
                                if (wordlen >= len)             /* Don't try again if the same word */
                                {
                                        if (!output)
-                                               output = PageOutput(nl_count, pager);
+                                               output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL);
                                        break;
                                }
                                len = wordlen;
@@ -509,7 +509,7 @@ helpSQL(const char *topic, unsigned short int pager)
                        }
 
                        if (!output)
-                               output = PageOutput(nl_count, pager);
+                               output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL);
 
                        for (i = 0; QL_HELP[i].cmd; i++)
                        {
index d52a3347970fd957910fb09de33b36d29fae2f75..437fa4d663ae6c5b61f967542402c5ff1cc7a0fa 100644 (file)
@@ -474,7 +474,7 @@ printHistory(const char *fname, unsigned short int pager)
        if (fname == NULL)
        {
                /* 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;
        }
        else
index f6f931084132b91e72f41307b0a6300cae1dcfbc..9c12dbe049a58b311d79a452d5c0cc66e4110bdd 100644 (file)
@@ -811,7 +811,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
        if (!is_pager && fout == stdout && output_columns > 0 &&
                (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;
        }
 
@@ -2497,15 +2497,19 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
  * PageOutput
  *
  * Tests if pager is needed and returns appropriate FILE pointer.
+ *
+ * If the topt argument is NULL no pager is used.
  */
 FILE *
-PageOutput(int lines, unsigned short int pager)
+PageOutput(int lines, const printTableOpt *topt)
 {
        /* 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;
                FILE       *pagerpipe;
+               unsigned short int  pager =  topt->pager;
+               int         min_lines = topt->pager_min_lines;
 
 #ifdef TIOCGWINSZ
                int                     result;
@@ -2514,7 +2518,9 @@ PageOutput(int lines, unsigned short int pager)
                result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size);
 
                /* >= 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
                        pagerprog = getenv("PAGER");
@@ -2814,7 +2820,7 @@ IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expande
                                lines++;
                }
 
-               *fout = PageOutput(lines + extra_lines, cont->opt->pager);
+               *fout = PageOutput(lines + extra_lines, cont->opt);
                *is_pager = (*fout != stdout);
        }
        else
index a1a89d01dbbf1311cda3d7d10c182f461f35bf1d..66cdaf32ae743c175b3bfda946ececc1b5975217 100644 (file)
@@ -89,6 +89,8 @@ typedef struct printTableOpt
                                                                 * 1=dividing lines, 2=full */
        unsigned short int pager;       /* use pager for output (if to stdout and
                                                                 * 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            start_table;    /* print start decoration, eg <table> */
        bool            stop_table;             /* print stop decoration, eg </table> */
@@ -164,7 +166,7 @@ extern const printTextFormat pg_asciiformat_old;
 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 html_escaped_print(const char *in, FILE *fout);
index 7f09c141a90f5cdf4af137dd5fd02c511df86b80..d57901f778010d675cd79699579af7dca0074614 100644 (file)
@@ -129,6 +129,7 @@ main(int argc, char *argv[])
        pset.popt.topt.format = PRINT_ALIGNED;
        pset.popt.topt.border = 1;
        pset.popt.topt.pager = 1;
+       pset.popt.topt.pager_min_lines = 0;
        pset.popt.topt.start_table = true;
        pset.popt.topt.stop_table = true;
        pset.popt.topt.default_footer = true;
index e87b82b9910c4ce619f388293396d171ee289f90..a2a261595a6d0d70f05d4d7f1eef9d7ac32711a2 100644 (file)
@@ -65,6 +65,7 @@ linestyle                ascii
 null                     ''
 numericlocale            off
 pager                    1
+pager_min_lines          0
 recordsep                '\n'
 recordsep_zero           off
 tableattr