psql: Add variable to control keyword case in tab completion
This adds the variable COMP_KEYWORD_CASE, which controls in what case
keywords are completed. This is partially to let users configure the
change from commit 69f4f1c357
, but it
also offers more behaviors than were available before.
This commit is contained in:
parent
cf09230e19
commit
db84ba65ab
|
@ -2656,6 +2656,22 @@ bar
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>COMP_KEYWORD_CASE</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Determines which letter case to use when completing an SQL key word.
|
||||||
|
If set to <literal>lower</literal> or <literal>upper</literal>, the
|
||||||
|
completed word will be in lower or upper case, respectively. If set
|
||||||
|
to <literal>preserve-lower</literal>
|
||||||
|
or <literal>preserve-upper</literal> (the default), the completed word
|
||||||
|
will be in the case of the word already entered, but words being
|
||||||
|
completed without anything entered will be in lower or upper case,
|
||||||
|
respectively.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>DBNAME</varname></term>
|
<term><varname>DBNAME</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
|
@ -697,7 +697,7 @@ static char **complete_from_variables(char *text,
|
||||||
const char *prefix, const char *suffix);
|
const char *prefix, const char *suffix);
|
||||||
static char *complete_from_files(const char *text, int state);
|
static char *complete_from_files(const char *text, int state);
|
||||||
|
|
||||||
static char *pg_strdup_same_case(const char *s, const char *ref);
|
static char *pg_strdup_keyword_case(const char *s, const char *ref);
|
||||||
static PGresult *exec_query(const char *query);
|
static PGresult *exec_query(const char *query);
|
||||||
|
|
||||||
static void get_previous_words(int point, char **previous_words, int nwords);
|
static void get_previous_words(int point, char **previous_words, int nwords);
|
||||||
|
@ -3125,7 +3125,7 @@ create_or_drop_command_generator(const char *text, int state, bits32 excluded)
|
||||||
{
|
{
|
||||||
if ((pg_strncasecmp(name, text, string_length) == 0) &&
|
if ((pg_strncasecmp(name, text, string_length) == 0) &&
|
||||||
!(words_after_create[list_index - 1].flags & excluded))
|
!(words_after_create[list_index - 1].flags & excluded))
|
||||||
return pg_strdup_same_case(name, text);
|
return pg_strdup_keyword_case(name, text);
|
||||||
}
|
}
|
||||||
/* if nothing matches, return NULL */
|
/* if nothing matches, return NULL */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3412,9 +3412,9 @@ complete_from_list(const char *text, int state)
|
||||||
if (completion_case_sensitive)
|
if (completion_case_sensitive)
|
||||||
return pg_strdup(item);
|
return pg_strdup(item);
|
||||||
else
|
else
|
||||||
/* If case insensitive matching was requested initially, return
|
/* If case insensitive matching was requested initially, adjust
|
||||||
* it in the case of what was already entered. */
|
* the case according to setting. */
|
||||||
return pg_strdup_same_case(item, text);
|
return pg_strdup_keyword_case(item, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3451,9 +3451,9 @@ complete_from_const(const char *text, int state)
|
||||||
if (completion_case_sensitive)
|
if (completion_case_sensitive)
|
||||||
return pg_strdup(completion_charp);
|
return pg_strdup(completion_charp);
|
||||||
else
|
else
|
||||||
/* If case insensitive matching was requested initially, return it
|
/* If case insensitive matching was requested initially, adjust the
|
||||||
* in the case of what was already entered. */
|
* case according to setting. */
|
||||||
return pg_strdup_same_case(completion_charp, text);
|
return pg_strdup_keyword_case(completion_charp, text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3561,28 +3561,49 @@ complete_from_files(const char *text, int state)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make a pg_strdup copy of s and convert it to the same case as ref.
|
* Make a pg_strdup copy of s and convert the case according to
|
||||||
|
* COMP_KEYWORD_CASE variable, using ref as the text that was already entered.
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
pg_strdup_same_case(const char *s, const char *ref)
|
pg_strdup_keyword_case(const char *s, const char *ref)
|
||||||
{
|
{
|
||||||
char *ret, *p;
|
char *ret, *p;
|
||||||
unsigned char first = ref[0];
|
unsigned char first = ref[0];
|
||||||
|
int tocase;
|
||||||
|
const char *varval;
|
||||||
|
|
||||||
|
varval = GetVariable(pset.vars, "COMP_KEYWORD_CASE");
|
||||||
|
if (!varval)
|
||||||
|
tocase = 0;
|
||||||
|
else if (strcmp(varval, "lower") == 0)
|
||||||
|
tocase = -2;
|
||||||
|
else if (strcmp(varval, "preserve-lower") == 0)
|
||||||
|
tocase = -1;
|
||||||
|
else if (strcmp(varval, "preserve-upper") == 0)
|
||||||
|
tocase = +1;
|
||||||
|
else if (strcmp(varval, "upper") == 0)
|
||||||
|
tocase = +2;
|
||||||
|
else
|
||||||
|
tocase = 0;
|
||||||
|
|
||||||
|
/* default */
|
||||||
|
if (tocase == 0)
|
||||||
|
tocase = +1;
|
||||||
|
|
||||||
if (isalpha(first))
|
|
||||||
{
|
|
||||||
ret = pg_strdup(s);
|
ret = pg_strdup(s);
|
||||||
if (islower(first))
|
|
||||||
|
if (tocase == -2
|
||||||
|
|| ((tocase == -1 || tocase == +1) && islower(first))
|
||||||
|
|| (tocase == -1 && !isalpha(first))
|
||||||
|
)
|
||||||
for (p = ret; *p; p++)
|
for (p = ret; *p; p++)
|
||||||
*p = pg_tolower((unsigned char) *p);
|
*p = pg_tolower((unsigned char) *p);
|
||||||
else
|
else
|
||||||
for (p = ret; *p; p++)
|
for (p = ret; *p; p++)
|
||||||
*p = pg_toupper((unsigned char) *p);
|
*p = pg_toupper((unsigned char) *p);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return pg_strdup(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue