Compare commits

...

13 Commits

Author SHA1 Message Date
asrul10
d11017d792 Merge pull request #12 from asrul10/feat/read-file
feat: read file and add to prompt
2024-02-08 12:00:21 +07:00
asrul10
1c4113d0c2 feat: read file and add to prompt 2024-02-08 11:57:25 +07:00
asrul10
00b2ea6614 Merge pull request #10 from asrul10/feat/copy-clipboard
(feat) Copy to clipboard
2023-12-19 10:12:35 +07:00
asrul10
9538b0fed5 feat: copy to clipboard 2023-12-19 10:09:26 +07:00
asrul10
5141cb69a3 update 2023-12-19 09:30:22 +07:00
asrul10
ae90ef6cfb Merge pull request #8 from asrul10/feature/regenerate-gpt
Add a feature to regenerate the result and some minor improvements
2023-04-09 10:56:43 +07:00
asrul10
7f81b1942b style: update version 2023-04-09 10:54:35 +07:00
asrul10
dafcaaff0f docs: update example result 2023-04-09 10:53:11 +07:00
asrul10
fbb68d2a28 feat: add regenerate options 2023-04-09 10:51:26 +07:00
asrul10
2d6fef23aa chore: set default options to (N)o execute 2023-04-09 10:33:53 +07:00
asrul10
432bfc61db feat: add example usage if there is no option 2023-04-09 10:30:13 +07:00
asrul10
0e50c8ec04 feat: remove borders to make it easy to copy 2023-04-09 10:25:50 +07:00
asrul10
148e1d9420 fix: box result 2023-03-25 22:26:38 +07:00
6 changed files with 120 additions and 59 deletions

View File

@@ -18,18 +18,21 @@ Or you can [download lcg executable file](https://github.com/asrul10/linux-comma
```bash ```bash
> lcg I want to extract linux-command-gpt.tar.gz file > lcg I want to extract linux-command-gpt.tar.gz file
Completed in 0.92 seconds Completed in 0.92 seconds
┌────────────────────────────────────┐
tar -xvzf linux-command-gpt.tar.gz tar -xvzf linux-command-gpt.tar.gz
└────────────────────────────────────┘
Are you sure you want to execute the command? (Y/n): Do you want to (c)opy, (r)egenerate, or take (N)o action on the command? (c/r/N):
``` ```
To use the "copy to clipboard" feature, you need to install either the `xclip` or `xsel` package.
### Options ### Options
```bash ```bash
> lcg [options] > lcg [options]
--help output usage information --help -h output usage information
--version output the version number --version -v output the version number
--update-key update the API key --file -f read command from file
--delete-key delete the API key --update-key -u update the API key
--delete-key -d delete the API key
``` ```

2
go.mod
View File

@@ -1,3 +1,5 @@
module github.com/asrul/linux-command-gpt module github.com/asrul/linux-command-gpt
go 1.18 go 1.18
require github.com/atotto/clipboard v0.1.4

2
go.sum Normal file
View File

@@ -0,0 +1,2 @@
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=

View File

@@ -4,7 +4,7 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@@ -88,7 +88,7 @@ func (gpt3 *Gpt3) loadApiKey() bool {
if _, err := os.Stat(apiKeyFile); os.IsNotExist(err) { if _, err := os.Stat(apiKeyFile); os.IsNotExist(err) {
return false return false
} }
apiKey, err := ioutil.ReadFile(apiKeyFile) apiKey, err := os.ReadFile(apiKeyFile)
if err != nil { if err != nil {
return false return false
} }
@@ -144,7 +144,7 @@ func (gpt3 *Gpt3) Completions(ask string) string {
if err != nil { if err != nil {
panic(err) panic(err)
} }
req.Body = ioutil.NopCloser(bytes.NewBuffer(payloadJson)) req.Body = io.NopCloser(bytes.NewBuffer(payloadJson))
client := &http.Client{} client := &http.Client{}
resp, err := client.Do(req) resp, err := client.Do(req)
@@ -153,7 +153,7 @@ func (gpt3 *Gpt3) Completions(ask string) string {
} }
defer resp.Body.Close() defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
panic(err) panic(err)
} }

124
main.go
View File

