touchtype: A Progressive Touch Typing Trainer for Emacs

touchtype: A Progressive Touch Typing Trainer for Emacs

1. About   emacs typing education

touchtype-banner.jpeg

Figure 1: JPEG produced with DALL-E 4o

There are plenty of typing tutors on the web. keybr.com is one of the best, a progressive trainer that unlocks keys one at a time as your speed and accuracy improve. But it runs in a browser, and if you spend most of your day in Emacs, context-switching to a browser tab for typing practice is enough friction to skip it entirely. touchtype brings that progressive training model into Emacs, along with 12 additional training modes, detailed statistics, and support for alternative keyboard layouts.

2. Why Build a Typing Tutor in Emacs   emacs motivation

The obvious question. There are two practical answers.

First, friction kills habits. If practicing typing requires opening a browser, navigating to a URL, and breaking your editing flow, you'll do it less. An M-x touchtype that's always one command away makes it trivially easy to slot in a quick session between tasks.

An M-x touchtype that's always one command away makes it trivially easy to slot in a quick session between tasks.

Second, Emacs users type Emacs. A web-based trainer gives you prose and maybe some generic code snippets. touchtype has a dedicated code mode with 42 real snippets across 8 languages (Python, Rust, Go, JavaScript, TypeScript, Emacs Lisp, Shell, SQL, C), and it respects your Emacs keybindings. Backspace, word-delete (M-DEL, C-backspace), and even Evil mode bindings all work as expected. You're practicing in the same environment you'll be typing in.

3. Progressive Training   emacs algorithm

Progressive mode is the flagship training mode, directly inspired by keybr.com. It starts you on just two keys, f and j, the home-row index fingers. You practice pseudo-words made from those two characters until your speed and accuracy cross a confidence threshold, then a third key unlocks. Then a fourth. You work through the entire keyboard one key at a time, in an order that spirals outward from the home row.

3.1. Confidence Scoring

Each key has a confidence score between 0.0 and 1.0, calculated from both speed and accuracy:

target_ms        = 60000 / (target_wpm * 5)
avg_ms           = total_ms / hits
speed_confidence = min(1.0, target_ms / avg_ms)
accuracy         = hits / (hits + misses)
confidence       = accuracy * speed_confidence

Both dimensions must be high for full confidence. A key you type quickly but inaccurately won't unlock the next one, and neither will a key you type accurately but slowly. The unlock threshold is touchtype-unlock-threshold (default: 0.80).

A new key unlocks only when every currently unlocked key meets the threshold. This prevents rushing: you can't advance by nailing the new key while your old keys decay.

3.2. Pseudo-Word Generation

touchtype generates practice words using an English bigram frequency table, a 26x26 matrix of character transition weights. Generation works as a weighted random walk:

  1. Pick a starting character, weighted by total outgoing bigram frequency.
  2. Sample the next character from that character's bigram row, filtered to the currently allowed alphabet.
  3. Terminate with probability that increases exponentially with word length (naturally producing 4-7 character words).
  4. Inject the focused character (the most recently unlocked key) at a random position with 40% probability.

This produces words that feel like English, they follow natural letter patterns, even though they aren't real words. The focused character injection ensures you get enough practice on new keys without making every word feel artificial.

3.3. Focus Character Rotation

After each line, touchtype picks a "focus character" to emphasize:

  • 70% of the time: the most recently unlocked key (deliberate practice on the new key).
  • 30% of the time: a random key below the confidence threshold (remediation for weak keys).

This rotation ensures that newly unlocked keys get concentrated practice while weak older keys aren't forgotten.

3.4. Unlock Orders by Layout

The unlock order depends on your keyboard layout, spiraling outward from the home row by English letter frequency:

Layout Order
QWERTY fjdkslahetniourGcmpbywvxqz
Dvorak uhetonasidrljgcmfpbkwvyxqz
Colemak neiostahrdlufywpgmcbkvxjqz
Workman nehtosaidrljgcmfpbkwvyxqz
Custom User-provided via touchtype-custom-unlock-order

4. Training Modes   emacs modes

touchtype has 13 training modes. Progressive is the headline, but the others cover different practice needs.

4.1. Word-Based Modes

