{"id":13478250,"url":"https://github.com/max-niederman/ttyper","last_synced_at":"2025-10-22T06:29:29.227Z","repository":{"id":37264523,"uuid":"338940591","full_name":"max-niederman/ttyper","owner":"max-niederman","description":"Terminal-based typing test.","archived":false,"fork":false,"pushed_at":"2025-01-28T09:16:45.000Z","size":2342,"stargazers_count":1227,"open_issues_count":41,"forks_count":86,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-03-25T18:55:06.527Z","etag":null,"topics":["cli","rust","terminal","terminal-based","tui","typing","typing-game","typing-practice"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/max-niederman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["max-niederman"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":null}},"created_at":"2021-02-15T01:30:59.000Z","updated_at":"2025-03-25T15:33:41.000Z","dependencies_parsed_at":"2023-09-29T05:50:18.883Z","dependency_job_id":"ab1f1e9f-0ead-4571-a84f-a52e1871fc37","html_url":"https://github.com/max-niederman/ttyper","commit_stats":{"total_commits":144,"total_committers":24,"mean_commits":6.0,"dds":"0.18055555555555558","last_synced_commit":"0bc580714d7a8be60effea3e289cfbe5af412fae"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-niederman%2Fttyper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-niederman%2Fttyper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-niederman%2Fttyper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/max-niederman%2Fttyper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/max-niederman","download_url":"https://codeload.github.com/max-niederman/ttyper/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245802278,"owners_count":20674627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","rust","terminal","terminal-based","tui","typing","typing-game","typing-practice"],"created_at":"2024-07-31T16:01:54.609Z","updated_at":"2025-10-22T06:29:24.182Z","avatar_url":"https://github.com/max-niederman.png","language":"Rust","readme":"# ttyper\n\n[![Crates.io](https://img.shields.io/crates/v/ttyper)](https://crates.io/crates/ttyper)\n[![GitHub Stars](https://img.shields.io/github/stars/max-niederman/ttyper)](https://github.com/max-niederman/ttyper)\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/max-niederman/ttyper/rust.yml)](https://github.com/max-niederman/ttyper/actions)\n![GitHub commit activity](https://img.shields.io/github/commit-activity/m/max-niederman/ttyper)\n[![Discord](https://img.shields.io/discord/1233267011963060275?logo=discord)](https://discord.gg/3wJyrBsKXu)\n[![License](https://img.shields.io/crates/l/ttyper)](./LICENSE.md)\n\nttyper is a terminal-based typing test built with Rust and Ratatui.\n\n![Recording](./resources/recording.gif)\n\n## chat\n\nIf you're interested in contributing to ttyper, need help with an issue, or just want to hang out, you should join [the development Discord server](https://discord.gg/3wJyrBsKXu).\n\n## installation\n\n### pre-built binaries\n\nPre-built binaries are available for most architectures on [GitHub releases](https://github.com/max-niederman/ttyper/releases). If your system is not supported or you have another problem, feel free to open an issue.\n\n### cargo\n\n```bash\ncargo install ttyper\n```\n\n### arch linux\n\n```bash\npacman -S ttyper\n```\n\n### nix\n\n```bash\nnix-env -iA nixpkgs.ttyper # or nixos.ttyper on NixOS\n```\n\n### scoop\n\n```bash\nscoop install ttyper\n```\n\n## usage\n\nFor usage instructions, you can run `ttyper --help`:\n\n```\nttyper 1.5.0\nTerminal-based typing test.\n\nUSAGE:\n    ttyper [FLAGS] [OPTIONS] [contents]\n\nFLAGS:\n    -d, --debug             \n    -h, --help              Prints help information\n        --list-languages    List installed languages\n        --no-backtrack      Disable backtracking to completed words\n        --sudden-death      Enable sudden death mode to restart on first error\n    -V, --version           Prints version information\n\nOPTIONS:\n    -c, --config \u003cconfig\u003e                  Use config file\n    -l, --language \u003clanguage\u003e              Specify test language\n        --language-file \u003clanguage-file\u003e    Specify test language in file\n    -w, --words \u003cwords\u003e                    Specify word count [default: 50]\n\nARGS:\n    \u003ccontents\u003e\n```\n\n### examples\n\n| command                        |                             test contents |\n| :----------------------------- | ----------------------------------------: |\n| `ttyper`                       |   50 of the 200 most common english words |\n| `ttyper -w 100`                |  100 of the 200 most common English words |\n| `ttyper -w 100 -l english1000` | 100 of the 1000 most common English words |\n| `ttyper --language-file lang`  |      50 random words from the file `lang` |\n| `ttyper text.txt`              |  contents of `text.txt` split at newlines |\n\n## languages\n\nThe following languages are available by default:\n\n| name                 |                         description |\n| :------------------- | ----------------------------------: |\n| `c`                  |          The C programming language |\n| `csharp`             |         The C# programming language |\n| `english100`         |       100 most common English words |\n| `english200`         |       200 most common English words |\n| `english1000`        |      1000 most common English words |\n| `english-advanced`   |              Advanced English words |\n| `english-pirate`     |       50 pirate speak English words |\n| `french100`          |        100 most common French words |\n| `french200`          |        200 most common French words |\n| `french1000`         |       1000 most common French words |\n| `german`             |        207 most common German words |\n| `german1000`         |       1000 most common German words |\n| `german10000`        |      10000 most common German words |\n| `go`                 |         The Go programming language |\n| `html`               |           HyperText Markup Language |\n| `java`               |       The Java programming language |\n| `javascript`         | The Javascript programming language |\n| `norwegian`          |     200 most common Norwegian words |\n| `php`                |        The PHP programming language |\n| `portuguese`         |    100 most common Portuguese words |\n| `portuguese200`      |    200 most common Portuguese words |\n| `portuguese1000`     |   1000 most common Portuguese words |\n| `portuguese-advanced`|           Advanced Portuguese words |\n| `python`             |     The Python programming language |\n| `qt`                 |                The QT GUI framework |\n| `ruby`               |       The Ruby programming language |\n| `rust`               |       The Rust programming language |\n| `spanish`            |       100 most common Spanish words |\n| `ukrainian`          |     100 most common Ukrainian words |\n\nAdditional languages can be added by creating a file in `TTYPER_CONFIG_DIR/language` with a word on each line. On Linux, the config directory is `$HOME/.config/ttyper`; on Windows, it's `C:\\Users\\user\\AppData\\Roaming\\ttyper`; and on macOS it's `$HOME/Library/Application Support/ttyper`.\n\n## config\n\nConfiguration is specified by the `config.toml` file in the config directory (e.g. `$HOME/.config/ttyper/config.toml`).\n\nThe default values with explanations are below:\n\n```toml\n# the language used when one is not manually specified\ndefault_language = \"english200\"\n\n[theme]\n# default style (this includes empty cells)\ndefault = \"none\"\n\n# title text styling\ntitle = \"white;bold\"\n\n## test styles ##\n\n# input box border\ninput_border = \"cyan\"\n# prompt box border\nprompt_border = \"green\"\n\n# border type\nborder_type = \"rounded\"\n\n# correctly typed words\nprompt_correct = \"green\"\n# incorrectly typed words\nprompt_incorrect = \"red\"\n# untyped words\nprompt_untyped = \"gray\"\n\n# correctly typed letters in current word\nprompt_current_correct = \"green;bold\"\n# incorrectly typed letters in current word\nprompt_current_incorrect = \"red;bold\"\n# untyped letters in current word\nprompt_current_untyped = \"blue;bold\"\n\n# cursor character\nprompt_cursor = \"none;underlined\"\n\n## results styles ##\n\n# overview text\nresults_overview = \"cyan;bold\"\n# overview border\nresults_overview_border = \"cyan\"\n\n# worst keys text\nresults_worst_keys = \"cyan;bold\"\n# worst keys border\nresults_worst_keys_border = \"cyan\"\n\n# results chart default (includes plotted data)\nresults_chart = \"cyan\"\n# results chart x-axis label\nresults_chart_x = \"cyan\"\n# results chart y-axis label\nresults_chart_y = \"gray;italic\"\n\n# restart/quit prompt in results ui\nresults_restart_prompt = \"gray;italic\"\n```\n\n### style format\n\nThe configuration uses a custom style format which can specify most [ANSI escape styling codes](\u003chttps://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters\u003e), encoded as a string.\n\nStyles begin with the color specification, which can be a single color (the foreground), or two colors seperated by a colon (the foreground and background). Colors can be one of sixteen specified by your terminal, a 24-bit hex color code, `none`, or `reset`.\n\nAfter the colors, you can optionally specify modifiers seperated by a semicolon. A list of modifiers is below:\n\n- `bold`\n- `crossed_out`\n- `dim`\n- `hidden`\n- `italic`\n- `rapid_blink`\n- `slow_blink`\n- `reversed`\n- `underlined`\n\nSome examples:\n\n- `blue:white;italic` specifies italic blue text on a white background.\n- `none;italic;bold;underlined` specifies underlined, italicized, and bolded text with no set color or background.\n- `00ff00:000000` specifies text of color `#00ff00` (pure green) on a background of `#000000` (pure black).\n\nIn [extended Backus-Naur form](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form):\n\n```ebnf\nstyle     = colors, { \";\", modifier }, [ \";\" ] ;\n\ncolors    = color, [ \":\", color ] ;\ncolor     = \"none\"\n          | \"reset\"\n          | \"black\"\n          | \"white\"\n          | \"red\"\n          | \"green\"\n          | \"yellow\"\n          | \"blue\"\n          | \"magenta\"\n          | \"cyan\"\n          | \"gray\"\n          | \"darkgray\"\n          | \"lightred\"\n          | \"lightgreen\"\n          | \"lightyellow\"\n          | \"lightblue\"\n          | \"lightmagenta\"\n          | \"lightcyan\"\n          | 6 * hex digit ;\nhex digit = ? hexadecimal digit; 1-9, a-z, and A-Z ? ;\n\nmodifier  = \"bold\"\n          | \"crossed_out\"\n          | \"dim\"\n          | \"hidden\"\n          | \"italic\"\n          | \"rapid_blink\"\n          | \"slow_blink\"\n          | \"reversed\"\n          | \"underlined\" ;\n```\n\n### border types\n\nThe following border types are supported in the config file.\n\n- `plain`\n- `rounded` (default)\n- `double`\n- `thick`\n- `quadrantinside`\n- `quadrantoutside`\n\nIf you're familiar with [serde](https://serde.rs), you can also read [the deserialization code](./src/config.rs).\n","funding_links":["https://github.com/sponsors/max-niederman"],"categories":["Rust","cli","💻 Apps","\u003ca name=\"typing\"\u003e\u003c/a\u003eTyping test and practice","Table of Contents"],"sub_categories":["🚀 Productivity and Utilities"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax-niederman%2Fttyper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmax-niederman%2Fttyper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmax-niederman%2Fttyper/lists"}