Hi. I've improved the patch. It works in expanded mode when either format option is set to wrapped (\pset format wrapped), or we have no pager, or pager doesn't chop long lines (so you can still use the trick). Target output width is taken from either columns option (\pset columns 70), or environment variable $COLUMNS, or terminal size. And it's also compatible with any border style (\pset border 0|1|2).
Here are some examples: postgres=# \x 1 postgres=# \pset format wrapped postgres=# \pset border 0 postgres=# select * from wide_table; * Record 1 value afadsafasd fasdf asdfasd fsad fas df sadf sad f sadf sadf sa df sadfsadfa sd fsad fsa df sadf asd fa sfd sadfsadf asdf sad f sadf sad fadsf * Record 2 value afadsafasd fasdf asdfasd postgres=# \pset border 1 postgres=# \pset columns 70 postgres=# select * from wide_table; -[ RECORD 1 ]--------------------------------------------------------- value | afadsafasd fasdf asdfasd fsad fas df sadf sad f sadf sadf sa | df sadfsadfasd fsad fsa df sadf asd fa sfd sadfsadf asdf sad f | sadf sad fadsf -[ RECORD 2 ]--------------------------------------------------------- value | afadsafasd fasdf asdfasd postgres=# \pset border 2 postgres=# \pset columns 60 postgres=# select * from wide_table; +-[ RECORD 1 ]---------------------------------------------+ | value | afadsafasd fasdf asdfasd fsad fas df sadf sad f | | | sadf sadf sa df sadfsadfasd fsad fsa df sadf as | | | d fa sfd sadfsadf asdf sad f sadf sad fadsf | +-[ RECORD 2 ]---------------------------------------------+ | value | afadsafasd fasdf asdfasd | +-------+--------------------------------------------------+ Regards, Sergey 2013/12/10 Jeff Janes <jeff.ja...@gmail.com> > On Mon, Dec 2, 2013 at 10:45 PM, Sergey Muraviov < > sergey.k.murav...@gmail.com> wrote: > >> Hi. >> >> Psql definitely have a problem with displaying "wide" tables. >> Even in expanded mode, they look horrible. >> So I tried to solve this problem. >> > > I get compiler warnings: > > print.c: In function 'print_aligned_vertical': > print.c:1238: warning: ISO C90 forbids mixed declarations and code > print.c: In function 'print_aligned_vertical': > print.c:1238: warning: ISO C90 forbids mixed declarations and code > > But I really like this and am already benefiting from it. No point in > having the string of hyphens between every record wrap to be 30 lines long > just because one field somewhere down the list does so. And configuring > the pager isn't much of a solution because the pager doesn't know that the > hyphens are semantically different than the other stuff getting thrown at > it. > > Cheers, > > Jeff > > > -- Best regards, Sergey Muraviov
From be9f01777599dc5e84c417e5cae56459677a88d4 Mon Sep 17 00:00:00 2001 From: Sergey Muraviov <sergey.k.murav...@gmail.com> Date: Wed, 11 Dec 2013 20:17:26 +0400 Subject: [PATCH] wrapped tables in expanded mode --- src/bin/psql/print.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 5 deletions(-) diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 736225c..4c37f7d 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -124,6 +124,7 @@ const printTextFormat pg_utf8format = /* Local functions */ static int strlen_max_width(unsigned char *str, int *target_width, int encoding); +static bool IsWrappingNeeded(const printTableContent *cont, bool is_pager); static void IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expanded, FILE **fout, bool *is_pager); @@ -1234,6 +1235,45 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) fprintf(fout, "%s\n", cont->title); } + if (IsWrappingNeeded(cont, is_pager)) + { + int output_columns = 0; + /* + * Choose target output width: \pset columns, or $COLUMNS, or ioctl + */ + if (cont->opt->columns > 0) + output_columns = cont->opt->columns; + else + { + if (cont->opt->env_columns > 0) + output_columns = cont->opt->env_columns; +#ifdef TIOCGWINSZ + else + { + struct winsize screen_size; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1) + output_columns = screen_size.ws_col; + } +#endif + } + + output_columns -= hwidth; + + if (opt_border == 0) + output_columns -= 1; + else + { + output_columns -= 3; /* -+- */ + + if (opt_border > 1) + output_columns -= 4; /* +--+ */ + } + + if ((output_columns > 0) && (dwidth > output_columns)) + dwidth = output_columns; + } + /* print records */ for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) { @@ -1294,12 +1334,49 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) if (!dcomplete) { - if (opt_border < 2) - fprintf(fout, "%s\n", dlineptr[line_count].ptr); + if (dlineptr[line_count].width > dwidth) + { + int offset = 0; + int chars_to_output = dlineptr[line_count].width; + while (chars_to_output > 0) + { + int target_width, bytes_to_output; + + if (offset > 0) + { + if (opt_border == 2) + fprintf(fout, "%s ", dformat->leftvrule); + + fprintf(fout, "%*s", hwidth, " "); + + if (opt_border > 0) + fprintf(fout, " %s ", dformat->midvrule); + else + fputc(' ', fout); + } + + target_width = dwidth; + bytes_to_output = strlen_max_width(dlineptr[line_count].ptr + offset, + &target_width, encoding); + fputnbytes(fout, (char *)(dlineptr[line_count].ptr + offset), bytes_to_output); + chars_to_output -= target_width; + offset += bytes_to_output; + + if (opt_border < 2) + fputc('\n', fout); + else + fprintf(fout, "%*s %s\n", dwidth - target_width, "", dformat->rightvrule); + } + } else - fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr, - dwidth - dlineptr[line_count].width, "", - dformat->rightvrule); + { + if (opt_border < 2) + fprintf(fout, "%s\n", dlineptr[line_count].ptr); + else + fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr, + dwidth - dlineptr[line_count].width, "", + dformat->rightvrule); + } if (!dlineptr[line_count + 1].ptr) dcomplete = 1; @@ -2175,6 +2252,42 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout) /* Public functions */ /********************************/ +/* + * IsWrappingNeeded + * + * Tests if wrapping is needed + */ +static bool +IsWrappingNeeded(const printTableContent *cont, bool is_pager) +{ + const char *pagerprog = 0, + *less_options = 0; + + if ((cont->opt->format == PRINT_WRAPPED) || (is_pager == false)) + return true; + + pagerprog = getenv("PAGER"); + if (!pagerprog) + pagerprog = DEFAULT_PAGER; + + if (strcmp(pagerprog, "less") != 0) + return true; + + less_options = getenv("LESS"); + if (!less_options) + return true; +/* + * Test for -S option + * Causes lines longer than the screen width to be chopped rather + * than folded. That is, the portion of a long line that does not + * fit in the screen width is not shown. The default is to fold + * long lines; that is, display the remainder on the next line. + */ + if (strchr(less_options, 'S')) + return false; + else + return true; +} /* * PageOutput -- 1.8.3.1
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers