Skip to content

Commit ac58e4c

Browse files
authored
Merge pull request #128 from dakra/125-add-apm
Add new measurement: Actions Per Minute, Actions Per Character
2 parents 0e22fe4 + d9354c7 commit ac58e4c

1 file changed

Lines changed: 31 additions & 9 deletions

File tree

speed-type.el

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ Net WPM: %d
382382
Net CPM: %d
383383
Gross WPM: %d
384384
Gross CPM: %d
385+
APM: %d
386+
APC: %.3f
385387
Accuracy: %.2f%%
386388
Total time: %s
387389
Total chars: %d
@@ -401,6 +403,8 @@ Note: 'nil' values are excluded from the calculations.
401403
| Net CPM: | %7d | %7d | %7d | %7d | %7d |
402404
| Gross WPM: | %7d | %7d | %7d | %7d | %7d |
403405
| Gross CPM: | %7d | %7d | %7d | %7d | %7d |
406+
| APM: | %7d | %7d | %7d | %7d | %7d |
407+
| APC: | %7.3f | %7.3f | %7.3f | %7.3f | %7.3f |
404408
| Accuracy: | %6.2f%% | %6.2f%% | %6.2f%% | %6.2f%% | %6.2f%% |
405409
| Total time: | %6.1fs | %6.1fs | %6.1fs | %6.1fs | %6.1fs |
406410
| Total chars: | %7d | %7d | %7d | %7d | %7d |
@@ -464,7 +468,9 @@ It's a property-only-change when modified-tick is the same in before and after."
464468
It's used in the before-change-hook.")
465469
(defvar-local speed-type--buffer nil)
466470
(defvar-local speed-type--content-buffer nil)
467-
(defvar-local speed-type--entries 0 "Counts the number of keystrokes typed.")
471+
(defvar-local speed-type--entries 0 "Count the number of inserted characters typed (but each only ones).")
472+
(defvar-local speed-type--actions 0 "Count the number of key typed (which are bound to a command).")
473+
468474
(defvar-local speed-type--errors 0 "Counts mistyped characters.")
469475
(defvar-local speed-type--current-correct-streak 0 "Tracks the correct streak since last error or beginning.")
470476
(defvar-local speed-type--best-correct-streak 0 "The highest count of consecutively correct typed characters.")
@@ -532,7 +538,7 @@ Computes words-per-minute as (ENTRIES/5) / (SECONDS/60)."
532538
(round (speed-type--/ (/ entries 5.0)
533539
(speed-type--seconds-to-minutes seconds))))
534540

