denops.vimを使ってポモドーロタイマーを実装してみた
はじめに
denops.vimを使って、Vim/Neovim上でポモドーロテクニックを実践するためのプラグインを作成してみました。
この記事ではdenops-pomodoro.vimの使い方やdenops.vimを使ってプラグインを実装する上でのノウハウなどについて紹介します。
denops.vimとは?
denops.vimとはDenoを使ってVimやNeovimのプラグインを書くためのエコシステムです。
より詳しくは以下の記事を参照いただければと思います。
denops-pomodoro.vimの使い方
必要なもの
- denops.vim (必須)
- vim-airline (任意)
- デスクトップ通知用のコマンド (後述)
コマンド
基本的な機能は以下の3つのコマンドによって提供されます。
PomodoroStart
PomodoroPause
PomodoroResume
PomodoroStart
コマンドでタイマーを開始できます。
タイマーの残り時間が0になると、デスクトップ通知が行われます。
:PomodoroStart
タイマーを一時停止したいときはPomodoroPause
コマンドを実行します。
:PomodoroPause
一時停止したタイマーを再開したいときはPomodoroResume
コマンドを実行します。
:PomodoroResume
PomodoroReset
コマンドを実行するとタイマーを初期状態にリセットできます。
:PomodoroReset
タイマーの残り時間の確認方法
現時点では、以下の2つの手段を用意しています。
PomodoroEchoコマンド
このコマンドを実行すると、Vimのエコーエリアに残り時間が表示されます。
:PomodoroEcho
vim-airlineとの統合
denops-pomodoro.vimはvim-airlineとの統合をサポートしています。
以下は設定例です。
function! s:airline_after_init() abort
let g:airline_section_c .= airline#section#create_right(['pomodoro'])
endfunction
autocmd User AirlineAfterInit call <SID>airline_after_init()
このように設定しておくと、以下の画像のようにタイマーが表示されます。("🍅 15:19"
の部分)
設定
Vimの変数によってタイマーなどの挙動をカスタマイズできます。
変数 | 説明 | デフォルト値 |
---|---|---|
g:pomodoro_work_minutes |
作業時間を分単位で指定します | 25 |
g:pomodoro_short_break_minutes |
小休憩時間を分単位で指定します | 5 |
g:pomodoro_long_break_minutes |
休憩時間を分単位で指定します | 25 |
g:pomodoro_work_sign |
作業時間中にタイマーの横に表示される文字 | "🍅" |
g:pomodoro_short_break_sign |
小休憩時間中にタイマーの横に表示される文字 | "☕" |
g:pomodoro_long_break_sign |
休憩時間中にタイマーの横に表示される文字 | "😴" |
g:pomodoro_pause_sign |
タイマーの一時停止中に表示される文字 | "⏸️" |
デスクトップ通知
デスクトップ通知はdeno-notifier.tsというモジュールを作成して、実装しています。
現時点では、以下のプログラムがサポートされています (正直なところ、MacとWindowsではまだ十分にテストができていないです...😭)
- Linux:
notify-send
- Mac:
osascript
- Windows: Snoretoast
denops.vimに関するノウハウ
main.ts
)の型チェックについて
プラグイン(denopsのプラグインはデフォルトでは型チェックが行われません。
そのため、CIでdeno cache
コマンドを実行し、型チェックをしておくとよいのではないかと思います。
# 省略...
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: denoland/setup-deno@main
with:
deno-version: "1.11.0"
- name: Type check
run: |
deno cache --unstable denops/pomodoro/main.ts
デバッグについて
プラグインをデバッグしたいときはdenops#server#restart()
でdenopsのサーバプロセスを再起動すると便利です。
:call denops#server#restart()
この関数を実行すると各denopsプラグインがリロードされます。
長時間走る処理について
denops.vimではDispatcherで登録したハンドラが一定時間以内に応答を返さなかった場合、タイムアウトエラーが発生するようです。
そのため、長時間処理を走らせたい場合などは、匿名関数でラップする必要がありそうです。
例)
denops.dispatcher = {
async start(): Promise<void> {
if (pomodoro) {
await pomodoro.pause();
}
pomodoro = await createPomodoro(vim);
// 長時間走る処理は匿名関数でラップする!
(async () => {
do {
await Promise.any([
pomodoro.start(),
disposed,
]);
} while (!pomodoro.isPaused());
})();
},
// ...省略...
};
テストについて
denops.vimはDenoを使用しているため、Deno.test
でテストコードを書けます。
そのため、プラグインのエントリポイントであるmain.ts
からはできるだけ主要な処理を分離しておき、個別にテストコードを書けるようにしておくと便利だと思いました。
課題
- デスクトップ通知周りがまだちょっと貧弱...😭
- vim-airline以外のプラグインとも連携したい。
おわりに
今回、denops.vimでプラグインを作ってみて、以下の点がとてもよかったと感じました。
- Denoでプラグインを書けること😍
- 型チェックの安心感
- テストランナ・リンタ・フォーマッタ・LSP等、開発に必要なものの大部分がDenoで提供されている。
- 外部ライブラリの依存管理が楽
- Denoとdenops.vimさえ入ってれば動くので、普通のVimプラグインと同じような感覚で配布できる。
denops.vimはとても便利だと思いますので、もし興味がありましたらぜひ使ってみてください!
Discussion
長時間走る処理について ですが、そもそもタイムアウトを設定する意義が薄いと思い直したので 10 秒から 7 日に伸ばしました。
なるほど! ありがとうございます!!
記事の方にも追記しておきます🙇♂️