public
Created

Starcraft Minor Mode for Emacs

  • Download Gist
starcraft.el
Emacs Lisp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
;; -*- coding: utf-8 -*-
;; starcraft.el -- track user APM (actions per minute) while using Emacs
;;
;; Copyright 2010 by Michael Steder
;; Author: Michael Steder (steder@gmail.com)
;; Created: 2010
;; Version: 1.0
;; Keywords: Actions per minute
;;
;; Inspired by a love of Starcraft and someones offhand comment
;; that their APM at work was significantly higher than their
;; Starcraft APM I started to wonder how I would determine if that
;; were actually true for myself. Being an Emacs user I felt
;; that the obvious way to answer this question was to develop
;; an Emacs mode that tracks emacs commands/actions.
;;
;; This is also an exercise in learning how to extend Emacs with
;; a new minor mode which may be more useful.
;;
;; Usage:
;; Add this file to a directory in emacs load path and add the following
;; to your ~/init.el or ~/.emacs file:
;;
;; (require 'starcraft)
;; (starcraft-mode t)
;;
 
;; Defining a minor mode:
 
(defgroup starcraft nil
"Customization group for starcraft mode"
:package-version '(starcraft . "1.0")
:group 'local
:prefix "starcraft")
 
(defun starcraft-mode-activate ()
(add-hook 'pre-command-hook 'starcraft-count-action)
(starcraft-stopwatch-start)
(starcraft-mode-idle-timer-start)
)
 
(defun starcraft-mode-deactivate ()
(remove-hook 'pre-command-hook 'starcraft-count-action)
(starcraft-mode-idle-timer-stop)
)
 
(define-minor-mode starcraft-mode
"Starcraft mode records actions (Emacs commands) per minute"
:global t
:init-value nil
:lighter " sc"
:keymap nil
:group 'starcraft
 
(if starcraft-mode
(starcraft-mode-activate)
(starcraft-mode-deactivate)
)
)
 
;; Mode hook which counts actions
(defvar starcraft-actions 0)
 
(defun starcraft-count-action ()
"Updates the counter and restarts the stopwatch if necessary (the stopwatch can be stopped by going idle)"
(let ((command real-last-command))
(when command
(setq starcraft-actions (+ starcraft-actions 1))
(when (not starcraft-stopwatch-running)
(starcraft-stopwatch-start))
)
)
)
 
;; stopwatch stuff to track the total non-idle time
(defvar starcraft-start-time 0.0)
(defvar starcraft-elapsed-time 0.0)
(defvar starcraft-stopwatch-running nil)
 
(defun starcraft-stopwatch-stop ()
"Updates the elapsed time and marks the stopwatch as no longer running"
(setq starcraft-elapsed-time (starcraft-stopwatch-read))
(setq starcraft-stopwatch-running nil)
)
 
(defun starcraft-stopwatch-reset ()
"Resets the stopwatch to a time of zero"
(setq starcraft-elapsed-time 0.0)
(setq starcraft-start-time (float-time))
)
 
(defun starcraft-stopwatch-start ()
"Updates the start time and marks the stopwatch as running"
(setq starcraft-stopwatch-running t)
(setq starcraft-start-time (float-time))
)
 
(defun starcraft-stopwatch-read ()
"Returns the current elapsed time"
(if starcraft-stopwatch-running
(setq xtime (+ starcraft-elapsed-time (- (float-time) starcraft-start-time)))
starcraft-elapsed-time))
 
;; idle hooks:
"Currently apm is calculated over the full duration of the emacs session. Idle time
is included and will cause your APM to drop. This may be consistent with the starcraft
meaning of APM and it may not.
 
I'm thinking that when emacs goes idle that I'll report the current APM and stop the stopwatch.
This way your APM doesn't drop drastically when you go to lunch and leave emacs running. The bottomline
is that while in starcraft it makes sense to calculate APM over the course of the entire game
that's because they can assume that you are actively playing the whole time the game is running
and is not paused.
 
Obviously the next step is a webservice that allows you to record your emacs apm and compete
with other emacs users... ;-)
 
"
(defvar starcraft-mode-idle-timer nil)
(defvar starcraft-mode-idle-threshold 10)
 
;; idle callback
(defun starcraft-mode-idle-callback ()
""
(starcraft-stopwatch-stop)
(starcraft-apm)
)
 
(defun starcraft-mode-idle-timer-start ()
""
(when (timerp starcraft-mode-idle-timer)
(cancel-timer starcraft-mode-idle-timer))
(setq starcraft-mode-idle-timer (run-with-idle-timer starcraft-mode-idle-threshold t 'starcraft-mode-idle-callback))
)
 
(defun starcraft-mode-idle-timer-stop ()
""
(when (timerp starcraft-mode-idle-timer)
(cancel-timer starcraft-mode-idle-timer))
)
 
(defun starcraft-apm ()
"The actual apm calculation"
(interactive)
(message
(let ((xtime (starcraft-stopwatch-read)))
(format "APM: %6.2f (%d in %6.2f seconds)"
(/ starcraft-actions xtime) starcraft-actions xtime)
)
)
)
 
(provide 'starcraft)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.