diff --git a/pkg/constants/args.go b/pkg/constants/args.go index 57d4c9cf8..8923d3f5c 100644 --- a/pkg/constants/args.go +++ b/pkg/constants/args.go @@ -64,6 +64,7 @@ var ArgOutput = ArgFromMetaquery(CmdOutput) var ArgSeparator = ArgFromMetaquery(CmdSeparator) var ArgHeader = ArgFromMetaquery(CmdHeaders) var ArgMultiLine = ArgFromMetaquery(CmdMulti) +var ArgAutoComplete = ArgFromMetaquery(CmdAutoComplete) // BoolToOnOff converts a boolean value onto the string "on" or "off" func BoolToOnOff(val bool) string { diff --git a/pkg/constants/default_options.go b/pkg/constants/default_options.go index a402ec6b8..7d3469c4f 100644 --- a/pkg/constants/default_options.go +++ b/pkg/constants/default_options.go @@ -29,6 +29,7 @@ const DefaultConnectionConfigContent = ` # search_path = "" # comma-separated string # search_path_prefix = "" # comma-separated string # watch = true # true, false +# auto_complete = true # true, false # } # options "general" { diff --git a/pkg/constants/metaquery_commands.go b/pkg/constants/metaquery_commands.go index 9e1063dfe..c7f6720d7 100644 --- a/pkg/constants/metaquery_commands.go +++ b/pkg/constants/metaquery_commands.go @@ -20,6 +20,7 @@ const ( CmdSearchPath = ".search_path" // Set or show search-path CmdSearchPathPrefix = ".search_path_prefix" // set search path prefix CmdCache = ".cache" // cache control + CmdAutoComplete = ".auto_complete" // enable or disable auto complete ) // ArgFromMetaquery converts a metaquery of form '.header' into the config argument used to set the mode, i.e. 'header' diff --git a/pkg/interactive/interactive_client.go b/pkg/interactive/interactive_client.go index e6814177f..8231c5523 100644 --- a/pkg/interactive/interactive_client.go +++ b/pkg/interactive/interactive_client.go @@ -576,6 +576,9 @@ func (c *InteractiveClient) shouldExecute(line string, namedQuery bool) bool { } func (c *InteractiveClient) queryCompleter(d prompt.Document) []prompt.Suggest { + if !cmdconfig.Viper().GetBool(constants.ArgAutoComplete) { + return nil + } if !c.isInitialised() { return nil } @@ -630,6 +633,7 @@ func (c *InteractiveClient) queryCompleter(d prompt.Document) []prompt.Suggest { // } } + return prompt.FilterHasPrefix(s, d.GetWordBeforeCursor(), true) } diff --git a/pkg/query/metaquery/definitions.go b/pkg/query/metaquery/definitions.go index 97668597d..f09fbe08b 100644 --- a/pkg/query/metaquery/definitions.go +++ b/pkg/query/metaquery/definitions.go @@ -144,5 +144,16 @@ func init() { validator: exactlyNArgs(1), description: "Set a prefix to the current search-path", }, + constants.CmdAutoComplete: { + title: "auto-complete", + handler: setAutoComplete, + validator: booleanValidator(constants.CmdAutoComplete, validatorFromArgsOf(constants.CmdAutoComplete)), + description: "Enable or disable auto-completion", + args: []metaQueryArg{ + {value: constants.ArgOn, description: "Turn on auto-completion"}, + {value: constants.ArgOff, description: "Turn off auto-completion"}, + }, + completer: completerFromArgsOf(constants.CmdAutoComplete), + }, } } diff --git a/pkg/query/metaquery/handlers.go b/pkg/query/metaquery/handlers.go index 0a40f212d..4e6f26f8d 100644 --- a/pkg/query/metaquery/handlers.go +++ b/pkg/query/metaquery/handlers.go @@ -416,3 +416,8 @@ func buildTable(rows [][]string, autoMerge bool) string { } return t.Render() } + +func setAutoComplete(ctx context.Context, input *HandlerInput) error { + cmdconfig.Viper().Set(constants.ArgAutoComplete, typeHelpers.StringToBool(input.args()[0])) + return nil +} diff --git a/pkg/steampipeconfig/load_config_test.go b/pkg/steampipeconfig/load_config_test.go index 6d4d4338a..092887d6b 100644 --- a/pkg/steampipeconfig/load_config_test.go +++ b/pkg/steampipeconfig/load_config_test.go @@ -34,8 +34,10 @@ var terminalSeparator = "," var terminalTiming = false var terminalSearchPath = "aws,gcp" var generalUpdateCheck = "true" +var terminalAutoComplete = true var workspaceMulti = true +var workspaceAutoComplete = true var workspaceOutput = "json" var workspaceSearchPath = "bar,aws,gcp" var workspaceSearchPathPrefix = "foobar" @@ -235,12 +237,13 @@ var testCasesLoadConfig = map[string]loadConfigTest{ QueryTimeout: &databaseQueryTimeout, }, TerminalOptions: &options.Terminal{ - Output: &terminalOutput, - Separator: &terminalSeparator, - Header: &terminalHeader, - Multi: &terminalMulti, - Timing: &terminalTiming, - SearchPath: &terminalSearchPath, + Output: &terminalOutput, + Separator: &terminalSeparator, + Header: &terminalHeader, + Multi: &terminalMulti, + Timing: &terminalTiming, + SearchPath: &terminalSearchPath, + AutoComplete: &terminalAutoComplete, }, GeneralOptions: &options.General{ UpdateCheck: &generalUpdateCheck, @@ -314,6 +317,7 @@ var testCasesLoadConfig = map[string]loadConfigTest{ Timing: &terminalTiming, SearchPath: &terminalSearchPath, SearchPathPrefix: &workspaceSearchPathPrefix, + AutoComplete: &terminalAutoComplete, }, GeneralOptions: &options.General{ UpdateCheck: &generalUpdateCheck, @@ -382,6 +386,7 @@ var testCasesLoadConfig = map[string]loadConfigTest{ Timing: &terminalTiming, SearchPath: &workspaceSearchPath, SearchPathPrefix: &workspaceSearchPathPrefix, + AutoComplete: &workspaceAutoComplete, }, GeneralOptions: &options.General{ UpdateCheck: &generalUpdateCheck, @@ -445,12 +450,13 @@ var testCasesLoadConfig = map[string]loadConfigTest{ QueryTimeout: &databaseQueryTimeout, }, TerminalOptions: &options.Terminal{ - Output: &terminalOutput, - Separator: &terminalSeparator, - Header: &terminalHeader, - Multi: &terminalMulti, - Timing: &terminalTiming, - SearchPath: &terminalSearchPath, + Output: &terminalOutput, + Separator: &terminalSeparator, + Header: &terminalHeader, + Multi: &terminalMulti, + Timing: &terminalTiming, + SearchPath: &terminalSearchPath, + AutoComplete: &terminalAutoComplete, }, GeneralOptions: &options.General{ UpdateCheck: &generalUpdateCheck, @@ -472,12 +478,13 @@ var testCasesLoadConfig = map[string]loadConfigTest{ QueryTimeout: &databaseQueryTimeout, }, TerminalOptions: &options.Terminal{ - Output: &terminalOutput, - Separator: &terminalSeparator, - Header: &terminalHeader, - Multi: &terminalMulti, - Timing: &terminalTiming, - SearchPath: &terminalSearchPath, + Output: &terminalOutput, + Separator: &terminalSeparator, + Header: &terminalHeader, + Multi: &terminalMulti, + Timing: &terminalTiming, + SearchPath: &terminalSearchPath, + AutoComplete: &terminalAutoComplete, }, GeneralOptions: &options.General{ UpdateCheck: &generalUpdateCheck, diff --git a/pkg/steampipeconfig/options/terminal.go b/pkg/steampipeconfig/options/terminal.go index 7361860fa..84e9f8280 100644 --- a/pkg/steampipeconfig/options/terminal.go +++ b/pkg/steampipeconfig/options/terminal.go @@ -17,6 +17,7 @@ type Terminal struct { SearchPath *string `hcl:"search_path"` SearchPathPrefix *string `hcl:"search_path_prefix"` Watch *bool `hcl:"watch"` + AutoComplete *bool `hcl:"auto_complete"` } // ConfigMap :: create a config map to pass to viper @@ -49,6 +50,9 @@ func (t *Terminal) ConfigMap() map[string]interface{} { if t.Watch != nil { res[constants.ArgWatch] = t.Watch } + if t.AutoComplete != nil { + res[constants.ArgAutoComplete] = t.AutoComplete + } return res } @@ -81,6 +85,9 @@ func (t *Terminal) Merge(otherOptions Options) { if o.Watch != nil { t.Watch = o.Watch } + if o.AutoComplete != nil { + t.AutoComplete = o.AutoComplete + } } } @@ -129,6 +136,11 @@ func (t *Terminal) String() string { } else { str = append(str, fmt.Sprintf(" Watch: %v", *t.Watch)) } + if t.AutoComplete == nil { + str = append(str, " AutoComplete: nil") + } else { + str = append(str, fmt.Sprintf(" AutoComplete: %v", *t.AutoComplete)) + } return strings.Join(str, "\n") }