@@ -4,12 +4,13 @@ import (
"fmt" "fmt"
"math" "math"
"os" "os"
"os/exec"
"os/user" "os/user"
"strings" "strings"
"time" "time"
"github.com/asrul/linux-command-gpt/gpt" "github.com/asrul/linux-command-gpt/gpt"
"github.com/asrul/linux-command-gpt/reader"
"github.com/atotto/clipboard"
) )
const ( const (
@@ -26,14 +27,17 @@ const (
Usage: lcg [options] Usage: lcg [options]
--help output usage information --help -h output usage information
--version output the version number --version -v output the version number
--update-key update the API key --file -f read command from file
--delete-key delete the API key --update-key -u update the API key
--delete-key -d delete the API key
Example Usage: lcg I want to extract linux-command-gpt.tar.gz file
Example Usage: lcg --file /path/to/file.json I want to print object questions with jq
` `
VERSION = "0.1.0" VERSION = "0.2.1"
CMD_HELP = 100 CMD_HELP = 100
CMD_VERSION = 101 CMD_VERSION = 101
CMD_UPDATE = 102 CMD_UPDATE = 102
@@ -57,6 +61,37 @@ func handleCommand(cmd string) int {
return CMD_COMPLETION return CMD_COMPLETION
} }
func getCommand(gpt3 gpt.Gpt3, cmd string) (string, float64) {
gpt3.InitKey()
s := time.Now()
done := make(chan bool)
go func() {
loadingChars := []rune{'-', '\\', '|', '/'}
i := 0
for {
select {
case <-done:
fmt.Printf("\r")
return
default:
fmt.Printf("\rLoading %c", loadingChars[i])
i = (i + 1) % len(loadingChars)
time.Sleep(30 * time.Millisecond)
}
}
}()
r := gpt3.Completions(cmd)
done <- true
elapsed := time.Since(s).Seconds()
elapsed = math.Round(elapsed*100) / 100
if r == "" {
return "", elapsed
}
return r, elapsed
}
func main() { func main() {
currentUser, err := user.Current() currentUser, err := user.Current()
if err != nil { if err != nil {
@@ -65,9 +100,24 @@ func main() {
args := os.Args args := os.Args
cmd := "" cmd := ""
file := ""
if len(args) > 1 { if len(args) > 1 {
cmd = strings.Join(args[1:], " ") start := 1
if args[1] == "--file" || args[1] == "-f" {
file = args[2]
start = 3
} }
cmd = strings.Join(args[start:], " ")
}
if file != "" {
err := reader.FileToPrompt(&cmd, file)
if err != nil {
fmt.Println(err)
return
}
}
h := handleCommand(cmd) h := handleCommand(cmd)
if h == CMD_HELP { if h == CMD_HELP {
@@ -98,51 +148,31 @@ func main() {
return return
} }
gpt3.InitKey() c := "R"
s := time.Now() r := ""
done := make(chan bool) elapsed := 0.0
go func() { for c == "R" || c == "r" {
loadingChars := []rune{'-', '\\', '|', '/'} r, elapsed = getCommand(gpt3, cmd)
i := 0 c = "N"
for { fmt.Printf("Completed in %v seconds\n\n", elapsed)
select { fmt.Println(r)
case <-done: fmt.Print("\nDo you want to (c)opy, (r)egenerate, or take (N)o action on the command? (c/r/N): ")
fmt.Printf("\r") fmt.Scanln(&c)
return
default: // No action
fmt.Printf("\rLoading %c", loadingChars[i]) if c == "N" || c == "n" {
i = (i + 1) % len(loadingChars) return
time.Sleep(30 * time.Millisecond) }
} }
}
}()
r := gpt3.Completions(cmd)
done <- true
if r == "" { if r == "" {
return return
} }
c := "Y" // Copy to clipboard
elapsed := time.Since(s).Seconds() if c == "C" || c == "c" {
elapsed = math.Round(elapsed*100) / 100 clipboard.WriteAll(r)
fmt.Printf("Completed in %v seconds\n", elapsed) fmt.Println("\033[33mCopied to clipboard")
fmt.Printf("┌%s┐\n", strings.Repeat("─", len(r)+2))
fmt.Printf("│ %s │\n", r)
fmt.Printf("└%s┘\n", strings.Repeat("─", len(r)+2))
fmt.Print("Are you sure you want to execute the command? (Y/n): ")
fmt.Scanln(&c)
if c != "Y" && c != "y" {
return return
} }
cmsplit := strings.Split(r, " ")
cm := exec.Command(cmsplit[0], cmsplit[1:]...)
out, err := cm.Output()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Println(string(out))
} }

24
reader/file.go Normal file
View File

@@ -0,0 +1,24 @@
package reader
import (
"bufio"
"os"
)
func FileToPrompt(cmd *string, filePath string) error {
f, err := os.Open(filePath)
if err != nil {
return err
}
defer f.Close()
reader := bufio.NewReader(f)
*cmd = *cmd + "\nFile path: " + filePath + "\n"
for {
line, err := reader.ReadString('\n')
if err != nil {
break
}
*cmd = *cmd + "\n" + line
}
return nil
}