@@ -54,6 +54,11 @@ instance Pretty Log where
54
54
" Found notes in " <> pretty (show file) <> " : ["
55
55
<> pretty (intercalate " , " (fmap (\ (s, p) -> " \" " <> s <> " \" at " <> T. pack (show p)) notes)) <> " ]"
56
56
57
+ {-
58
+ The first time the user requests a jump-to-definition on a note reference, the
59
+ project is indexed and searched for all note definitions. Their location and
60
+ title is then saved in the HLS database to be retrieved for all future requests.
61
+ -}
57
62
descriptor :: Recorder (WithPriority Log ) -> PluginId -> PluginDescriptor IdeState
58
63
descriptor recorder plId = (defaultPluginDescriptor plId)
59
64
{ Ide.Types. pluginRules = findNotesRules recorder
@@ -89,12 +94,18 @@ jumpToNote state _ param
89
94
uriOrig = toNormalizedUri $ param ^. (L. textDocument . L. uri)
90
95
err s = maybe (throwError $ PluginInternalError s) pure
91
96
atPos c arr = case arr A. ! 0 of
97
+ -- We check if the line we are currently at contains a note
98
+ -- reference. However, we need to know if the cursor is within the
99
+ -- match or somewhere else. The second entry of the array contains
100
+ -- the title of the note as extracted by the regex.
92
101
(_, (c', len)) -> if c' <= c && c <= c' + len
93
102
then Just (fst (arr A. ! 1 )) else Nothing
94
103
jumpToNote _ _ _ = throwError $ PluginInternalError " conversion to normalized file path failed"
95
104
96
105
findNotesInFile :: NormalizedFilePath -> Recorder (WithPriority Log ) -> Action (Maybe (HM. HashMap Text Position ))
97
106
findNotesInFile file recorder = do
107
+ -- GetFileContents only returns a value if the file is open in the editor of
108
+ -- the user. If not, we need to read it from disk.
98
109
contentOpt <- (snd =<< ) <$> use GetFileContents file
99
110
content <- case contentOpt of
100
111
Just x -> pure x
@@ -105,6 +116,12 @@ findNotesInFile file recorder = do
105
116
pure $ Just m
106
117
where
107
118
uint = fromIntegral . toInteger
119
+ -- the regex library returns the character index of the match. However
120
+ -- to return the position from HLS we need it as a (line, character)
121
+ -- tuple. To convert between the two we count the newline characters and
122
+ -- reset the current character index every time. For every regex match,
123
+ -- once we have counted up to their character index, we save the current
124
+ -- line and character values instead.
108
125
toPositions matches = snd . fst . T. foldl' (\ case
109
126
(([] , m), _) -> const (([] , m), (0 , 0 , 0 ))
110
127
((x@ (name, (char, _)): xs, m), (n, nc, c)) -> \ char' ->
0 commit comments