dict @ 786ff5cff8d6fdca6dd80bd0807619bdea5f0f51

  1package ui
  2
  3import (
  4	"context"
  5	"fmt"
  6	"log/slog"
  7
  8	"github.com/gdamore/tcell/v2"
  9	"github.com/rivo/tview"
 10	"github.com/urfave/cli/v2"
 11
 12	"git.gabrielgio.me/dict/db"
 13)
 14
 15const (
 16	memory = ":memory:"
 17)
 18
 19var UICommand = &cli.Command{
 20	Name:  "ui",
 21	Usage: "interactive dictionary",
 22	Flags: []cli.Flag{
 23		&cli.StringFlag{
 24			Name:  "database",
 25			Value: "main.dict",
 26			Usage: "Dictionary database location",
 27		},
 28	},
 29	Action: func(cCtx *cli.Context) error {
 30		name := cCtx.String("database")
 31		return Run(context.Background(), name)
 32	},
 33}
 34
 35func Run(ctx context.Context, name string) error {
 36	db, err := db.Open(memory)
 37	if err != nil {
 38		return err
 39	}
 40
 41	err = db.Restore(ctx, name)
 42	if err != nil {
 43		return err
 44	}
 45
 46	textView := tview.NewTextView().
 47		SetDynamicColors(true).
 48		SetRegions(true)
 49
 50	input := tview.NewInputField().
 51		SetChangedFunc(func(v string) {
 52			textView.Clear()
 53
 54			words, err := db.SelectDict(ctx, v, 100)
 55			if err != nil {
 56				return
 57			}
 58
 59			lastWord := ""
 60			for _, w := range words {
 61
 62				if lastWord == w.Word {
 63					fmt.Fprintf(textView, "%s\n", w.Line)
 64				} else if lastWord == "" {
 65					fmt.Fprintf(textView, "[bold]%s[normal]\n", w.Word)
 66					fmt.Fprintf(textView, "%s\n", w.Line)
 67				} else {
 68					fmt.Fprintf(textView, "\n[bold]%s[normal]\n", w.Word)
 69					fmt.Fprintf(textView, "%s\n", w.Line)
 70				}
 71
 72				lastWord = w.Word
 73			}
 74		}).
 75		SetAutocompleteFunc(func(v string) []string {
 76			if len(v) == 0 {
 77				return []string{}
 78			}
 79
 80			vs, err := db.SelectSpell(ctx, v)
 81			if err != nil {
 82				slog.Error("Error select spelling", "error", err)
 83				return []string{}
 84			}
 85
 86			return vs
 87		})
 88
 89	input.SetDoneFunc(func(key tcell.Key) {
 90		if key == tcell.KeyEscape {
 91			textView.Clear()
 92			input.SetText("")
 93		}
 94	})
 95
 96	grid := tview.NewGrid().
 97		SetRows(1, 0, 3).
 98		AddItem(input, 0, 0, 1, 3, 0, 0, false).
 99		AddItem(textView, 1, 0, 1, 3, 0, 0, false)
100
101	err = tview.NewApplication().
102		SetRoot(grid, true).
103		SetFocus(input).
104		Run()
105
106	return err
107}