Hi,

Pavel Stehule <pavel.steh...@gmail.com>:
> > I strongly agree. It was a lot of work to find a workable solution for 
> > pspg. Special chars that starting result and maybe other, that ending 
> > result can significantly increase robustness and can reduce code. I think 
> > it can be better to use form feed at the end of form - like it is semantic 
> > of form feed. You know, at this moment, the result is complete. 
> > https://en.wikipedia.org/wiki/Page_break
>
> It's easier to print a form feed before the result, but it's okay at the end.
>
> > I don't think using it by default can be the best. Lot of people don't use 
> > specialized pagers, but it can be set by \pset. Form feed should be used on 
> > end
> >
> > \pset formfeed [on, off]
>
> I think it's a good idea to be able to switch with \pset.

I have created a patch that allows you to turn it on and off in \pset.
The attached patch adds the following features.


Formfeed can be turned on with the command line option or \pset.
Formfeed (\f\n) is output after the query execution result by \watch.

I think the considerations are as follows.

* Is formfeed output after the result, not before?
* Is the formfeed output only "\f\n"?
* Is the formfeed output only executed by \watch?
* Is the name "formfeed" appropriate?

If the formfeed is output before the query result,
it will be better if the screen is reset when the formfeed is read.

Furthermore, if the terminal clear string can be set instead of the
formfeed character,
the \watch output can be fixedly displayed without a pager.

(I noticed that if I set it in the title, it would behave similarly in
the current version.
    # \C '\033[2J;\033[0;0H'
    # SELECT now();\watch 1
)

Also, it may be good to output formfeed when outputting a file with
`\o result.txt`
other than \watch.
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index caabb06c53..68a876c8bd 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -256,6 +256,16 @@ EOF
       </listitem>
     </varlistentry>
 
+    <varlistentry>
+      <term><option>--formfeed</option></term>
+      <listitem>
+      <para>
+      Turn on the formfeed. This is equivalent to
+      <command>\pset formfeed</command>.
+      </para>
+      </listitem>
+    </varlistentry>
+
     <varlistentry>
       <term><option>-h <replaceable class="parameter">hostname</replaceable></option></term>
       <term><option>--host=<replaceable class="parameter">hostname</replaceable></option></term>
@@ -2879,6 +2889,14 @@ lo_import 152801
           Unique abbreviations are allowed.
           </para>
 
+          <varlistentry>
+          <term><literal>formfeed</literal></term>
+          <listitem>
+          <para>
+          Outputs formfeed after every result when using the
+          <literal>\watch</literal> command.
+          </para>
+
           <para><literal>aligned</literal> format is the standard,
           human-readable, nicely formatted text output; this is the default.
           </para>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 292cff5df9..2a1fd6a22d 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2242,8 +2242,8 @@ exec_command_pset(PsqlScanState scan_state, bool active_branch)
 			int			i;
 			static const char *const my_list[] = {
 				"border", "columns", "csv_fieldsep", "expanded", "fieldsep",
-				"fieldsep_zero", "footer", "format", "linestyle", "null",
-				"numericlocale", "pager", "pager_min_lines",
+				"fieldsep_zero", "footer", "format", "formfeed", "linestyle",
+				"null", "numericlocale", "pager", "pager_min_lines",
 				"recordsep", "recordsep_zero",
 				"tableattr", "title", "tuples_only",
 				"unicode_border_linestyle",
@@ -4532,6 +4532,16 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
 		if (value)
 			popt->topt.columns = atoi(value);
 	}
+
+	/* toggle output formfeed */
+	else if (strcmp(param, "formfeed") == 0)
+	{
+		if (value)
+			return ParseVariableBool(value, param, &popt->topt.formfeed);
+		else
+			popt->topt.formfeed = !popt->topt.formfeed;
+	}
+
 	else
 	{
 		pg_log_error("\\pset: unknown option: %s", param);
@@ -4701,6 +4711,15 @@ printPsetInfo(const char *param, printQueryOpt *popt)
 			printf(_("Tuples only is off.\n"));
 	}
 
