Skip to content

Commit

Permalink
feat(dap): support codelldb (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcjkb authored Nov 1, 2023
1 parent d09d787 commit af12503
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 43 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@ All notable changes to this project will be documented in this file.
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`.

## [3.3.3] - 2023-10-31
- 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)].
Expand Down
53 changes: 47 additions & 6 deletions doc/rustaceanvim.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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:
36 changes: 30 additions & 6 deletions lua/rustaceanvim/config/check.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---@mod rustaceanvim.config.check rustaceanvim configuration check

local types = require('rustaceanvim.types.internal')

local M = {}

---@param path string
Expand Down Expand Up @@ -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
Expand Down
29 changes: 24 additions & 5 deletions lua/rustaceanvim/config/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
56 changes: 45 additions & 11 deletions lua/rustaceanvim/config/internal.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local vim = vim
local types = require('rustaceanvim.types.internal')

local RustaceanConfig

Expand Down Expand Up @@ -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]
Expand All @@ -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,
},
Expand All @@ -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
Expand Down
20 changes: 15 additions & 5 deletions lua/rustaceanvim/dap.lua
Original file line number Diff line number Diff line change
@@ -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()
Expand All @@ -18,17 +18,21 @@ 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 = {}

---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',
Expand Down Expand Up @@ -107,7 +111,9 @@ end
function M.start(args)
vim.notify('Compiling a debug build for debugging. This might take some time...')

if Types.evaluate(config.dap.auto_generate_source_map) then
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()
end

Expand Down Expand Up @@ -183,8 +189,12 @@ function M.start(args)
-- https://www.kernel.org/doc/html/latest/admin-guide/LSM/Yama.html
runInTerminal = false,
}
local final_config = is_generate_source_map_enabled
and next(source_map) ~= nil
and vim.tbl_deep_extend('force', dap_config, { sourceMap = source_map })
or dap_config
-- start debugging
dap.run(vim.tbl_deep_extend('force', dap_config, { sourceMap = source_map }))
dap.run(final_config)
end)
end)
end
Expand Down
30 changes: 21 additions & 9 deletions lua/rustaceanvim/health.lua
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 = {
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -87,10 +91,18 @@ local external_dependencies = {
Called by `:RustLsp explainError`.
]],
},
{
name = 'lldb',
}
if adapter ~= false then
table.insert(external_dependencies, {
name = adapter.name or 'debug adapter',
get_binaries = function()
return { 'lldb' }
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
Expand All @@ -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)
Expand Down

0 comments on commit af12503

Please sign in to comment.