From efea8a72f2d887a6cec58e272e003cf7571465e1 Mon Sep 17 00:00:00 2001 From: Binaek Sarkar Date: Wed, 2 Nov 2022 21:10:13 +0530 Subject: [PATCH] Fixes issue where 'Alt` keyboard combinations would error in WSL. Closes #2549 --- go.mod | 2 +- go.sum | 4 +-- pkg/constants/ascii.go | 14 ---------- pkg/interactive/interactive_client.go | 40 ++++++++++++--------------- pkg/utils/useragent.go | 3 +- pkg/utils/wsl.go | 27 ++++++++++++++---- 6 files changed, 44 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index fb51062d1..922b020db 100644 --- a/go.mod +++ b/go.mod @@ -219,7 +219,7 @@ require ( ) replace ( - github.com/c-bata/go-prompt => github.com/turbot/go-prompt v0.2.6-steampipe.3 + github.com/c-bata/go-prompt => github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50 github.com/deislabs/oras => github.com/oras-project/oras v0.9.0 github.com/docker/distribution => github.com/distribution/distribution v2.7.1+incompatible github.com/docker/docker => github.com/moby/moby v20.10.17+incompatible diff --git a/go.sum b/go.sum index 4a0a78a86..2b75d205f 100644 --- a/go.sum +++ b/go.sum @@ -1065,8 +1065,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/tombuildsstuff/giovanni v0.15.1/go.mod h1:0TZugJPEtqzPlMpuJHYfXY6Dq2uLPrXf98D2XQSxNbA= github.com/turbot/go-kit v0.5.0-rc.1 h1:E3Mn9uazBPOpXbZoo+rzF811t5AKrYDOtz+0bvkeHJA= github.com/turbot/go-kit v0.5.0-rc.1/go.mod h1:wbYT3zaI9Jb6+V99IgnW9Yx69995WDeoiLxVVZPh3/Y= -github.com/turbot/go-prompt v0.2.6-steampipe.3 h1:uPv7Ni7hqw6raBeSayr84tT9oBR5C2xP64kaIq01ARc= -github.com/turbot/go-prompt v0.2.6-steampipe.3/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= +github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50 h1:zs87uA6QZsYLk4RRxDOIxt8ro/B2V6HzoMWm05Lo7ao= +github.com/turbot/go-prompt v0.2.6-steampipe.0.0.20221028122246-eb118ec58d50/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw= github.com/turbot/steampipe-cloud-sdk-go v0.1.4-alpha.1 h1:kHCC9UzNMsUaPAQ2rHm8zpTRSpWDROm/JKjAPEaacwM= github.com/turbot/steampipe-cloud-sdk-go v0.1.4-alpha.1/go.mod h1:8M2CspUHgCGqDCJV+FNn+boBPyLRHyzDinYnoZ/kZYw= github.com/turbot/steampipe-plugin-sdk/v4 v4.1.7 h1:8DPSro6w7FKMig8d/jHF0rChN4tzEwnEKEZZLNp5DGA= diff --git a/pkg/constants/ascii.go b/pkg/constants/ascii.go index de428b793..ee3b884b7 100644 --- a/pkg/constants/ascii.go +++ b/pkg/constants/ascii.go @@ -10,17 +10,3 @@ var ( // AltRightArrowASCIICode :: AltRightArrowASCIICode = []byte{0x1b, 0x1b, 0x5B, 0x43} ) - -var ( - SuppressedASCIICodes = [][]byte{ - // Alt+UpArrow - {27, 27, 91, 65}, - // Alt+DownArrow - {27, 27, 91, 66}, - } - - SuppressedASCIICodesForWSL = [][]byte{ - // Alt+D - {195, 176}, - } -) diff --git a/pkg/interactive/interactive_client.go b/pkg/interactive/interactive_client.go index 8231c5523..30cca99e2 100644 --- a/pkg/interactive/interactive_client.go +++ b/pkg/interactive/interactive_client.go @@ -1,9 +1,9 @@ package interactive import ( + "bytes" "context" "fmt" - "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" "log" "os" "os/signal" @@ -29,6 +29,7 @@ import ( "github.com/turbot/steampipe/pkg/query/queryresult" "github.com/turbot/steampipe/pkg/schema" "github.com/turbot/steampipe/pkg/statushooks" + "github.com/turbot/steampipe/pkg/steampipeconfig/modconfig" "github.com/turbot/steampipe/pkg/utils" "github.com/turbot/steampipe/pkg/version" ) @@ -345,8 +346,13 @@ func (c *InteractiveClient) runInteractivePrompt(ctx context.Context) (ret utils ASCIICode: constants.AltRightArrowASCIICode, Fn: prompt.GoRightWord, }), - // ignore suppressed ASCII codes - prompt.OptionAddASCIICodeBind(c.suppressOnInput()...), + prompt.OptionBufferPreHook(func(input string) (modifiedInput string, ignore bool) { + // if this is not WSL, return as-is + if !utils.IsWSL() { + return input, false + } + return cleanBufferForWSL(input) + }), ) // set this to a default c.autocompleteOnEmpty = false @@ -355,26 +361,16 @@ func (c *InteractiveClient) runInteractivePrompt(ctx context.Context) (ret utils return } -// suppressOnInput adds handlers which explicitly ignores certain ASCII codes from input -func (c *InteractiveClient) suppressOnInput() []prompt.ASCIICodeBind { - mapped := utils.Map(constants.SuppressedASCIICodes, func(k []byte) prompt.ASCIICodeBind { - return prompt.ASCIICodeBind{ - ASCIICode: k, - Fn: func(b *prompt.Buffer) { /* ignore */ }, - } - }) - - isWSL, _ := utils.IsWSL() - if isWSL { - mapped = append(mapped, utils.Map(constants.SuppressedASCIICodesForWSL, func(k []byte) prompt.ASCIICodeBind { - return prompt.ASCIICodeBind{ - ASCIICode: k, - Fn: func(b *prompt.Buffer) { /* ignore */ }, - } - })...) +func cleanBufferForWSL(s string) (string, bool) { + b := []byte(s) + // in WSL, 'Alt' combo-characters are denoted by [27, ASCII of character] + // if we get a combination which has 27 as prefix - we should ignore it + // this is inline with other interactive clients like pgcli + if len(b) > 1 && bytes.HasPrefix(b, []byte{byte(27)}) { + // ignore it + return "", true } - - return mapped + return string(b), false } func (c *InteractiveClient) breakMultilinePrompt(buffer *prompt.Buffer) { diff --git a/pkg/utils/useragent.go b/pkg/utils/useragent.go index 841a12545..502f40a8b 100644 --- a/pkg/utils/useragent.go +++ b/pkg/utils/useragent.go @@ -28,8 +28,7 @@ func BuildRequestPayload(signature string, payload map[string]interface{}) *byte // change the platform to "windows_linux" if we are running in "Windows Subsystem for Linux" if runtime.GOOS == "linux" { - wsl, err := IsWSL() - if err == nil && wsl { + if IsWSL() { requestPayload["os_platform"] = "windows_linux" } } diff --git a/pkg/utils/wsl.go b/pkg/utils/wsl.go index 0e9b91e35..d7136857e 100644 --- a/pkg/utils/wsl.go +++ b/pkg/utils/wsl.go @@ -1,22 +1,39 @@ package utils import ( + "log" "os" "runtime" "strings" ) -// IsWSL :: detects whether app is running in WSL environment +// cache for the WSL value, so that we don't have to query the OS all the time +var isWsl *bool = nil + +// IsWSL detects whether app is running in WSL environment // refer to: https://github.com/Microsoft/WSL/issues/423#issuecomment-679190758 -func IsWSL() (bool, error) { +func IsWSL() bool { + if isWsl != nil { + return *isWsl + } if runtime.GOOS != "linux" { - return false, nil + *isWsl = false + return false } // https://github.com/Microsoft/WSL/issues/2299#issuecomment-361366982 osReleaseContent, err := os.ReadFile("/proc/version") if err != nil { - return false, err + log.Println("[TRACE] could not read /proc/version for evaluating WSL: ", err) + // WSL systems will always have the /proc/version file. + // if we can't read the file, then this must be some other + // flavour of linux which doesn't use it - or there's something + // fundamentally wrong with the installation. + // + // in both cases - assume this is not WSL + return false } osRelease := strings.ToLower(string(osReleaseContent)) - return (strings.Contains(osRelease, "microsoft") || strings.Contains(osRelease, "wsl")), nil + w := (strings.Contains(osRelease, "microsoft") || strings.Contains(osRelease, "wsl")) + isWsl = &w + return *isWsl }