static const char *completion_info_charp; /* to pass a second string */
static const char *completion_info_charp2; /* to pass a third string */
static const SchemaQuery *completion_squery; /* to pass a SchemaQuery */
+static bool completion_case_sensitive; /* completion is case sensitive */
/*
* A few macros to ease typing. You can use these to complete the given
matches = completion_matches(text, complete_from_schema_query); \
} while (0)
+#define COMPLETE_WITH_LIST_CS(list) \
+do { \
+ completion_charpp = list; \
+ completion_case_sensitive = true; \
+ matches = completion_matches(text, complete_from_list); \
+} while (0)
+
#define COMPLETE_WITH_LIST(list) \
do { \
completion_charpp = list; \
+ completion_case_sensitive = false; \
matches = completion_matches(text, complete_from_list); \
} while (0)
#define COMPLETE_WITH_CONST(string) \
do { \
completion_charp = string; \
+ completion_case_sensitive = false; \
matches = completion_matches(text, complete_from_const); \
} while (0)
static char **complete_from_variables(char *text,
const char *prefix, const char *suffix);
+static char *pg_strdup_same_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);
/* If a backslash command was started, continue */
if (text[0] == '\\')
- COMPLETE_WITH_LIST(backslash_commands);
+ COMPLETE_WITH_LIST_CS(backslash_commands);
/* Variable interpolation */
else if (text[0] == ':' && text[1] != ':')
"null", "fieldsep", "tuples_only", "title", "tableattr",
"linestyle", "pager", "recordsep", NULL};
- COMPLETE_WITH_LIST(my_list);
+ COMPLETE_WITH_LIST_CS(my_list);
}
else if (strcmp(prev2_wd, "\\pset") == 0)
{
{"unaligned", "aligned", "wrapped", "html", "latex",
"troff-ms", NULL};
- COMPLETE_WITH_LIST(my_list);
+ COMPLETE_WITH_LIST_CS(my_list);
}
else if (strcmp(prev_wd, "linestyle") == 0)
{
static const char *const my_list[] =
{"ascii", "old-ascii", "unicode", NULL};
- COMPLETE_WITH_LIST(my_list);
+ COMPLETE_WITH_LIST_CS(my_list);
}
}
else if (strcmp(prev_wd, "\\set") == 0)
{
if ((pg_strncasecmp(name, text, string_length) == 0) &&
!(words_after_create[list_index - 1].flags & excluded))
- return pg_strdup(name);
+ return pg_strdup_same_case(name, text);
}
/* if nothing matches, return NULL */
return NULL;
{
list_index = 0;
string_length = strlen(text);
- casesensitive = true;
+ casesensitive = completion_case_sensitive;
matches = 0;
}
/* Second pass is case insensitive, don't bother counting matches */
if (!casesensitive && pg_strncasecmp(text, item, string_length) == 0)
- return pg_strdup(item);
+ {
+ 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);
+ }
}
/*
static char *
complete_from_const(const char *text, int state)
{
- (void) text; /* We don't care about what was entered
- * already. */
-
psql_assert(completion_charp);
if (state == 0)
- return pg_strdup(completion_charp);
+ {
+ 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);
+ }
else
return NULL;
}
}
varnames[nvars] = NULL;
- COMPLETE_WITH_LIST((const char * const *) varnames);
+ COMPLETE_WITH_LIST_CS((const char * const *) varnames);
for (i = 0; i < nvars; i++)
free(varnames[i]);
/* HELPER FUNCTIONS */
+/*
+ * Make a pg_strdup copy of s and convert it to the same case as ref.
+ */
+static char *
+pg_strdup_same_case(const char *s, const char *ref)
+{
+ char *ret, *p;
+ unsigned char first = ref[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;
+ }
+ else
+ return pg_strdup(s);
+}
+
+
/*
* Execute a query and report any errors. This should be the preferred way of
* talking to the database in this file.