-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
130 lines (105 loc) · 2.38 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"flag"
"fmt"
"os"
"time"
"github.com/nsf/termbox-go"
"github.com/ale-cci/gopm/chunk"
"github.com/ale-cci/gopm/tui"
"github.com/ale-cci/gopm/wpm"
)
type App struct {
box *tui.WpmBox
iterator chunk.Iterator
counter wpm.KeystrokeCounter
text *tui.ParsedText
}
func (app *App) Build(maxX int, maxY int) []tui.Widget {
app.counter = wpm.KeystrokeCounter{}
app.box = tui.NewWpmBox(1, 3, maxX-2, maxY-4, app.text, &app.counter)
app.reloadText()
app.box.ScrollOff = 4
return []tui.Widget{
tui.NewWpmBar(1, 1, maxX-2, 1, &app.counter),
app.box,
}
}
func (app *App) reloadText() {
text := app.iterator.Current()
app.counter.Reset()
app.counter.Capacity = len(text)
app.text = tui.NewParsedText(text)
app.box.SetText(app.text)
}
func (app *App) insKey(char rune) {
if app.counter.IsStartPosition() {
app.counter.Start = time.Now()
}
correct := app.text.RuneAt(app.counter.Inserted()) == char
app.box.IncCursor()
app.counter.InsKey(correct)
}
func (app *App) OnEvent(ev termbox.Event) bool {
switch ev.Type {
case termbox.EventKey:
switch ev.Key {
case termbox.KeyCtrlC:
return true
case termbox.KeySpace:
app.insKey(' ')
case termbox.KeyEnter:
app.insKey('\n')
case termbox.KeyTab:
app.insKey('\t')
case termbox.KeyCtrlN:
app.iterator.Next()
app.reloadText()
case termbox.KeyCtrlP:
app.iterator.Prev()
app.reloadText()
case termbox.KeyBackspace, termbox.KeyBackspace2:
app.box.DecCursor()
app.counter.Backspace()
default:
if ev.Ch != 0 {
app.insKey(ev.Ch)
}
}
case termbox.EventError:
panic(ev.Err)
}
if app.counter.IsEndPosition() {
app.iterator.Next()
app.reloadText()
}
return false
}
func NewApp(chunkIterator chunk.Iterator) *App {
return &App{iterator: chunkIterator}
}
func main() {
flag.Parse()
filenames := flag.Args()
if len(filenames) == 0 {
fmt.Println("No filename provided")
return
}
chunkedFiles := make([]chunk.Iterator, len(filenames))
for i, filename := range filenames {
if _, err := os.Stat(filename); os.IsNotExist(err) {
fmt.Printf("Unable to open file %q\n", filename)
os.Exit(1)
}
file, err := os.Open(filename)
if err != nil {
panic(err)
}
defer file.Close()
chunkedFiles[i] = chunk.NewChunkedFile(file, 40)
}
chunkIterator := &chunk.ChunkIterator{Files: chunkedFiles}
app := NewApp(chunkIterator)
tui.Run(app)
return
}