Mode Description
Progressive Keys unlock one-at-a-time; pseudo-words from unlocked alphabet
Full Words 4,258 real English words, filtered to unlocked keys
Common Words Top N most frequent words (default: 100)
Letters All 26 lowercase letters, pseudo-words from full alphabet
Letters + Numbers Full alphabet + digits 0-9
Letters + Numbers + Symbols + punctuation: .,;'!?-
Custom User-provided text (prompt, region, or buffer)

4.2. N-gram Drills

Mode Description
Bigram Drill 100 common English bigrams, repeated on a line
Trigram Drill 100 common English trigrams
Tetragram Drill 100 common English tetragrams
N-gram Mixed Random mix of bi/tri/tetragrams per line

Each drill isolates a specific motor pattern. Bigram drills target two-finger transitions (th, he, in). Tetragram drills build four-character muscle memory for common word fragments (tion, ight, that).

4.3. Special Modes

Mode Description
Narrative Random passages from 20 Project Gutenberg classics (cached locally)
Code 42 real code snippets across 8 languages

Narrative mode downloads and caches books from Project Gutenberg, then serves random 400-character passages that land on word boundaries. The book list includes Pride and Prejudice, Alice's Adventures in Wonderland, Sherlock Holmes, Frankenstein, Moby Dick, and 15 others. You can add any valid Gutenberg ID to touchtype-narrative-book-list.

Code mode draws from a curated set of snippets: Python (8), Rust (7), Go (5), JavaScript/TypeScript (6), Emacs Lisp (4), Shell (4), SQL (4), and C (5). It includes the full printable ASCII range (chars 32-126), so you practice brackets, operators, and indentation, not just alphanumerics.

5. The Session Experience   emacs interface

A touchtype session runs in a dedicated buffer with a clean, distraction-free layout:

                        (blank padding, ~1/3 screen height)

already typed line      (completed: purple=correct, red=wrong)
already typed line

current target text_    (active: gray=untyped, purple=correct, red=wrong)

upcoming preview text   (preview lines, gray, read-only)
upcoming preview text

Net: 42  Gross: 45  Acc: 96%  Consistency: 85%
Time: 1:23  Words: 15/30  Corrections: 3  Mode: progressive  Keys: fjdksl

Completed lines scroll up above the active line. Preview lines (configurable via touchtype-preview-lines, default: 2) let you read ahead. The status line at the bottom updates live with net/gross WPM, accuracy, consistency, elapsed time, word count, correction count, current mode, and (in progressive mode) the unlocked key set.

5.1. Pace Caret

Enable touchtype-pace-caret to show a ghost cursor that moves at your target WPM. It's a visual indicator of whether you're ahead of or behind your target pace, without the pressure of a countdown timer.

5.2. Session Types

Sessions can be word-count based or timed:

  • Word-count: Default 30 words. Presets: short (15), medium (30), long (60), marathon (120). Set with M-x touchtype-set-session-length or a C-u N prefix argument.
  • Timed: Default 60 seconds via M-x touchtype-timed. The timer starts on your first keypress, not when the buffer opens. Idle gaps longer than touchtype-idle-threshold (default: 10 seconds) are excluded from WPM calculations.

6. Demo: Progressive Session   emacs demonstration

A progressive session from start to key unlock.

7. Demo: Narrative Mode   emacs demonstration

Typing a passage from a Project Gutenberg classic.

8. Demo: Code Mode   emacs demonstration

Practicing a Rust code snippet with brackets, operators, and indentation.

9. Error Modes   emacs configuration

touchtype offers three error behaviors, controlled by touchtype-error-mode:

Mode Behavior
Normal Errors highlighted in red but cursor advances. Backspace to correct or continue.
Stop on Letter Cursor won't advance until the correct character is typed. Forces immediate correction.
Stop on Word Cursor advances within a word, but you can't cross the word boundary (space) until all errors in the current word are corrected via backspace.

Normal mode is the default and matches how most typing tests work. Stop-on-letter is the most strict, useful for building accuracy at the expense of speed. Stop-on-word is a middle ground that lets you attempt the whole word before requiring corrections.

10. Session End Summary   emacs statistics

When a session ends, touchtype displays a comprehensive summary with expandable sections:

