Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb48b9cb

Browse files
committed
Teach psql to do tab completion for names of psql variables.
Completion is supported in the context of \set and when interpolatinga variable value using :foo etc.In passing, fix some places in tab-complete.c that weren't followingproject style for comment formatting.Pavel Stehule, reviewed by Itagaki Takahiro
1 parent2ec993a commitb48b9cb

File tree

1 file changed

+134
-63
lines changed

1 file changed

+134
-63
lines changed

‎src/bin/psql/tab-complete.c

Lines changed: 134 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -576,20 +576,24 @@ static char *complete_from_query(const char *text, int state);
576576
staticchar*complete_from_schema_query(constchar*text,intstate);
577577
staticchar*_complete_from_query(intis_schema_query,
578578
constchar*text,intstate);
579-
staticchar*complete_from_const(constchar*text,intstate);
580579
staticchar*complete_from_list(constchar*text,intstate);
580+
staticchar*complete_from_const(constchar*text,intstate);
581+
staticchar**complete_from_variables(char*text,
582+
constchar*prefix,constchar*suffix);
581583

582584
staticPGresult*exec_query(constchar*query);
583585

584586
staticchar*previous_word(intpoint,intskip);
585587

586-
#if0
588+
#ifdefNOT_USED
587589
staticchar*quote_file_name(char*text,intmatch_type,char*quote_pointer);
588590
staticchar*dequote_file_name(char*text,charquote_char);
589591
#endif
590592

591593

592-
/* Initialize the readline library for our purposes. */
594+
/*
595+
* Initialize the readline library for our purposes.
596+
*/
593597
void
594598
initialize_readline(void)
595599
{
@@ -607,11 +611,14 @@ initialize_readline(void)
607611
}
608612

609613

610-
/* The completion function. Acc. to readline spec this gets passed the text
611-
entered to far and its start and end in the readline buffer. The return value
612-
is some partially obscure list format that can be generated by the readline
613-
libraries completion_matches() function, so we don't have to worry about it.
614-
*/
614+
/*
615+
* The completion function.
616+
*
617+
* According to readline spec this gets passed the text entered so far and its
618+
* start and end positions in the readline buffer. The return value is some
619+
* partially obscure list format that can be generated by readline's
620+
* completion_matches() function, so we don't have to worry about it.
621+
*/
615622
staticchar**
616623
psql_completion(char*text,intstart,intend)
617624
{
@@ -1943,7 +1950,7 @@ psql_completion(char *text, int start, int end)
19431950
pg_strcasecmp(prev_wd,"WRAPPER")==0)
19441951
COMPLETE_WITH_QUERY(Query_for_list_of_fdws);
19451952

1946-
/* GRANT && REVOKE*/
1953+
/* GRANT && REVOKE*/
19471954
/* Complete GRANT/REVOKE with a list of privileges */
19481955
elseif (pg_strcasecmp(prev_wd,"GRANT")==0||
19491956
pg_strcasecmp(prev_wd,"REVOKE")==0)
@@ -2512,7 +2519,6 @@ psql_completion(char *text, int start, int end)
25122519
pg_strcasecmp(prev3_wd,"\\copy")!=0)
25132520
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_tsv,NULL);
25142521

2515-
25162522
/* Backslash commands */
25172523
/* TODO: \dc \dd \dl */
25182524
elseif (strcmp(prev_wd,"\\connect")==0||strcmp(prev_wd,"\\c")==0)
@@ -2582,6 +2588,10 @@ psql_completion(char *text, int start, int end)
25822588

25832589
COMPLETE_WITH_LIST(my_list);
25842590
}
2591+
elseif (strcmp(prev_wd,"\\set")==0)
2592+
{
2593+
matches=complete_from_variables(text,"","");
2594+
}
25852595
elseif (strcmp(prev_wd,"\\sf")==0||strcmp(prev_wd,"\\sf+")==0)
25862596
COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_functions,NULL);
25872597
elseif (strcmp(prev_wd,"\\cd")==0||
@@ -2594,6 +2604,16 @@ psql_completion(char *text, int start, int end)
25942604
)
25952605
matches=completion_matches(text,filename_completion_function);
25962606

2607+
/* Variable interpolation */
2608+
elseif (text[0]==':'&&text[1]!=':')
2609+
{
2610+
if (text[1]=='\'')
2611+
matches=complete_from_variables(text,":'","'");
2612+
elseif (text[1]=='"')
2613+
matches=complete_from_variables(text,":\"","\"");
2614+
else
2615+
matches=complete_from_variables(text,":","");
2616+
}
25972617

