🕌

nvim-dapでプログラムにコマンドライン引数を渡す

2023/01/07に公開

概要

年末年始を利用してvimからneovimに移行し、ついでにDebuggerとしてnvim-dapを導入しました。

nvim-dapでデバッグ対象のプログラムにコマンドライン引数を渡したい場合、nvim-dap全体の設定ファイル内を利用する必要があります。
特定プロジェクトのために全体の設定ファイルを変更するのは面倒だったので、プロジェクトルート直下に専用ファイルを置いてコマンドライン引数を記述し、それを設定ファイルから読み込むようにしました。

ただ、今回は完全に個人用途なので妥協していますが、独自ファイルを利用するのはあまり推奨されない気がします。
より良い方法などあればコメントいただけると助かります!

問題

nvim-dapの設定から関連する箇所を以下に抜粋します。
公式のwikiを参考にしたrust用の記述です。

~/.config/nvim/init.lua
dap.configurations.rust = {
  {
    name = "Rust Debug",
    type = "codelldb",
    request = "launch",
    program = function()
      return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
    end,
    cwd = '${workspaceFolder}',
    stopOnEntry = false,
    args = {}
  },
}

argsがコマンドライン引数としてプログラムに渡されるので、例えばargs = {2}と書けばプログラムに2が渡されます。
この方法は以下の問題があります。

  • 特定プログラムのデバッグのために、全体の設定ファイルを編集する必要がある

対応

プロジェクトルート直下に.debug.luaというファイルを用意し、nvim-dapの設定ファイルから読み込むようにしました。

.debug.lua
-- コマンドライン引数として2を渡す
return {
  args = { 2 }
}
~/.config/nvim/init.lua
local function load_workspace_config()
  local path = vim.fn.getcwd() .. '/.debug.lua'
  local ok, config = pcall(dofile, path)
  if not ok then
    config = {}
  end
  return config
end

local workspace_config = load_workspace_config()
dap.configurations.rust = {
  {
    name = "Rust Debug",
    type = "codelldb",
    request = "launch",
    program = function()
      return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
    end,
    cwd = '${workspaceFolder}',
    stopOnEntry = false,
    args = workspace_config.args or {}
  },
}

この方法は以下が嬉しいです。

  • nvim-dap自体の設定ファイルを変更する必要がなく、.debug.luaを編集してneovimを再起動すれば、新しい設定でデバッグできる
  • (やろうと思えば) nvim-dapの各種設定をプロジェクト単位で上書きすることが可能

一方で以下がよくない点です。

  • 独自ファイルをプロジェクトルート直下に用意する必要がある

その他の選択肢

独自ファイルを用意しない方法として以下の方法もありそうでしたが、今回は採用しませんでした。

  • nvim-dapのrunを使った関数を用意し、デバッグ実行時にユーザーが入力する
    • 毎回入力するのはめんどくさそう
  • nvim-dapは部分的にVSCodeのlaunch.jsをサポートしているのでそれを使う
    • argsだけ上書きするといった使い方ができなそうだった
    • 僕がVSCodeを普段利用していない
    • 詳しくは:h load_launchjs

(チーム開発のような場面ではload_launchjsの方がよさそう)

参考

Discussion