10.1. Speed and Accuracy

  • Net WPM: (total_chars / 5 - uncorrected_errors) / minutes
  • Gross WPM: (total_chars / 5) / minutes
  • Net/Gross CPM: Characters per minute (wpm * 5)
  • Accuracy: Percentage, ignoring corrected mistakes
  • Raw Accuracy: True first-attempt accuracy, including corrections in the denominator

10.2. Session Metrics

  • Time: Elapsed excluding idle periods (mm:ss)
  • Characters: Total keypresses including errors
  • Corrections: Backspace count
  • Uncorrected Errors: Mistakes left unfixed
  • Consistency: Coefficient of variation of per-line WPM, subtracted from 100%
  • WPM Sparkline: A Unicode bar chart (▁▂▃▄▅▆▇█) showing per-line WPM with min-max range
  • Streak: Current daily practice streak
  • Total Time: Cumulative across all sessions

10.3. Expandable Weak Sections

The summary includes collapsible sections for your weakest letters, bigrams, trigrams, and tetragrams. Press RET on any section header to expand it. Weakest letters show the top 10 by confidence (expandable to all 26). N-gram sections show the top 5, expandable to 50. This tells you exactly what to focus on in your next session.

If you set a new personal best for that mode's net WPM, a banner announces it.

11. Demo: Statistics View   emacs demonstration

The full statistics view with trends and per-letter confidence.

12. Statistics and Persistence   emacs statistics

M-x touchtype-stats-view shows a comprehensive dashboard:

  • Overall summary: Total sessions, total words, average WPM, average accuracy, streak, cumulative practice time.
  • Per-letter confidence chart: All 26 letters sorted weakest-to-strongest with a visual bar chart (20 characters wide, 0.0-1.0 scale).
  • Weakest bigrams: Top 10 (minimum 5 hits) with confidence bars.
  • Weakest trigrams and tetragrams: Top 10 each.
  • WPM trend: Last N sessions with direction indicator (^ improving, v declining, - stable).
  • Accuracy trend: Same format.
  • Session history: Tabular format with date, WPM, accuracy, mode, word count.
  • Personal bests: Best WPM and accuracy per mode.

All statistics persist to ~/.emacs.d/touchtype-stats.el as s-expressions. The file is auto-created on first use.

12.1. Export

M-x touchtype-export writes your data to JSON or CSV. The JSON export includes sessions, per-letter stats with confidence scores, streak, and total practice time. The CSV export is a simple table of sessions (date, WPM, accuracy, mode, words).

13. Customization Reference   emacs configuration

13.1. Training Parameters

Variable Default Description
touchtype-target-wpm 40 Target WPM for confidence scoring
touchtype-unlock-threshold 0.80 Confidence threshold for key unlock
touchtype-session-length 30 Words per session
touchtype-session-duration 60 Seconds for timed sessions
touchtype-error-mode 'normal Error handling behavior
touchtype-idle-threshold 10 Seconds before gap excluded from WPM
touchtype-word-length-min 4 Minimum pseudo-word length
touchtype-word-length-max 8 Maximum pseudo-word length
touchtype-common-words-count 100 Top N words for common-words mode

13.2. Display

Variable Default Description
touchtype-preview-lines 2 Preview lines shown below active
touchtype-pace-caret nil Show ghost cursor at target WPM

13.3. Layout and Persistence

Variable Default Description
touchtype-keyboard-layout 'qwerty Layout (qwerty/dvorak/colemak/workman/custom)
touchtype-custom-unlock-order nil Custom unlock order string
touchtype-stats-file ~/.emacs.d/touchtype-stats.el Statistics file path
touchtype-stats-history-length 20 Sessions retained for trends

13.4. Narrative Mode

Variable Default Description
touchtype-narrative-cache-dir ~/.emacs.d/touchtype/ Cache directory for books
touchtype-narrative-passage-chars 400 Characters per passage
touchtype-narrative-book-list 20 Gutenberg IDs Books to sample from

14. Getting Started   emacs installation

touchtype is on GitHub. It requires Emacs 29.1+ with no external dependencies.

(use-package touchtype
  :ensure (:host github :repo "chiply/touchtype"))

Start with M-x touchtype-progressive for the flagship progressive mode, or M-x touchtype to pick a mode interactively. Prefix any mode command with C-u N to set the session length (e.g., C-u 60 M-x touchtype-progressive for a 60-word session). Check your progress with M-x touchtype-stats-view and export with M-x touchtype-export.