diff --git a/cmd/edit.go b/cmd/edit.go index 7f11493..28a9ccd 100644 --- a/cmd/edit.go +++ b/cmd/edit.go @@ -2,8 +2,10 @@ package cmd import ( "fmt" + "log" "os" "strconv" + "strings" "github.com/spf13/cobra" @@ -24,17 +26,46 @@ zet edit|e latest } var id int + var query string if args[0] == "latest" { id = lib.GetLatestZet() - } else { - i, err := strconv.Atoi(args[0]) - if err != nil { - os.Exit(1) - } + lib.EditZet(id) - id = i + os.Exit(0) + } + + if id, err := strconv.Atoi(args[0]); err == nil { + lib.EditZet(id) + + os.Exit(0) + } + + query = args[0] + + ids := lib.SearchZets(query) + + if len(ids) == 1 { + lib.EditZet(ids[0]) + + os.Exit(0) + } + + zets := lib.ParseZetList(ids) + + selected, err := lib.SelectWithFzf(zets) + + if err != nil { + log.Fatalf("No zet selected.") + } + + parts := strings.SplitN(selected, " ", 2) + + id, err = strconv.Atoi(parts[0]) + + if err != nil { + log.Fatal(err) } lib.EditZet(id) diff --git a/cmd/view.go b/cmd/view.go index 0f34ba8..2809087 100644 --- a/cmd/view.go +++ b/cmd/view.go @@ -2,8 +2,10 @@ package cmd import ( "fmt" + "log" "os" "strconv" + "strings" "github.com/spf13/cobra" @@ -24,17 +26,46 @@ zet view|v latest } var id int + var query string if args[0] == "latest" { id = lib.GetLatestZet() - } else { - i, err := strconv.Atoi(args[0]) - if err != nil { - os.Exit(1) - } + fmt.Println(lib.ViewZet(id)) - id = i + os.Exit(0) + } + + if id, err := strconv.Atoi(args[0]); err == nil { + fmt.Println(lib.ViewZet(id)) + + os.Exit(0) + } + + query = args[0] + + ids := lib.SearchZets(query) + + if len(ids) == 1 { + fmt.Println(lib.ViewZet(ids[0])) + + os.Exit(0) + } + + zets := lib.ParseZetList(ids) + + selected, err := lib.SelectWithFzf(zets) + + if err != nil { + log.Fatalf("No zet selected.") + } + + parts := strings.SplitN(selected, " ", 2) + + id, err = strconv.Atoi(parts[0]) + + if err != nil { + log.Fatal(err) } fmt.Println(lib.ViewZet(id)) diff --git a/internal/lib/ansi.go b/internal/lib/ansi.go new file mode 100644 index 0000000..b5a29d7 --- /dev/null +++ b/internal/lib/ansi.go @@ -0,0 +1,9 @@ +package lib + +import "regexp" + +var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`) + +func StripANSI(s string) string { + return ansiRegex.ReplaceAllString(s, "") +} diff --git a/internal/lib/fzf.go b/internal/lib/fzf.go new file mode 100644 index 0000000..ebccab9 --- /dev/null +++ b/internal/lib/fzf.go @@ -0,0 +1,34 @@ +package lib + +import ( + "bytes" + "os" + "os/exec" + "strings" +) + +func SelectWithFzf(items []string) (string, error) { + cmd := exec.Command("fzf", "--ansi") + + var input bytes.Buffer + + for _, item := range items { + input.WriteString(item + "\n") + } + + cmd.Stdin = &input + + var output bytes.Buffer + cmd.Stdout = &output + cmd.Stderr = os.Stderr + + err := cmd.Run() + + if err != nil { + return "", err + } + + selected := strings.TrimSpace(output.String()) + + return selected, nil +} diff --git a/internal/lib/json.go b/internal/lib/json.go index 47f3381..074b6f6 100644 --- a/internal/lib/json.go +++ b/internal/lib/json.go @@ -3,13 +3,10 @@ package lib import ( "encoding/json" "fmt" - "regexp" "strconv" "strings" ) -var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;]*m`) - type Item struct { ID int `json:"id"` Title string `json:"title"` @@ -19,7 +16,7 @@ func AsJSON(zets []string) (string, error) { var items []Item for _, entry := range zets { - cleanEntry := stripANSI(entry) + cleanEntry := StripANSI(entry) parts := strings.SplitN(cleanEntry, " ", 2) id, _ := strconv.Atoi(parts[0]) @@ -42,7 +39,3 @@ func AsJSON(zets []string) (string, error) { return string(jsonData), nil } - -func stripANSI(s string) string { - return ansiRegex.ReplaceAllString(s, "") -}