From c5d11882834a3ef762bf311058506ea7c2159fe2 Mon Sep 17 00:00:00 2001 From: Marc Jakobi Date: Wed, 1 Nov 2023 20:58:39 +0100 Subject: [PATCH] feat(dap): default to codelldb server config if codelldb is found --- CHANGELOG.md | 5 ++- doc/rustaceanvim.txt | 53 +++++++++++++++++++++++--- lua/rustaceanvim/config/check.lua | 36 +++++++++++++++--- lua/rustaceanvim/config/init.lua | 29 +++++++++++--- lua/rustaceanvim/config/internal.lua | 56 ++++++++++++++++++++++------ lua/rustaceanvim/dap.lua | 12 ++++-- lua/rustaceanvim/health.lua | 30 ++++++++++----- 7 files changed, 179 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75da2fec..e0f4c3a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## Added +- Auto-create `codelldb` configurations. + ## Fixed +- DAP: Support `codelldb` configurations [[#40](https://github.com/mrcjkb/rustaceanvim/issues/40)]. - DAP: Don't pass in an empty source map table if the `auto_generate_source_map` setting evaluates to `false`. @@ -14,7 +18,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Default rust-analyzer configuration [[#37](https://github.com/mrcjkb/rustaceanvim/issues/37)]. Thanks again, [@eero-lehtinen](https://github.com/eero-lehtinen)! -## Fixed ## [3.3.2] - 2023-10-31 ## Fixed - Cargo workspace reload using removed command [[#36](https://github.com/mrcjkb/rustaceanvim/pull/36)]. diff --git a/doc/rustaceanvim.txt b/doc/rustaceanvim.txt index 95364002..bd11f698 100644 --- a/doc/rustaceanvim.txt +++ b/doc/rustaceanvim.txt @@ -142,16 +142,57 @@ RustaceanDapOpts *RustaceanDapOpts* @field rust-analyzer? table Options to send to rust-analyzer. See: https://rust-analyzer.github.io/manual.html#configuration Fields: ~ - {adapter?} (RustaceanDapAdapterOpts) Options for the debug adapter - {auto_generate_source_map} (fun():boolean|boolean) Whether to auto-generate a source map for the standard library. + {adapter?} (DapExecutableConfig|DapServerConfig|disable|fun():DapExecutableConfig|DapServerConfig|disable) -RustaceanDapAdapterOpts *RustaceanDapAdapterOpts* +disable *disable* + + Type: ~ + false + + +DapCommand *DapCommand* + + Type: ~ + string + + +DapExecutableConfig *DapExecutableConfig* + + Fields: ~ + {type} (dap_adapter_type_executable) The type of debug adapter. + {command} (string) Default: `"lldb-vscode"`. + {args?} (string) Default: unset. + {name?} (string) Default: `"lldb"`. + + +DapServerConfig *DapServerConfig* Fields: ~ - {type?} (string) The type of debug adapter (default: `"executable"`) - {command?} (string) Default: `"lldb-vscode"` - {name?} (string) Default: `"rustaceanvim_lldb"` + {type} (dap_adapter_type_server) The type of debug adapter. + {host?} (string) The host to connect to. + {port} (string) The port to connect to. + {executable} (DapExecutable) The executable to run + {name?} (string) + + +DapExecutable *DapExecutable* + + Fields: ~ + {command} (string) The executable. + {args} (string[]) Its arguments. + + +dap_adapter_type_executable *dap_adapter_type_executable* + + Type: ~ + + + +dap_adapter_type_server *dap_adapter_type_server* + + Type: ~ + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/lua/rustaceanvim/config/check.lua b/lua/rustaceanvim/config/check.lua index eecc27c9..8fefb94c 100644 --- a/lua/rustaceanvim/config/check.lua +++ b/lua/rustaceanvim/config/check.lua @@ -1,5 +1,7 @@ ---@mod rustaceanvim.config.check rustaceanvim configuration check +local types = require('rustaceanvim.types.internal') + local M = {} ---@param path string @@ -75,12 +77,34 @@ function M.validate(cfg) end end local dap = cfg.dap - local adapter = dap.adapter - ok, err = validate('dap.adapter', { - command = { adapter.command, 'string' }, - name = { adapter.name, 'string' }, - type = { adapter.type, 'string' }, - }) + local adapter = types.evaluate(dap.adapter) + if adapter == false then + ok = true + elseif adapter.type == 'executable' then + ---@cast adapter DapExecutableConfig + ok, err = validate('dap.adapter', { + command = { adapter.command, 'string' }, + name = { adapter.name, 'string', true }, + args = { adapter.args, 'table', true }, + }) + elseif adapter.type == 'server' then + ---@cast adapter DapServerConfig + ok, err = validate('dap.adapter', { + command = { adapter.executable, 'table' }, + name = { adapter.name, 'string', true }, + host = { adapter.host, 'string', true }, + port = { adapter.port, 'string' }, + }) + if ok then + ok, err = validate('dap.adapter.executable', { + command = { adapter.executable.command, 'string' }, + args = { adapter.executable.args, 'table', true }, + }) + end + else + ok = false + err = 'dap.adapter: Expected DapExecutableConfig, DapServerConfig or false' + end if not ok then return false, err end diff --git a/lua/rustaceanvim/config/init.lua b/lua/rustaceanvim/config/init.lua index 2fb076e1..444344d0 100644 --- a/lua/rustaceanvim/config/init.lua +++ b/lua/rustaceanvim/config/init.lua @@ -82,12 +82,31 @@ vim.g.rustaceanvim = vim.g.rustaceanvim ---@field rust-analyzer? table Options to send to rust-analyzer. See: https://rust-analyzer.github.io/manual.html#configuration ---@class RustaceanDapOpts ----@field adapter? RustaceanDapAdapterOpts Options for the debug adapter +---@field adapter? DapExecutableConfig | DapServerConfig | disable | fun():(DapExecutableConfig | DapServerConfig | disable) Defaults to a `DapServerConfig` if `codelldb` is detected, and to a `DapExecutableConfig` if `lldb` is detected. Set to `false` to disable. ---@field auto_generate_source_map fun():boolean | boolean Whether to auto-generate a source map for the standard library. ----@class RustaceanDapAdapterOpts ----@field type? string The type of debug adapter (default: `"executable"`) ----@field command? string Default: `"lldb-vscode"` ----@field name? string Default: `"rustaceanvim_lldb"` +---@alias disable false + +---@alias DapCommand string + +---@class DapExecutableConfig +---@field type dap_adapter_type_executable The type of debug adapter. +---@field command string Default: `"lldb-vscode"`. +---@field args? string Default: unset. +---@field name? string Default: `"lldb"`. + +---@class DapServerConfig +---@field type dap_adapter_type_server The type of debug adapter. +---@field host? string The host to connect to. +---@field port string The port to connect to. +---@field executable DapExecutable The executable to run +---@field name? string + +---@class DapExecutable +---@field command string The executable. +---@field args string[] Its arguments. + +---@alias dap_adapter_type_executable "executable" +---@alias dap_adapter_type_server "server" return M diff --git a/lua/rustaceanvim/config/internal.lua b/lua/rustaceanvim/config/internal.lua index fc20a8fc..e8017d9f 100644 --- a/lua/rustaceanvim/config/internal.lua +++ b/lua/rustaceanvim/config/internal.lua @@ -1,4 +1,4 @@ -local vim = vim +local types = require('rustaceanvim.types.internal') local RustaceanConfig @@ -154,7 +154,6 @@ local RustaceanDefaultConfig = { ---@type boolean | fun():boolean Whether to automatically attach the LSP client. ---Defaults to `true` if the `rust-analyzer` executable is found. auto_attach = function() - local types = require('rustaceanvim.types.internal') local cmd = types.evaluate(RustaceanConfig.server.cmd) ---@cast cmd string[] local rs_bin = cmd[1] @@ -181,18 +180,38 @@ local RustaceanDefaultConfig = { --- debugging stuff --- @class RustaceanDapConfig dap = { - --- @class RustaceanDapAdapterConfig - adapter = { - ---@type string - type = 'executable', - ---@type string - command = 'lldb-vscode', - ---@type string - name = 'lldb', - }, + --- @type DapExecutableConfig | DapServerConfig | disable | fun():(DapExecutableConfig | DapServerConfig | disable) + adapter = function() + --- @type DapExecutableConfig | DapServerConfig | disable + local result = false + if vim.fn.executable('codelldb') == 1 then + ---@cast result DapServerConfig + result = { + type = 'server', + host = '127.0.0.1', + port = '${port}', + executable = { + command = 'codelldb', + args = { '--port', '${port}' }, + }, + } + elseif vim.fn.executable('lldb') or vim.fn.executable('lldb-vscode') then + ---@cast result DapExecutableConfig + result = { + type = 'executable', + command = 'lldb-vscode', + name = 'lldb', + } + end + return result + end, --- Whether to auto-generate a source map for the standard library. ---@type boolean | fun():boolean auto_generate_source_map = function() + local adapter = types.evaluate(RustaceanConfig.dap.adapter) + if adapter == false then + return false + end return vim.fn.executable('rustc') == 1 end, }, @@ -207,6 +226,21 @@ end ---@type RustaceanConfig RustaceanConfig = vim.tbl_deep_extend('force', {}, RustaceanDefaultConfig, opts) +-- Override user dap.adapter config in a backward compatible way +if opts.dap and opts.dap.adapter then + local user_adapter = opts.dap.adapter + local default_adapter = types.evaluate(RustaceanConfig.dap.adapter) + if + type(user_adapter) == 'table' + and type(default_adapter) == 'table' + and user_adapter.type == default_adapter.type + then + RustaceanConfig.dap.adapter = vim.tbl_deep_extend('force', default_adapter, user_adapter) + elseif user_adapter ~= nil then + RustaceanConfig.dap.adapter = user_adapter + end +end + local check = require('rustaceanvim.config.check') local ok, err = check.validate(RustaceanConfig) if not ok then diff --git a/lua/rustaceanvim/dap.lua b/lua/rustaceanvim/dap.lua index 5e88c828..76780bda 100644 --- a/lua/rustaceanvim/dap.lua +++ b/lua/rustaceanvim/dap.lua @@ -1,6 +1,6 @@ local config = require('rustaceanvim.config.internal') local compat = require('rustaceanvim.compat') -local Types = require('rustaceanvim.types.internal') +local types = require('rustaceanvim.types.internal') local function scheduled_error(err) vim.schedule(function() @@ -18,10 +18,13 @@ if not ok then } end local dap = require('dap') -if config.dap.adapter ~= false then +local adapter = types.evaluate(config.dap.adapter) +--- @cast adapter DapExecutableConfig | DapServerConfig | boolean + +if adapter ~= false then ---@TODO: Add nvim-dap to lua-ls lint ---@diagnostic disable-next-line: assign-type-mismatch - dap.adapters.rt_lldb = config.dap.adapter + dap.adapters.rt_lldb = adapter end local M = {} @@ -29,6 +32,7 @@ local M = {} ---For the heroes who want to use it ---@param codelldb_path string ---@param liblldb_path string +---@return DapServerConfig function M.get_codelldb_adapter(codelldb_path, liblldb_path) return { type = 'server', @@ -107,7 +111,7 @@ end function M.start(args) vim.notify('Compiling a debug build for debugging. This might take some time...') - local is_generate_source_map_enabled = Types.evaluate(config.dap.auto_generate_source_map) + local is_generate_source_map_enabled = types.evaluate(config.dap.auto_generate_source_map) ---@cast is_generate_source_map_enabled boolean if is_generate_source_map_enabled then generate_source_map() diff --git a/lua/rustaceanvim/health.lua b/lua/rustaceanvim/health.lua index 90146f41..34212b51 100644 --- a/lua/rustaceanvim/health.lua +++ b/lua/rustaceanvim/health.lua @@ -1,10 +1,11 @@ ---@mod rustaceanvim.health Health checks -local health = {} - -local Types = require('rustaceanvim.types.internal') +local types = require('rustaceanvim.types.internal') ---@type RustaceanConfig local config = require('rustaceanvim.config.internal') + +local health = {} + local h = vim.health or require('health') local start = h.start or h.report_start local ok = h.ok or h.report_ok @@ -17,6 +18,9 @@ local warn = h.warn or h.report_warn ---@field url string URL (markdown) ---@field info string Additional information +local adapter = types.evaluate(config.dap.adapter) +---@cast adapter DapExecutableConfig | DapServerConfig | boolean + ---@type LuaDependency[] local lua_dependencies = { { @@ -46,7 +50,7 @@ local external_dependencies = { if not config then return default end - local cmd = Types.evaluate(config.server.cmd) + local cmd = types.evaluate(config.server.cmd) if not cmd or #cmd == 0 then return default end @@ -87,10 +91,18 @@ local external_dependencies = { Called by `:RustLsp explainError`. ]], }, - { - name = config.dap.adapter.name, +} +if adapter ~= false then + table.insert(external_dependencies, { + name = adapter.name or 'debug adapter', get_binaries = function() - return { config.dap.adapter.command } + if adapter.type == 'executable' then + ---@cast adapter DapExecutableConfig + return { 'lldb', adapter.command } + else + ---@cast adapter DapServerConfig + return { 'codelldb', adapter.executable.command } + end end, optional = function() return true @@ -100,8 +112,8 @@ local external_dependencies = { A debug adapter (defaults to: LLDB). Required for debugging features. ]], - }, -} + }) +end ---@param dep LuaDependency local function check_lua_dependency(dep)