Commit db84ba65 authored by Peter Eisentraut's avatar Peter Eisentraut

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 69f4f1c3, but it
also offers more behaviors than were available before.
parent cf09230e
...@@ -2656,6 +2656,22 @@ bar ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,27 +3561,48 @@ complete_from_files(const char *text, int state) ...@@ -3561,27 +3561,48 @@ 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;
if (isalpha(first)) /* default */
{ if (tocase == 0)
ret = pg_strdup(s); tocase = +1;
if (islower(first))
for (p = ret; *p; p++) ret = pg_strdup(s);
*p = pg_tolower((unsigned char) *p);
else if (tocase == -2
for (p = ret; *p; p++) || ((tocase == -1 || tocase == +1) && islower(first))
*p = pg_toupper((unsigned char) *p); || (tocase == -1 && !isalpha(first))
return ret; )
} for (p = ret; *p; p++)
*p = pg_tolower((unsigned char) *p);
else else
return pg_strdup(s); for (p = ret; *p; p++)
*p = pg_toupper((unsigned char) *p);
return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment