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