Skip to content

Commit f0a8ae4

Browse files
authored
feat(dap): add support for nvim-dap with haskell-debug-adapter (#180)
<!-- markdownlint-disable --> ###### Description of changes ###### Things done - [x] Tested, as applicable: - [x] Manually - [x] Added plenary specs - [x] Updated [CHANGELOG.md](https://github.com/MrcJkb/haskell-tools.nvim/blob/master/CHANGELOG.md) (if applicable). - [x] Fits [CONTRIBUTING.md](https://github.com/MrcJkb/haskell-tools.nvim/blob/master/CONTRIBUTING.md)
1 parent 8944241 commit f0a8ae4

File tree

32 files changed

+908
-48
lines changed

32 files changed

+908
-48
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.10.0] - 2023-04-17
9+
### Added
10+
- Support for [`nvim-dap`](https://github.com/mfussenegger/nvim-dap)
11+
with [`haskell-debug-adapter`](https://hackage.haskell.org/package/haskell-debug-adapter),
12+
an experimental debug adapter for Haskell.
13+
814
## [1.9.7] - 2023-04-15
915
### Fixed
1016
- Remove some prints.

README.md

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
installation (recommended for better hoogle search performance)
4545
- [`fast-tags`](https://github.com/elaforge/fast-tags)
4646
(for automatic tag generation as a fallback for [`vim.lsp.tagfunc`](https://neovim.io/doc/user/lsp.html#vim.lsp.tagfunc())).
47+
- [`haskell-debug-adapter`](https://github.com/phoityne/haskell-debug-adapter/) and
48+
[`nvim-dap`](https://github.com/mfussenegger/nvim-dap).
4749

4850
## Installation
4951

@@ -97,7 +99,6 @@ To get started quickly with the default setup, add the following to `~/.config/n
9799

98100
```lua
99101
local ht = require('haskell-tools')
100-
local buffer = vim.api.nvim_get_current_buf()
101102
local def_opts = { noremap = true, silent = true, }
102103
ht.start_or_attach {
103104
hls = {
@@ -124,6 +125,10 @@ vim.keymap.set('n', '<leader>rf', function()
124125
ht.repl.toggle(vim.api.nvim_buf_get_name(0))
125126
end, def_opts)
126127
vim.keymap.set('n', '<leader>rq', ht.repl.quit, opts)
128+
129+
-- Detect nvim-dap launch configurations
130+
-- (requires nvim-dap and haskell-debug-adapter)
131+
ht.dap.discover_configurations(bufnr)
127132
```
128133

129134
>**Note**
@@ -137,37 +142,31 @@ to generate a database.
137142
138143
## Features
139144

140-
- [x] Basic haskell-language-server functionality on par with `nvim-lspconfig.hls`
141-
142-
### Beyond `nvim-lspconfig.hls`
143-
144-
- [x] Dynamically load `haskell-language-server` settings per project from JSON files.
145-
- [x] Clean shutdown of language server on exit to prevent corrupted files
145+
- [x] **Set up a `haskell-language-server` client.**
146+
- [x] **Dynamically load `haskell-language-server` settings per project
147+
from JSON files.**
148+
- [x] **Clean shutdown of language server on exit to prevent corrupted files**
146149
([see ghc #14533](https://gitlab.haskell.org/ghc/ghc/-/issues/14533)).
147-
- [x] Automatically adds capabilities for the following plugins, if loaded:
150+
- [x] **Automatically adds capabilities for the following plugins, if loaded:**
148151
- [cmp-nvim-lsp](https://github.com/hrsh7th/cmp-nvim-lsp)
149152
(provides completion sources for [nvim-cmp](https://github.com/hrsh7th/nvim-cmp)).
150153
- [nvim-lsp-selection-range](https://github.com/camilledejoye/nvim-lsp-selection-range)
151154
(Adds haskell-specific [expand selection](https://haskell-language-server.readthedocs.io/en/latest/features.html#selection-range)
152155
support).
153-
- [x] Automatically refreshes code lenses by default,
154-
which haskell-language-server heavily relies on. [Can be disabled.](#advanced-configuration)
156+
- [x] **Automatically refreshes code lenses by default,**
157+
which `haskell-language-server` heavily relies on. [Can be disabled.](#advanced-configuration)
155158

156159
![codeLens](https://user-images.githubusercontent.com/12857160/219738949-c20ed266-3b2d-441e-82fe-faf50f5c582a.gif)
157160

158-
### Beyond haskell-language-server
159-
160-
The below features are not implemented by haskell-language-server.
161-
162-
#### Evaluate all code snippets at once
161+
- [x] **Evaluate all code snippets at once**
163162

164163
`haskell-language-server` can evaluate code snippets using code lenses.
165164
`haskell-tools.nvim` provides a `require('haskell-tools').lsp.buf_eval_all()`
166165
shortcut to evaluate all of them at once.
167166

168167
![evalAll](https://user-images.githubusercontent.com/12857160/219743339-e7b7f4e0-478b-4310-a903-36d0a5564937.gif)
169168

170-
#### Hoogle-search for signature
169+
- [x] **Hoogle-search for signature**
171170

172171
- Search for the type signature under the cursor.
173172
- Falls back to the word under the cursor if the type signature cannot be determined.
@@ -182,14 +181,14 @@ require('haskell-tools').hoogle.hoogle_signature()
182181

183182
![hoogleSig](https://user-images.githubusercontent.com/12857160/219745914-505a8fc8-9cb9-49fe-b763-a0dea2a3420b.gif)
184183

185-
#### Hole-driven development powered by Hoogle
184+
- [x] **Hole-driven development powered by Hoogle**
186185

187186
With the `<C-r>` keymap,
188187
the Hoogle search telescope integration can be used to fill holes.
189188

190189
![hoogleHole](https://user-images.githubusercontent.com/12857160/219751911-f45e4131-afad-47b3-b016-1d341c71c114.gif)
191190

192-
#### GHCi repl
191+
- [x] **GHCi repl**
193192

194193
Start a GHCi repl for the current project / buffer.
195194

@@ -202,11 +201,11 @@ Start a GHCi repl for the current project / buffer.
202201

203202
![repl](https://user-images.githubusercontent.com/12857160/219758588-68f3c06f-5804-4279-b23d-1bdcc050d892.gif)
204203

205-
#### Open project/package files for the current buffer
204+
- [x] **Open project/package files for the current buffer**
206205

207206
![commands](https://user-images.githubusercontent.com/12857160/219760916-06785cd5-f90a-4bb9-9ca8-94edbd655d46.gif)
208207

209-
#### Hover actions
208+
- [x] **Hover actions**
210209

211210
Inspired by [rust-tools.nvim](https://github.com/simrat39/rust-tools.nvim),
212211
this plugin adds the following hover actions (if available):
@@ -225,7 +224,7 @@ users can benefit from syntax highliting of code snippets.
225224

226225
![hoverActions](https://user-images.githubusercontent.com/12857160/219763211-61fc4207-4300-41f2-99c4-6a420cf940f2.gif)
227226

228-
#### Automatically generate tags
227+
- [x] **Automatically generate tags**
229228

230229
On attaching, Neovim's LSP client will set up [`tagfunc`](https://neovim.io/doc/user/lsp.html#vim.lsp.tagfunc())
231230
to query the language server for locations to jump to.
@@ -239,7 +238,20 @@ this plugin will set up `autocmd`s to automatically generate tags:
239238

240239
This feature can be tweaked or disabled in the [advanced configuration](#advanced-configuration).
241240

242-
### Planned
241+
- [x] **Auto-detect `haskell-debug-adapter` configurations**
242+
243+
If the [`nvim-dap`](https://github.com/mfussenegger/nvim-dap) plugin is installed,
244+
you can use `haskell-tools.nvim` to auto-detect [`haskell-debug-adapter`](https://hackage.haskell.org/package/haskell-debug-adapter)
245+
configurations.
246+
247+
![dap](https://user-images.githubusercontent.com/12857160/232348888-4fea5393-d624-417e-b994-6eb44113a3d9.gif)
248+
249+
>**Note**
250+
>
251+
>`haskell-debug-adapter` is an experimental design and implementation of
252+
>a debug adapter for Haskell.
253+
254+
- [ ] **Planned**
243255

244256
For planned features, refer to the [issues](https://github.com/MrcJkb/haskell-tools.nvim/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement).
245257

@@ -312,6 +324,9 @@ require('haskell-tools').start_or_attach {
312324
-- Events to trigger package tag generation
313325
package_events = { 'BufWritePost' },
314326
},
327+
dap = {
328+
cmd = { 'haskell-debug-adapter' },
329+
},
315330
},
316331
hls = { -- LSP client options
317332
-- ...
@@ -427,6 +442,14 @@ iron.setup {
427442
}
428443
```
429444

445+
### Create `haskell-debug-adapter` launch configurations
446+
447+
There are two ways this plugin will detect `haskell-debug-adapter` launch configurations:
448+
449+
1. Automatically, by parsing Cabal or Stack project files.
450+
1. By loading a [`launch.json`](https://github.com/phoityne/hdx4vsc/tree/master/configs)
451+
file in the project root.
452+
430453
### Available functions and commands
431454

432455
For a complete overview, enter `:help haskell-tools` in Neovim.
@@ -517,10 +540,10 @@ ht.project.open_package_yaml()
517540
ht.project.open_package_cabal()
518541

519542
-- Search for files within the current (sub)package
520-
-- `opts`: Optional telescope.nvim find_files options
543+
---@param opts: Optional telescope.nvim `find_files` options
521544
ht.project.telescope_package_files(opts)
522545
-- Live grep within the current (sub)package
523-
-- `opts`: Optional telescope.nvim live_grep options
546+
---@param opts: Optional telescope.nvim `live_grep` options
524547
ht.project.telescope_package_grep(opts)
525548
```
526549

@@ -532,14 +555,14 @@ The following functions depend on [`fast-tags`](https://github.com/elaforge/fast
532555
local ht = require('haskell-tools')
533556

534557
-- Generate tags for the whole project
535-
-- `path`: An optional file path, defaults to the current buffer
536-
-- `opts`: Optional options:
537-
-- `opts.refresh`: Whether to refresh tags
538-
-- if they have already been generated for a project
558+
---@param path: An optional file path, defaults to the current buffer
559+
---@param opts: Optional options:
560+
---@param opts.refresh: Whether to refresh tags
561+
--- if they have already been generated for a project
539562
ht.tags.generate_project_tags(path, opts)
540563

541564
-- Generate tags for the whole project
542-
-- `path`: An optional file path, defaults to the current buffer
565+
---@param path: An optional file path, defaults to the current buffer
543566
ht.tags.generate_package_tags(path)
544567
```
545568

@@ -562,6 +585,20 @@ To load the extension, call
562585
require('telescope').load_extension('ht')
563586
```
564587

588+
#### DAP
589+
590+
```lua
591+
local ht = require('haskell-tools')
592+
593+
---@param bufnr integer The buffer number
594+
---@param opts table? Optional
595+
---@param opts.autodetect: (boolean)
596+
--- Whether to auto-detect launch configurations
597+
---@param opts.settings_file_pattern: (string)
598+
--- File name or pattern to search for. Defaults to 'launch.json'
599+
ht.dap.discover_configurations(bufnr, opts)
600+
```
601+
565602
## Troubleshooting
566603

567604
For a health check, run `:checkhealth haskell-tools`

doc/haskell-tools.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Introduction ·································
55
The haskell-tools module ······································· |haskell-tools|
66
haskell-tools configuration ····························· |haskell-tools.config|
77
haskell-tools LSP client setup ····························· |haskell-tools.lsp|
8+
haskell-tools nvim-dap setup ······························· |haskell-tools.dap|
89
haskell-tools Hoogle search ····························· |haskell-tools.hoogle|
910
haskell-tools GHCi REPL module ···························· |haskell-tools.repl|
1011
haskell-tools Project module ··························· |haskell-tools.project|
@@ -98,6 +99,7 @@ HTOpts *HTOpts*
9899
Fields: ~
99100
{tools} (ToolsOpts) haskell-tools plugin options
100101
{hls} (HaskellLspClientOpts) haskell-language-server client options
102+
{dap} (HTDapOpts) haskell-debug-adapter client options
101103

102104

103105
ToolsOpts *ToolsOpts*
@@ -201,6 +203,15 @@ HaskellLspClientOpts *HaskellLspClientOpts*
201203
|https://haskell-language-server.readthedocs.io/en/latest/configuration.html.|
202204

203205

206+
HTDapOpts *HTDapOpts*
207+
@comment To print all options that are available for your haskell-language-server version, run `haskell-language-server-wrapper generate-default-config`
208+
209+
Fields: ~
210+
{cmd} (string[]) The command to start haskell-debug-adapter with.
211+
{logFile} (string) Log file path for detected configurations.
212+
{logLevel} ("Debug"|"Info"|"Warning"|"Error") The log level for detected configurations.
213+
214+
204215
config.defaults *config.defaults*
205216

206217
Type: ~
@@ -300,6 +311,35 @@ lsp.buf_eval_all({bufnr}) *lsp.buf_eval_all*
300311
(nil)
301312

302313

314+
==============================================================================
315+
haskell-tools nvim-dap setup *haskell-tools.dap*
316+
317+
AddDapConfigOpts *AddDapConfigOpts*
318+
319+
Fields: ~
320+
{autodetect} (boolean) Whether ta automatically detect launch configurations for the project
321+
{settings_file_pattern} (string) File name or pattern to search for. Defaults to 'launch.json'
322+
323+
324+
*dap.discover_configurations*
325+
dap.discover_configurations({bufnr}, {opts})
326+
Discover nvim-dap launch configurations for haskell-debug-adapter.
327+
328+
Parameters: ~
329+
{bufnr} (number|nil) The buffer number
330+
{opts} (AddDapConfigOpts|nil)
331+
332+
Returns: ~
333+
(nil)
334+
335+
336+
dap.setup() *dap.setup*
337+
Setup the DAP module. Called by the haskell-tools setup.
338+
339+
Returns: ~
340+
(nil)
341+
342+
303343
==============================================================================
304344
haskell-tools Hoogle search *haskell-tools.hoogle*
305345

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
formatting = pre-commit-check-for system;
136136
inherit
137137
(checkPkgs)
138-
lints
138+
typecheck
139139
haskell-tools-test
140140
haskell-tools-test-no-hls
141141
haskell-tools-test-no-telescope

lua/haskell-tools/config.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
---@class HTOpts
44
---@field tools ToolsOpts haskell-tools plugin options
55
---@field hls HaskellLspClientOpts haskell-language-server client options
6+
---@field dap HTDapOpts haskell-debug-adapter client options
67

78
---@class ToolsOpts
89
---@field codeLens CodeLensOpts LSP client codeLens options
@@ -66,6 +67,11 @@
6667
---@see https://haskell-language-server.readthedocs.io/en/latest/configuration.html.
6768
---@comment To print all options that are available for your haskell-language-server version, run `haskell-language-server-wrapper generate-default-config`
6869

70+
---@class HTDapOpts
71+
---@field cmd string[] The command to start haskell-debug-adapter with.
72+
---@field logFile string Log file path for detected configurations.
73+
---@field logLevel 'Debug' | 'Info' | 'Warning' | 'Error' The log level for detected configurations.
74+
6975
local ht = require('haskell-tools')
7076
local deps = require('haskell-tools.deps')
7177

@@ -241,6 +247,12 @@ config.defaults = {
241247
},
242248
},
243249
},
250+
---@type HTDapOpts
251+
dap = {
252+
cmd = { 'haskell-debug-adapter' },
253+
logFile = vim.fn.stdpath('data') .. '/haskell-dap.log',
254+
logLevel = 'Warning',
255+
},
244256
}
245257

246258
---@type HTOpts

0 commit comments

Comments
 (0)