Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+6-3
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

+121-18
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)