dict @ 1e36d1ba1ba9659ffd01e06e93ffee670f842ff8

  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}