535-
(defun speed-type--gross-cpm (entries seconds)
541+
(defun speed-type--gross-Xpm (entries seconds)
536542
"Return gross characters-per-minute.
537543
538544
Computes characters-per-minute as ENTRIES / (SECONDS/60)."
@@ -555,7 +561,7 @@ UNCORRECTED-ERRORS = ERRORS - CORRECTIONS
555561
Computes net characters-per-minute as:
556562
UNCORRECTED-ERRORS = ERRORS - CORRECTIONS
557563
(ENTRIES - UNCORRECTED-ERRORS) / (SECONDS/60)."
558-
(let ((net-cpm (round (- (speed-type--gross-cpm entries seconds)
564+
(let ((net-cpm (round (- (speed-type--gross-Xpm entries seconds)
559565
(speed-type--/ (- errors corrections)
560566
(speed-type--seconds-to-minutes seconds))))))
561567
(if (> 0 net-cpm) 0 net-cpm)))
@@ -597,6 +603,7 @@ If the structure is changed, SPEED-TYPE-FILE-FORMAT-VERSION must
597603
be incremented and a migration must be coded in
598604
SPEED-TYPE-MAYBE-UPGRADE-FILE-FORMAT."
599605
(let ((entries speed-type--entries)
606+
(actions speed-type--actions)
600607
(errors speed-type--errors)
601608
(corrections speed-type--corrections)
602609
(seconds (speed-type--elapsed-time speed-type--time-register)))
@@ -612,7 +619,9 @@ SPEED-TYPE-MAYBE-UPGRADE-FILE-FORMAT."
612619
(cons 'speed-type--elapsed-time seconds)
613620
(cons 'speed-type--time-register speed-type--time-register)
614621
(cons 'speed-type--gross-wpm (speed-type--gross-wpm entries seconds))
615-
(cons 'speed-type--gross-cpm (speed-type--gross-cpm entries seconds))
622+
(cons 'speed-type--gross-cpm (speed-type--gross-Xpm entries seconds))
623+
(cons 'speed-type--gross-apm (speed-type--gross-Xpm actions seconds))
624+
(cons 'speed-type--apc (speed-type--/ (float actions) entries))
616625
(cons 'speed-type--net-wpm (speed-type--net-wpm entries errors corrections seconds))
617626
(cons 'speed-type--net-cpm (speed-type--net-cpm entries errors corrections seconds))
618627
(cons 'speed-type--accuracy (speed-type--accuracy entries (- entries errors) corrections))
@@ -883,14 +892,16 @@ Additional provide length and skill-value."
883892
(speed-type--calc-median 'speed-type--net-cpm stats) (speed-type--calc-avg 'speed-type--net-cpm stats) (speed-type--calc-standard-deviation 'speed-type--net-cpm stats) (speed-type--calc-min 'speed-type--net-cpm stats) (speed-type--calc-max 'speed-type--net-cpm stats)
884893
median-gross-wpm avg-gross-wpm (speed-type--calc-standard-deviation 'speed-type--gross-wpm stats) min-gross-wpm max-gross-wpm
885894
(speed-type--calc-median 'speed-type--gross-cpm stats) (speed-type--calc-avg 'speed-type--gross-cpm stats) (speed-type--calc-standard-deviation 'speed-type--gross-cpm stats) (speed-type--calc-min 'speed-type--gross-cpm stats) (speed-type--calc-max 'speed-type--gross-cpm stats)
895+
(speed-type--calc-median 'speed-type--gross-apm stats) (speed-type--calc-avg 'speed-type--gross-apm stats) (speed-type--calc-standard-deviation 'speed-type--gross-apm stats) (speed-type--calc-min 'speed-type--gross-apm stats) (speed-type--calc-max 'speed-type--gross-apm stats)
896+
(speed-type--calc-median 'speed-type--apc stats) (speed-type--calc-avg 'speed-type--apc stats) (speed-type--calc-standard-deviation 'speed-type--apc stats) (speed-type--calc-min 'speed-type--apc stats) (speed-type--calc-max 'speed-type--apc stats)
886897
(speed-type--calc-median 'speed-type--accuracy stats) (speed-type--calc-avg 'speed-type--accuracy stats) (speed-type--calc-standard-deviation 'speed-type--accuracy stats) (speed-type--calc-min 'speed-type--accuracy stats) (speed-type--calc-max 'speed-type--accuracy stats)
887898
(speed-type--calc-median 'speed-type--elapsed-time stats) (speed-type--calc-avg 'speed-type--elapsed-time stats) (speed-type--calc-standard-deviation 'speed-type--elapsed-time stats) (speed-type--calc-min 'speed-type--elapsed-time stats) (speed-type--calc-max 'speed-type--elapsed-time stats)
888899
(speed-type--calc-median 'speed-type--entries stats) (speed-type--calc-avg 'speed-type--entries stats) (speed-type--calc-standard-deviation 'speed-type--entries stats) (speed-type--calc-min 'speed-type--entries stats) (speed-type--calc-max 'speed-type--entries stats)
889900
(speed-type--calc-median 'speed-type--corrections stats) (speed-type--calc-avg 'speed-type--corrections stats) (speed-type--calc-standard-deviation 'speed-type--corrections stats) (speed-type--calc-min 'speed-type--corrections stats) (speed-type--calc-max 'speed-type--corrections stats)
890901
(speed-type--calc-median 'speed-type--best-correct-streak stats) (speed-type--calc-avg 'speed-type--best-correct-streak stats) (speed-type--calc-standard-deviation 'speed-type--best-correct-streak stats) (speed-type--calc-min 'speed-type--best-correct-streak stats) (speed-type--calc-max 'speed-type--best-correct-streak stats)
891902
(speed-type--calc-median 'speed-type--errors stats) (speed-type--calc-avg 'speed-type--errors stats) (speed-type--calc-standard-deviation 'speed-type--errors stats) (speed-type--calc-min 'speed-type--errors stats) (speed-type--calc-max 'speed-type--errors stats)
892903
(speed-type--calc-median 'speed-type--non-consecutive-errors stats) (speed-type--calc-avg 'speed-type--non-consecutive-errors stats) (speed-type--calc-standard-deviation 'speed-type--non-consecutive-errors stats) (speed-type--calc-min 'speed-type--non-consecutive-errors stats) (speed-type--calc-max 'speed-type--non-consecutive-errors stats)))
893-
'(0 "empty" "empty" "empty" "empty" "empty" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)))
904+
'(0 "empty" "empty" "empty" "empty" "empty" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)))
894905

895906
(defun speed-type-display-menu ()
896907
"Display and set controls the user can make in this speed-type session.
@@ -1310,15 +1321,17 @@ Expects CURRENT-BUFFER to be buffer of speed-type session."
13101321
(setq speed-type--last-changed-text (buffer-substring start end)
13111322
speed-type--last-modified-tick (buffer-chars-modified-tick)))
13121323

1313-
(defun speed-type-format-stats (entries errors non-consecutive-errors corrections best-correct-streak seconds)
1324+
(defun speed-type-format-stats (entries actions errors non-consecutive-errors corrections best-correct-streak seconds)
13141325
"Format statistic data using given arguments:
1315-
ENTRIES ERRORS NON-CONSECUTIVE-ERRORS CORRECTIONS BEST-CORRECT-STREAK SECONDS."
1326+
ENTRIES ACTIONS ERRORS NON-CONSECUTIVE-ERRORS CORRECTIONS BEST-CORRECT-STREAK SECONDS."
13161327
(format speed-type-stats-format
13171328
(speed-type--skill (speed-type--net-wpm entries errors corrections seconds))
13181329
(speed-type--net-wpm entries errors corrections seconds)
13191330
(speed-type--net-cpm entries errors corrections seconds)
13201331
(speed-type--gross-wpm entries seconds)
1321-
(speed-type--gross-cpm entries seconds)
1332+
(speed-type--gross-Xpm entries seconds)
1333+
(speed-type--gross-Xpm actions seconds)
1334+
(speed-type--/ (float actions) entries)
13221335
(speed-type--accuracy entries (- entries errors) corrections)
13231336
(format-seconds "%M %z%S" seconds)
13241337
entries
@@ -1332,6 +1345,7 @@ ENTRIES ERRORS NON-CONSECUTIVE-ERRORS CORRECTIONS BEST-CORRECT-STREAK SECONDS."
13321345
"Remove typing hooks from the buffer and print statistics."
13331346
(interactive)
13341347
(unless (derived-mode-p 'speed-type-mode) (user-error "Not in a speed-type buffer: cannot complete session"))
1348+
(remove-hook 'pre-command-hook #'speed-type--action-counter-hook t)
13351349
(remove-hook 'post-command-hook #'speed-type-preview-logger t)
13361350
(speed-type-finish-animation speed-type--buffer)
13371351
(remove-hook 'before-change-functions #'speed-type--before-change t)
@@ -1349,6 +1363,7 @@ ENTRIES ERRORS NON-CONSECUTIVE-ERRORS CORRECTIONS BEST-CORRECT-STREAK SECONDS."
13491363
(when speed-type--author (insert (propertize (format ", by %s" speed-type--author) 'face 'italic)))
13501364
(insert (speed-type-format-stats
13511365
speed-type--entries
1366+
speed-type--actions
13521367
speed-type--errors
13531368
speed-type--non-consecutive-errors
13541369
speed-type--corrections
@@ -1362,6 +1377,7 @@ ENTRIES ERRORS NON-CONSECUTIVE-ERRORS CORRECTIONS BEST-CORRECT-STREAK SECONDS."
13621377
(not (boundp 'speed-type--preview-buffer))
13631378
(null speed-type--preview-buffer)
13641379
(null speed-type--time-register)
1380+
(null speed-type--idle-pause-timer)
13651381
(member this-command '(self-insert-command speed-type-code-ret speed-type-code-tab))
13661382
(null this-command))
13671383
(let ((new-last-pos (point)))
@@ -1463,7 +1479,7 @@ END is a point where the check stops to scan for diff."
14631479
(when non-consecutive-error-p (cl-incf speed-type--non-consecutive-errors))
14641480
(add-text-properties pos (1+ pos) '(speed-type-char-status error))
14651481
(speed-type-add-extra-words (+ (or speed-type-add-extra-words-on-error 0)
1466-
(or (and non-consecutive-error-p speed-type-add-extra-words-on-non-consecutive-errors) 0)))))
1482+
(or (and non-consecutive-error-p speed-type-add-extra-words-on-non-consecutive-errors) 0)))))
14671483
(cl-incf speed-type--entries)
14681484
(let ((f (if is-same 'speed-type-correct-face (if non-consecutive-error-p 'speed-type-error-face 'speed-type-consecutive-error-face))))
14691485
(let ((overlay (make-overlay pos (1+ pos))))
@@ -1745,6 +1761,7 @@ CALLBACK is called when the setup process has been completed."
17451761
(goto-char 0)
17461762
(add-hook 'before-change-functions #'speed-type--before-change nil t)
17471763
(add-hook 'post-command-hook #'speed-type-preview-logger nil t)
1764+
(add-hook 'pre-command-hook #'speed-type--action-counter-hook nil t)
17481765
(add-hook 'after-change-functions #'speed-type--change nil t)
17491766
(add-hook 'kill-buffer-hook #'speed-type--kill-buffer-hook nil t)
17501767
(setq-local post-self-insert-hook nil)
@@ -1828,6 +1845,11 @@ START and END are supplied to `insert-buffer-substring'."
18281845
(setq-local speed-type--content-buffer nil)
18291846
(kill-buffer cbuf))))
18301847

1848+
(defun speed-type--action-counter-hook ()
1849+
"Count actions on `pre-command-hook'."
1850+
(unless (or (null speed-type--time-register) (null speed-type--idle-pause-timer) (null this-command))
1851+
(setq speed-type--actions (+ speed-type--actions 1))))
1852+
18311853
(cl-defstruct speed-type-transform-context
18321854
"Define what context-variable are present when running transform-hook.
18331855

0 commit comments

Comments
 (0)