+	/* show toggle output formfeed */
+	else if (strcmp(param, "formfeed") == 0)
+	{
+		if (popt->topt.formfeed)
+			printf(_("formfeed is on.\n"));
+		else
+			printf(_("formfeed is off.\n"));
+	}
+
 	/* Unicode style formatting */
 	else if (strcmp(param, "unicode_border_linestyle") == 0)
 	{
@@ -4895,6 +4914,8 @@ pset_value_string(const char *param, printQueryOpt *popt)
 		return popt->title ? pset_quoted_string(popt->title) : pstrdup("");
 	else if (strcmp(param, "tuples_only") == 0)
 		return pstrdup(pset_bool_string(popt->topt.tuples_only));
+	else if (strcmp(param, "formfeed") == 0)
+		return pstrdup(pset_bool_string(popt->topt.formfeed));
 	else if (strcmp(param, "unicode_border_linestyle") == 0)
 		return pstrdup(_unicode_linestyle2string(popt->topt.unicode_border_linestyle));
 	else if (strcmp(param, "unicode_column_linestyle") == 0)
diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c
index d65b9a124f..63eff20c55 100644
--- a/src/bin/psql/common.c
+++ b/src/bin/psql/common.c
@@ -647,6 +647,8 @@ PSQLexecWatch(const char *query, const printQueryOpt *opt, FILE *printQueryFout)
 	{
 		case PGRES_TUPLES_OK:
 			printQuery(res, opt, fout, false, pset.logfile);
+			if (opt->topt.formfeed)
+				fprintf(fout, "\f\n");
 			break;
 
 		case PGRES_COMMAND_OK:
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 56afa6817e..78b8fa0463 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -68,7 +68,7 @@ usage(unsigned short int pager)
 	 * Keep this line count in sync with the number of lines printed below!
 	 * Use "psql --help=options | wc" to count correctly.
 	 */
-	output = PageOutput(63, pager ? &(pset.popt.topt) : NULL);
+	output = PageOutput(64, pager ? &(pset.popt.topt) : NULL);
 
 	fprintf(output, _("psql is the PostgreSQL interactive terminal.\n\n"));
 	fprintf(output, _("Usage:\n"));
@@ -117,6 +117,7 @@ usage(unsigned short int pager)
 	fprintf(output, _("  -R, --record-separator=STRING\n"
 					  "                           record separator for unaligned output (default: newline)\n"));
 	fprintf(output, _("  -t, --tuples-only        print rows only\n"));
+	fprintf(output, _("      --formfeed           output after every result when using the \\watch command\n"));
 	fprintf(output, _("  -T, --table-attr=TEXT    set HTML table tag attributes (e.g., width, border)\n"));
 	fprintf(output, _("  -x, --expanded           turn on expanded table output\n"));
 	fprintf(output, _("  -z, --field-separator-zero\n"
@@ -282,7 +283,7 @@ slashUsage(unsigned short int pager)
 			ON(pset.popt.topt.format == PRINT_HTML));
 	fprintf(output, _("  \\pset [NAME [VALUE]]   set table output option\n"
 					  "                         (border|columns|csv_fieldsep|expanded|fieldsep|\n"
-					  "                         fieldsep_zero|footer|format|linestyle|null|\n"
+					  "                         fieldsep_zero|footer|format|formfeed|linestyle|null|\n"
 					  "                         numericlocale|pager|pager_min_lines|recordsep|\n"
 					  "                         recordsep_zero|tableattr|title|tuples_only|\n"
 					  "                         unicode_border_linestyle|unicode_column_linestyle|\n"
@@ -348,7 +349,7 @@ helpVariables(unsigned short int pager)
 	 * Windows builds currently print one fewer line than non-Windows builds.
 	 * Using the larger number is fine.
 	 */
-	output = PageOutput(161, pager ? &(pset.popt.topt) : NULL);
+	output = PageOutput(163, pager ? &(pset.popt.topt) : NULL);
 
 	fprintf(output, _("List of specially treated variables\n\n"));
 
@@ -449,6 +450,8 @@ helpVariables(unsigned short int pager)
 					  "    enable or disable display of the table footer [on, off]\n"));
 	fprintf(output, _("  format\n"
 					  "    set output format [unaligned, aligned, wrapped, html, asciidoc, ...]\n"));
+	fprintf(output, _("  formfeed\n"
+					  "    output formfeed [on, off]\n"));
 	fprintf(output, _("  linestyle\n"
 					  "    set the border line drawing style [ascii, old-ascii, unicode]\n"));
 	fprintf(output, _("  null\n"
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index be9dec749d..76ced1d232 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -173,6 +173,7 @@ main(int argc, char *argv[])
 
 	pset.popt.topt.csvFieldSep[0] = DEFAULT_CSV_FIELD_SEP;
 	pset.popt.topt.csvFieldSep[1] = '\0';
+	pset.popt.topt.formfeed = false;
 
 	pset.popt.topt.unicode_border_linestyle = UNICODE_LINESTYLE_SINGLE;
 	pset.popt.topt.unicode_column_linestyle = UNICODE_LINESTYLE_SINGLE;
@@ -518,6 +519,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options)
 		{"no-psqlrc", no_argument, NULL, 'X'},
 		{"help", optional_argument, NULL, 1},
 		{"csv", no_argument, NULL, 2},
+		{"formfeed", no_argument, NULL, 3},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -714,6 +716,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts *options)
 			case 2:
 				pset.popt.topt.format = PRINT_CSV;
 				break;
+			case 3:
+				pset.popt.topt.formfeed = true;
+				break;
 			default:
 		unknown_option:
 				fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h
index 836b4e29a8..92e0bf4c16 100644
--- a/src/include/fe_utils/print.h
+++ b/src/include/fe_utils/print.h
@@ -125,6 +125,7 @@ typedef struct printTableOpt
 	unicode_linestyle unicode_border_linestyle;
 	unicode_linestyle unicode_column_linestyle;
 	unicode_linestyle unicode_header_linestyle;
+	bool		formfeed;		/* output formfeed after every result */
 } printTableOpt;
 
 /*

Reply via email to