Various improvements.
- Added -showwpm - Added -g - Added -noreport - Updated generated themes. - Improved automatic line wrapping. - Fixed timer bug. - Moved -o to -oneshot - The exit code now corresponds to the exit action - Updated documentation.
This commit is contained in:
2
Makefile
2
Makefile
@ -2,6 +2,8 @@ all:
|
||||
go build -o bin/tt *.go
|
||||
install:
|
||||
install -m755 bin/tt /usr/local/bin
|
||||
assets:
|
||||
python3 tools/themegen.py | gofmt > generatedThemes.go
|
||||
rel:
|
||||
GOOS=darwin GOARCH=386 go build -o binaries/tt-osx_386 *.go
|
||||
GOOS=darwin GOARCH=amd64 go build -o binaries/tt-osx_amd64 *.go
|
||||
|
41
README.md
41
README.md
@ -33,31 +33,17 @@ Best served on a terminal with truecolor and cursor shape support (e.g kitty, it
|
||||
|
||||
# Usage
|
||||
|
||||
By default 50 words from the top 200 words in the English language are used to
|
||||
By default 50 words from the top 1000 words in the English language are used to
|
||||
constitute the test. Custom text can be supplied by piping aribirary text to
|
||||
the program. Each paragraph in the input is shown as a separate segment of the
|
||||
text.
|
||||
|
||||
E.G
|
||||
|
||||
- `shuf -n 40 /etc/dictionaries-common/words|tt` produces a test consisting of 40 random words drawn from `/etc/dictionaries-common/words`.
|
||||
- `curl http://api.quotable.io/random|jq -r .content|tt` produces a test consisting of a random quote.
|
||||
|
||||
- `tt -n <num>` produces a test consisting of *num* randomly drawn english words
|
||||
- `tt -t 10` starts a test which timesout after 10 seconds.
|
||||
- `tt -theme <theme>` Starts tt with the provided theme (see `-list themes` for a list of options)
|
||||
- `tt -csv` outputs the csv formatted results to STDOUT
|
||||
|
||||
The default behaviour is equivalent to 'tt -n 50'
|
||||
|
||||
See `-help` for an exhaustive and up to date list.
|
||||
|
||||
## Keys
|
||||
|
||||
- Pressing `escape` at any point restarts the test.
|
||||
- `C-c` exits the test.
|
||||
|
||||
# Configuration
|
||||
## Configuration
|
||||
|
||||
The theme can be configured by setting the following options in `~/.ttrc`:
|
||||
|
||||
@ -68,3 +54,26 @@ The theme can be configured by setting the following options in `~/.ttrc`:
|
||||
- `hicol3`: The colour used to highlight the next word.
|
||||
- `errcol`: The colour used to highlight errors.
|
||||
- `theme`: The theme from which default colors are drawn, a list of builtin themes can be obtained via `-list themes`.
|
||||
|
||||
## Examples
|
||||
|
||||
- `tt -n 10` produces a test consisting of 10 randomly drawn english words
|
||||
- `tt -n 50 -g 5` produces a test consisting of 50 randomly drawn words in 5 groups of 10 words each.
|
||||
- `tt -t 10` starts a timed test consisting of 50 words
|
||||
- `tt -theme gruvbox` Starts tt with the gruvbox theme
|
||||
|
||||
The default behaviour is equivalent to `tt -n 50`.
|
||||
|
||||
See `-help` for an exhaustive list of options.
|
||||
|
||||
## Recipes
|
||||
|
||||
`tt` is designed to be easily scriptable and integrate nicely with other with
|
||||
other *nix tools. With a little shell scripting most features the user can
|
||||
conceive of should be possible to implement. Below are some simple examples of
|
||||
what can be achieved.
|
||||
|
||||
- `shuf -n 40 /usr/local/dict/words|tt` Produces a test consisting of 40 random words drawn from your system's dictionary.
|
||||
- `curl http://api.quotable.io/random|jq -r .content|tt` Produces a test consisting of a random quote.
|
||||
- `alias ttd='tt -csv >> ~/wpm.csv'` Creates an alias called ttd which keeps a log of your progress in your home directory`.
|
||||
|
||||
|
1438
generatedThemes.go
Normal file
1438
generatedThemes.go
Normal file
File diff suppressed because it is too large
Load Diff
3597
tools/terminal_themes.json
Normal file
3597
tools/terminal_themes.json
Normal file
File diff suppressed because it is too large
Load Diff
48
tools/themegen.py
Normal file
48
tools/themegen.py
Normal file
@ -0,0 +1,48 @@
|
||||
import os
|
||||
import json
|
||||
|
||||
# Generates themes from terminal_themes.json (itself generated from some long forgotten github repo [possibly guake]).
|
||||
|
||||
f = os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
'terminal_themes.json')
|
||||
|
||||
themes = json.loads(open(f).read())
|
||||
|
||||
|
||||
def blend(src, dest, opacity):
|
||||
src = src[1:]
|
||||
dest = dest[1:]
|
||||
|
||||
dr, dg, db = [int(dest[i:i + 2], 16) for i in (0, 2, 4)]
|
||||
sr, sg, sb = [int(src[i:i + 2], 16) for i in (0, 2, 4)]
|
||||
|
||||
sr = sr * opacity + dr * (1 - opacity)
|
||||
sg = sg * opacity + dg * (1 - opacity)
|
||||
sb = sb * opacity + db * (1 - opacity)
|
||||
|
||||
return "#%.2x%.2x%.2x" % (int(sr), int(sg), int(sb))
|
||||
|
||||
|
||||
print("//GENERATED CODE, DO NOT EDIT BY HAND (see themegen.py)\n\n")
|
||||
print("package main\n")
|
||||
print("var generatedThemes = map[string]map[string]string{")
|
||||
|
||||
for name, t in themes.items():
|
||||
print('\t"%s": map[string]string{' % name)
|
||||
|
||||
# Meat (alter these to taste)
|
||||
mapping = {
|
||||
"bgcol": t['background'],
|
||||
"fgcol": t['foreground'],
|
||||
"hicol": t['color7'],
|
||||
"hicol2": blend(t['background'], t['color9'], .3),
|
||||
"hicol3": t['color9'],
|
||||
"errcol": t['color1'],
|
||||
}
|
||||
|
||||
for k, v in mapping.items():
|
||||
print('\t\t"%s": "%s",' % (k, v))
|
||||
|
||||
print("\t},")
|
||||
|
||||
print("}")
|
110
tt.go
110
tt.go
@ -17,12 +17,12 @@ import (
|
||||
|
||||
var scr tcell.Screen
|
||||
var csvMode bool
|
||||
var rawMode bool
|
||||
|
||||
type result struct {
|
||||
wpm int
|
||||
cpm int
|
||||
accuracy float64
|
||||
wpm int
|
||||
cpm int
|
||||
accuracy float64
|
||||
timestamp int64
|
||||
}
|
||||
|
||||
var results []result
|
||||
@ -45,16 +45,16 @@ func readConfig() map[string]string {
|
||||
return cfg
|
||||
}
|
||||
|
||||
func exit() {
|
||||
func exit(rc int) {
|
||||
scr.Fini()
|
||||
|
||||
if csvMode {
|
||||
for _, r := range results {
|
||||
fmt.Printf("%d,%d,%.2f\n", r.wpm, r.cpm, r.accuracy)
|
||||
fmt.Printf("%d,%d,%.2f,%d\n", r.wpm, r.cpm, r.accuracy, r.timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
os.Exit(0)
|
||||
os.Exit(rc)
|
||||
}
|
||||
|
||||
func showReport(scr tcell.Screen, cpm, wpm int, accuracy float64) {
|
||||
@ -69,30 +69,37 @@ func showReport(scr tcell.Screen, cpm, wpm int, accuracy float64) {
|
||||
if key, ok := scr.PollEvent().(*tcell.EventKey); ok && key.Key() == tcell.KeyEscape {
|
||||
return
|
||||
} else if ok && key.Key() == tcell.KeyCtrlC {
|
||||
exit()
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var n int
|
||||
var contentFn func() []string
|
||||
var ngroups int
|
||||
var contentFn func(sw, sh int) []string
|
||||
var rawMode bool
|
||||
var oneShotMode bool
|
||||
var wrapSz int
|
||||
var maxLineLen int
|
||||
var noSkip bool
|
||||
var noReport bool
|
||||
var timeout int
|
||||
var listFlag string
|
||||
var err error
|
||||
var themeName string
|
||||
var showWpm bool
|
||||
|
||||
flag.IntVar(&n, "n", 50, "The number of random words which constitute the test.")
|
||||
flag.IntVar(&wrapSz, "w", 80, "Wraps the input text at the given number of columns (ignored if -raw is present).")
|
||||
flag.IntVar(&ngroups, "g", 1, "The number of groups into which the generated test is split.")
|
||||
flag.IntVar(&maxLineLen, "w", 80, "The maximum line length in characters. (ignored if -raw is present).")
|
||||
flag.IntVar(&timeout, "t", -1, "Terminate the test after the given number of seconds.")
|
||||
|
||||
flag.BoolVar(&showWpm, "showwpm", false, "Display WPM whilst typing.")
|
||||
flag.BoolVar(&noSkip, "noskip", false, "Disable word skipping when space is pressed.")
|
||||
flag.BoolVar(&csvMode, "csv", false, "Print the test results to stdout in the form <wpm>,<cpm>,<accuracy>.")
|
||||
flag.BoolVar(&oneShotMode, "oneshot", false, "Automatically exit after a single run (useful for scripts).")
|
||||
flag.BoolVar(&noReport, "noreport", false, "Don't show a report at the end of the test (useful in conjunction with -o).")
|
||||
flag.BoolVar(&csvMode, "csv", false, "Print the test results to stdout in the form wpm,cpm,accuracy,time.")
|
||||
flag.BoolVar(&rawMode, "raw", false, "Don't reflow text or show one paragraph at a time.")
|
||||
flag.BoolVar(&oneShotMode, "o", false, "Automatically exit after a single run (useful for scripts).")
|
||||
flag.StringVar(&themeName, "theme", "", "The theme to use (overrides ~/.ttrc).")
|
||||
flag.StringVar(&listFlag, "list", "", "-list themes prints a list of available themes.")
|
||||
|
||||
@ -134,20 +141,46 @@ Options:`)
|
||||
}
|
||||
|
||||
if rawMode {
|
||||
contentFn = func() []string { return []string{string(b)} }
|
||||
contentFn = func(sw, sh int) []string { return []string{string(b)} }
|
||||
} else {
|
||||
s := strings.Replace(string(b), "\r", "", -1)
|
||||
s = regexp.MustCompile("\n\n+").ReplaceAllString(s, "\n\n")
|
||||
content := strings.Split(strings.Trim(s, "\n"), "\n\n")
|
||||
contentFn = func(sw, sh int) []string {
|
||||
wsz := maxLineLen
|
||||
if wsz > sw {
|
||||
wsz = sw - 8
|
||||
}
|
||||
|
||||
for i, _ := range content {
|
||||
content[i] = strings.Replace(wordWrap(strings.Trim(content[i], " "), wrapSz), "\n", " \n", -1)
|
||||
s := strings.Replace(string(b), "\r", "", -1)
|
||||
s = regexp.MustCompile("\n\n+").ReplaceAllString(s, "\n\n")
|
||||
content := strings.Split(strings.Trim(s, "\n"), "\n\n")
|
||||
|
||||
for i, _ := range content {
|
||||
content[i] = strings.Replace(wordWrap(strings.Trim(content[i], " "), wsz), "\n", " \n", -1)
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
contentFn = func() []string { return content }
|
||||
}
|
||||
} else {
|
||||
contentFn = func() []string { return []string{randomText(n, wrapSz)} }
|
||||
contentFn = func(sw, sh int) []string {
|
||||
wsz := maxLineLen
|
||||
if wsz > sw {
|
||||
wsz = sw - 8
|
||||
}
|
||||
|
||||
if ngroups > n {
|
||||
ngroups = n
|
||||
}
|
||||
|
||||
r := make([]string, ngroups)
|
||||
sz := n / ngroups
|
||||
for i := 0; i < ngroups-1; i++ {
|
||||
r[i] = randomText(sz, wsz)
|
||||
}
|
||||
|
||||
r[ngroups-1] = randomText(sz+n%ngroups, wsz)
|
||||
|
||||
return r
|
||||
}
|
||||
}
|
||||
|
||||
cfg := readConfig()
|
||||
@ -214,29 +247,38 @@ Options:`)
|
||||
}
|
||||
|
||||
typer := NewTyper(scr, fgcol, bgcol, hicol, hicol2, hicol3, errcol)
|
||||
if noSkip {
|
||||
typer.SkipWord = false
|
||||
}
|
||||
typer.SkipWord = !noSkip
|
||||
typer.ShowWpm = showWpm
|
||||
|
||||
if timeout != -1 {
|
||||
timeout *= 1E9
|
||||
}
|
||||
|
||||
for {
|
||||
nerrs, ncorrect, t, exitKey := typer.Start(contentFn(), time.Duration(timeout))
|
||||
sw, sh := scr.Size()
|
||||
nerrs, ncorrect, t, rc := typer.Start(contentFn(sw, sh), time.Duration(timeout))
|
||||
|
||||
switch exitKey {
|
||||
case 0:
|
||||
switch rc {
|
||||
case TyperComplete:
|
||||
cpm := int(float64(ncorrect) / (float64(t) / 60E9))
|
||||
wpm := cpm / 5
|
||||
accuracy := float64(ncorrect) / float64(nerrs+ncorrect) * 100
|
||||
|
||||
results = append(results, result{wpm, cpm, accuracy})
|
||||
if oneShotMode {
|
||||
exit()
|
||||
results = append(results, result{wpm, cpm, accuracy, time.Now().Unix()})
|
||||
if !noReport {
|
||||
showReport(scr, cpm, wpm, accuracy)
|
||||
}
|
||||
showReport(scr, cpm, wpm, accuracy)
|
||||
case tcell.KeyCtrlC:
|
||||
exit()
|
||||
if oneShotMode {
|
||||
exit(0)
|
||||
}
|
||||
case TyperSigInt:
|
||||
exit(1)
|
||||
|
||||
case TyperResize:
|
||||
//Resize events restart the test, this shouldn't be a problem in the vast majority of cases
|
||||
//and allows us to avoid baking rewrapping logic into the typer.
|
||||
|
||||
//TODO: implement state-preserving resize (maybe)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
88
typer.go
88
typer.go
@ -2,16 +2,26 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
)
|
||||
|
||||
const (
|
||||
TyperComplete = iota
|
||||
TyperSigInt
|
||||
TyperEscape
|
||||
TyperResize
|
||||
)
|
||||
|
||||
type typer struct {
|
||||
Scr tcell.Screen
|
||||
OnStart func()
|
||||
SkipWord bool
|
||||
ShowWpm bool
|
||||
tty *os.File
|
||||
|
||||
currentWordStyle tcell.Style
|
||||
nextWordStyle tcell.Style
|
||||
@ -26,9 +36,14 @@ func NewTyper(scr tcell.Screen, fgcol, bgcol, hicol, hicol2, hicol3, errcol tcel
|
||||
Foreground(fgcol).
|
||||
Background(bgcol)
|
||||
|
||||
tty, err := os.OpenFile("/dev/tty", os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &typer{
|
||||
Scr: scr,
|
||||
SkipWord: true,
|
||||
tty: tty,
|
||||
|
||||
backgroundStyle: def,
|
||||
correctStyle: def.Foreground(hicol),
|
||||
@ -52,7 +67,7 @@ func (t *typer) highlight(text []cell, idx int, currentWordStyle, nextWordStyle
|
||||
}
|
||||
}
|
||||
|
||||
func (t *typer) Start(text []string, timeout time.Duration) (nerrs, ncorrect int, duration time.Duration, exitKey tcell.Key) {
|
||||
func (t *typer) Start(text []string, timeout time.Duration) (nerrs, ncorrect int, duration time.Duration, rc int) {
|
||||
timeLeft := timeout
|
||||
|
||||
for i, p := range text {
|
||||
@ -64,7 +79,7 @@ func (t *typer) Start(text []string, timeout time.Duration) (nerrs, ncorrect int
|
||||
startImmediately = false
|
||||
}
|
||||
|
||||
e, c, exitKey, d = t.start(p, timeLeft, startImmediately)
|
||||
e, c, rc, d = t.start(p, timeLeft, startImmediately)
|
||||
|
||||
nerrs += e
|
||||
ncorrect += c
|
||||
@ -77,7 +92,7 @@ func (t *typer) Start(text []string, timeout time.Duration) (nerrs, ncorrect int
|
||||
}
|
||||
}
|
||||
|
||||
if exitKey != 0 {
|
||||
if rc != TyperComplete {
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -85,13 +100,12 @@ func (t *typer) Start(text []string, timeout time.Duration) (nerrs, ncorrect int
|
||||
return
|
||||
}
|
||||
|
||||
func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool) (nerrs int, ncorrect int, exitKey tcell.Key, duration time.Duration) {
|
||||
|
||||
func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool) (nerrs int, ncorrect int, rc int, duration time.Duration) {
|
||||
var startTime time.Time
|
||||
text := stringToCells(s)
|
||||
|
||||
nc, nr := calcStringDimensions(s)
|
||||
sw, sh := scr.Size()
|
||||
nc, nr := calcStringDimensions(s)
|
||||
x := (sw - nc) / 2
|
||||
y := (sh - nr) / 2
|
||||
|
||||
@ -99,27 +113,15 @@ func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool)
|
||||
text[i].style = t.backgroundStyle
|
||||
}
|
||||
|
||||
fmt.Printf("\033[5 q")
|
||||
t.tty.WriteString("\033[5 q")
|
||||
|
||||
//Assumes original cursor shape was a block (the one true cursor shape), there doesn't appear to be a
|
||||
//good way to save/restore the shape if the user has changed it from the otcs.
|
||||
defer fmt.Printf("\033[2 q")
|
||||
defer t.tty.WriteString("\033[2 q")
|
||||
|
||||
t.Scr.SetStyle(t.backgroundStyle)
|
||||
idx := 0
|
||||
|
||||
redraw := func() {
|
||||
if timeLimit != -1 && !startTime.IsZero() {
|
||||
remaining := timeLimit - time.Now().Sub(startTime)
|
||||
drawString(t.Scr, x+nc/2, y+nr+1, strconv.Itoa(int(remaining/1E9)), -1, t.backgroundStyle)
|
||||
}
|
||||
|
||||
//Potentially inefficient, but seems to be good enough
|
||||
drawCells(t.Scr, x, y, text, idx)
|
||||
|
||||
t.Scr.Show()
|
||||
}
|
||||
|
||||
calcStats := func() {
|
||||
nerrs = 0
|
||||
ncorrect = 0
|
||||
@ -132,10 +134,32 @@ func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool)
|
||||
}
|
||||
}
|
||||
|
||||
exitKey = 0
|
||||
rc = TyperComplete
|
||||
duration = time.Now().Sub(startTime)
|
||||
}
|
||||
|
||||
redraw := func() {
|
||||
if timeLimit != -1 && !startTime.IsZero() {
|
||||
remaining := timeLimit - time.Now().Sub(startTime)
|
||||
drawString(t.Scr, x+nc/2, y+nr+1, " ", -1, t.backgroundStyle)
|
||||
drawString(t.Scr, x+nc/2, y+nr+1, strconv.Itoa(int(remaining/1E9)), -1, t.backgroundStyle)
|
||||
}
|
||||
|
||||
if t.ShowWpm && !startTime.IsZero() {
|
||||
calcStats()
|
||||
if duration > 1E7 { //Avoid flashing large numbers on test start.
|
||||
wpm := int((float64(ncorrect) / 5) / (float64(duration) / 60E9))
|
||||
drawString(t.Scr, x+nc/2-4, y-2, fmt.Sprintf("WPM: %-10d\n", wpm), -1, t.backgroundStyle)
|
||||
}
|
||||
}
|
||||
|
||||
//Potentially inefficient, but seems to be good enough
|
||||
|
||||
drawCells(t.Scr, x, y, text, idx)
|
||||
|
||||
t.Scr.Show()
|
||||
}
|
||||
|
||||
deleteWord := func() {
|
||||
t.highlight(text, idx, t.backgroundStyle, t.backgroundStyle)
|
||||
|
||||
@ -173,7 +197,7 @@ func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool)
|
||||
default:
|
||||
}
|
||||
|
||||
time.Sleep(time.Duration(1E8))
|
||||
time.Sleep(time.Duration(5E8))
|
||||
t.Scr.PostEventWait(nil)
|
||||
}
|
||||
}
|
||||
@ -194,25 +218,20 @@ func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool)
|
||||
|
||||
switch ev := ev.(type) {
|
||||
case *tcell.EventResize:
|
||||
t.Scr.Sync()
|
||||
t.Scr.Clear()
|
||||
|
||||
nc, nr = calcStringDimensions(s)
|
||||
sw, sh = scr.Size()
|
||||
x = (sw - nc) / 2
|
||||
y = (sh - nr) / 2
|
||||
rc = TyperResize
|
||||
return
|
||||
case *tcell.EventKey:
|
||||
if startTime.IsZero() {
|
||||
startTime = time.Now()
|
||||
}
|
||||
|
||||
switch key := ev.Key(); key {
|
||||
case tcell.KeyEscape,
|
||||
tcell.KeyCtrlC:
|
||||
case tcell.KeyCtrlC:
|
||||
rc = TyperSigInt
|
||||
|
||||
nerrs = -1
|
||||
ncorrect = -1
|
||||
exitKey = key
|
||||
return
|
||||
case tcell.KeyEscape:
|
||||
rc = TyperEscape
|
||||
|
||||
return
|
||||
case tcell.KeyCtrlL:
|
||||
@ -288,5 +307,6 @@ func (t *typer) start(s string, timeLimit time.Duration, startImmediately bool)
|
||||
|
||||
redraw()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
205
util.go
205
util.go
@ -53,211 +53,8 @@ func init() {
|
||||
func randomText(n int, ncols int) string {
|
||||
r := ""
|
||||
|
||||
words := []string{
|
||||
"the",
|
||||
"be",
|
||||
"of",
|
||||
"and",
|
||||
"a",
|
||||
"to",
|
||||
"in",
|
||||
"he",
|
||||
"have",
|
||||
"it",
|
||||
"that",
|
||||
"for",
|
||||
"they",
|
||||
"I",
|
||||
"with",
|
||||
"as",
|
||||
"not",
|
||||
"on",
|
||||
"she",
|
||||
"at",
|
||||
"by",
|
||||
"this",
|
||||
"we",
|
||||
"you",
|
||||
"do",
|
||||
"but",
|
||||
"from",
|
||||
"or",
|
||||
"which",
|
||||
"one",
|
||||
"would",
|
||||
"all",
|
||||
"will",
|
||||
"there",
|
||||
"say",
|
||||
"who",
|
||||
"make",
|
||||
"when",
|
||||
"can",
|
||||
"more",
|
||||
"if",
|
||||
"no",
|
||||
"man",
|
||||
"out",
|
||||
"other",
|
||||
"so",
|
||||
"what",
|
||||
"time",
|
||||
"up",
|
||||
"go",
|
||||
"about",
|
||||
"than",
|
||||
"into",
|
||||
"could",
|
||||
"state",
|
||||
"only",
|
||||
"new",
|
||||
"year",
|
||||
"some",
|
||||
"take",
|
||||
"come",
|
||||
"these",
|
||||
"know",
|
||||
"see",
|
||||
"use",
|
||||
"get",
|
||||
"like",
|
||||
"then",
|
||||
"first",
|
||||
"any",
|
||||
"work",
|
||||
"now",
|
||||
"may",
|
||||
"such",
|
||||
"give",
|
||||
"over",
|
||||
"think",
|
||||
"most",
|
||||
"even",
|
||||
"find",
|
||||
"day",
|
||||
"also",
|
||||
"after",
|
||||
"way",
|
||||
"many",
|
||||
"must",
|
||||
"look",
|
||||
"before",
|
||||
"great",
|
||||
"back",
|
||||
"through",
|
||||
"long",
|
||||
"where",
|
||||
"much",
|
||||
"should",
|
||||
"well",
|
||||
"people",
|
||||
"down",
|
||||
"own",
|
||||
"just",
|
||||
"because",
|
||||
"good",
|
||||
"each",
|
||||
"those",
|
||||
"feel",
|
||||
"seem",
|
||||
"how",
|
||||
"high",
|
||||
"too",
|
||||
"place",
|
||||
"little",
|
||||
"world",
|
||||
"very",
|
||||
"still",
|
||||
"nation",
|
||||
"hand",
|
||||
"old",
|
||||
"life",
|
||||
"tell",
|
||||
"write",
|
||||
"become",
|
||||
"here",
|
||||
"show",
|
||||
"house",
|
||||
"both",
|
||||
"between",
|
||||
"need",
|
||||
"mean",
|
||||
"call",
|
||||
"develop",
|
||||
"under",
|
||||
"last",
|
||||
"right",
|
||||
"move",
|
||||
"thing",
|
||||
"general",
|
||||
"school",
|
||||
"never",
|
||||
"same",
|
||||
"another",
|
||||
"begin",
|
||||
"while",
|
||||
"number",
|
||||
"part",
|
||||
"turn",
|
||||
"real",
|
||||
"leave",
|
||||
"might",
|
||||
"want",
|
||||
"point",
|
||||
"form",
|
||||
"off",
|
||||
"child",
|
||||
"few",
|
||||
"small",
|
||||
"since",
|
||||
"against",
|
||||
"ask",
|
||||
"late",
|
||||
"home",
|
||||
"interest",
|
||||
"large",
|
||||
"person",
|
||||
"end",
|
||||
"open",
|
||||
"public",
|
||||
"follow",
|
||||
"during",
|
||||
"present",
|
||||
"without",
|
||||
"again",
|
||||
"hold",
|
||||
"govern",
|
||||
"around",
|
||||
"possible",
|
||||
"head",
|
||||
"consider",
|
||||
"word",
|
||||
"program",
|
||||
"problem",
|
||||
"however",
|
||||
"lead",
|
||||
"system",
|
||||
"set",
|
||||
"order",
|
||||
"eye",
|
||||
"plan",
|
||||
"run",
|
||||
"keep",
|
||||
"face",
|
||||
"fact",
|
||||
"group",
|
||||
"play",
|
||||
"stand",
|
||||
"increase",
|
||||
"early",
|
||||
"course",
|
||||
"change",
|
||||
"help",
|
||||
"line",
|
||||
}
|
||||
|
||||
for i := 0; i < n; i++ {
|
||||
r += words[rand.Int()%len(words)]
|
||||
r += defaultWordList[rand.Int()%len(defaultWordList)]
|
||||
if i != n-1 {
|
||||
r += " "
|
||||
}
|
||||
|
106
words.go
Normal file
106
words.go
Normal file
@ -0,0 +1,106 @@
|
||||
package main
|
||||
|
||||
//Top 1000 words in English.
|
||||
|
||||
var defaultWordList = []string{
|
||||
"as", "I", "his", "that", "he", "was", "for", "on", "are", "with",
|
||||
"they", "be", "at", "one", "have", "this", "from", "by", "hot", "word",
|
||||
"but", "what", "some", "is", "it", "you", "or", "had", "the", "of",
|
||||
"to", "and", "a", "in", "we", "can", "out", "other", "were", "which",
|
||||
"do", "their", "time", "if", "will", "how", "said", "an", "each", "tell",
|
||||
"does", "set", "three", "want", "air", "well", "also", "play", "small", "end",
|
||||
"put", "home", "read", "hand", "port", "large", "spell", "add", "even", "land",
|
||||
"here", "must", "big", "high", "such", "follow", "act", "why", "ask", "men",
|
||||
"change", "went", "light", "kind", "off", "need", "house", "picture", "try", "us",
|
||||
"again", "animal", "point", "mother", "world", "near", "build", "self", "earth", "father",
|
||||
"any", "new", "work", "part", "take", "get", "place", "made", "live", "where",
|
||||
"after", "back", "little", "only", "round", "man", "year", "came", "show", "every",
|
||||
"good", "me", "give", "our", "under", "name", "very", "through", "just", "form",
|
||||
"sentence", "great", "think", "say", "help", "low", "line", "differ", "turn", "cause",
|
||||
"much", "mean", "before", "move", "right", "boy", "old", "too", "same", "she",
|
||||
"all", "there", "when", "up", "use", "your", "way", "about", "many", "then",
|
||||
"them", "write", "would", "like", "so", "these", "her", "long", "make", "thing",
|
||||
"see", "him", "two", "has", "look", "more", "day", "could", "go", "come",
|
||||
"did", "number", "sound", "no", "most", "people", "my", "over", "know", "water",
|
||||
"than", "call", "first", "who", "may", "down", "side", "been", "now", "find",
|
||||
"head", "stand", "own", "page", "should", "country", "found", "answer", "school", "grow",
|
||||
"study", "still", "learn", "plant", "cover", "food", "sun", "four", "between", "state",
|
||||
"keep", "eye", "never", "last", "let", "thought", "city", "tree", "cross", "farm",
|
||||
"hard", "start", "might", "story", "saw", "far", "sea", "draw", "left", "late",
|
||||
"run", "don’t", "while", "press", "close", "night", "real", "life", "few", "north",
|
||||
"book", "carry", "took", "science", "eat", "room", "friend", "began", "idea", "fish",
|
||||
"mountain", "stop", "once", "base", "hear", "horse", "cut", "sure", "watch", "color",
|
||||
"face", "wood", "main", "open", "seem", "together", "next", "white", "children", "begin",
|
||||
"got", "walk", "example", "ease", "paper", "group", "always", "music", "those", "both",
|
||||
"mark", "often", "letter", "until", "mile", "river", "car", "feet", "care", "second",
|
||||
"enough", "plain", "girl", "usual", "young", "ready", "above", "ever", "red", "list",
|
||||
"though", "feel", "talk", "bird", "soon", "body", "dog", "family", "direct", "pose",
|
||||
"leave", "song", "measure", "door", "product", "black", "short", "numeral", "class", "wind",
|
||||
"question", "happen", "complete", "ship", "area", "half", "rock", "order", "fire", "south",
|
||||
"problem", "piece", "told", "knew", "pass", "since", "top", "whole", "king", "street",
|
||||
"inch", "multiply", "nothing", "course", "stay", "wheel", "full", "force", "blue", "object",
|
||||
"decide", "surface", "deep", "moon", "island", "foot", "system", "busy", "test", "record",
|
||||
"boat", "common", "gold", "possible", "plane", "stead", "dry", "wonder", "laugh", "thousand",
|
||||
"ago", "ran", "check", "game", "shape", "equate", "hot", "miss", "brought", "heat",
|
||||
"snow", "tire", "bring", "yes", "distant", "fill", "east", "paint", "language", "among",
|
||||
"unit", "power", "town", "fine", "certain", "fly", "fall", "lead", "cry", "dark",
|
||||
"machine", "note", "wait", "plan", "figure", "star", "box", "noun", "field", "rest",
|
||||
"correct", "able", "pound", "done", "beauty", "drive", "stood", "contain", "front", "teach",
|
||||
"week", "final", "gave", "green", "oh", "quick", "develop", "ocean", "warm", "free",
|
||||
"minute", "strong", "special", "mind", "behind", "clear", "tail", "produce", "fact", "space",
|
||||
"heard", "best", "hour", "better", "true", "during", "hundred", "five", "remember", "step",
|
||||
"early", "hold", "west", "ground", "interest", "reach", "fast", "verb", "sing", "listen",
|
||||
"six", "table", "travel", "less", "morning", "ten", "simple", "several", "vowel", "toward",
|
||||
"war", "lay", "against", "pattern", "slow", "center", "love", "person", "money", "serve",
|
||||
"appear", "road", "map", "rain", "rule", "govern", "pull", "cold", "notice", "voice",
|
||||
"energy", "hunt", "probable", "bed", "brother", "egg", "ride", "cell", "believe", "perhaps",
|
||||
"pick", "sudden", "count", "square", "reason", "length", "represent", "art", "subject", "region",
|
||||
"size", "vary", "settle", "speak", "weight", "general", "ice", "matter", "circle", "pair",
|
||||
"include", "divide", "syllable", "felt", "grand", "ball", "yet", "wave", "drop", "heart",
|
||||
"am", "present", "heavy", "dance", "engine", "position", "arm", "wide", "sail", "material",
|
||||
"fraction", "forest", "sit", "race", "window", "store", "summer", "train", "sleep", "prove",
|
||||
"lone", "leg", "exercise", "wall", "catch", "mount", "wish", "sky", "board", "joy",
|
||||
"winter", "sat", "written", "wild", "instrument", "kept", "glass", "grass", "cow", "job",
|
||||
"edge", "sign", "visit", "past", "soft", "fun", "bright", "gas", "weather", "month",
|
||||
"million", "bear", "finish", "happy", "hope", "flower", "clothe", "strange", "gone", "trade",
|
||||
"melody", "trip", "office", "receive", "row", "mouth", "exact", "symbol", "die", "least",
|
||||
"trouble", "shout", "except", "wrote", "seed", "tone", "join", "suggest", "clean", "break",
|
||||
"lady", "yard", "rise", "bad", "blow", "oil", "blood", "touch", "grew", "cent",
|
||||
"mix", "team", "wire", "cost", "lost", "brown", "wear", "garden", "equal", "sent",
|
||||
"choose", "fell", "fit", "flow", "fair", "bank", "collect", "save", "control", "decimal",
|
||||
"ear", "else", "quite", "broke", "case", "middle", "kill", "son", "lake", "moment",
|
||||
"scale", "loud", "spring", "observe", "child", "straight", "consonant", "nation", "dictionary", "milk",
|
||||
"speed", "method", "organ", "pay", "age", "section", "dress", "cloud", "surprise", "quiet",
|
||||
"stone", "tiny", "climb", "cool", "design", "poor", "lot", "experiment", "bottom", "key",
|
||||
"iron", "single", "stick", "flat", "twenty", "skin", "smile", "crease", "hole", "jump",
|
||||
"baby", "eight", "village", "meet", "root", "buy", "raise", "solve", "metal", "whether",
|
||||
"push", "seven", "paragraph", "third", "shall", "held", "hair", "describe", "cook", "floor",
|
||||
"either", "result", "burn", "hill", "safe", "cat", "century", "consider", "type", "law",
|
||||
"bit", "coast", "copy", "phrase", "silent", "tall", "sand", "soil", "roll", "temperature",
|
||||
"finger", "industry", "value", "fight", "lie", "beat", "excite", "natural", "view", "sense",
|
||||
"capital", "won’t", "chair", "danger", "fruit", "rich", "thick", "soldier", "process", "operate",
|
||||
"practice", "separate", "difficult", "doctor", "please", "protect", "noon", "crop", "modern", "element",
|
||||
"hit", "student", "corner", "party", "supply", "whose", "locate", "ring", "character", "insect",
|
||||
"caught", "period", "indicate", "radio", "spoke", "atom", "human", "history", "effect", "electric",
|
||||
"expect", "bone", "rail", "imagine", "provide", "agree", "thus", "gentle", "woman", "captain",
|
||||
"guess", "necessary", "sharp", "wing", "create", "neighbor", "wash", "bat", "rather", "crowd",
|
||||
"corn", "compare", "poem", "string", "bell", "depend", "meat", "rub", "tube", "famous",
|
||||
"dollar", "stream", "fear", "sight", "thin", "triangle", "planet", "hurry", "chief", "colony",
|
||||
"clock", "mine", "tie", "enter", "major", "fresh", "search", "send", "yellow", "gun",
|
||||
"allow", "print", "dead", "spot", "desert", "suit", "current", "lift", "rose", "arrive",
|
||||
"master", "track", "parent", "shore", "division", "sheet", "substance", "favor", "connect", "post",
|
||||
"spend", "chord", "fat", "glad", "original", "share", "station", "dad", "bread", "charge",
|
||||
"proper", "bar", "offer", "segment", "slave", "duck", "instant", "market", "degree", "populate",
|
||||
"chick", "dear", "enemy", "reply", "drink", "occur", "support", "speech", "nature", "range",
|
||||
"steam", "motion", "path", "liquid", "log", "meant", "quotient", "teeth", "shell", "neck",
|
||||
"oxygen", "sugar", "death", "pretty", "skill", "women", "season", "solution", "magnet", "silver",
|
||||
"thank", "branch", "match", "suffix", "especially", "fig", "afraid", "huge", "sister", "steel",
|
||||
"discuss", "forward", "similar", "guide", "experience", "score", "apple", "bought", "led", "pitch",
|
||||
"coat", "mass", "card", "band", "rope", "slip", "win", "dream", "evening", "condition",
|
||||
"feed", "tool", "total", "basic", "smell", "valley", "nor", "double", "seat", "continue",
|
||||
"block", "chart", "hat", "sell", "success", "company", "subtract", "event", "particular", "deal",
|
||||
"swim", "term", "opposite", "wife", "shoe", "shoulder", "spread", "arrange", "camp", "invent",
|
||||
"cotton", "born", "determine", "quart", "nine", "truck", "noise", "level", "chance", "gather",
|
||||
"shop", "stretch", "throw", "shine", "property", "column", "molecule", "select", "wrong", "gray",
|
||||
"repeat", "require", "broad", "prepare", "salt", "nose", "plural", "anger", "claim", "continent",
|
||||
}
|
Reference in New Issue
Block a user