25982618
/*
25992619
* Finally, we look through the list of "things", such as TABLE, INDEX and
@@ -2643,23 +2663,24 @@ psql_completion(char *text, int start, int end)
26432663
}
26442664

26452665

2666+
/*
2667+
* GENERATOR FUNCTIONS
2668+
*
2669+
* These functions do all the actual work of completing the input. They get
2670+
* passed the text so far and the count how many times they have been called
2671+
* so far with the same text.
2672+
* If you read the above carefully, you'll see that these don't get called
2673+
* directly but through the readline interface.
2674+
* The return value is expected to be the full completion of the text, going
2675+
* through a list each time, or NULL if there are no more matches. The string
2676+
* will be free()'d by readline, so you must run it through strdup() or
2677+
* something of that sort.
2678+
*/
26462679

2647-
/* GENERATOR FUNCTIONS
2648-
2649-
These functions do all the actual work of completing the input. They get
2650-
passed the text so far and the count how many times they have been called so
2651-
far with the same text.
2652-
If you read the above carefully, you'll see that these don't get called
2653-
directly but through the readline interface.
2654-
The return value is expected to be the full completion of the text, going
2655-
through a list each time, or NULL if there are no more matches. The string
2656-
will be free()'d by readline, so you must run it through strdup() or
2657-
something of that sort.
2658-
*/
2659-
2660-
/* This one gives you one from a list of things you can put after CREATE
2661-
as defined above.
2662-
*/
2680+
/*
2681+
* This one gives you one from a list of things you can put after CREATE
2682+
* as defined above.
2683+
*/
26632684
staticchar*
26642685
create_command_generator(constchar*text,intstate)
26652686
{
@@ -2677,7 +2698,8 @@ create_command_generator(const char *text, int state)
26772698
/* find something that matches */
26782699
while ((name=words_after_create[list_index++].name))
26792700
{
2680-
if ((pg_strncasecmp(name,text,string_length)==0)&& !words_after_create[list_index-1].noshow)
2701+
if ((pg_strncasecmp(name,text,string_length)==0)&&
2702+
!words_after_create[list_index-1].noshow)
26812703
returnpg_strdup(name);
26822704
}
26832705
/* if nothing matches, return NULL */
@@ -2745,26 +2767,27 @@ complete_from_schema_query(const char *text, int state)
27452767
}
27462768

27472769

2748-
/* This creates a list of matching things, according to a query pointed to
2749-
by completion_charp.
2750-
The query can be one of two kinds:
2751-
- A simple query which must contain a %d and a %s, which will be replaced
2752-
by the string length of the text and the text itself. The query may also
2753-
have up to four more %s in it; the first two such will be replaced by the
2754-
value of completion_info_charp, the next two by the value of
2755-
completion_info_charp2.
2756-
or:
2757-
- A schema query used for completion of both schema and relation names;
2758-
these are more complex and must contain in the following order:
2759-
%d %s %d %s %d %s %s %d %s
2760-
where %d is the string length of the text and %s the text itself.
2761-
2762-
It is assumed that strings should be escaped to become SQL literals
2763-
(that is, what is in the query is actually ... '%s' ...)
2764-
2765-
See top of file for examples of both kinds of query.
2766-
*/
2767-
2770+
/*
2771+
* This creates a list of matching things, according to a query pointed to
2772+
* by completion_charp.
2773+
* The query can be one of two kinds:
2774+
*
2775+
* 1. A simple query which must contain a %d and a %s, which will be replaced
2776+
* by the string length of the text and the text itself. The query may also
2777+
* have up to four more %s in it; the first two such will be replaced by the
2778+
* value of completion_info_charp, the next two by the value of
2779+
* completion_info_charp2.
2780+
*
2781+
* 2. A schema query used for completion of both schema and relation names.
2782+
* These are more complex and must contain in the following order:
2783+
* %d %s %d %s %d %s %s %d %s
2784+
* where %d is the string length of the text and %s the text itself.
2785+
*
2786+
* It is assumed that strings should be escaped to become SQL literals
2787+
* (that is, what is in the query is actually ... '%s' ...)
2788+
*
2789+
* See top of file for examples of both kinds of query.
2790+
*/
27682791
staticchar*
27692792
_complete_from_query(intis_schema_query,constchar*text,intstate)
27702793
{
@@ -2950,10 +2973,11 @@ _complete_from_query(int is_schema_query, const char *text, int state)
29502973
}
29512974

29522975

