Skip to content

Commit

Permalink
v0.4.0
Browse files Browse the repository at this point in the history
  Partial rewrite.

  Changes too numerous to list (see the man page).

  Highlights:

 - Added -quotes.
 - Added support for navigating between tests via right/left.
 - Now store the user's position within a file if one is specified.
 - Improved documentation.
  • Loading branch information
lemnos committed Jan 16, 2021
1 parent bae57c2 commit 3dc96b8
Show file tree
Hide file tree
Showing 19 changed files with 22,527 additions and 381 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,13 @@
# 0.4.0:
Too numerous to list (see the man page)

Highlights:

- Added -quotes.
- Added support for navigating between tests via right/left.
- Now store the user's position within a file if one is specified.
- Improved documentation.

# 0.3.0:
- Added support for custom word lists (`-words).
- `-theme` now accepts a path.
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Expand Up @@ -2,9 +2,11 @@ all:
go build -o bin/tt *.go
install:
install -m755 bin/tt /usr/local/bin
install -m755 tt.1.gz /usr/share/man/man1
assets:
python3 ./scripts/themegen.py
./scripts/pack themes/ words/ > packed.go
./scripts/pack themes/ words/ quotes/ > packed.go
pandoc -s -t man -o - man.md|gzip > tt.1.gz
rel:
GOOS=darwin GOARCH=amd64 go build -o bin/tt-osx *.go
GOOS=windows GOARCH=amd64 go build -o bin/tt.exe *.go
Expand Down
45 changes: 22 additions & 23 deletions README.md
Expand Up @@ -9,19 +9,17 @@ A terminal based typing test.
## Linux

```
sudo curl -L https://github.com/lemnos/tt/releases/download/v0.3.0/tt-linux -o /usr/local/bin/tt && sudo chmod +x /usr/local/bin/tt
sudo curl -L https://github.com/lemnos/tt/releases/download/v0.4.0/tt-linux -o /usr/local/bin/tt && sudo chmod +x /usr/local/bin/tt
sudo curl /usr/share/man/man1/tt.1.gz -o https://github.com/lemnos/tt/releases/download/v0.4.0/tt.1.gz -L
```

## OSX

```
sudo curl -L https://github.com/lemnos/tt/releases/download/v0.3.0/tt-osx -o /usr/local/bin/tt && sudo chmod +x /usr/local/bin/tt
sudo curl -L https://github.com/lemnos/tt/releases/download/v0.4.0/tt-osx -o /usr/local/bin/tt && sudo chmod +x /usr/local/bin/tt
sudo curl /usr/share/man/man1/tt.1.gz -o https://github.com/lemnos/tt/releases/download/v0.4.0/tt.1.gz -L
```

## Windows

There is a [windows binary](https://github.com/lemnos/tt/releases/download/0.0.2/tt.exe) but it is largely untested. Using WSL is strongly encouraged (or alternatively switching to a proper OS ;)).

## From source

```
Expand All @@ -38,21 +36,33 @@ Best served on a terminal with truecolor and cursor shape support (e.g kitty, it
# Usage

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 arbitrary text to
the program. Each paragraph in the input is shown as a separate segment of the
text.
constitute the test. Custom text can be supplied by piping arbitrary text to the
program. Each paragraph in the input is shown as a separate segment of the text.
See `man tt` or `man.md` for a complete description and a comprehensive set of
options.

## Keys

- Pressing `escape` at any point restarts the test.
- `C-c` exits the test.
- `right` moves to the next test.
- `left` moves to the previous test.

## Examples

- `tt -n 10` produces a test consisting of 10 randomly drawn English words
- `tt -quotes en` Starts quote mode with the builtin quote list 'en'.
- `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 -theme gruvbox` Starts tt with the gruvbox theme
- `tt -t 10` starts a timed test lasting 10 seconds.
- `tt -theme gruvbox` Starts tt with the gruvbox theme.

`tt` is designed to be easily scriptable and integrate nicely 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/share/dict/words|tt` Produces a test consisting of 40 random words drawn from your system's dictionary.
- `curl http://api.quotable.io/random|jq '[.text=.content|.attribution=.author]'|tt -quotes -` Produces a test consisting of a random quote.
- `alias ttd='tt -csv >> ~/wpm.csv'` Creates an alias called ttd which keeps a log of progress in your home directory`.

The default behaviour is equivalent to `tt -n 50`.

Expand All @@ -64,14 +74,3 @@ Custom themes and word lists can be defined in `~/.tt/themes` and `~/.tt/words`
and used in conjunction with the `-theme` and `-words` flags. A list of
preloaded themes and word lists can be found in `words/` and `themes/` and are
accessible by default using the respective flags.

## Recipes

`tt` is designed to be easily scriptable and integrate nicely 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/share/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`.
7 changes: 7 additions & 0 deletions TODO
@@ -0,0 +1,7 @@
Keep track of errors.
Generate word sets based on errors
Consolidate documentation.
Add option to export errors.
Add -nobackspace
-adaptive/-tutor mode which learns from your mistake.
Add -blind
30 changes: 30 additions & 0 deletions datatest.go
@@ -0,0 +1,30 @@
package main

func generateTestFromData(data []byte, raw bool, split bool) func() []segment {
if raw {
return func() []segment { return []segment{segment{string(data), ""}} }
} else if split {
paragraphs := getParagraphs(string(data))
i := 0

return func() []segment {
if i < len(paragraphs) {
p := paragraphs[i]
i++
return []segment{segment{p, ""}}
} else {
return nil
}
}
} else {
return func() []segment {
var segments []segment

for _, p := range getParagraphs(string(data)) {
segments = append(segments, segment{p, ""})
}

return segments
}
}
}
42 changes: 42 additions & 0 deletions db.go
@@ -0,0 +1,42 @@
package main

import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
)

var FILE_STATE_DB string
var MISTAKE_DB string

func init() {
if home, ok := os.LookupEnv("HOME"); !ok {
die("Could not resolve home directory.")
} else {
FILE_STATE_DB = filepath.Join(home, ".tt/", ".db")
MISTAKE_DB = filepath.Join(home, ".tt/", ".errors")
}
}

func readValue(path string, o interface{}) error {
b, err := ioutil.ReadFile(path)

if err != nil {
return err
}

return json.Unmarshal(b, o)
}

func writeValue(path string, o interface{}) {
b, err := json.Marshal(o)
if err != nil {
panic(err)
}

err = ioutil.WriteFile(path, b, 0600)
if err != nil {
panic(err)
}
}
44 changes: 44 additions & 0 deletions doc
@@ -0,0 +1,44 @@
usage: tt [options] [file]

Modes
-words WORDFILE Specifies the file from which words are randomly
generated (default: 1000en).
-quotes QUOTEFILE Starts quote mode in which quotes are randomly generated
from the given file. The file should be JSON encoded and
have the following form:

[{"text": "foo", attribution: "bar"}]

Word Mode
-n GROUPSZ Sets the number of words which constitute a group.
-g NGROUPS Sets the number of groups which constitute a test.

File Mode
-start PARAGRAPH The offset of the starting paragraph, set this to 0 to
reset progress on a given file.
Aesthetics
-showwpm Display WPM whilst typing.
-theme THEMEFILE The theme to use.
-w The maximum line length in characters. This option is
ignored if -raw is present.

Test Parameters
-t SECONDS Terminate the test after the given number of seconds.
-noskip Disable word skipping when space is pressed.

Scripting
-oneshot Automatically exit after a single run.
-noreport Don't show a report at the end of a test.
-csv Print the test results to stdout in the form:
[wpm],[cpm],[accuracy],[timestamp].
-raw Don't reflow STDIN text or show one paragraph at a time.
Note that line breaks are determined exclusively by the
input.
-multi Treat each input paragraph as a self contained test.

Misc
-list TYPE Lists internal resources of the given type.
TYPE=[themes|quotes|words]

Version
-v Print the current version.
45 changes: 45 additions & 0 deletions filetest.go
@@ -0,0 +1,45 @@
package main

import (
"io/ioutil"
"path/filepath"
)

func generateTestFromFile(path string, startParagraph int) func() []segment {
var paragraphs []string
var db map[string]int
var err error

if path, err = filepath.Abs(path); err != nil {
panic(err)
}

if err := readValue(FILE_STATE_DB, &db); err != nil {
db = map[string]int{}
}

if startParagraph != -1 {
db[path] = startParagraph
writeValue(FILE_STATE_DB, db)
}

idx := db[path] - 1

if b, err := ioutil.ReadFile(path); err != nil {
die("Failed to read %s.", path)
} else {
paragraphs = getParagraphs(string(b))
}

return func() []segment {
idx++
db[path] = idx
writeValue(FILE_STATE_DB, db)

if idx >= len(paragraphs) {
return nil
}

return []segment{segment{paragraphs[idx], ""}}
}
}
1 change: 0 additions & 1 deletion go.sum
Expand Up @@ -8,7 +8,6 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down

0 comments on commit 3dc96b8

Please sign in to comment.