Created
September 26, 2025 22:03
-
-
Save kipawaa/87d81730b8e953b07a68412126aeb969 to your computer and use it in GitHub Desktop.
Vim WPM
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| " Provides a WPM function that returns an estimate of the current typing speed. | |
| " intended use is with the status bar: add this file to `.vim/plugin` and | |
| " `set statusline += WPM: %{WPM()}` in your `.vimrc`. | |
| " WARNING: due to possible initialization issues, the first reported values | |
| " can be wildly inaccurate. | |
| " uses a circular buffer of `num_samples` wordcounts and `num_samples` times | |
| " to sample WPM over (approximately) `num_samples` seconds and update the | |
| " output of the `WPM` function (approximately) every 1s. | |
| " The amount of time to estimate over. | |
| " you can change this, but testing showed that somewhere from 7-10 is best for | |
| " practical estimates. | |
| let s:num_samples = 10 | |
| " use a circular buffer of `num_samples` different wordcounts | |
| let s:word_counts = map(range(s:num_samples), {-> wordcount().words}) | |
| " similarly, use a circular buffer of `num_samples` times | |
| let s:times = map(range(s:num_samples), {-> reltime()}) | |
| " initialize wpm, index and sample_time | |
| let s:wpm = 0 | |
| let s:i = 0 | |
| let s:last_sample_time = reltime() | |
| function WPM() | |
| " Returns the current WPM estimated by the change in wordcount over | |
| " (approximately) the last `num_samples` seconds. | |
| " Output is updated (approximately) every 1 second | |
| " update s:wpm only if it's been at least 1s since the last update | |
| if reltimefloat(reltime(s:last_sample_time)) > 1 | |
| " get change in word count | |
| let l:word_delta = max([wordcount().words - s:word_counts[s:i], 0]) | |
| " get time since last sample | |
| let l:time_delta = reltime(s:times[s:i]) | |
| " set wpm | |
| let s:wpm = (l:word_delta / reltimefloat(l:time_delta)) * 60 | |
| " reset word count and timer | |
| let s:word_counts[s:i] = wordcount().words | |
| let s:times[s:i] = reltime() | |
| " reset last sample time | |
| let s:last_sample_time = reltime() | |
| " increment buffer | |
| let s:i = (s:i + 1) % s:num_samples | |
| endif | |
| " return most recent WPM value | |
| return s:wpm | |
| endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment