diff --git a/src/bin/psql/create_help.pl b/src/bin/psql/create_help.pl
index f969f9308617c8e2cdd9606666d34dc72b3b7c3d..0fc0f487ce29676609cb00208acc0a7d03bd4834 100644
--- a/src/bin/psql/create_help.pl
+++ b/src/bin/psql/create_help.pl
@@ -5,7 +5,7 @@
 #
 # Copyright (c) 2000-2008, PostgreSQL Global Development Group
 #
-# $PostgreSQL: pgsql/src/bin/psql/create_help.pl,v 1.16 2008/01/01 19:45:55 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/psql/create_help.pl,v 1.17 2008/01/20 21:13:55 tgl Exp $
 #################################################################
 
 #
@@ -51,20 +51,21 @@ print OUT
 #ifndef $define
 #define $define
 
-#define N_(x) (x) /* gettext noop */
+#define N_(x) (x)				/* gettext noop */
 
 struct _helpStruct
 {
-    char	   *cmd;	   /* the command name */
-    char	   *help;	   /* the help associated with it */
-    char	   *syntax;	   /* the syntax associated with it */
+	const char	   *cmd;		/* the command name */
+	const char	   *help;		/* the help associated with it */
+	const char	   *syntax;		/* the syntax associated with it */
 };
 
 
-static struct _helpStruct QL_HELP[] = {
+static const struct _helpStruct QL_HELP[] = {
 ";
 
 $count = 0;
+$maxlen = 0;
 
 foreach $file (sort readdir DIR) {
     local ($cmdname, $cmddesc, $cmdsynopsis);
@@ -113,7 +114,9 @@ foreach $file (sort readdir DIR) {
         $cmdsynopsis =~ s/\"/\\"/g;
 
 	print OUT "    { \"$cmdname\",\n      N_(\"$cmddesc\"),\n      N_(\"$cmdsynopsis\") },\n\n";
-        $count++;
+
+	$count++;
+	$maxlen = ($maxlen >= length $cmdname) ? $maxlen : length $cmdname;
     }
     else {
 	print STDERR "$0: parsing file '$file' failed (N='$cmdname' D='$cmddesc')\n";
@@ -125,7 +128,8 @@ print OUT "
 };
 
 
-#define QL_HELP_COUNT $count
+#define QL_HELP_COUNT	$count		/* number of help items */
+#define QL_MAX_CMD_LEN	$maxlen		/* largest strlen(cmd) */
 
 
 #endif /* $define */
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index e9f2e0db08659edcb62ac527c6da66be0390ff66..9d0eb40a24a297cf8e37ad434dfd36f8d0e20c8a 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2008, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.121 2008/01/01 19:45:56 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.122 2008/01/20 21:13:55 tgl Exp $
  */
 #include "postgres_fe.h"
 
@@ -19,6 +19,14 @@
 #include <win32.h>
 #endif
 
+#ifndef WIN32
+#include <sys/ioctl.h>			/* for ioctl() */
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
 #include "pqsignal.h"
 
 #include "common.h"
@@ -147,15 +155,6 @@ usage(void)
  *
  * print out help for the backslash commands
  */
-
-#ifndef TIOCGWINSZ
-struct winsize
-{
-	int			ws_row;
-	int			ws_col;
-};
-#endif
-
 void
 slashUsage(unsigned short int pager)
 {
@@ -280,24 +279,46 @@ helpSQL(const char *topic, unsigned short int pager)
 
 	if (!topic || strlen(topic) == 0)
 	{
-		int			i;
-		int			items_per_column = (QL_HELP_COUNT + 2) / 3;
+		/* Print all the available command names */
+		int			screen_width;
+		int			ncolumns;
+		int			nrows;
 		FILE	   *output;
+		int			i;
+		int			j;
 
-		output = PageOutput(items_per_column + 1, pager);
+#ifdef TIOCGWINSZ
+		struct winsize screen_size;
+
+		if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1)
+			screen_width = 80;	/* ioctl failed, assume 80 */
+		else
+			screen_width = screen_size.ws_col;
+#else
+		screen_width = 80;		/* default assumption */
+#endif
+
+		ncolumns = (screen_width - 3) / (QL_MAX_CMD_LEN + 1);
+		ncolumns = Max(ncolumns, 1);
+		nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns;
+
+		output = PageOutput(nrows + 1, pager);
 
 		fputs(_("Available help:\n"), output);
 
-		for (i = 0; i < items_per_column; i++)
+		for (i = 0; i < nrows; i++)
 		{
-			fprintf(output, "  %-26s%-26s",
-					VALUE_OR_NULL(QL_HELP[i].cmd),
-					VALUE_OR_NULL(QL_HELP[i + items_per_column].cmd));
-			if (i + 2 * items_per_column < QL_HELP_COUNT)
-				fprintf(output, "%-26s",
-						VALUE_OR_NULL(QL_HELP[i + 2 * items_per_column].cmd));
+			fprintf(output, "  ");
+			for (j = 0; j < ncolumns-1; j++)
+				fprintf(output, "%-*s",
+						QL_MAX_CMD_LEN + 1,
+						VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd));
+			if (i + j * nrows < QL_HELP_COUNT)
+				fprintf(output, "%s",
+						VALUE_OR_NULL(QL_HELP[i + j * nrows].cmd));
 			fputc('\n', output);
 		}
+
 		/* Only close if we used the pager */
 		if (output != stdout)
 		{
@@ -317,7 +338,7 @@ helpSQL(const char *topic, unsigned short int pager)
 		size_t		len,
 					wordlen;
 		int			nl_count = 0;
-		char	   *ch;
+		const char *ch;
 
 		/* User gets two chances: exact match, then the first word */