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.
This commit is contained in:
parent
7d835ff4db
commit
e15c4ab5fb
|
@ -2827,7 +2827,9 @@ bar
|
||||||
they are sent to the server. The switch for this is
|
they are sent to the server. The switch for this is
|
||||||
<option>-e</option>. If set to <literal>errors</literal> then only
|
<option>-e</option>. If set to <literal>errors</literal> then only
|
||||||
failed queries are displayed on standard error output. The switch
|
failed queries are displayed on standard error output. The switch
|
||||||
for this is <option>-b</option>.
|
for this is <option>-b</option>. If unset, or if set to
|
||||||
|
<literal>none</literal> (or any other value than those above) then
|
||||||
|
no queries are displayed.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -2892,8 +2894,9 @@ bar
|
||||||
list. If set to a value of <literal>ignoredups</literal>, lines
|
list. If set to a value of <literal>ignoredups</literal>, lines
|
||||||
matching the previous history line are not entered. A value of
|
matching the previous history line are not entered. A value of
|
||||||
<literal>ignoreboth</literal> combines the two options. If
|
<literal>ignoreboth</literal> combines the two options. If
|
||||||
unset, or if set to any other value than those above, all lines
|
unset, or if set to <literal>none</literal> (or any other value
|
||||||
read in interactive mode are saved on the history list.
|
than those above), all lines read in interactive mode are
|
||||||
|
saved on the history list.
|
||||||
</para>
|
</para>
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
|
|
|
@ -813,8 +813,11 @@ static char *_complete_from_query(int is_schema_query,
|
||||||
const char *text, int state);
|
const char *text, int state);
|
||||||
static char *complete_from_list(const char *text, int state);
|
static char *complete_from_list(const char *text, int state);
|
||||||
static char *complete_from_const(const char *text, int state);
|
static char *complete_from_const(const char *text, int state);
|
||||||
|
static void append_variable_names(char ***varnames, int *nvars,
|
||||||
|
int *maxvars, const char *varname,
|
||||||
|
const char *prefix, const char *suffix);
|
||||||
static char **complete_from_variables(const char *text,
|
static char **complete_from_variables(const char *text,
|
||||||
const char *prefix, const char *suffix);
|
const char *prefix, const char *suffix, bool need_value);
|
||||||
static char *complete_from_files(const char *text, int state);
|
static char *complete_from_files(const char *text, int state);
|
||||||
|
|
||||||
static char *pg_strdup_keyword_case(const char *s, const char *ref);
|
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)
|
||||||
else if (text[0] == ':' && text[1] != ':')
|
else if (text[0] == ':' && text[1] != ':')
|
||||||
{
|
{
|
||||||
if (text[1] == '\'')
|
if (text[1] == '\'')
|
||||||
matches = complete_from_variables(text, ":'", "'");
|
matches = complete_from_variables(text, ":'", "'", true);
|
||||||
else if (text[1] == '"')
|
else if (text[1] == '"')
|
||||||
matches = complete_from_variables(text, ":\"", "\"");
|
matches = complete_from_variables(text, ":\"", "\"", true);
|
||||||
else
|
else
|
||||||
matches = complete_from_variables(text, ":", "");
|
matches = complete_from_variables(text, ":", "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If no previous word, suggest one of the basic sql commands */
|
/* If no previous word, suggest one of the basic sql commands */
|
||||||
|
@ -3604,9 +3607,71 @@ psql_completion(const char *text, int start, int end)
|
||||||
COMPLETE_WITH_LIST_CS(my_list);
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcmp(prev_wd, "\\unset") == 0)
|
||||||
|
{
|
||||||
|
matches = complete_from_variables(text, "", "", true);
|
||||||
|
}
|
||||||
else if (strcmp(prev_wd, "\\set") == 0)
|
else if (strcmp(prev_wd, "\\set") == 0)
|
||||||
{
|
{
|
||||||
matches = complete_from_variables(text, "", "");
|
matches = complete_from_variables(text, "", "", false);
|
||||||
|
}
|
||||||
|
else if (strcmp(prev2_wd, "\\set") == 0)
|
||||||
|
{
|
||||||
|
static const char *const boolean_value_list[] =
|
||||||
|
{"on", "off", NULL};
|
||||||
|
|
||||||
|
if (strcmp(prev_wd, "AUTOCOMMIT") == 0)
|
||||||
|
COMPLETE_WITH_LIST_CS(boolean_value_list);
|
||||||
|
else if (strcmp(prev_wd, "COMP_KEYWORD_CASE") == 0)
|
||||||
|
{
|
||||||
|
static const char *const my_list[] =
|
||||||
|
{"lower", "upper", "preserve-lower", "preserve-upper", NULL};
|
||||||
|
|
||||||
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
|
}
|
||||||
|
else if (strcmp(prev_wd, "ECHO") == 0)
|
||||||
|
{
|
||||||
|
static const char *const my_list[] =
|
||||||
|
{"errors", "queries", "all", "none", NULL};
|
||||||
|
|
||||||
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
|
}
|
||||||
|
else if (strcmp(prev_wd, "ECHO_HIDDEN") == 0)
|
||||||
|
{
|
||||||
|
static const char *const my_list[] =
|
||||||
|
{"noexec", "off", "on", NULL};
|
||||||
|
|
||||||
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
|
}
|
||||||
|
else if (strcmp(prev_wd, "HISTCONTROL") == 0)
|
||||||
|
{
|
||||||
|
static const char *const my_list[] =
|
||||||
|
{"ignorespace", "ignoredups", "ignoreboth", "none", NULL};
|
||||||
|
|
||||||
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
|
}
|
||||||
|
else if (strcmp(prev_wd, "ON_ERROR_ROLLBACK") == 0)
|
||||||
|
{
|
||||||
|
static const char *const my_list[] =
|
||||||
|
{"on", "off", "interactive", NULL};
|
||||||
|
|
||||||
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
|
}
|
||||||
|
else if (strcmp(prev_wd, "ON_ERROR_STOP") == 0)
|
||||||
|
COMPLETE_WITH_LIST_CS(boolean_value_list);
|
||||||
|
else if (strcmp(prev_wd, "QUIET") == 0)
|
||||||
|
COMPLETE_WITH_LIST_CS(boolean_value_list);
|
||||||
|
else if (strcmp(prev_wd, "SINGLELINE") == 0)
|
||||||
|
COMPLETE_WITH_LIST_CS(boolean_value_list);
|
||||||
|
else if (strcmp(prev_wd, "SINGLESTEP") == 0)
|
||||||
|
COMPLETE_WITH_LIST_CS(boolean_value_list);
|
||||||
|
else if (strcmp(prev_wd, "VERBOSITY") == 0)
|
||||||
|
{
|
||||||
|
static const char *const my_list[] =
|
||||||
|
{"default", "verbose", "terse", NULL};
|
||||||
|
|
||||||
|
COMPLETE_WITH_LIST_CS(my_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(prev_wd, "\\sf") == 0 || strcmp(prev_wd, "\\sf+") == 0)
|
else if (strcmp(prev_wd, "\\sf") == 0 || strcmp(prev_wd, "\\sf+") == 0)
|
||||||
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
|
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions, NULL);
|
||||||
|
@ -4052,13 +4117,40 @@ complete_from_const(const char *text, int state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function appends the variable name with prefix and suffix to
|
||||||
|
* the variable names array.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
append_variable_names(char ***varnames, int *nvars,
|
||||||
|
int *maxvars, const char *varname,
|
||||||
|
const char *prefix, const char *suffix)
|
||||||
|
{
|
||||||
|
if (*nvars >= *maxvars)
|
||||||
|
{
|
||||||
|
*maxvars *= 2;
|
||||||
|
*varnames = (char **) realloc(*varnames,
|
||||||
|
((*maxvars) + 1) * sizeof(char *));
|
||||||
|
if (!(*varnames))
|
||||||
|
{
|
||||||
|
psql_error("out of memory\n");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(*varnames)[(*nvars)++] = psprintf("%s%s%s", prefix, varname, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function supports completion with the name of a psql variable.
|
* This function supports completion with the name of a psql variable.
|
||||||
* The variable names can be prefixed and suffixed with additional text
|
* The variable names can be prefixed and suffixed with additional text
|
||||||
* to support quoting usages.
|
* to support quoting usages. If need_value is true, only the variables
|
||||||
|
* that have the set values are picked up.
|
||||||
*/
|
*/
|
||||||
static char **
|
static char **
|
||||||
complete_from_variables(const char *text, const char *prefix, const char *suffix)
|
complete_from_variables(const char *text, const char *prefix, const char *suffix,
|
||||||
|
bool need_value)
|
||||||
{
|
{
|
||||||
char **matches;
|
char **matches;
|
||||||
char **varnames;
|
char **varnames;
|
||||||
|
@ -4067,23 +4159,34 @@ complete_from_variables(const char *text, const char *prefix, const char *suffix
|
||||||
int i;
|
int i;
|
||||||
struct _variable *ptr;
|
struct _variable *ptr;
|
||||||
|
|
||||||
|
static const char *const known_varnames[] = {
|
||||||
|
"AUTOCOMMIT", "COMP_KEYWORD_CASE", "DBNAME", "ECHO", "ECHO_HIDDEN",
|
||||||
|
"ENCODING", "FETCH_COUNT", "HISTCONTROL", "HISTFILE", "HISTSIZE",
|
||||||
|
"HOST", "IGNOREEOF", "LASTOID", "ON_ERROR_ROLLBACK", "ON_ERROR_STOP",
|
||||||
|
"PORT", "PROMPT1", "PROMPT2", "PROMPT3", "QUIET", "SINGLELINE",
|
||||||
|
"SINGLESTEP", "USER", "VERBOSITY", NULL
|
||||||
|
};
|
||||||
|
|
||||||
varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
|
varnames = (char **) pg_malloc((maxvars + 1) * sizeof(char *));
|
||||||
|
|
||||||
|
if (!need_value)
|
||||||
|
{
|
||||||
|
for (i = 0; known_varnames[i] && nvars < maxvars; i++)
|
||||||
|
append_variable_names(&varnames, &nvars, &maxvars,
|
||||||
|
known_varnames[i], prefix, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
for (ptr = pset.vars->next; ptr; ptr = ptr->next)
|
for (ptr = pset.vars->next; ptr; ptr = ptr->next)
|
||||||
{
|
{
|
||||||
if (nvars >= maxvars)
|
if (need_value && !(ptr->value))
|
||||||
|
continue;
|
||||||
|
for (i = 0; known_varnames[i]; i++) /* remove duplicate entry */
|
||||||
{
|
{
|
||||||
maxvars *= 2;
|
if (strcmp(ptr->name, known_varnames[i]) == 0)
|
||||||
varnames = (char **) realloc(varnames,
|
continue;
|
||||||
(maxvars + 1) * sizeof(char *));
|
|
||||||
if (!varnames)
|
|
||||||
{
|
|
||||||
psql_error("out of memory\n");
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
append_variable_names(&varnames, &nvars, &maxvars, ptr->name,
|
||||||
varnames[nvars++] = psprintf("%s%s%s", prefix, ptr->name, suffix);
|
prefix, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
varnames[nvars] = NULL;
|
varnames[nvars] = NULL;
|
||||||
|
|
Loading…
Reference in New Issue