Skip to content

Commit 020258f

Browse files
committed
Treat case of tab-completion keywords a bit more carefully.
When completing keywords that are offered alongside names obtained from a query, preserve the user's choice of keyword case. This would have been messy to do before 02b8048, but now it's fairly simple. A complication is that we want keywords to be shown in upper case in any tab-completion menus that include both keywords and non-keywords, so we can't switch their case until enough has been typed that only keyword(s) remain to be chosen. Also, adjust some places where 02b8048 thoughtlessly held over a previous choice to display keywords in lower case. (I think I got confused as to whether those words were keywords or variable names, but they're the former.) Dagfinn Ilmari Mannsåker and Tom Lane Discussion: https://postgr.es/m/8735l41ynm.fsf@wibble.ilmari.org
1 parent a5a9d77 commit 020258f

File tree

2 files changed

+62
-29
lines changed

2 files changed

+62
-29
lines changed

src/bin/psql/t/010_tab_completion.pl

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
# set up a few database objects
4242
$node->safe_psql('postgres',
43-
"CREATE TABLE tab1 (f1 int primary key, f2 text);\n"
43+
"CREATE TABLE tab1 (c1 int primary key, c2 text);\n"
4444
. "CREATE TABLE mytab123 (f1 int, f2 text);\n"
4545
. "CREATE TABLE mytab246 (f1 int, f2 text);\n"
4646
. "CREATE TABLE \"mixedName\" (f1 int, f2 text);\n"
@@ -317,14 +317,30 @@ sub clear_line
317317

318318
clear_line();
319319

320-
# check completion of a keyword offered in addition to object names
321-
# (that code path currently doesn't preserve case of what's typed)
322-
check_completion(
323-
"comment on constraint foo on dom\t",
324-
qr|DOMAIN|,
325-
"offer keyword in addition to query result");
326-
327-
clear_query();
320+
# check completion of a keyword offered in addition to object names;
321+
# such a keyword should obey COMP_KEYWORD_CASE once only keyword
322+
# completions are possible
323+
foreach (
324+
[ 'lower', 'CO', 'column' ],
325+
[ 'upper', 'co', 'COLUMN' ],
326+
[ 'preserve-lower', 'co', 'column' ],
327+
[ 'preserve-upper', 'CO', 'COLUMN' ],)
328+
{
329+
my ($case, $in, $out) = @$_;
330+
331+
check_completion(
332+
"\\set COMP_KEYWORD_CASE $case\n",
333+
qr/postgres=#/,
334+
"set completion case to '$case'");
335+
check_completion("alter table tab1 rename c\t\t",
336+
qr|COLUMN|,
337+
"offer keyword COLUMN for input c<TAB>, COMP_KEYWORD_CASE = $case");
338+
clear_query();
339+
check_completion("alter table tab1 rename $in\t\t\t",
340+
qr|$out|,
341+
"offer keyword $out for input $in<TAB>, COMP_KEYWORD_CASE = $case");
342+
clear_query();
343+
}
328344

329345
# send psql an explicit \q to shut it down, else pty won't close properly
330346
$timer->start(5);

src/bin/psql/tab-complete.c

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,9 +1320,11 @@ initialize_readline(void)
13201320
rl_basic_word_break_characters = WORD_BREAKS;
13211321

13221322
/*
1323-
* We should include '"' in rl_completer_quote_characters too, but that
1324-
* will require some upgrades to how we handle quoted identifiers, so
1325-
* that's for another day.
1323+
* Ideally we'd include '"' in rl_completer_quote_characters too, which
1324+
* should allow us to complete quoted identifiers that include spaces.
1325+
* However, the library support for rl_completer_quote_characters is
1326+
* presently too inconsistent to want to mess with that. (Note in
1327+
* particular that libedit has this variable but completely ignores it.)
13261328
*/
13271329
rl_completer_quote_characters = "'";
13281330

@@ -2059,7 +2061,7 @@ psql_completion(const char *text, int start, int end)
20592061
COMPLETE_WITH("SET", "RESET");
20602062
else if (Matches("ALTER", "SYSTEM", "SET|RESET"))
20612063
COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_alter_system_set_vars,
2062-
"all");
2064+
"ALL");
20632065
else if (Matches("ALTER", "SYSTEM", "SET", MatchAny))
20642066
COMPLETE_WITH("TO");
20652067
/* ALTER VIEW <name> */
@@ -4039,16 +4041,18 @@ psql_completion(const char *text, int start, int end)
40394041
/* Complete with a variable name */
40404042
else if (TailMatches("SET|RESET") && !TailMatches("UPDATE", MatchAny, "SET"))
40414043
COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_set_vars,
4042-
"constraints",
4043-
"transaction",
4044-
"session",
4045-
"role",
4046-
"tablespace",
4047-
"all");
4044+
"CONSTRAINTS",
4045+
"TRANSACTION",
4046+
"SESSION",
4047+
"ROLE",
4048+
"TABLESPACE",
4049+
"ALL");
40484050
else if (Matches("SHOW"))
40494051
COMPLETE_WITH_QUERY_PLUS(Query_for_list_of_show_vars,
4050-
"session authorization",
4051-
"all");
4052+
"SESSION AUTHORIZATION",
4053+
"ALL");
4054+
else if (Matches("SHOW", "SESSION"))
4055+
COMPLETE_WITH("AUTHORIZATION");
40524056
/* Complete "SET TRANSACTION" */
40534057
else if (Matches("SET", "TRANSACTION"))
40544058
COMPLETE_WITH("SNAPSHOT", "ISOLATION LEVEL", "READ", "DEFERRABLE", "NOT DEFERRABLE");
@@ -4742,7 +4746,8 @@ _complete_from_query(const char *simple_query,
47424746
{
47434747
static int list_index,
47444748
num_schema_only,
4745-
num_other;
4749+
num_query_other,
4750+
num_keywords;
47464751
static PGresult *result = NULL;
47474752
static bool non_empty_object;
47484753
static bool schemaquoted;
@@ -4765,7 +4770,8 @@ _complete_from_query(const char *simple_query,
47654770
/* Reset static state, ensuring no memory leaks */
47664771
list_index = 0;
47674772
num_schema_only = 0;
4768-
num_other = 0;
4773+
num_query_other = 0;
4774+
num_keywords = 0;
47694775
PQclear(result);
47704776
result = NULL;
47714777

@@ -4986,7 +4992,10 @@ _complete_from_query(const char *simple_query,
49864992

49874993
/* In verbatim mode, we return all the items as-is */
49884994
if (verbatim)
4995+
{
4996+
num_query_other++;
49894997
return pg_strdup(item);
4998+
}
49904999

49915000
/*
49925001
* In normal mode, a name requiring quoting will be returned only
@@ -5007,7 +5016,7 @@ _complete_from_query(const char *simple_query,
50075016
if (item == NULL && nsp != NULL)
50085017
num_schema_only++;
50095018
else
5010-
num_other++;
5019+
num_query_other++;
50115020

50125021
return requote_identifier(nsp, item, schemaquoted, objectquoted);
50135022
}
@@ -5031,8 +5040,12 @@ _complete_from_query(const char *simple_query,
50315040
list_index++;
50325041
if (pg_strncasecmp(text, item, strlen(text)) == 0)
50335042
{
5034-
num_other++;
5035-
return pg_strdup(item);
5043+
num_keywords++;
5044+
/* Match keyword case if we are returning only keywords */
5045+
if (num_schema_only == 0 && num_query_other == 0)
5046+
return pg_strdup_keyword_case(item, text);
5047+
else
5048+
return pg_strdup(item);
50365049
}
50375050
}
50385051
}
@@ -5049,8 +5062,12 @@ _complete_from_query(const char *simple_query,
50495062
list_index++;
50505063
if (pg_strncasecmp(text, item, strlen(text)) == 0)
50515064
{
5052-
num_other++;
5053-
return pg_strdup(item);
5065+
num_keywords++;
5066+
/* Match keyword case if we are returning only keywords */
5067+
if (num_schema_only == 0 && num_query_other == 0)
5068+
return pg_strdup_keyword_case(item, text);
5069+
else
5070+
return pg_strdup(item);
50545071
}
50555072
}
50565073
}
@@ -5062,7 +5079,7 @@ _complete_from_query(const char *simple_query,
50625079
* completion subject text, which is not what we want.
50635080
*/
50645081
#ifdef HAVE_RL_COMPLETION_APPEND_CHARACTER
5065-
if (num_schema_only > 0 && num_other == 0)
5082+
if (num_schema_only > 0 && num_query_other == 0 && num_keywords == 0)
50665083
rl_completion_append_character = '\0';
50675084
#endif
50685085

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy