@@ -813,8 +813,11 @@ static char *_complete_from_query(int is_schema_query,
813
813
const char * text , int state );
814
814
static char * complete_from_list (const char * text , int state );
815
815
static char * complete_from_const (const char * text , int state );
816
+ static void append_variable_names (char * * * varnames , int * nvars ,
817
+ int * maxvars , const char * varname ,
818
+ const char * prefix , const char * suffix );
816
819
static char * * complete_from_variables (const char * text ,
817
- const char * prefix , const char * suffix );
820
+ const char * prefix , const char * suffix , bool need_value );
818
821
static char * complete_from_files (const char * text , int state );
819
822
820
823
static char * pg_strdup_keyword_case (const char * s , const char * ref );
@@ -925,11 +928,11 @@ psql_completion(const char *text, int start, int end)
925
928
else if (text [0 ] == ':' && text [1 ] != ':' )
926
929
{
927
930
if (text [1 ] == '\'' )
928
- matches = complete_from_variables (text , ":'" , "'" );
931
+ matches = complete_from_variables (text , ":'" , "'" , true );
929
932
else if (text [1 ] == '"' )
930
- matches = complete_from_variables (text , ":\"" , "\"" );
933
+ matches = complete_from_variables (text , ":\"" , "\"" , true );
931
934
else
932
- matches = complete_from_variables (text , ":" , "" );
935
+ matches = complete_from_variables (text , ":" , "" , true );
933
936
}
934
937
935
938
/* If no previous word, suggest one of the basic sql commands */
@@ -3604,9 +3607,71 @@ psql_completion(const char *text, int start, int end)
3604
3607
COMPLETE_WITH_LIST_CS (my_list );
3605
3608
}
3606
3609
}
3610
+ else if (strcmp (prev_wd , "\\unset" ) == 0 )
3611
+ {
3612
+ matches = complete_from_variables (text , "" , "" , true);
3613
+ }
3607
3614
else if (strcmp (prev_wd , "\\set" ) == 0 )
3608
3615
{
3609
- matches = complete_from_variables (text , "" , "" );
3616
+ matches = complete_from_variables (text , "" , "" , false);
3617
+ }
3618
+ else if (strcmp (prev2_wd , "\\set" ) == 0 )
3619
+ {
3620
+ static const char * const boolean_value_list [] =
3621
+ {"on" , "off" , NULL };
3622
+
3623
+ if (strcmp (prev_wd , "AUTOCOMMIT" ) == 0 )
3624
+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3625
+ else if (strcmp (prev_wd , "COMP_KEYWORD_CASE" ) == 0 )
3626
+ {
3627
+ static const char * const my_list [] =
3628
+ {"lower" , "upper" , "preserve-lower" , "preserve-upper" , NULL };
3629
+
3630
+ COMPLETE_WITH_LIST_CS (my_list );
3631
+ }
3632
+ else if (strcmp (prev_wd , "ECHO" ) == 0 )
3633
+ {
3634
+ static const char * const my_list [] =
3635
+ {"errors" , "queries" , "all" , "none" , NULL };
3636
+
3637
+ COMPLETE_WITH_LIST_CS (my_list );
3638
+ }
3639
+ else if (strcmp (prev_wd , "ECHO_HIDDEN" ) == 0 )
3640
+ {
3641
+ static const char * const my_list [] =
3642
+ {"noexec" , "off" , "on" , NULL };
3643
+
3644
+ COMPLETE_WITH_LIST_CS (my_list );
3645
+ }
3646
+ else if (strcmp (prev_wd , "HISTCONTROL" ) == 0 )
3647
+ {
3648
+ static const char * const my_list [] =
3649
+ {"ignorespace" , "ignoredups" , "ignoreboth" , "none" , NULL };
3650
+
3651
+ COMPLETE_WITH_LIST_CS (my_list );
3652
+ }
3653
+ else if (strcmp (prev_wd , "ON_ERROR_ROLLBACK" ) == 0 )
3654
+ {
3655
+ static const char * const my_list [] =
3656
+ {"on" , "off" , "interactive" , NULL };
3657
+
3658
+ COMPLETE_WITH_LIST_CS (my_list );
3659
+ }
3660
+ else if (strcmp (prev_wd , "ON_ERROR_STOP" ) == 0 )
3661
+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3662
+ else if (strcmp (prev_wd , "QUIET" ) == 0 )
3663
+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3664
+ else if (strcmp (prev_wd , "SINGLELINE" ) == 0 )
3665
+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3666
+ else if (strcmp (prev_wd , "SINGLESTEP" ) == 0 )
3667
+ COMPLETE_WITH_LIST_CS (boolean_value_list );
3668
+ else if (strcmp (prev_wd , "VERBOSITY" ) == 0 )
3669
+ {
3670
+ static const char * const my_list [] =
3671
+ {"default" , "verbose" , "terse" , NULL };
3672
+
3673
+ COMPLETE_WITH_LIST_CS (my_list );
3674
+ }
3610
3675
}
3611
3676
else if (strcmp (prev_wd , "\\sf" ) == 0 || strcmp (prev_wd , "\\sf+" ) == 0 )
3612
3677
COMPLETE_WITH_SCHEMA_QUERY (Query_for_list_of_functions , NULL );
@@ -4052,13 +4117,40 @@ complete_from_const(const char *text, int state)
4052
4117
}
4053
4118
4054
4119
4120
+ /*
4121
+ * This function appends the variable name with prefix and suffix to
4122
+ * the variable names array.
4123
+ */
4124
+ static void
4125
+ append_variable_names (char * * * varnames , int * nvars ,
4126
+ int * maxvars , const char * varname ,
4127
+ const char * prefix , const char * suffix )
4128
+ {
4129
+ if (* nvars >= * maxvars )
4130
+ {
4131
+ * maxvars *= 2 ;
4132
+ * varnames = (char * * ) realloc (* varnames ,
4133
+ ((* maxvars ) + 1 ) * sizeof (char * ));
4134
+ if (!(* varnames ))
4135
+ {
4136
+ psql_error ("out of memory\n" );
4137
+ exit (EXIT_FAILURE );
4138
+ }
4139
+ }
4140
+
4141
+ (* varnames )[(* nvars )++ ] = psprintf ("%s%s%s" , prefix , varname , suffix );
4142
+ }
4143
+
4144
+
4055
4145
/*
4056
4146
* This function supports completion with the name of a psql variable.
4057
4147
* The variable names can be prefixed and suffixed with additional text
4058
- * to support quoting usages.
4148
+ * to support quoting usages. If need_value is true, only the variables
4149
+ * that have the set values are picked up.
4059
4150
*/
4060
4151
static char * *
4061
- complete_from_variables (const char * text , const char * prefix , const char * suffix )
4152
+ complete_from_variables (const char * text , const char * prefix , const char * suffix ,
4153
+ bool need_value )
4062
4154
{
4063
4155
char * * matches ;
4064
4156
char * * varnames ;
@@ -4067,23 +4159,34 @@ complete_from_variables(const char *text, const char *prefix, const char *suffix
4067
4159
int i ;
4068
4160
struct _variable * ptr ;
4069
4161
4162
+ static const char * const known_varnames [] = {
4163
+ "AUTOCOMMIT" , "COMP_KEYWORD_CASE" , "DBNAME" , "ECHO" , "ECHO_HIDDEN" ,
4164
+ "ENCODING" , "FETCH_COUNT" , "HISTCONTROL" , "HISTFILE" , "HISTSIZE" ,
4165
+ "HOST" , "IGNOREEOF" , "LASTOID" , "ON_ERROR_ROLLBACK" , "ON_ERROR_STOP" ,
4166
+ "PORT" , "PROMPT1" , "PROMPT2" , "PROMPT3" , "QUIET" , "SINGLELINE" ,
4167
+ "SINGLESTEP" , "USER" , "VERBOSITY" , NULL
4168
+ };
4169
+
4070
4170
varnames = (char * * ) pg_malloc ((maxvars + 1 ) * sizeof (char * ));
4071
4171
4172
+ if (!need_value )
4173
+ {
4174
+ for (i = 0 ; known_varnames [i ] && nvars < maxvars ; i ++ )
4175
+ append_variable_names (& varnames , & nvars , & maxvars ,
4176
+ known_varnames [i ], prefix , suffix );
4177
+ }
4178
+
4072
4179
for (ptr = pset .vars -> next ; ptr ; ptr = ptr -> next )
4073
4180
{
4074
- if (nvars >= maxvars )
4181
+ if (need_value && !(ptr -> value ))
4182
+ continue ;
4183
+ for (i = 0 ; known_varnames [i ]; i ++ ) /* remove duplicate entry */
4075
4184
{
4076
- maxvars *= 2 ;
4077
- varnames = (char * * ) realloc (varnames ,
4078
- (maxvars + 1 ) * sizeof (char * ));
4079
- if (!varnames )
4080
- {
4081
- psql_error ("out of memory\n" );
4082
- exit (EXIT_FAILURE );
4083
- }
4185
+ if (strcmp (ptr -> name , known_varnames [i ]) == 0 )
4186
+ continue ;
4084
4187
}
4085
-
4086
- varnames [ nvars ++ ] = psprintf ( "%s%s%s" , prefix , ptr -> name , suffix );
4188
+ append_variable_names ( & varnames , & nvars , & maxvars , ptr -> name ,
4189
+ prefix , suffix );
4087
4190
}
4088
4191
4089
4192
varnames [nvars ] = NULL ;
0 commit comments