8000 feat: continuous timed mode — stream words until the clock stops (#6) by hindriix · Pull Request #26 · jrnxf/thokr · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ Usage: thokr [OPTIONS]

Options:
-w, --number-of-words <NUMBER_OF_WORDS>
number of words to use in test [default: 15]
number of words to use in test (initial buffer only when timed) [default: 15]
-f, --full-sentences <NUMBER_OF_SENTENCES>
number of sentences to use in test
-s, --number-of-secs <NUMBER_OF_SECS>
number of seconds to run test
run a timed test for this many seconds; words stream continuously until the clock stops (unless -p or -f fixes the text)
-p, --prompt <PROMPT>
custom prompt to use
-l, --supported-language <SUPPORTED_LANGUAGE>
Expand All @@ -70,20 +70,31 @@ Options:

### Examples

| command | test contents |
|:----------------------------|-----------------------------------------------------------------:|
| `thokr` | 50 of the 200 most common english words |
| `thokr -w 100` | 100 of the 200 most common English words |
| `thokr -w 100 -l english1k` | 100 of the 1000 most common English words |
| `thokr -w 10 -s 5` | 10 of the 200 most common English words (hard stop at 5 seconds) |
| `thokr -p "$(cat foo.txt)"` | custom prompt with the output of `cat foo.txt` |
| `thokr -f 4` | 4 grammatical sentences with full stops; overrides word settings |
| `thokr --pace 60` | 15 most common words with a ghost caret racing at 60 wpm |
| `thokr -d` | 15 words, but the test ends the instant you mistype a character |
| command | test contents |
|:----------------------------------|------------------------------------------------------------------------:|
| `thokr` | 50 of the 200 most common english words |
| `thokr -w 100` | 100 of the 200 most common English words |
| `thokr -w 100 -l english1k` | 100 of the 1000 most common English words |
| `thokr -s 30` | 30-second timed test, words stream continuously until time runs out |
| `thokr -s 60 -l english1k` | 60-second timed test drawing from the 1000 most common words |
| `thokr -p "$(cat foo.txt)" -s 30` | custom prompt with a 30s cap (fixed text, stops early if you finish it) |
| `thokr -p "$(cat foo.txt)"` | custom prompt with the output of `cat foo.txt` |
| `thokr -f 4` | 4 grammatical sentences with full stops; overrides word settings |
| `thokr --pace 60` | 15 most common words with a ghost caret racing at 60 wpm |
| `thokr -d` | 15 words, but the test ends the instant you mistype a character |

_During a test you can press ← to start over or → to see a new prompt (assuming
you didn't supply a custom one)_

### Timed (continuous) mode

Passing `-s <seconds>` on its own runs a **continuous** test: fresh words stream
in as you type and the test only ends when the clock hits zero. A long prompt
scrolls a few lines at a time so the layout stays put. `-w` then just sets the
size of the initial on-screen buffer. Combining `-s` with a custom prompt (`-p`)
or sentences (`-f`) keeps the text fixed, so the test still ends when you finish
it or the timer expires, whichever comes first.

## Supported Languages

The following languages are available by default:
Expand Down
5 changes: 5 additions & 0 deletions src/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ impl Language {
.collect();
picked.join(" ")
}

/// Every word of the list, for continuous (timed) mode to draw from.
pub fn word_pool(self) -> Vec<String> {
self.words().lines().map(str::to_string).collect()
}
}

/// `count` random sentences joined by spaces, and how many words they hold.
Expand Down
21 changes: 18 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,16 @@ use std::{
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Cli {
/// number of words to use in test
/// number of words to use in test (initial buffer only when timed)
#[arg(short = 'w', long, default_value_t = 15)]
number_of_words: usize,

/// number of sentences to use in test
#[arg(short = 'f', long = "full-sentences")]
number_of_sentences: Option<usize>,

/// number of seconds to run test
/// run a timed test for this many seconds; words stream continuously until
/// the clock stops (unless -p or -f fixes the text)
#[arg(short = 's', long)]
number_of_secs: Option<usize>,

Expand Down Expand Up @@ -90,11 +91,23 @@ impl App {
}
}

/// A timed test on the default words streams fresh ones until the clock
/// stops. A custom prompt or sentences are fixed text, so they end at
/// their own length.
fn is_continuous(cli: &Cli) -> bool {
cli.number_of_secs.is_some() && cli.prompt.is_none() && cli.number_of_sentences.is_none()
}

fn new_thok(cli: &Cli, prompt: String, word_count: usize) -> Thok {
let number_of_secs = cli.number_of_secs.map(|secs| secs as f64);
let mut thok = Thok::new(prompt, word_count, number_of_secs);
thok.pace_wpm = cli.pace.map(f64::from);
thok.death_mode = cli.death_mode;
if Self::is_continuous(cli) {
thok.refill_words = cli.supported_language.word_pool();
// so the prompt has its full length from the first frame
thok.refill_if_needed();
}
thok
}

Expand All @@ -110,7 +123,9 @@ impl App {
self.thok = Self::new_thok(&self.cli, prompt, word_count);
}

fn draw(&self, frame: &mut ratatui::Frame) {
fn draw(&mut self, frame: &mut ratatui::Frame) {
// a timed test streams words to fill the lines the screen shows
self.thok.set_line_width(ui::line_width(frame.area()));
ui::draw(frame, &self.thok);
}

Expand Down
26 changes: 13 additions & 13 deletions src/snapshots/thokr__ui__tests__running_in_a_narrow_terminal.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@ expression: "draw(&thok, 30, 14)"
---





it was the best of
times it was the
worst of times it
was the age of
wisdom it was the
age of foolishness
it was the epoch of
belief it was the
epoch of incredulity







..............................
..............................
..............................
..............................
..............................
.....aaaaaaaaaaaabaaaaaa......
.....aaaaacccccccccccc........
.....cccccccccccccccccc.......
.....ccccccccccccccc..........
.....cccccccccccccccccc.......
.....ccccccccccccccccccc......
.....cccccccccccccccccccc.....
.....cccccccccccccccccc.......
.....cccccccccccccccccccc.....
..............................
..............................
..............................
..............................
..............................
..............................

a = fg Green, BOLD
b = fg Red, BOLD
c = fg Reset, BOLD | DIM
cursor = Some(Position { x: 10, y: 3 })
cursor = Some(Position { x: 10, y: 6 })
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
source: src/ui.rs
expression: "draw(&thok, 20, 6)"
---

it was the
best of
times it
was the
worst of
times it



....................
.....aaaaaabbbbb....
.....bbbbbbbb.......
.....bbbbbbbbb......
.....bbbbbbbb.......
.....bbbbbbbbb......
.....bbbbbbbbb......
....................
....................

a = fg Green, BOLD
b = fg Reset, BOLD | DIM
cursor = Some(Position { x: 11, y: 0 })
cursor = Some(Position { x: 11, y: 1 })
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ expression: "draw(&thok, 15, 6)"
aaaaa
bbb
ccccc
dd


...............
.....aaaaab....
.....bbbb......
.....bbbbbb....
.....bb........
...............
...............

a = fg Green, BOLD
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ expression: "draw(&thok, 15, 6)"
aaaaa·
bbb
ccccc
dd


...............
.....aaaaab....
.....cccc......
.....cccccc....
.....cc........
...............
...............

a = fg Green, BOLD
Expand Down
Loading
Loading
0