2953-
/* This function returns in order one of a fixed, NULL pointer terminated list
2954-
of strings (if matching). This can be used if there are only a fixed number
2955-
SQL words that can appear at certain spot.
2956-
*/
2976+
/*
2977+
* This function returns in order one of a fixed, NULL pointer terminated list
2978+
* of strings (if matching). This can be used if there are only a fixed number
2979+
* SQL words that can appear at certain spot.
2980+
*/
29572981
staticchar*
29582982
complete_from_list(constchar*text,intstate)
29592983
{
@@ -3006,12 +3030,13 @@ complete_from_list(const char *text, int state)
30063030
}
30073031

30083032

3009-
/* This function returns one fixed string the first time even if it doesn't
3010-
match what's there, and nothing the second time. This should be used if there
3011-
is only one possibility that can appear at a certain spot, so misspellings
3012-
will be overwritten.
3013-
The string to be passed must be in completion_charp.
3014-
*/
3033+
/*
3034+
* This function returns one fixed string the first time even if it doesn't
3035+
* match what's there, and nothing the second time. This should be used if
3036+
* there is only one possibility that can appear at a certain spot, so
3037+
* misspellings will be overwritten. The string to be passed must be in
3038+
* completion_charp.
3039+
*/
30153040
staticchar*
30163041
complete_from_const(constchar*text,intstate)
30173042
{
@@ -3026,6 +3051,55 @@ complete_from_const(const char *text, int state)
30263051
}
30273052

30283053

3054+
/*
3055+
* This function supports completion with the name of a psql variable.
3056+
* The variable names can be prefixed and suffixed with additional text
3057+
* to support quoting usages.
3058+
*/
3059+
staticchar**
3060+
complete_from_variables(char*text,constchar*prefix,constchar*suffix)
3061+
{
3062+
char**matches;
3063+
intoverhead=strlen(prefix)+strlen(suffix)+1;
3064+
constchar**varnames;
3065+
intnvars=0;
3066+
intmaxvars=100;
3067+
inti;
3068+
struct_variable*ptr;
3069+
3070+
varnames= (constchar**)pg_malloc((maxvars+1)*sizeof(char*));
3071+
3072+
for (ptr=pset.vars->next;ptr;ptr=ptr->next)
3073+
{
3074+
char*buffer;
3075+
3076+
if (nvars >=maxvars)
3077+
{
3078+
maxvars *=2;
3079+
varnames= (constchar**)realloc(varnames,
3080+
(maxvars+1)*sizeof(char*));
3081+
if (!varnames)
3082+
{
3083+
psql_error("out of memory\n");
3084+
exit(EXIT_FAILURE);
3085+
}
3086+
}
3087+
3088+
buffer= (char*)pg_malloc(strlen(ptr->name)+overhead);
3089+
sprintf(buffer,"%s%s%s",prefix,ptr->name,suffix);
3090+
varnames[nvars++]=buffer;
3091+
}
3092+
3093+
varnames[nvars]=NULL;
3094+
COMPLETE_WITH_LIST(varnames);
3095+
3096+
for (i=0;i<nvars;i++)
3097+
free((void*)varnames[i]);
3098+
free(varnames);
3099+
3100+
returnmatches;
3101+
}
3102+
30293103

30303104
/* HELPER FUNCTIONS */
30313105

@@ -3046,7 +3120,7 @@ exec_query(const char *query)
30463120

30473121
if (PQresultStatus(result)!=PGRES_TUPLES_OK)
30483122
{
3049-
#if0
3123+
#ifdefNOT_USED
30503124
psql_error("tab completion query failed: %s\nQuery was:\n%s\n",
30513125
PQerrorMessage(pset.db),query);
30523126
#endif
@@ -3058,7 +3132,6 @@ exec_query(const char *query)
30583132
}
30593133

30603134

3061-
30623135
/*
30633136
* Return the word (space delimited) before point. Set skip > 0 to
30643137
* skip that many words; e.g. skip=1 finds the word before the
@@ -3133,7 +3206,7 @@ previous_word(int point, int skip)
31333206
returns;
31343207
}
31353208

3136-
#if0
3209+
#ifdefNOT_USED
31373210

31383211
/*
31393212
* Surround a string with single quotes. This works for both SQL and
@@ -3158,8 +3231,6 @@ quote_file_name(char *text, int match_type, char *quote_pointer)
31583231
returns;
31593232
}
31603233

3161-
3162-
31633234
staticchar*
31643235
dequote_file_name(char*text,charquote_char)
31653236
{
@@ -3175,6 +3246,6 @@ dequote_file_name(char *text, char quote_char)
31753246

31763247
returns;
31773248
}
3178-
#endif/*0 */
3249+
#endif/*NOT_USED */
31793250

31803251
#endif/* USE_READLINE */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp