@@ -13,22 +13,28 @@ module Development.IDE.Spans.Common (
13
13
, spanDocToMarkdownForTest
14
14
, DocMap
15
15
, TyThingMap
16
+ , srcSpanToMdLink
16
17
) where
17
18
18
19
import Control.DeepSeq
20
+ import Data.Bifunctor (second )
19
21
import Data.List.Extra
20
22
import Data.Maybe
21
- import qualified Data.Text as T
22
- import GHC.Generics
23
-
23
+ import qualified Data.Text as T
24
+ import Development.IDE.GHC.Util
25
+ import qualified Documentation.Haddock.Parser as H
26
+ import qualified Documentation.Haddock.Types as H
24
27
import GHC
28
+ import GHC.Generics
29
+ import System.FilePath
25
30
26
- import Data.Bifunctor (second )
27
31
import Development.IDE.GHC.Compat
28
- import Development.IDE.GHC.Orphans ()
29
- import Development.IDE.GHC.Util
30
- import qualified Documentation.Haddock.Parser as H
31
- import qualified Documentation.Haddock.Types as H
32
+ import qualified Development.IDE.GHC.Compat.Util as Util
33
+ import Development.IDE.GHC.Orphans ()
34
+ import Language.LSP.Protocol.Types
35
+ import qualified Language.LSP.Protocol.Lens as JL
36
+ import Control.Lens
37
+ import Language.LSP.Protocol.Lens (HasUri (uri ))
32
38
33
39
type DocMap = NameEnv SpanDoc
34
40
type TyThingMap = NameEnv TyThing
@@ -109,7 +115,13 @@ spanDocUrisToMarkdown (SpanDocUris mdoc msrc) = catMaybes
109
115
[ linkify " Documentation" <$> mdoc
110
116
, linkify " Source" <$> msrc
111
117
]
112
- where linkify title uri = " [" <> title <> " ](" <> uri <> " )"
118
+
119
+ -- | Generate a markdown link.
120
+ --
121
+ -- >>> linkify "Title" "uri"
122
+ -- "[Title](Uri)"
123
+ linkify :: T. Text -> T. Text -> T. Text
124
+ linkify title uri = " [" <> title <> " ](" <> uri <> " )"
113
125
114
126
spanDocToMarkdownForTest :: String -> String
115
127
spanDocToMarkdownForTest
@@ -215,3 +227,35 @@ splitForList s
215
227
= case lines s of
216
228
[] -> " "
217
229
(first: rest) -> unlines $ first : map ((" " ++ ) . trimStart) rest
230
+
231
+ -- | Generate a source link for the 'Location' according to VSCode's supported form:
232
+ -- https://github.com/microsoft/vscode/blob/b3ec8181fc49f5462b5128f38e0723ae85e295c2/src/vs/platform/opener/common/opener.ts#L151-L160
233
+ --
234
+ srcSpanToMdLink :: Location -> T. Text
235
+ srcSpanToMdLink location =
236
+ let
237
+ uri = location ^. JL. uri
238
+ range = location ^. JL. range
239
+ -- LSP 'Range' starts at '0', but link locations start at '1'.
240
+ intText n = T. pack $ show (n + 1 )
241
+ srcRangeText =
242
+ T. concat
243
+ [ " L"
244
+ , intText (range ^. JL. start . JL. line)
245
+ , " ,"
246
+ , intText (range ^. JL. start . JL. character)
247
+ , " -L"
248
+ , intText (range ^. JL. end . JL. line)
249
+ , " ,"
250
+ , intText (range ^. JL. end . JL. character)
251
+ ]
252
+
253
+ -- If the 'Location' is a 'FilePath', display it in shortened form.
254
+ -- This avoids some redundancy and better readability for the user.
255
+ title = case uriToFilePath uri of
256
+ Just fp -> T. pack (takeFileName fp) <> " :" <> intText (range ^. JL. start . JL. line)
257
+ Nothing -> getUri uri
258
+
259
+ srcLink = getUri uri <> " #" <> srcRangeText
260
+ in
261
+ linkify title srcLink
0 commit comments