Skip to content

Commit e15c4ab

Browse files
committed
Add tab-completion for \unset and valid setting values of psql variables.
This commit also changes tab-completion for \set so that it displays all the special variables like COMP_KEYWORD_CASE. Previously it displayed only variables having the set values. Which was not user-friendly for those who want to set the unset variables. This commit also changes tab-completion for :variable so that only the variables having the set values are displayed. Previously even unset variables were displayed. Pavel Stehule, modified by me.
1 parent 7d835ff commit e15c4ab

File tree

2 files changed

+127
-21
lines changed

2 files changed

+127
-21
lines changed

doc/src/sgml/ref/psql-ref.sgml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,9 @@ bar
28272827
they are sent to the server. The switch for this is
28282828
<option>-e</option>. If set to <literal>errors</literal> then only
28292829
failed queries are displayed on standard error output. The switch
2830-
for this is <option>-b</option>.
2830+
for this is <option>-b</option>. If unset, or if set to
2831+
<literal>none</literal> (or any other value than those above) then
2832+
no queries are displayed.
28312833
</para>
28322834
</listitem>
28332835
</varlistentry>
@@ -2892,8 +2894,9 @@ bar
28922894
list. If set to a value of <literal>ignoredups</literal>, lines
28932895
matching the previous history line are not entered. A value of
28942896
<literal>ignoreboth</literal> combines the two options. If
2895-
unset, or if set to any other value than those above, all lines
2896-
read in interactive mode are saved on the history list.
2897+
unset, or if set to <literal>none</literal> (or any other value
2898+
than those above), all lines read in interactive mode are
2899+
saved on the history list.
28972900
</para>
28982901
<note>
28992902
<para>

src/bin/psql/tab-complete.c

Lines changed: 121 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,11 @@ static char *_complete_from_query(int is_schema_query,
813813
const char *text, int state);
814814
static char *complete_from_list(const char *text, int state);
815815
static char *complete_from_const(const char *text, int state);
816+
static void append_variable_names(char ***varnames, int *nvars,
817+
int *maxvars, const char *varname,
818+
const char *prefix, const char *suffix);
816819
static char **complete_from_variables(const char *text,
817-
const char *prefix, const char *suffix);
820+
const char *prefix, const char *suffix, bool need_value);
818821
static char *complete_from_files(const char *text, int state);
819822

820823
static char *pg_strdup_keyword_case(const char *s, const char *ref);
@@ -925,11 +928,11 @@ psql_completion(const char *text, int start, int end)
925928
else if (text[0] == ':' && text[1] != ':')
926929
{
927930
if (text[1] == '\'')
928-
matches = complete_from_variables(text, ":'", "'");
931+
matches = complete_from_variables(text, ":'", "'", true);
929932
else if (text[1] == '"')
930-
matches = complete_from_variables(text, ":\"", "\"");
933+
matches = complete_from_variables(text, ":\"", "\"", true);
931934
else
932-
matches = complete_from_variables(text, ":", "");
935+
matches = complete_from_variables(text, ":", "", true);
933936
}
934937

935938
/* If no previous word, suggest one of the basic sql commands */
@@ -3604,9 +3607,71 @@ psql_completion(const char *text, int start, int end)
36043607
COMPLETE_WITH_LIST_CS(my_list);
36053608
}
36063609
}
3610+
else if (strcmp(prev_wd, "\\unset") == 0)
3611+
{
3612+
matches = complete_from_variables(text, "", "", true);
3613+
}
36073614
else if (strcmp(prev_wd, "\\set") == 0)
36083615
{
3609-
matches = complete_from_variables(text, "", "");
3616+
matches = complete_from_variables(text, "", "", false);
3617+
}
3618+
else if (strcmp(prev2_wd, "\\set") == 0)
3619+
{
3620+
static const char *const boolean_value_list[] =
3621+
{"on", "off", NULL};
3622+
3623+
if (strcmp(prev_wd, "AUTOCOMMIT") == 0)
3624+
COMPLETE_WITH_LIST_CS(boolean_value_list);
3625+
else if (strcmp(prev_wd, "COMP_KEYWORD_CASE") == 0)
3626+
{
3627+
static const char *const my_list[] =
3628+
{"lower", "upper", "preserve-lower", "preserve-upper", NULL};
3629+
3630+
COMPLETE_WITH_LIST_CS(my_list);
3631+
}
3632+
else if (strcmp(prev_wd, "ECHO") == 0)
3633+
{
3634+
static const char *const my_list[] =
3635+
{"errors", "queries", "all", "none", NULL};
3636+
3637+
COMPLETE_WITH_LIST_CS(my_list);
3638+
}
3639+
else if (strcmp(prev_wd, "ECHO_HIDDEN") == 0)
3640+
{
3641+
static const char *const my_list[] =
3642+
{"noexec", "off", "on", NULL};
3643+
3644+
COMPLETE_WITH_LIST_CS(my_list);
3645+
}
3646+
else if (strcmp(prev_wd, "HISTCONTROL") == 0)
3647+
{
3648+
static const char *const my_list[] =
3649+
{"ignorespace", "ignoredups", "ignoreboth", "none", NULL};
3650+
3651+
COMPLETE_WITH_LIST_CS(my_list);
3652+
}
3653+
else if (strcmp(prev_wd, "ON_ERROR_ROLLBACK") == 0)
3654+
{
3655+
static const char *const my_list[] =
3656+
{"on", "off", "interactive", NULL};
3657+
3658+
COMPLETE_WITH_LIST_CS(my_list);
3659+
}
3660+
else if (strcmp(prev_wd, "ON_ERROR_STOP") == 0)
3661+
COMPLETE_WITH_LIST_CS(boolean_value_list);
3662+
else if (strcmp(prev_wd, "QUIET") == 0)
3663+
COMPLETE_WITH_LIST_CS(boolean_value_list);
3664+
else if (strcmp(prev_wd, "SINGLELINE") == 0)
3665+
COMPLETE_WITH_LIST_CS(boolean_value_list);
3666+
else if (strcmp(prev_wd, "SINGLESTEP") == 0)
3667+
COMPLETE_WITH_LIST_CS(boolean_value_list);
3668+
else if (strcmp(prev_wd, "VERBOSITY") == 0)
3669+
{
3670+
static const char *const my_list[] =
3671+
{"default", "verbose", "terse", NULL};
3672+
3673+
COMPLETE_WITH_LIST_CS(my_list);
3674+
}
36103675
}
36113676
else if (strcmp(prev_wd, "\\sf") == 0 || strcmp(prev_wd, "\\sf+") == 0)
36123677
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
@@ -4052,13 +4117,40 @@ complete_from_const(const char *text, int state)
40524117
}
40534118

