commit 3b7bfee9afa33983ed6c09dfdf1c31b4f41dc5be
parent b4cb819fe26aa013fa744e8b859d01c991733805
Author: dwrz <dwrz@dwrz.net>
Date: Sun, 22 Mar 2026 12:55:16 +0000
Remove wisdom
Diffstat:
3 files changed, 0 insertions(+), 451 deletions(-)
diff --git a/cmd/wisdom/wisdom.go b/cmd/wisdom/wisdom.go
@@ -1,50 +0,0 @@
-package main
-
-import (
- "flag"
- "os"
- "path/filepath"
-
- "code.dwrz.net/src/pkg/log"
- "code.dwrz.net/src/pkg/terminal"
- "code.dwrz.net/src/pkg/wisdom"
-)
-
-func main() {
- var l = log.New(os.Stderr)
-
- flag.Parse()
-
- dir, err := os.UserConfigDir()
- if err != nil {
- l.Error.Fatalf("failed to get user config dir: %v", err)
- }
-
- var params = wisdom.Parameters{
- Log: l,
- Path: filepath.Join(dir, "wisdom"),
- }
-
- terminal, err := terminal.New(os.Stdin.Fd())
- if err != nil {
- l.Error.Printf("failed to create terminal: %v", err)
- }
-
- if terminal != nil {
- size, err := terminal.Size()
- if err != nil {
- l.Error.Printf("failed to get terminal size: %v", err)
- }
-
- params.Size = *size
- }
-
- w, err := wisdom.New(params)
- if err != nil {
- l.Error.Fatalf("failed to create command: %v", err)
- }
-
- if err := w.Command(flag.CommandLine.Args()); err != nil {
- l.Error.Fatal(err)
- }
-}
diff --git a/pkg/wisdom/quote/quote.go b/pkg/wisdom/quote/quote.go
@@ -1,46 +0,0 @@
-package quote
-
-import (
- "strings"
-)
-
-type Quote struct {
- Author string `json:"author"`
- Comment string `json:"comment"`
- Source string `json:"source"`
- Tags map[string]struct{} `json:"tags"`
- Text string `json:"text"`
-}
-
-func (q *Quote) Render() string {
- var str strings.Builder
-
- str.WriteString(q.Text)
-
- if q.Author != "" || q.Source != "" {
- str.WriteString("\n\n")
- }
- if q.Author != "" {
- str.WriteString(q.Author)
- }
- if q.Author != "" && q.Source != "" {
- str.WriteString(", ")
- }
- if q.Source != "" {
- str.WriteString(q.Source)
- }
- if q.Comment != "" {
- str.WriteString("\n\n")
- str.WriteString(q.Comment)
- }
- if len(q.Tags) > 0 {
- str.WriteString("\nTags: ")
- var tags string
- for tag := range q.Tags {
- tags += tag + " "
- }
- str.WriteString(tags)
- }
-
- return str.String()
-}
diff --git a/pkg/wisdom/wisdom.go b/pkg/wisdom/wisdom.go
@@ -1,355 +0,0 @@
-package wisdom
-
-import (
- "bufio"
- "encoding/json"
- "fmt"
- "io"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
- "unicode"
-
- "github.com/google/uuid"
- "github.com/mattn/go-runewidth"
-
- "code.dwrz.net/src/pkg/log"
- "code.dwrz.net/src/pkg/store"
- "code.dwrz.net/src/pkg/terminal"
- "code.dwrz.net/src/pkg/text"
- "code.dwrz.net/src/pkg/wisdom/quote"
-)
-
-const coll = "data"
-
-type Parameters struct {
- Log *log.Logger
- Path string
- Size terminal.Size
-}
-
-type Wisdom struct {
- log *log.Logger
- store *store.Store
- size terminal.Size
-}
-
-func New(p Parameters) (*Wisdom, error) {
- store, err := store.New(store.Parameters{
- Log: p.Log,
- Path: p.Path,
- })
- if err != nil {
- return nil, fmt.Errorf("failed to create store: %v", err)
- }
-
- if err := store.NewCollection(coll); err != nil {
- return nil, fmt.Errorf("failed to create collection: %v", err)
- }
-
- return &Wisdom{
- log: p.Log,
- store: store,
- size: p.Size,
- }, nil
-}
-
-func (w *Wisdom) Command(args []string) error {
- // Show a random quote by default.
- if len(args) == 0 {
- d, err := w.store.Collection(coll).Random()
- if err != nil {
- return fmt.Errorf("failed to load quote: %v", err)
- }
-
- var q quote.Quote
- if err := d.Unmarshal(&q); err != nil {
- return fmt.Errorf(
- "failed to unmarshal document: %v", err,
- )
- }
-
- fmt.Println(q.Render())
-
- return nil
- }
-
- command, rest := args[0], args[1:]
- switch command {
- case "add":
- if err := w.add(); err != nil {
- return fmt.Errorf("failed to add quote: %v", err)
- }
-
- case "edit":
- if err := w.edit(rest); err != nil {
- return fmt.Errorf("failed to edit quote: %v", err)
- }
-
- case "show":
- if err := w.show(rest); err != nil {
- return fmt.Errorf("failed to show quote: %v", err)
- }
-
- case "list":
- if err := w.list(); err != nil {
- return fmt.Errorf("failed to list quotes: %v", err)
- }
-
- case "remove":
- if err := w.remove(rest); err != nil {
- return fmt.Errorf("failed to remove quote: %v", err)
- }
-
- default:
- return fmt.Errorf("unrecognized command: %v", command)
- }
-
- return nil
-}
-
-func (w *Wisdom) add() error {
- var (
- in = bufio.NewReader(os.Stdin)
- str strings.Builder
- q = quote.Quote{
- Tags: map[string]struct{}{},
- }
- )
-
- // Text
- fmt.Print("Text (Ctrl-D for EOF):")
- if _, err := io.Copy(&str, os.Stdin); err != nil {
- if err != io.EOF {
- return fmt.Errorf("failed to read: %v", err)
- }
- }
- q.Text = strings.TrimRightFunc(str.String(), unicode.IsSpace)
- if q.Text == "" {
- return fmt.Errorf("missing text")
- }
- str.Reset()
-
- // Author
- fmt.Print("Author: ")
- line, err := in.ReadString('\n')
- if err != nil {
- return fmt.Errorf("failed to read: %v", err)
- }
- q.Author = strings.TrimSpace(line)
-
- // Source
- fmt.Print("Source: ")
- line, err = in.ReadString('\n')
- if err != nil {
- return fmt.Errorf("failed to read: %v", err)
- }
- q.Source = strings.TrimSpace(line)
-
- // Tags
- fmt.Print("Tags (comma delimited): ")
- line, err = in.ReadString('\n')
- if err != nil {
- return fmt.Errorf("failed to read: %v", err)
- }
- for _, t := range strings.Split(strings.TrimSpace(line), ",") {
- if t == "" {
- continue
- }
- q.Tags[t] = struct{}{}
- }
-
- // Comment
- fmt.Print("Comment (Ctrl-D for EOF): ")
- if _, err := io.Copy(&str, os.Stdin); err != nil {
- if err != io.EOF {
- return fmt.Errorf("failed to read: %v", err)
- }
- }
- q.Comment = strings.TrimSpace(str.String())
- str.Reset()
-
- if _, err := w.store.Collection(coll).Create(
- uuid.NewString(), q,
- ); err != nil {
- return fmt.Errorf("failed to create: %v", err)
- }
-
- return nil
-}
-
-func (w *Wisdom) edit(args []string) error {
- if len(args) == 0 {
- return fmt.Errorf("missing id")
- }
-
- editor := strings.Split(os.Getenv("EDITOR"), " ")
- if len(editor) == 0 {
- return fmt.Errorf("missing $EDITOR")
- }
-
- path, err := exec.LookPath(editor[0])
- if err != nil {
- return fmt.Errorf(
- "failed to find $EDITOR %s: %w", editor, err,
- )
- }
-
- for _, id := range args {
- d, err := w.store.Collection(coll).FindId(id)
- if err != nil {
- return fmt.Errorf("failed to load quote: %v", err)
- }
-
- temp := filepath.Join(os.TempDir(), "wisdom", id)
- if err := os.WriteFile(temp, d.Data, 0600); err != nil {
- return err
- }
-
- cmd := exec.Cmd{
- Path: path,
- Args: append(editor, temp),
- Stdin: os.Stdin,
- Stdout: os.Stdout,
- Stderr: os.Stderr,
- }
- if err := cmd.Run(); err != nil {
- return err
- }
-
- data, err := os.ReadFile(temp)
- if err != nil {
- return fmt.Errorf(
- "failed to read file %s: %w", temp, err,
- )
- }
-
- var q = "e.Quote{}
- if err := json.Unmarshal(data, q); err != nil {
- return fmt.Errorf(
- "failed to json unmarshal %s: %w", temp, err,
- )
- }
-
- if err := os.Remove(temp); err != nil {
- return fmt.Errorf("failed to remove temp file: %v", err)
- }
-
- d, err = w.store.Collection(coll).Create(uuid.NewString(), q)
- if err != nil {
- return fmt.Errorf(
- "failed to create new document: %v", err,
- )
- }
-
- if err := w.store.Collection(coll).Delete(id); err != nil {
- return fmt.Errorf(
- "failed to delete original document: %v", err,
- )
- }
- }
-
- return nil
-}
-
-func (w *Wisdom) list() error {
- docs, err := w.store.Collection(coll).All()
- if err != nil {
- return fmt.Errorf("failed to load quotes: %v", err)
- }
-
- var output strings.Builder
- output.WriteString("id,author,source,text\n")
- for _, d := range docs {
- var q = "e.Quote{}
-
- if err := d.Unmarshal(q); err != nil {
- w.log.Error.Printf(
- "failed to unmarshal document %s: %v",
- d.Id, err,
- )
- continue
- }
-
- var (
- line strings.Builder
- // Account for the final newline.
- space = int(w.size.Columns)
- )
- // Id
- line.WriteString(text.Truncate(d.Id, space))
- space -= runewidth.StringWidth(d.Id)
- line.WriteByte(',')
- space -= 1
-
- // Author
- line.WriteString(text.Truncate(q.Author, space))
- space -= runewidth.StringWidth(q.Author)
- line.WriteByte(',')
- space -= 1
-
- // Source
- line.WriteString(text.Truncate(q.Source, space))
- space -= runewidth.StringWidth(q.Source)
- line.WriteByte(',')
- space -= 1
-
- // Text
- t := strings.ReplaceAll(q.Text, "\n", " ")
- switch {
- case space < 1:
- // Don't output text.
- case len(t) > space:
- line.WriteString(text.Truncate(
- t,
- space-runewidth.RuneWidth('…'),
- ))
- line.WriteRune('…')
- default:
- line.WriteString(t)
- }
- line.WriteByte('\n')
-
- output.WriteString(line.String())
- }
-
- fmt.Println(output.String())
-
- return nil
-}
-
-func (w *Wisdom) remove(args []string) error {
- if len(args) == 0 {
- return fmt.Errorf("missing quote filename")
- }
-
- for _, name := range args {
- if err := w.store.Collection(coll).Delete(name); err != nil {
- return fmt.Errorf("failed to delete %s: %v", name, err)
- }
- }
-
- return nil
-}
-
-func (w *Wisdom) show(args []string) error {
- for _, id := range args {
- d, err := w.store.Collection(coll).FindId(id)
- if err != nil {
- return fmt.Errorf("failed to load quotes: %v", err)
- }
-
- var q = "e.Quote{}
- if err := d.Unmarshal(q); err != nil {
- return fmt.Errorf(
- "failed to unmarshal document %s: %v",
- d.Id, err,
- )
- }
-
- fmt.Println(q.Render())
- }
-
- return nil
-}