Version 0.2.2
- Modified -g to correspond to the number of groups rather than the group size. - Added -multi - Added -v - Changed the default behaviour to restart the currently generated test rather than generating a new one - Added a CHANGELOG :P
This commit is contained in:
parent
d5c9dc598a
commit
529158e690
6
CHANGELOG.md
Normal file
6
CHANGELOG.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# 0.2.2:
|
||||||
|
- Modified -g to correspond to the number of groups rather than the group size.
|
||||||
|
- Added -multi
|
||||||
|
- Added -v
|
||||||
|
- Changed the default behaviour to restart the currently generated test rather than generating a new one
|
||||||
|
- Added a CHANGELOG :P
|
@ -50,7 +50,7 @@ text.
|
|||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
- `tt -n 10` produces a test consisting of 10 randomly drawn English words
|
- `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 -n 10 -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 -t 10` starts a timed test consisting of 50 words
|
||||||
- `tt -theme gruvbox` Starts tt with the gruvbox theme
|
- `tt -theme gruvbox` Starts tt with the gruvbox theme
|
||||||
|
|
||||||
|
117
tt.go
117
tt.go
@ -77,7 +77,7 @@ func showReport(scr tcell.Screen, cpm, wpm int, accuracy float64) {
|
|||||||
func main() {
|
func main() {
|
||||||
var n int
|
var n int
|
||||||
var ngroups int
|
var ngroups int
|
||||||
var contentFn func(sw, sh int) []string
|
var testFn func() []string
|
||||||
var rawMode bool
|
var rawMode bool
|
||||||
var oneShotMode bool
|
var oneShotMode bool
|
||||||
var maxLineLen int
|
var maxLineLen int
|
||||||
@ -88,18 +88,23 @@ func main() {
|
|||||||
var err error
|
var err error
|
||||||
var themeName string
|
var themeName string
|
||||||
var showWpm bool
|
var showWpm bool
|
||||||
|
var multiMode bool
|
||||||
|
var versionFlag bool
|
||||||
|
|
||||||
flag.IntVar(&n, "n", 50, "The number of random words which constitute the test.")
|
flag.IntVar(&n, "n", 50, "The number of random words which constitute a unit of the test.")
|
||||||
flag.IntVar(&ngroups, "g", 1, "The number of groups into which the generated test is split.")
|
flag.IntVar(&ngroups, "g", 1, "The number of groups of which a test consists.")
|
||||||
flag.IntVar(&maxLineLen, "w", 80, "The maximum line length in characters. (ignored if -raw is present).")
|
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.IntVar(&timeout, "t", -1, "Terminate the test after the given number of seconds.")
|
||||||
|
|
||||||
|
flag.BoolVar(&versionFlag, "v", false, "Print the current version.")
|
||||||
|
|
||||||
flag.BoolVar(&showWpm, "showwpm", false, "Display WPM whilst typing.")
|
flag.BoolVar(&showWpm, "showwpm", false, "Display WPM whilst typing.")
|
||||||
flag.BoolVar(&noSkip, "noskip", false, "Disable word skipping when space is pressed.")
|
flag.BoolVar(&noSkip, "noskip", false, "Disable word skipping when space is pressed.")
|
||||||
flag.BoolVar(&oneShotMode, "oneshot", false, "Automatically exit after a single run (useful for scripts).")
|
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(&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(&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(&rawMode, "raw", false, "Don't reflow text or show one paragraph at a time.")
|
||||||
|
flag.BoolVar(&multiMode, "multi", false, "Treat each input paragraph as a self contained test.")
|
||||||
flag.StringVar(&themeName, "theme", "", "The theme to use (overrides ~/.ttrc).")
|
flag.StringVar(&themeName, "theme", "", "The theme to use (overrides ~/.ttrc).")
|
||||||
flag.StringVar(&listFlag, "list", "", "-list themes prints a list of available themes.")
|
flag.StringVar(&listFlag, "list", "", "-list themes prints a list of available themes.")
|
||||||
|
|
||||||
@ -134,51 +139,64 @@ Options:`)
|
|||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if versionFlag {
|
||||||
|
fmt.Fprintf(os.Stderr, "tt version 0.2.2\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
reflow := func(s string) string {
|
||||||
|
sw, _ := scr.Size()
|
||||||
|
|
||||||
|
wsz := maxLineLen
|
||||||
|
if wsz > sw {
|
||||||
|
wsz = sw - 8
|
||||||
|
}
|
||||||
|
|
||||||
|
s = regexp.MustCompile("\\s+").ReplaceAllString(s, " ")
|
||||||
|
return strings.Replace(
|
||||||
|
wordWrap(strings.Trim(s, " "), wsz),
|
||||||
|
"\n", " \n", -1)
|
||||||
|
}
|
||||||
|
|
||||||
if !isatty.IsTerminal(os.Stdin.Fd()) {
|
if !isatty.IsTerminal(os.Stdin.Fd()) {
|
||||||
b, err := ioutil.ReadAll(os.Stdin)
|
b, err := ioutil.ReadAll(os.Stdin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getParagraphs := func(s string) []string {
|
||||||
|
s = strings.Replace(s, "\r", "", -1)
|
||||||
|
s = regexp.MustCompile("\n\n+").ReplaceAllString(s, "\n\n")
|
||||||
|
return strings.Split(strings.Trim(s, "\n"), "\n\n")
|
||||||
|
}
|
||||||
|
|
||||||
if rawMode {
|
if rawMode {
|
||||||
contentFn = func(sw, sh int) []string { return []string{string(b)} }
|
testFn = func() []string { return []string{string(b)} }
|
||||||
|
} else if multiMode {
|
||||||
|
paragraphs := getParagraphs(string(b))
|
||||||
|
i := 0
|
||||||
|
|
||||||
|
testFn = func() []string {
|
||||||
|
if i < len(paragraphs) {
|
||||||
|
p := paragraphs[i]
|
||||||
|
i++
|
||||||
|
return []string{p}
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
contentFn = func(sw, sh int) []string {
|
testFn = func() []string {
|
||||||
wsz := maxLineLen
|
return getParagraphs(string(b))
|
||||||
if wsz > sw {
|
|
||||||
wsz = sw - 8
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
contentFn = func(sw, sh int) []string {
|
testFn = func() []string {
|
||||||
wsz := maxLineLen
|
|
||||||
if wsz > sw {
|
|
||||||
wsz = sw - 8
|
|
||||||
}
|
|
||||||
|
|
||||||
if ngroups > n {
|
|
||||||
ngroups = n
|
|
||||||
}
|
|
||||||
|
|
||||||
r := make([]string, ngroups)
|
r := make([]string, ngroups)
|
||||||
sz := n / ngroups
|
for i := 0; i < ngroups; i++ {
|
||||||
for i := 0; i < ngroups-1; i++ {
|
r[i] = randomText(n)
|
||||||
r[i] = randomText(sz, wsz)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r[ngroups-1] = randomText(sz+n%ngroups, wsz)
|
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -246,6 +264,13 @@ Options:`)
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
scr.Fini()
|
||||||
|
panic(r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
typer := NewTyper(scr, fgcol, bgcol, hicol, hicol2, hicol3, errcol)
|
typer := NewTyper(scr, fgcol, bgcol, hicol, hicol2, hicol3, errcol)
|
||||||
typer.SkipWord = !noSkip
|
typer.SkipWord = !noSkip
|
||||||
typer.ShowWpm = showWpm
|
typer.ShowWpm = showWpm
|
||||||
@ -254,10 +279,27 @@ Options:`)
|
|||||||
timeout *= 1E9
|
timeout *= 1E9
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
var showNext = true
|
||||||
sw, sh := scr.Size()
|
var paragraphs []string
|
||||||
nerrs, ncorrect, t, rc := typer.Start(contentFn(sw, sh), time.Duration(timeout))
|
|
||||||
|
|
||||||
|
for {
|
||||||
|
if showNext {
|
||||||
|
paragraphs = testFn()
|
||||||
|
|
||||||
|
if paragraphs == nil {
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !rawMode {
|
||||||
|
for i, _ := range paragraphs {
|
||||||
|
paragraphs[i] = reflow(paragraphs[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nerrs, ncorrect, t, rc := typer.Start(paragraphs, time.Duration(timeout))
|
||||||
|
|
||||||
|
showNext = false
|
||||||
switch rc {
|
switch rc {
|
||||||
case TyperComplete:
|
case TyperComplete:
|
||||||
cpm := int(float64(ncorrect) / (float64(t) / 60E9))
|
cpm := int(float64(ncorrect) / (float64(t) / 60E9))
|
||||||
@ -271,6 +313,7 @@ Options:`)
|
|||||||
if oneShotMode {
|
if oneShotMode {
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
|
showNext = true
|
||||||
case TyperSigInt:
|
case TyperSigInt:
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
4
util.go
4
util.go
@ -59,7 +59,7 @@ func init() {
|
|||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomText(n int, ncols int) string {
|
func randomText(n int) string {
|
||||||
r := ""
|
r := ""
|
||||||
|
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
@ -69,7 +69,7 @@ func randomText(n int, ncols int) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return strings.Replace(wordWrap(r, ncols), "\n", " \n", -1)
|
return strings.Replace(r, "\n", " \n", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func stringToCells(s string) []cell {
|
func stringToCells(s string) []cell {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user