Skip to content

Commit 03d418c

Browse files
jvanbrueggejhrcekfendor
authored
hls-notes-plugin: Initial implementation (#4126)
* hls-notes-plugin: Initial implementation * hls-notes-plugin: add to feature list and plugin table * hls-notes-plugin: Add more documentation comments * hls-notes-plugin: Fix tests after #3846, add CI job * hls-notes-plugin: Address review comments * hls-notes-plugin: Allow Note definition within single line comments * hls-notes-plugin: Improve "Note not found" error message * hls-notes-plugin: Allow single line notes to be indented * treewide: Add missing underscores to note definitions * hls-notes-plugin: Wait until HLS is done in tests * hls-notes-plugin: Fix tests on windows The regex did not allow windows line endings in note definitions --------- Co-authored-by: Jan Hrcek <[email protected]> Co-authored-by: fendor <[email protected]>
1 parent 306dbc6 commit 03d418c

File tree

23 files changed

+411
-40
lines changed

23 files changed

+411
-40
lines changed

.github/workflows/test.yml

+40-37
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ jobs:
7474
- ubuntu-latest
7575
- macOS-latest
7676
- windows-latest
77-
test:
77+
test:
7878
- true
7979
- false
8080
exclude:
@@ -112,140 +112,143 @@ jobs:
112112
113113
- if: matrix.test
114114
name: Test hls-graph
115-
run: cabal test hls-graph
115+
run: cabal test hls-graph
116116

117117
- if: needs.pre_job.outputs.should_skip_ghcide != 'true' && matrix.test
118118
name: Test ghcide
119119
# run the tests without parallelism to avoid running out of memory
120-
run: cabal test ghcide || cabal test ghcide
120+
run: cabal test ghcide || cabal test ghcide
121121

122122
- if: matrix.test
123123
name: Test hls-plugin-api
124-
run: cabal test hls-plugin-api || cabal test hls-plugin-api
124+
run: cabal test hls-plugin-api || cabal test hls-plugin-api
125125

126126
- if: matrix.test
127127
name: Test func-test suite
128128
env:
129129
HLS_TEST_EXE: hls
130130
HLS_WRAPPER_TEST_EXE: hls-wrapper
131-
run: cabal test func-test || cabal test func-test
131+
run: cabal test func-test || cabal test func-test
132132

133133
- if: matrix.test
134134
name: Test wrapper-test suite
135135
env:
136136
HLS_TEST_EXE: hls
137137
HLS_WRAPPER_TEST_EXE: hls-wrapper
138-
run: cabal test wrapper-test
138+
run: cabal test wrapper-test
139139

140140
- if: matrix.test
141141
name: Test hls-refactor-plugin
142-
run: cabal test hls-refactor-plugin-tests || cabal test hls-refactor-plugin-tests
142+
run: cabal test hls-refactor-plugin-tests || cabal test hls-refactor-plugin-tests
143143

144-
- if: matrix.test
144+
- if: matrix.test
145145
name: Test hls-floskell-plugin
146-
run: cabal test hls-floskell-plugin-tests || cabal test hls-floskell-plugin-tests
146+
run: cabal test hls-floskell-plugin-tests || cabal test hls-floskell-plugin-tests
147147

148148
- if: matrix.test
149149
name: Test hls-class-plugin
150-
run: cabal test hls-class-plugin-tests || cabal test hls-class-plugin-tests
150+
run: cabal test hls-class-plugin-tests || cabal test hls-class-plugin-tests
151151

152152
- if: matrix.test
153153
name: Test hls-pragmas-plugin
154-
run: cabal test hls-pragmas-plugin-tests || cabal test hls-pragmas-plugin-tests
154+
run: cabal test hls-pragmas-plugin-tests || cabal test hls-pragmas-plugin-tests
155155

156156
- if: matrix.test
157157
name: Test hls-eval-plugin
158-
run: cabal test hls-eval-plugin-tests || cabal test hls-eval-plugin-tests
158+
run: cabal test hls-eval-plugin-tests || cabal test hls-eval-plugin-tests
159159

160160
- if: matrix.test
161161
name: Test hls-splice-plugin
162-
run: cabal test hls-splice-plugin-tests || cabal test hls-splice-plugin-tests
162+
run: cabal test hls-splice-plugin-tests || cabal test hls-splice-plugin-tests
163163

164164
- if: matrix.test && matrix.ghc != '9.2'
165165
name: Test hls-stan-plugin
166-
run: cabal test hls-stan-plugin-tests || cabal test hls-stan-plugin-tests
166+
run: cabal test hls-stan-plugin-tests || cabal test hls-stan-plugin-tests
167167

168168
- if: matrix.test
169169
name: Test hls-stylish-haskell-plugin
170-
run: cabal test hls-stylish-haskell-plugin-tests || cabal test hls-stylish-haskell-plugin-tests
170+
run: cabal test hls-stylish-haskell-plugin-tests || cabal test hls-stylish-haskell-plugin-tests
171171

172-
- if: matrix.test
172+
- if: matrix.test
173173
name: Test hls-ormolu-plugin
174-
run: cabal test hls-ormolu-plugin-tests || cabal test hls-ormolu-plugin-tests
174+
run: cabal test hls-ormolu-plugin-tests || cabal test hls-ormolu-plugin-tests
175175

176-
- if: matrix.test
176+
- if: matrix.test
177177
name: Test hls-fourmolu-plugin
178-
run: cabal test hls-fourmolu-plugin-tests || cabal test hls-fourmolu-plugin-tests
178+
run: cabal test hls-fourmolu-plugin-tests || cabal test hls-fourmolu-plugin-tests
179179

180180
- if: matrix.test
181181
name: Test hls-explicit-imports-plugin test suite
182-
run: cabal test hls-explicit-imports-plugin-tests || cabal test hls-explicit-imports-plugin-tests
182+
run: cabal test hls-explicit-imports-plugin-tests || cabal test hls-explicit-imports-plugin-tests
183183

184184
- if: matrix.test
185185
name: Test hls-call-hierarchy-plugin test suite
186-
run: cabal test hls-call-hierarchy-plugin-tests || cabal test hls-call-hierarchy-plugin-tests
186+
run: cabal test hls-call-hierarchy-plugin-tests || cabal test hls-call-hierarchy-plugin-tests
187187

188188
- if: matrix.test && matrix.os != 'windows-latest'
189189
name: Test hls-rename-plugin test suite
190-
run: cabal test hls-rename-plugin-tests || cabal test hls-rename-plugin-tests
190+
run: cabal test hls-rename-plugin-tests || cabal test hls-rename-plugin-tests
191191

192-
- if: matrix.test
192+
- if: matrix.test
193193
name: Test hls-hlint-plugin test suite
194-
run: cabal test hls-hlint-plugin-tests || cabal test hls-hlint-plugin-tests
194+
run: cabal test hls-hlint-plugin-tests || cabal test hls-hlint-plugin-tests
195195

196196
- if: matrix.test
197197
name: Test hls-module-name-plugin test suite
198-
run: cabal test hls-module-name-plugin-tests || cabal test hls-module-name-plugin-tests
198+
run: cabal test hls-module-name-plugin-tests || cabal test hls-module-name-plugin-tests
199199

200200
- if: matrix.test
201201
name: Test hls-alternate-number-format-plugin test suite
202-
run: cabal test hls-alternate-number-format-plugin-tests || cabal test hls-alternate-number-format-plugin-tests
202+
run: cabal test hls-alternate-number-format-plugin-tests || cabal test hls-alternate-number-format-plugin-tests
203203

204204
- if: matrix.test
205205
name: Test hls-qualify-imported-names-plugin test suite
206-
run: cabal test hls-qualify-imported-names-plugin-tests || cabal test hls-qualify-imported-names-plugin-tests
206+
run: cabal test hls-qualify-imported-names-plugin-tests || cabal test hls-qualify-imported-names-plugin-tests
207207

208208
- if: matrix.test
209209
name: Test hls-code-range-plugin test suite
210-
run: cabal test hls-code-range-plugin-tests || cabal test hls-code-range-plugin-tests
210+
run: cabal test hls-code-range-plugin-tests || cabal test hls-code-range-plugin-tests
211211

212212
- if: matrix.test
213213
name: Test hls-change-type-signature test suite
214-
run: cabal test hls-change-type-signature-plugin-tests || cabal test hls-change-type-signature-plugin-tests
214+
run: cabal test hls-change-type-signature-plugin-tests || cabal test hls-change-type-signature-plugin-tests
215215

216216
- if: matrix.test
217217
name: Test hls-gadt-plugin test suit
218-
run: cabal test hls-gadt-plugin-tests || cabal test hls-gadt-plugin-tests
218+
run: cabal test hls-gadt-plugin-tests || cabal test hls-gadt-plugin-tests
219219

220220
- if: matrix.test
221221
name: Test hls-explicit-fixity-plugin test suite
222-
run: cabal test hls-explicit-fixity-plugin-tests || cabal test hls-explicit-fixity-plugin-tests
222+
run: cabal test hls-explicit-fixity-plugin-tests || cabal test hls-explicit-fixity-plugin-tests
223223

224224
- if: matrix.test
225225
name: Test hls-explicit-record-fields-plugin test suite
226-
run: cabal test hls-explicit-record-fields-plugin-tests || cabal test hls-explicit-record-fields-plugin-tests
226+
run: cabal test hls-explicit-record-fields-plugin-tests || cabal test hls-explicit-record-fields-plugin-tests
227227

228228
## version needs to be limited since the tests depend on cabal-fmt which only builds using specific ghc versions
229229
- if: matrix.test && matrix.ghc == '9.2'
230230
name: Test hls-cabal-fmt-plugin test suite
231-
run: cabal test hls-cabal-fmt-plugin-tests --flag=isolateCabalfmtTests || cabal test hls-cabal-fmt-plugin-tests --flag=isolateCabalfmtTests
231+
run: cabal test hls-cabal-fmt-plugin-tests --flag=isolateCabalfmtTests || cabal test hls-cabal-fmt-plugin-tests --flag=isolateCabalfmtTests
232232

233233
- if: matrix.test
234234
name: Test hls-cabal-plugin test suite
235-
run: cabal test hls-cabal-plugin-tests || cabal test hls-cabal-plugin-tests
235+
run: cabal test hls-cabal-plugin-tests || cabal test hls-cabal-plugin-tests
236236

237237
- if: matrix.test
238238
name: Test hls-retrie-plugin test suite
239-
run: cabal test hls-retrie-plugin-tests || cabal test hls-retrie-plugin-tests
239+
run: cabal test hls-retrie-plugin-tests || cabal test hls-retrie-plugin-tests
240240

241241
- if: matrix.test
242242
name: Test hls-overloaded-record-dot-plugin test suite
243-
run: cabal test hls-overloaded-record-dot-plugin-tests || cabal test hls-overloaded-record-dot-plugin-tests
243+
run: cabal test hls-overloaded-record-dot-plugin-tests || cabal test hls-overloaded-record-dot-plugin-tests
244244

245245
- if: matrix.test
246246
name: Test hls-semantic-tokens-plugin test suite
247-
run: cabal test hls-semantic-tokens-plugin-tests || cabal test hls-semantic-tokens-plugin-tests
247+
run: cabal test hls-semantic-tokens-plugin-tests || cabal test hls-semantic-tokens-plugin-tests
248248

249+
- if: matrix.test
250+
name: Test hls-notes-plugin test suite
251+
run: cabal test hls-notes-plugin-tests || cabal test hls-notes-plugin-tests
249252

250253
test_post_job:
251254
if: always()

CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
/plugins/hls-gadt-plugin @July541
2929
/plugins/hls-hlint-plugin @eddiemundo
3030
/plugins/hls-module-name-plugin
31+
/plugins/hls-notes-plugin @jvanbruegge
3132
/plugins/hls-ormolu-plugin @georgefst
3233
/plugins/hls-overloaded-record-dot-plugin @joyfulmantis
3334
/plugins/hls-pragmas-plugin @eddiemundo

docs/features.md

+6
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ Known limitations:
8181

8282
- Only works for [local definitions](https://github.com/haskell/haskell-language-server/issues/708).
8383

84+
## Jump to note definition
85+
86+
Provided by: `hls-notes-plugin`
87+
88+
Jump to the definition of a [GHC-style note](https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/coding-style#2-using-notes).
89+
8490
## Find references
8591

8692
Provided by: `ghcide`

docs/support/plugin-support.md

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ For example, a plugin to provide a formatter which has itself been abandoned has
5656
| `hls-gadt-plugin` | 2 | |
5757
| `hls-hlint-plugin` | 2 | |
5858
| `hls-module-name-plugin` | 2 | |
59+
| `hls-notes-plugin` | 2 | |
5960
| `hls-qualify-imported-names-plugin` | 2 | |
6061
| `hls-ormolu-plugin` | 2 | |
6162
| `hls-rename-plugin` | 2 | |

flake.nix

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
(pkgs.haskell.lib.justStaticExecutables (pkgs.haskell.lib.dontCheck pkgs.haskellPackages.opentelemetry-extra))
7070
capstone
7171
# ormolu
72-
# stylish-haskell
72+
stylish-haskell
7373
pre-commit
7474
] ++ lib.optionals (!stdenv.isDarwin)
7575
[ # tracy has a build problem on macos.

ghcide/src/Development/IDE/Core/Compile.hs

+3-1
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ tcRnModule hsc_env tc_helpers pmod = do
436436

437437

438438
-- Note [Clearing mi_globals after generating an iface]
439+
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
439440
-- GHC populates the mi_global field in interfaces for GHCi if we are using the bytecode
440441
-- interpreter.
441442
-- However, this field is expensive in terms of heap usage, and we don't use it in HLS
@@ -1366,7 +1367,7 @@ loadHieFile ncu f = do
13661367

13671368

13681369
{- Note [Recompilation avoidance in the presence of TH]
1369-
1370+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13701371
Most versions of GHC we currently support don't have a working implementation of
13711372
code unloading for object code, and no version of GHC supports this on certain
13721373
platforms like Windows. This makes it completely infeasible for interactive use,
@@ -1736,6 +1737,7 @@ pathToModuleName = mkModuleName . map rep
17361737
rep c = c
17371738

17381739
{- Note [Guidelines For Using CPP In GHCIDE Import Statements]
1740+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17391741
GHCIDE's interface with GHC is extensive, and unfortunately, because we have
17401742
to work with multiple versions of GHC, we have several files that need to use
17411743
a lot of CPP. In order to simplify the CPP in the import section of every file

ghcide/src/Development/IDE/Core/FileExists.hs

+3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import qualified System.Directory as Dir
4040
import qualified System.FilePath.Glob as Glob
4141

4242
{- Note [File existence cache and LSP file watchers]
43+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4344
Some LSP servers provide the ability to register file watches with the client, which will then notify
4445
us of file changes. Some clients can do this more efficiently than us, or generally it's a tricky
4546
problem
@@ -135,6 +136,7 @@ getFileExists :: NormalizedFilePath -> Action Bool
135136
getFileExists fp = use_ GetFileExists fp
136137

137138
{- Note [Which files should we watch?]
139+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
138140
The watcher system gives us a lot of flexibility: we can set multiple watchers, and they can all watch on glob
139141
patterns.
140142
@@ -201,6 +203,7 @@ fileExistsRulesFast recorder isWatched =
201203
else fileExistsSlow file
202204

203205
{- Note [Invalidating file existence results]
206+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
204207
We have two mechanisms for getting file existence information:
205208
- The file existence cache
206209
- The VFS lookup

ghcide/src/Development/IDE/Core/RuleTypes.hs

+1
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ makeLensesWith
512512
''Splices
513513

514514
{- Note [Client configuration in Rules]
515+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
515516
The LSP client configuration is stored by `lsp` for us, and is accesible in
516517
handlers through the LspT monad.
517518

ghcide/src/Development/IDE/Core/Rules.hs

+1
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ instance Default GhcSessionDepsConfig where
749749
}
750750

751751
-- | Note [GhcSessionDeps]
752+
-- ~~~~~~~~~~~~~~~~~~~~~
752753
-- For a file 'Foo', GhcSessionDeps "Foo.hs" results in an HscEnv which includes
753754
-- 1. HomeModInfo's (in the HUG/HPT) for all modules in the transitive closure of "Foo", **NOT** including "Foo" itself.
754755
-- 2. ModSummary's (in the ModuleGraph) for all modules in the transitive closure of "Foo", including "Foo" itself.

ghcide/src/Development/IDE/GHC/Error.hs

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ realSrcLocToPosition real =
9191
Position (fromIntegral $ srcLocLine real - 1) (fromIntegral $ srcLocCol real - 1)
9292

9393
-- Note [Unicode support]
94+
-- ~~~~~~~~~~~~~~~~~~~~~~
9495
-- the current situation is:
9596
-- LSP Positions use UTF-16 code units(Unicode may count as variable columns);
9697
-- GHC use Unicode code points(Unicode count as one column).

ghcide/src/Development/IDE/Plugin/HLS.hs

+1
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ instance Monoid IdeNotificationHandlers where
359359
mempty = IdeNotificationHandlers mempty
360360

361361
{- Note [Exception handling in plugins]
362+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
362363
Plugins run in LspM, and so have access to IO. This means they are likely to
363364
throw exceptions, even if only by accident or through calling libraries that
364365
throw exceptions. Ultimately, we're running a bunch of less-trusted IO code,

haskell-language-server.cabal

+59-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ common pedantic
6464
if flag(pedantic)
6565
ghc-options:
6666
-Werror
67-
-- Note [unused-packages] Some packages need CPP conditioned on MIN_VERSION_ghc(x,y,z).
67+
-- Note [unused-packages]
68+
-- ~~~~~~~~~~~~~~~~~~~~~~
69+
-- Some packages need CPP conditioned on MIN_VERSION_ghc(x,y,z).
6870
-- MIN_VERSION_<pkg> is CPP macro that cabal defines only when <pkg> is declared as a dependency.
6971
-- But -Wunused-packages still reports it as unused dependency if it's not imported.
7072
-- For packages with such "unused" dependencies we demote -Wunused-packages error
@@ -1628,6 +1630,61 @@ test-suite hls-semantic-tokens-plugin-tests
16281630
, data-default
16291631
, row-types
16301632

1633+
-----------------------------
1634+
-- notes plugin
1635+
-----------------------------
1636+
1637+
flag notes
1638+
description: Enable notes plugin
1639+
default: True
1640+
manual: True
1641+
1642+
common notes
1643+
if flag(notes)
1644+
build-depends: haskell-language-server:hls-notes-plugin
1645+
cpp-options: -Dhls_notes
1646+
1647+
library hls-notes-plugin
1648+
import: defaults, pedantic, warnings
1649+
buildable: True
1650+
exposed-modules:
1651+
Ide.Plugin.Notes
1652+
hs-source-dirs: plugins/hls-notes-plugin/src
1653+
build-depends:
1654+
, base >=4.12 && <5
1655+
, array
1656+
, ghcide == 2.7.0.0
1657+
, hls-graph == 2.7.0.0
1658+
, hls-plugin-api == 2.7.0.0
1659+
, lens
1660+
, lsp >=2.4
1661+
, mtl >= 2.2
1662+
, regex-tdfa >= 1.3.1
1663+
, text
1664+
, text-rope
1665+
, unordered-containers
1666+
default-extensions:
1667+
DataKinds
1668+
, DeriveAnyClass
1669+
, DerivingStrategies
1670+
, OverloadedStrings
1671+
, LambdaCase
1672+
, TypeFamilies
1673+
1674+
test-suite hls-notes-plugin-tests
1675+
import: defaults, pedantic, test-defaults, warnings
1676+
type: exitcode-stdio-1.0
1677+
hs-source-dirs: plugins/hls-notes-plugin/test
1678+
main-is: NotesTest.hs
1679+
build-depends:
1680+
, base
1681+
, directory
1682+
, filepath
1683+
, ghcide:ghcide-test-utils
1684+
, haskell-language-server:hls-notes-plugin
1685+
, hls-test-utils == 2.7.0.0
1686+
default-extensions: OverloadedStrings
1687+
16311688
----------------------------
16321689
----------------------------
16331690
-- HLS
@@ -1666,6 +1723,7 @@ library
16661723
, refactor
16671724
, overloadedRecordDot
16681725
, semanticTokens
1726+
, notes
16691727

16701728
exposed-modules:
16711729
Ide.Arguments

0 commit comments

Comments
 (0)