40544119

4120+
/*
4121+
* This function appends the variable name with prefix and suffix to
4122+
* the variable names array.
4123+
*/
4124+
static void
4125+
append_variable_names(char ***varnames, int *nvars,
4126+
int *maxvars, const char *varname,
4127+
const char *prefix, const char *suffix)
4128+
{
4129+
if (*nvars >= *maxvars)
4130+
{
4131+
*maxvars *= 2;
4132+
*varnames = (char **) realloc(*varnames,
4133+
((*maxvars) + 1) * sizeof(char *));
4134+
if (!(*varnames))
4135+
{
4136+
psql_error("out of memory\n");
4137+
exit(EXIT_FAILURE);
4138+
}
4139+
}
4140+
4141+
(*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
4142+
}
4143+
4144+
40554145
/*
40564146
* This function supports completion with the name of a psql variable.
40574147
* The variable names can be prefixed and suffixed with additional text
4058-
* to support quoting usages.
4148+
* to support quoting usages. If need_value is true, only the variables
4149+
* that have the set values are picked up.
40594150
*/
40604151
static char **
4061-
complete_from_variables(const char *text, const char *prefix, const char *suffix)
4152+
complete_from_variables(const char *text, const char *prefix, const char *suffix,
4153+
bool need_value)
40624154
{
40634155
char **matches;
40644156
char **varnames;
@@ -4067,23 +4159,34 @@ complete_from_variables(const char *text, const char *prefix, const char *suffix
40674159
int i;
40684160
struct _variable *ptr;
40694161

4162+
static const char *const known_varnames[] = {
4163+
"AUTOCOMMIT", "COMP_KEYWORD_CASE", "DBNAME", "ECHO", "ECHO_HIDDEN",
4164+
"ENCODING", "FETCH_COUNT", "HISTCONTROL", "HISTFILE", "HISTSIZE",
4165+
"HOST", "IGNOREEOF", "LASTOID", "ON_ERROR_ROLLBACK", "ON_ERROR_STOP",
4166+
"PORT", "PROMPT1", "PROMPT2", "PROMPT3", "QUIET", "SINGLELINE",
4167+
"SINGLESTEP", "USER", "VERBOSITY", NULL
4168+
};
4169+
40704170
varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
40714171

4172+
if (!need_value)
4173+
{
4174+
for (i = 0; known_varnames[i] && nvars < maxvars; i++)
4175+
append_variable_names(&varnames, &nvars, &maxvars,
4176+
known_varnames[i], prefix, suffix);
4177+
}
4178+
40724179
for (ptr = pset.vars->next; ptr; ptr = ptr->next)
40734180
{
4074-
if (nvars >= maxvars)
4181+
if (need_value && !(ptr->value))
4182+
continue;
4183+
for (i = 0; known_varnames[i]; i++) /* remove duplicate entry */
40754184
{
4076-
maxvars *= 2;
4077-
varnames = (char **) realloc(varnames,
4078-
(maxvars + 1) * sizeof(char *));
4079-
if (!varnames)
4080-
{
4081-
psql_error("out of memory\n");
4082-
exit(EXIT_FAILURE);
4083-
}
4185+
if (strcmp(ptr->name, known_varnames[i]) == 0)
4186+
continue;
40844187
}
4085-
4086-
varnames[nvars++] = psprintf("%s%s%s", prefix, ptr->name, suffix);
4188+
append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
4189+
prefix, suffix);
40874190
}
40884191

40894192
varnames[nvars] = NULL;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy