この記事は Emacs Advent Calendar 2017 及び しむどん Advent Calendar 2017 の20日目の記事です。
wakatime
プログラミングの作業時間を自動的に収集してグラフ化してくれます。org-modeなどでタスクの時間計測をしている方も多いと思いますが、wakatimeではファイルがあるディレクトリからリポジトリなどの情報を用いてプロジェクトごとの時間を計測します。
Emacsでwakatimeを使う
wakatimeには各種エディタやブラウザ向けにプラグインが提供されています。Emacsにはwakatime-modeが提供されています。wakatime-mode自体はMELPAからインストールできます。
wakatime-modeの内部ではCLIコマンドのwakatimeを利用しているためそちらもインストールする必要があります。これはPython製のコマンドのためpipでインストールします。
$ pip install wakatime
設定
wakatimeの設定は.wakatime.cfgに記述します。 api_key
にwakatimeのサイトで発行したapi_keyを設定します。
[settings]
debug = false
api_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
hidefilenames = false
exclude =
^COMMIT_EDITMSG$
^TAG_EDITMSG$
^/var/(?!www/).*
^/etc/
include =
.*
offline = true
timeout = 30
あとは.emacs.d/init.elに次を記述します。
(global-wakatime-mode t)
この状態でgitリポジトリ内のファイルを開くとリポジトリをプロジェクトと見立てて時間計測をしてくれます。
ファイルのないものに対して計測を行う
上記であればプロジェクトの時間計測を行ってくれますが、ファイルがないもの(例えばtwittering-modeなど)では集計してくれませんでした。ファイルじゃないバッファの場合もプロジェクトとして計測したかったので、バッファ名をプロジェクトとしてみたてるようにカスタマイズして使っています。
wakatime-client-commandはwakatimeコマンドを生成するための関数です。これを上書きしてファイル名がなかったらバッファ名を用いるように変更しています。
(defun wakatime-client-command (savep)
"Return client command executable and arguments.
Set SAVEP to non-nil for write action."
(format "%s%s--file \'%s\' %s --plugin \"%s/%s\" --time %.2f%s%s"
(if (s-blank wakatime-python-bin) "" (format "%s " wakatime-python-bin))
(if (s-blank wakatime-cli-path) "wakatime " (format "%s " wakatime-cli-path))
(or (buffer-file-name (current-buffer)) (buffer-name))
(if (buffer-file-name (current-buffer)) "" (format " --entity-type app --project \'%s\' " mode-name))
wakatime-user-agent
wakatime-version
(float-time)
(if savep " --write" "")
(if (s-blank wakatime-api-key) "" (format " --key %s" wakatime-api-key))))
(defun wakatime-save ()
"Send save notice to WakaTime."
(wakatime-call t))
(defun wakatime-bind-hooks ()
"Watch for activity in buffers."
(add-hook 'after-save-hook 'wakatime-save nil t)
(add-hook 'auto-save-hook 'wakatime-save nil t)
(add-hook 'first-change-hook 'wakatime-ping nil t))
(defun wakatime-unbind-hooks ()
"Stop watching for activity in buffers."
(remove-hook 'after-save-hook 'wakatime-save t)
(remove-hook 'auto-save-hook 'wakatime-save t)
(remove-hook 'first-change-hook 'wakatime-ping t))