1package main
2
3import (
4 "bufio"
5 "bytes"
6 "context"
7 "fmt"
8 "io"
9 "log/slog"
10 "math"
11 "os"
12 "strings"
13
14 "github.com/rivo/tview"
15)
16
17const (
18 memory = ":memory:"
19)
20
21func run(ctx context.Context, name string) error {
22 db, err := Open(memory)
23 if err != nil {
24 return err
25 }
26
27 err = db.Restore(ctx, name)
28 if err != nil {
29 return err
30 }
31
32 list := tview.NewList()
33
34 input := tview.NewInputField().
35 SetLabel("S:").
36 SetChangedFunc(func(v string) {
37 list.Clear()
38
39 words, err := db.SelectDict(ctx, v, 100)
40 if err != nil {
41 return
42 }
43
44 for _, w := range words {
45 list.AddItem(w.Word, w.Line, 0, nil)
46 }
47 }).
48 SetAutocompleteFunc(func(v string) []string {
49 if len(v) == 0 {
50 return []string{}
51 }
52
53 vs, err := db.SelectSpell(ctx, v)
54 if err != nil {
55 slog.Error("Error select spelling", "error", err)
56 return []string{}
57 }
58
59 return vs
60 })
61
62 grid := tview.NewGrid().
63 SetRows(1, 0, 3).
64 AddItem(input, 0, 0, 1, 3, 0, 0, false).
65 AddItem(list, 1, 0, 1, 3, 0, 0, false)
66
67 err = tview.NewApplication().
68 SetRoot(grid, true).
69 SetFocus(input).
70 Run()
71
72 return err
73}
74
75func importDict(ctx context.Context, name string) error {
76 db, err := Open(memory)
77 if err != nil {
78 return err
79 }
80 err = db.Migrate(ctx)
81 if err != nil {
82 return err
83 }
84
85 file, err := os.Open("dict.txt")
86 if err != nil {
87 return err
88 }
89 defer file.Close()
90
91 count := 0
92 total, err := LineCounter(file)
93 if err != nil {
94 return err
95 }
96
97 _, err = file.Seek(0, 0)
98 if err != nil {
99 return err
100 }
101
102 scanner := bufio.NewScanner(file)
103 for scanner.Scan() {
104 if strings.HasPrefix(scanner.Text(), "#") || scanner.Text() == "" {
105 continue
106 }
107
108 if err := db.InsertLine(ctx, scanner.Text()); err != nil {
109 return err
110 }
111 count++
112
113 if (count % 1234) == 0 {
114 fmt.Print("\033[G\033[K") // move the cursor left and clear the line
115 per := math.Ceil((float64(count) / float64(total)) * 100.0)
116 fmt.Printf("%d/%d (%.0f%%)", count, total, per)
117 }
118 }
119
120 fmt.Printf("Consolidating")
121 err = db.Consolidade(ctx)
122 if err != nil {
123 return err
124 }
125
126 err = db.Backup(ctx, name)
127 if err != nil {
128 return err
129 }
130 return nil
131}
132
133func LineCounter(r io.Reader) (int, error) {
134 var count int
135 const lineBreak = '\n'
136
137 buf := make([]byte, bufio.MaxScanTokenSize)
138
139 for {
140 bufferSize, err := r.Read(buf)
141 if err != nil && err != io.EOF {
142 return 0, err
143 }
144
145 var buffPosition int
146 for {
147 i := bytes.IndexByte(buf[buffPosition:], lineBreak)
148 if i == -1 || bufferSize == buffPosition {
149 break
150 }
151 buffPosition += i + 1
152 count++
153 }
154 if err == io.EOF {
155 break
156 }
157 }
158
159 return count, nil
160}