From c8d1c22a4ed5ce5986f3bed6cd4f8ce131c96f73 Mon Sep 17 00:00:00 2001 From: Juan Luis Talamante Arreola Date: Sat, 30 Sep 2023 08:45:08 -0700 Subject: [PATCH] feat: capability to send the client response to clipboard (#130) * feat: capability to send the client response to clipboard * feat: capability to send the client response to clipboard --- cli/root.go | 16 ++++++++++++++++ cli/root_test.go | 16 ++++++++++++++++ go.mod | 1 + go.sum | 7 +++++++ licenses/oss-licenses.md | 1 + 5 files changed, 41 insertions(+) diff --git a/cli/root.go b/cli/root.go index 41f24576..4c2e866a 100644 --- a/cli/root.go +++ b/cli/root.go @@ -28,6 +28,7 @@ import ( "os" "strings" + "github.com/atotto/clipboard" "github.com/spf13/cobra" "github.com/spf13/viper" "github.com/tbckr/sgpt/v2/api" @@ -217,6 +218,14 @@ ls | sort return err } + if config.GetBool("clipboard") { + slog.Debug("Sending client response to clipboard") + err := clipboard.WriteAll(response) + if err != nil { + return err + } + } + if config.GetBool("execute") { slog.Debug("Trying to execute response in shell") return shell.ExecuteCommandWithConfirmation(cmd.Context(), cmd.InOrStdin(), cmd.OutOrStdout(), response) @@ -278,6 +287,13 @@ func createFlags(cmd *cobra.Command, config *viper.Viper) { bindErrors = append(bindErrors, err) } + // clipboard flags + cmd.Flags().BoolP("clipboard", "b", false, "send client response to clipboard") + err = config.BindPFlag("clipboard", cmd.Flags().Lookup("clipboard")) + if err != nil { + bindErrors = append(bindErrors, err) + } + // chat flags cmd.Flags().StringP("chat", "c", "", "use an existing chat session or create a new one") err = config.BindPFlag("chat", cmd.Flags().Lookup("chat")) diff --git a/cli/root_test.go b/cli/root_test.go index 0655c7c5..ddc707dc 100644 --- a/cli/root_test.go +++ b/cli/root_test.go @@ -32,6 +32,7 @@ import ( "sync" "testing" + "github.com/atotto/clipboard" "github.com/sashabaranov/go-openai" "github.com/stretchr/testify/require" "github.com/tbckr/sgpt/v2/api" @@ -104,6 +105,21 @@ func TestRootCmd_SimplePromptOnly(t *testing.T) { wg.Wait() } +func TestRootCmd_SimpleClipboard(t *testing.T) { + prompt := "Say: Hello World!" + expected := "Hello World!" + + mem := &exitMemento{} + config := createTestConfig(t) + + root := newRootCmd(mem.Exit, config, mockIsPipedShell(false, nil), api.MockClient(strings.Clone(expected), nil)) + + root.Execute([]string{"--clipboard", prompt}) + require.Equal(t, 0, mem.code) + textInClipboard, _ := clipboard.ReadAll() + require.Equal(t, expected, textInClipboard) +} + func TestRootCmd_SimplePromptOverrideValuesWithConfigFile(t *testing.T) { prompt := "Say: Hello World!" mem := &exitMemento{} diff --git a/go.mod b/go.mod index eeb498d2..20e0680c 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/tbckr/sgpt/v2 go 1.21 require ( + github.com/atotto/clipboard v0.1.4 github.com/muesli/mango-cobra v1.2.0 github.com/muesli/roff v0.1.0 github.com/sashabaranov/go-openai v1.15.3 diff --git a/go.sum b/go.sum index a1c55d02..f76d4d4a 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -57,6 +59,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -99,6 +102,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -131,9 +135,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -155,6 +161,7 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sashabaranov/go-openai v1.15.3 h1:rzoNK9n+Cak+PM6OQ9puxDmFllxfnVea9StlmhglXqA= github.com/sashabaranov/go-openai v1.15.3/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= diff --git a/licenses/oss-licenses.md b/licenses/oss-licenses.md index 6744309b..aaeb6182 100644 --- a/licenses/oss-licenses.md +++ b/licenses/oss-licenses.md @@ -5,6 +5,7 @@ Some packages may only be included on certain architectures or operating systems ## Overview +- [github.com/atotto/clipboard](https://pkg.go.dev/github.com/atotto/clipboard) ([BSD 3-Clause](https://github.com/atotto/clipboard/blob/v0.1.4/LICENSE)) - [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.6.0/LICENSE)) - [github.com/hashicorp/hcl](https://pkg.go.dev/github.com/hashicorp/hcl) ([MPL-2.0](https://github.com/hashicorp/hcl/blob/v1.0.0/LICENSE)) - [github.com/inconshreveable/mousetrap](https://pkg.go.dev/github.com/inconshreveable/mousetrap) ([Apache-2.0](https://github.com/inconshreveable/mousetrap/blob/v1.1.0/LICENSE))