aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2012-05-08 21:03:45 +0300
committerPeter Eisentraut <peter_e@gmx.net>2012-05-08 21:06:08 +0300
commitdb84ba65ab5c0ad0b34d68ab5a687bc5f4ca3ba6 (patch)
tree25491cafe109aa10c59349954c9274df65f035d3
parentcf09230e1992a81e8e17441104d3c8a558abec04 (diff)
downloadpostgresql-db84ba65ab5c0ad0b34d68ab5a687bc5f4ca3ba6.tar.gz
postgresql-db84ba65ab5c0ad0b34d68ab5a687bc5f4ca3ba6.zip
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 69f4f1c3576abc535871c6cfa95539e32a36120f, but it also offers more behaviors than were available before.
-rw-r--r--doc/src/sgml/ref/psql-ref.sgml16
-rw-r--r--src/bin/psql/tab-complete.c65
2 files changed, 59 insertions, 22 deletions
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index d5e47b56e75..491246fea69 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2657,6 +2657,22 @@ bar
</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>
<term><varname>DBNAME</varname></term>
<listitem>
<para>
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 23b7a907f7e..a50e7356f1d 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -697,7 +697,7 @@ static char **complete_from_variables(char *text,
const char *prefix, const char *suffix);
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 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) &&
!(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 */
return NULL;
@@ -3412,9 +3412,9 @@ complete_from_list(const char *text, int state)
if (completion_case_sensitive)
return pg_strdup(item);
else
- /* If case insensitive matching was requested initially, return
- * it in the case of what was already entered. */
- return pg_strdup_same_case(item, text);
+ /* If case insensitive matching was requested initially, adjust
+ * the case according to setting. */
+ return pg_strdup_keyword_case(item, text);
}
}
@@ -3451,9 +3451,9 @@ complete_from_const(const char *text, int state)
if (completion_case_sensitive)
return pg_strdup(completion_charp);
else
- /* If case insensitive matching was requested initially, return it
- * in the case of what was already entered. */
- return pg_strdup_same_case(completion_charp, text);
+ /* If case insensitive matching was requested initially, adjust the
+ * case according to setting. */
+ return pg_strdup_keyword_case(completion_charp, text);
}
else
return NULL;
@@ -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 *
-pg_strdup_same_case(const char *s, const char *ref)
+pg_strdup_keyword_case(const char *s, const char *ref)
{
char *ret, *p;
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))
- {
- ret = pg_strdup(s);
- if (islower(first))
- for (p = ret; *p; p++)
- *p = pg_tolower((unsigned char) *p);
- else
- for (p = ret; *p; p++)
- *p = pg_toupper((unsigned char) *p);
- return ret;
- }
+ /* default */
+ if (tocase == 0)
+ tocase = +1;
+
+ ret = pg_strdup(s);
+
+ if (tocase == -2
+ || ((tocase == -1 || tocase == +1) && islower(first))
+ || (tocase == -1 && !isalpha(first))
+ )
+ for (p = ret; *p; p++)
+ *p = pg_tolower((unsigned char) *p);
else
- return pg_strdup(s);
+ for (p = ret; *p; p++)
+ *p = pg_toupper((unsigned char) *p);
+
+ return ret;
}