Neovimタスクランナーoverseer.nvimの使い方
Neovimのタスクランナープラグインoverseer.nvimの使い方・独自のタスクの追加方法などを解説します。
かなりボリュームのある記事です。
overseer.nvimとは
overseer.nvimはタスクランナーです。プロジェクトに応じたタスクを実行できます。
たとえばpnpm
を使っているプロジェクトであればpackage.json
のscripts
がpnpmで実行できます。
もちろん自分で設定したタスクも実行できます。
非同期に実行できる
:lua vim.fn.system({"sleep","5s"})
のように外部コマンドを実行すると、コマンドが終了するまで操作できません。
overseer.nvimを使えば、UIがブロックされずに非同期で実行できます。
ステータスや履歴が分かる
実行中・実行済みのタスクの履歴を表示できます。
導入方法
各々が使っているプラグインマネージャーでインストールします。
インストール
lazy.nvimだと次のように書いてインストールできます。
依存プラグイン
必須のプラグインはありません。
次のプラグインを入れると、そのプラグインが提供するUIに変化します。
- dressing.nvim:
vim.ui
のUIを変更 - telescope.nvim:選択系のUIを変更
- nvim-notify:通知のUIを変更
最低限の設定
最低限のプラグインの設定はsetup
を呼び出すだけで完了です。
lazy.nvimの場合、setup
の中身はopts
に書くためこの記述は不要です。この書き方について知りたい人は別の記事「lazy.nvimの使い方から起動を爆速にする方法までを解説」を読んでください。
lazy.nvimでの遅延読み込み
lazy.nvimでの遅延読み込みの例も載せておきます。
筆者は2つのコマンドに遅延読み込みを設定しています。各コマンドの詳細は後で解説します。
ビルトインのタスク
デフォルトの設定でもさまざまなビルドツール・タスクランナーを実行できます。
2025年1月時点で対応されているビルトインのツールは次のとおりです。
- make
- shell
- JavaScript関係:npm、pnpm、yarn、bun、deno
- Composer
- cargo
- cargo-make
- Rake
- tox
- mix
- Mage
- task
- just
.vscode/tasks.json
のタスクも実行できます。
pnpm
やyarn
、bun
などパッケージマネージャーはプロジェクトに合わせて表示してくれます。
タスクの実行方法
:OverseerRun
でプロジェクトに応じたタスクの一覧が出ます。
タスクを選んで<CR>
を押すとバックグラウンドで実行してくれます。
完了すると通知がきます。
実行結果の確認
実行完了後、成功ならSUCCESS
、失敗ならFAILURE
のような通知が来ます。
コマンドの出力結果を見たい場合:OverseerToggle
または:OverseerOpen
を実行します。
すると、次のようにタスクの実行履歴が表示されます。
左がタスクの履歴一覧、右が現在カーソルのある行のタスクの実行画面(後述)です。
タスクに依存関係があればネストで表示されます。
ステータスは次の6つです。
- RUNNING:実行中
- PENDING:保留中
- SUCCESS:成功
- FAILURE:失敗
- CANCELED:キャンセル済み
- DISPOSED:廃棄済み
タスク履歴の操作
タスクの履歴画面ではデフォルトでキーマップが設定されており、?
で確認できます。
次の表はよく使いそうなキーマップの一覧です。
key | |
---|---|
?/g? | デフォルトのキーバインドを確認 |
q | ウィンドウを閉じる |
<CR> | アクションメニューを開く |
<C-F> | タスクをfloating windowで開く |
p | タスクのプレビューをトグル |
[ | ウィンドウを狭くする |
] | ウィンドウを広くする |
バッファなのでj
やk
などで普通に移動できます。
アクションメニューの使い方
アクションメニューはターゲットとなるタスクに対して選んだアクションが実行されます。
たとえばタスクを停止するならstop
を選びます。すると、そのタスクのステータスがCANCELED
になります。
disposeとは
dispose
はタスクを停止して履歴から消すというアクションです。依存関係のあるタスクが失敗したとき、その後に実行予定だったタスクはステータスPENDING
(保留)になります。これを消すときに使います。
アクションメニューの呼び出し方
アクションメニューの呼び出しは次のとおりです。
- タスク履歴画面で
<CR>
:OverseerQuickAction
:最新のタスクのアクションメニューを開く:OverseerTaskAction
:タスクを選んでからアクションメニューを開く
タスクを開いて何ができるというんだ
タスクを〇〇で開くというアクションがちょいちょい出てきます。これらはタスクの実行画面を指定した種類のウィンドウで開くアクションです。
タスクの実行画面はNeovimの:terminal
と同じように操作できます。つまり、入力や実行結果のコピーができます。
入力をしたい場合、最初はノーマルモードなのでa
やI
などで挿入モードに切り替えてから入力します。
動画の例ではvertical
(左右分割)で開いています。a
で挿入モード切り替え後、1 2<CR>
を入力すると、3
が出力されています。
overseer.nvimの主要な概念
自作タスクを定義するときに登場する概念を紹介します。
タスクとは
タスクとは、実行される処理のことです。
たとえば、npm build
やmake deploy
などの外部コマンドです。
コンポーネントとは
コンポーネントはフックっぽいやつです。タスクに対し、依存関係の定義や出力・通知などを定義します。
たとえば、「実行結果はquickfixで表示するぞ」といったことを定義するのがコンポーネントの役割です。
テンプレートとは
テンプレートはタスクを組み立てるときに使われるものです。
つまり文字どおりタスクのテンプレートです。
タスクの内容はもちろん、タスクが有効になる条件やリスト化されたときの優先度を定義します。
また、外部コマンドの実行前にLuaの処理を挟むこともできます。
独自のタスクを作成する方法
自分でカスタマイズしたタスクを作成したい場合、いくつか手段があります。
- テンプレートから作成:ほぼこれ
:OverseerBuild
:その場限りのタスクで使う- APIの実行
この記事では一番よく使うであろう「テンプレートから作成」を解説します。
テンプレートの置き場所
自作タスクの元となる「テンプレート」はlua/overseer/template
ディレクトリ以下に置きます。
そして、setup
のtemplates
に次のようにディレクトリ.ファイル名
またはファイル名
を書いて登録します。
ちなみにファイルに分けずAPIでテンプレートを作成する方法もありますが、結局処理が長くなってファイルを分けると思うので割愛します。
テンプレートの書き方
いよいよテンプレートの書き方です。まずは簡単な例をお見せしましょう。name
はタスクの名前です。
テンプレートに必須なのはname
とbuilder
だけです。
builderの書き方
builder
はそのタスクが呼び出されたときの処理です。実行したい外部コマンドをreturnします。returnされるのはoverseer.TaskDefinition
という型です。
cmdとargs
cmd
は「文字列のテーブル」か「文字列」を渡します。引数はargs
に渡します。
echo hello
のように引数を直接cmd
に書きたい場合や、|
といったshellの機能を使ってまとめてコマンドを書きたいケースが出てきます。
そんなときはcmdを文字列にします。
複数のコマンドを使う場合、別々にタスク化して順番に実行させる方法もあります(後述)。
cppのビルドの例
ここからは実際に使える例をお見せします。まずはC++のビルドです。
builder
でNeovimのAPIを呼び出してファル名を取得していますね。condition
で呼び出せるかどうかの条件を決めています。
quickfixで開く
コンパイルエラーになったらどの行が問題かを知りたいところです。
そこで、タスクが失敗したらquickfixで開くというコンポーネントを追加します。
ヘルプ::help on_output_quickfix
defaultコンポーネントとは?
default
はデフォルトのコンポーネント集です。タスク完了後の通知など、細かい設定をユーザーがやらなくてもいいように短くしてくれています。components
がない場合はdefault
になります。
components
をカスタマイズするときはおまじないだと思ってセットで書いておくのが吉です。
詳しく知りたい人向けに後で解説します。
依存関係のある例
C++でビルドした実行ファイルを実行する例です。先ほど定義した「g++でビルドするタスク」を先に実行させます。
dependencies
依存関係のあるタスクではdependencies
コンポーネントを使います。task_names
のテーブルに他のタスクのname
を書きます。
あるいは、task_names
の中に直接タスク内容を書いてもかまいません。
依存タスクを順番に実行したい
task_names
は複数のタスクを登録できます。通常だとテーブル内のタスクを一斉に実行します。
上記のタスクだとsleep 2
、slee 3
、sleep 5
の順で実行が完了するということです。
これをリストどおりに順番に実行したい場合、次のように引数が必要です。
上記のタスクだと「sleep 5
が完了後にsleep 3
を実行開始」というように順番に実行してくれます。
ヘルプ::help dependencies
(名前被りありそうなので:help overseer-components
のほうがいいかも?)
open_output
open_output
コンポーネントを使うと、実行画面を開けます。quickfixと違ってファイルの行に基づいた出力が必要なければopen_output
を使いましょう。
すでに説明しましたが、実行画面はNeovimの:terminal
と同じように操作できます。
ヘルプ::help open_output
Luaの処理だけをタスクとして追加する方法
ここまでは全部外部コマンドでした。ここではLuaの処理をテンプレートとして定義します。
筆者がブログを書くときに使っているテンプレートです。
Luaだけの処理をするときのbuilder
Luaの処理をbuilder
のreturn前に書きます。
cmd
は必須パラメータであるため適当に書きます。空文字だと履歴が分かりづらくなるため、筆者は上記のように登場した変数を表示させています。
優先度の設定
:OverseerRun
で表示されるタスクのリストはpriority
で並び替えられます。数字の小さいほうが優先されます。
特定のディレクトリだけで使うタスク
タスクが特定のディレクトリだけで使う場合、テンプレートのcondition
のdir
で指定します。
他のプラグインとの連携
他のプラグインとの連携例を紹介します。
ステータスプラグインとの連携
lualine.nvimにタスクの実行状況を表示できます。
テンプレートの補完を効かせる
この記事では、---@type
のようなLua Language Serverのアノテーション機能がちょっと登場しました。
今回のreturn {}
のような「require()
を使わないけど補完させたい」というときに便利です。
具体的にはプラグインlazydev.nvimを使って次のように設定しています。
よくある問題とその解決
エンカウント率高めな問題と解決方法もまとめました。
登録したテンプレートがリストに表示されない
setupのtemplates
に追加しているか、名前が正しいかを確認してください。
あるいはテンプレートのcondition
とマッチしているか確認してください。
dependenciesのタスクが順番に実行されない
依存タスクを順番に実行したいで説明したとおり、sequential=true
を追加しましょう。
挿入モードになってしまう
タスク実行時に挿入モードへ切り替わってしまう人がいるかもしれません。
次のようにstartinsert
を定義しているとそうなります。
この設定を削除するか、overseer.nvimのときだけオフにします。
ここで、プラグイン作者stevearcさんの設定を見てみましょう。
変数vim.b.overseer_task
を使ってoverseerかどうか判定していますね。
あえてタスクを失敗させたい
あえてタスクを失敗させるときはfalse
コマンドを使いましょう。Luaの処理で分岐させたいときに便利です。
たとえば筆者は「dependencies
を機械的に作成し、存在しなければタスクを失敗とする」というテンプレートを作りました。
記事を書いているときの画像変換のテンプレートで使っています。
on_exit_set_statusに関するエラーが出る
components
をいじっていると次のようなエラーになることがあります。
これはおそらくdefault
コンポーネントを使っていないからでしょう。次の項目に出てくるon_exit_set_statusを読んでください。
結局default componentとは?
途中で説明を省いたdefaultコンポーネントについて筆者が調べた内容を解説します。
default
コンポーネントは次の5つのコンポーネントの集まりです。
設定を変更する機会が一番ありそうなon_complete_notify
から解説します。
on_complete_notify
on_complete_notify
はタスク終了時の通知設定です。
「defaultコンポーネントを使いたいけど通知はいらない」という場合はstatuses
を空にします。
ヘルプ:;help on_complete_notify
display_duration
display_duration
はタスクの実行時間をどの詳細レベルで表示するか、という設定です。
タスク履歴でL
を押すと詳細レベルが上がります。
たとえば次がデフォルト設定での詳細レベル1です。
次が詳細レベル2です。2秒のタスクでした。
デフォルトコンポーネントでは{ "display_duration", detail_level = 2 }
と設定されているため、実行時間はレベル2以上で開示されます。
詳細レベル3だと、どんなコンポーネント設定だったのかも確認できます。
ヘルプ::help display_duration
on_output_summarize
on_output_summarize
は「詳細レベル2・3のときに表示する出力の行数」を指定します。デフォルトだと4行です。
ヘルプ::help on_output_summarize
on_exit_set_status
on_exit_set_status
は「タスクが成功したと見なす終了コード」を指定します。終了コード0
は指定しなくても成功扱いです。
たとえば、次のタスクは終了コード1が返って失敗します。
次のように設定すると0
だけでなく1
も成功扱いにしてくれます。
default
コンポーネントを使わない場合は必ずon_exit_set_status
を入れましょう。そうしないと次のようにエラーになります。
ヘルプ::help on_exit_set_status
on_complete_dispose
on_complete_dispose
は「タスクが完了して何秒後に履歴を消すか」という設定です。
通常であれば「タスクを実行してから5分経過」「Neovimを終了する」のどちらかで履歴から消えます。
この設定を変えたい場合に活用します。
次の例では、タスク完了の1分後に履歴から消えるように設定しています。
ヘルプ::help on_complete_dispose
公式ドキュメント
まだ紹介しきれていない機能やオプションがたくさんあります。詳しくは公式ドキュメントへどうぞ。
- ヘルプ:
:help overseer
- GitHubリポジトリ:stevearc/overseer.nvim
- ドキュメント集:overseer.nvim/doc
Neovimから離れずにいろいろ作業できるようになり、スーパーキノコを食べた気分です。
ちなみにoverseerは監督者って意味らしいです。