Hi,
I have created a small patch to postgres source (in particular the
psql part of it) that modifies the way tab expansion is handled.

The idea is to be able to toggle tab expansion, having the default set
to ON (as it is now). If turned off, tab characters on command line in
interactive mode are not evaluated nor expanded, but just copied.

Tab expansion can either be turned off using command line option (-C) or
controlled by \tab internal command of psql.

Attached you can find a patch. I haven't created any regression tests
as tab expansion works only in interactive mode.
My patch is relative to origin/REL9_4_STABLE branch as that is the one
I started from.

My plea is to have this change merged into the main stream so that it
becomes available in upcoming releases.

This modification introduces new (optional) command line option and a
new internal backslash command.
It does not create any backward compatibility issues as the default
behavior remains unchanged.

regards
bogdan

>From e3ba6cda83b64246c2b4d3df01f62444f4b37c9d Mon Sep 17 00:00:00 2001
From: Bogdan Pilch <bogdan.pi...@opensynergy.com>
Date: Sun, 7 Sep 2014 18:59:12 +0200
Subject: [PATCH] Implemented support for turning off/on tab completion (in
 readline).

---
 src/bin/psql/command.c      | 20 ++++++++++++++++++++
 src/bin/psql/help.c         |  1 +
 src/bin/psql/input.c        |  9 +++++++++
 src/bin/psql/input.h        |  1 +
 src/bin/psql/mainloop.c     |  3 +++
 src/bin/psql/settings.h     |  1 +
 src/bin/psql/startup.c      |  7 ++++++-
 src/bin/psql/tab-complete.c |  9 +++++++++
 src/bin/psql/tab-complete.h |  1 +
 9 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 741a72d..e14b15b 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1343,6 +1343,26 @@ exec_command(const char *cmd,
 		free(value);
 	}
 
+	/* \tab -- toggle tab completion */
+	else if (strcmp(cmd, "tab") == 0)
+	{
+		char	   *opt = psql_scan_slash_option(scan_state,
+												 OT_NORMAL, NULL, false);
+
+		if (opt)
+			pset.tab_completion = ParseVariableBool(opt);
+		else
+			pset.tab_completion = !pset.tab_completion;
+		if (!pset.quiet)
+		{
+			if (pset.tab_completion)
+				puts(_("Tab completion is on."));
+			else
+				puts(_("Tab completion is off."));
+		}
+		free(opt);
+	}
+
 	/* \timing -- toggle timing of queries */
 	else if (strcmp(cmd, "timing") == 0)
 	{
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 3aa3c16..afc90b8 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -87,6 +87,7 @@ usage(void)
 
 	printf(_("\nInput and output options:\n"));
 	printf(_("  -a, --echo-all           echo all input from script\n"));
+	printf(_("  -C, --tab-completion-off turn off tab completion\n"));
 	printf(_("  -e, --echo-queries       echo commands sent to server\n"));
 	printf(_("  -E, --echo-hidden        display queries that internal commands generate\n"));
 	printf(_("  -L, --log-file=FILENAME  send session log to file\n"));
diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c
index aa32a3f..96f73c6 100644
--- a/src/bin/psql/input.c
+++ b/src/bin/psql/input.c
@@ -263,6 +263,15 @@ decode_history(void)
 
 
 /*
+ * Just a wrapper function for readline setup
+ */
+void
+set_input_completion(void)
+{
+	set_readline_completion();
+}
+
+/*
  * Put any startup stuff related to input in here. It's good to maintain
  * abstraction this way.
  *
diff --git a/src/bin/psql/input.h b/src/bin/psql/input.h
index 1d10a22..ad1eede 100644
--- a/src/bin/psql/input.h
+++ b/src/bin/psql/input.h
@@ -41,6 +41,7 @@
 char	   *gets_interactive(const char *prompt);
 char	   *gets_fromFile(FILE *source);
 
+void		set_input_completion(void);
 void		initializeInput(int flags);
 bool		saveHistory(char *fname, int max_lines, bool appendFlag, bool encodeFlag);
 
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index c3aff20..92546e0 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -123,6 +123,9 @@ MainLoop(FILE *source)
 
 		fflush(stdout);
 
+		/* Modify readline settings if necessary */
+		set_input_completion();
+
 		/*
 		 * get another line
 		 */
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index 0a60e68..7e5e98c 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -89,6 +89,7 @@ typedef struct _psqlSettings
 	uint64		lineno;			/* also for error reporting */
 
 	bool		timing;			/* enable timing of all queries */
+	bool		tab_completion;		/* enable/disable tab completion in interactive mode */
 
 	FILE	   *logfile;		/* session log file handle */
 
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 45653a1..df9d720 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -121,6 +121,7 @@ main(int argc, char *argv[])
 	pset.copyStream = NULL;
 	pset.cur_cmd_source = stdin;
 	pset.cur_cmd_interactive = false;
+	pset.tab_completion = true;
 
 	/* We rely on unmentioned fields of pset.popt to start out 0/false/NULL */
 	pset.popt.topt.format = PRINT_ALIGNED;
@@ -372,6 +373,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 		{"record-separator-zero", no_argument, NULL, '0'},
 		{"single-step", no_argument, NULL, 's'},
 		{"single-line", no_argument, NULL, 'S'},
+		{"tab-completion-off", no_argument, NULL, 'C'},
 		{"tuples-only", no_argument, NULL, 't'},
 		{"table-attr", required_argument, NULL, 'T'},
 		{"username", required_argument, NULL, 'U'},
@@ -391,7 +393,7 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 
 	memset(options, 0, sizeof *options);
 
-	while ((c = getopt_long(argc, argv, "aAc:d:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
+	while ((c = getopt_long(argc, argv, "aAc:Cd:eEf:F:h:HlL:no:p:P:qR:sStT:U:v:VwWxXz?01",
 							long_options, &optindex)) != -1)
 	{
 		switch (c)
@@ -412,6 +414,9 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 				else
 					options->action = ACT_SINGLE_QUERY;
 				break;
+			case 'C':
+				pset.tab_completion = false;
+				break;
 			case 'd':
 				options->dbname = pg_strdup(optarg);
 				break;
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 96de778..9ed2d0f 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -830,6 +830,15 @@ initialize_readline(void)
 	 */
 }
 
+/*
+ * Set the readline to inhibit or allow command completion
+ * based on global pset.tab_completion
+ */
+void
+set_readline_completion(void)
+{
+	rl_inhibit_completion = ( pset.tab_completion ? 0 : 1 );
+}
 
 /*
  * The completion function.
diff --git a/src/bin/psql/tab-complete.h b/src/bin/psql/tab-complete.h
index 5022ca2..e6226b9 100644
--- a/src/bin/psql/tab-complete.h
+++ b/src/bin/psql/tab-complete.h
@@ -11,5 +11,6 @@
 #include "postgres_fe.h"
 
 void		initialize_readline(void);
+void		set_readline_completion(void);
 
 #endif
-- 
1.9.1

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to