Skip to content

Commit ae0f7b9

Browse files
committed
Update documentation
1 parent 3a87d9f commit ae0f7b9

File tree

3 files changed

+94
-83
lines changed

3 files changed

+94
-83
lines changed

plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,9 +295,9 @@ completion recorder _ide _ complParams = do
295295
logWith recorder Debug $ LogCompletionContext ctx pos
296296
let completer = Completions.contextToCompleter ctx
297297
completions <- completer completerRecorder completionContext
298-
pure $ Completions.mkCompletionItems completions
298+
pure $ map Completions.mkCompletionItem completions
299299
where
300300
completerRecorder = cmapWithPrio LogCompletions recorder
301301
pos = VFS.cursorPos prefix
302302
context = Completions.getContext completerRecorder completionContext (cnts ^. VFS.file_text)
303-
completionContext = Completions.getCabalCompletionContext fp prefix
303+
completionContext = Completions.getCabalPrefixInfo fp prefix

plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completions.hs

Lines changed: 63 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,24 @@ import qualified Text.Fuzzy.Parallel as Fuzzy
3434
data Log
3535
= LogFilePathCompleterIOError FilePath IOError
3636
| LogFileSplitError Position
37+
| LogUnknownKeyWordInContextError KeyWordName
38+
| LogUnknownStanzaNameInContextError StanzaName
3739
deriving (Show)
3840

3941
instance Pretty Log where
4042
pretty = \case
4143
LogFilePathCompleterIOError fp ioErr ->
4244
"Filepath:" <+> viaShow fp <+> viaShow ioErr
43-
LogFileSplitError pos -> "Position: " <+> viaShow pos
44-
45-
45+
LogFileSplitError pos -> "Position:" <+> viaShow pos
46+
LogUnknownKeyWordInContextError kw ->
47+
"Lookup failed for:" <+> viaShow kw
48+
LogUnknownStanzaNameInContextError sn ->
49+
"Lookup failed for:" <+> viaShow sn
4650

4751
{- | Takes information needed to build possible completion items
4852
and returns the list of possible completion items
4953
-}
50-
type Completer = Recorder (WithPriority Log) -> CabalCompletionContext -> IO [CabalCompletionItem]
54+
type Completer = Recorder (WithPriority Log) -> CabalPrefixInfo -> IO [CabalCompletionItem]
5155

5256
-- | Contains information needed for a completion action
5357
data CabalCompletionItem = CabalCompletionItem
@@ -81,11 +85,11 @@ data StanzaContext
8185
-}
8286
data KeyWordContext
8387
= -- | Key word context, where a keyword
84-
-- occurs right before the current position,
85-
-- with no value associated to it
88+
-- occurs right before the current word
89+
-- to be completed
8690
KeyWord KeyWordName
8791
| -- | Keyword context where no keyword occurs
88-
-- right before the current position
92+
-- right before the current word to be completed
8993
None
9094
deriving (Eq, Show, Read)
9195

@@ -113,7 +117,7 @@ type StanzaName = T.Text
113117
necessary to complete filepaths and other values
114118
in a cabal file.
115119
-}
116-
data CabalCompletionContext = CabalCompletionContext
120+
data CabalPrefixInfo = CabalPrefixInfo
117121
{ completionPrefix :: T.Text
118122
-- ^ text prefix to complete
119123
, completionSuffix :: Maybe T.Text
@@ -123,7 +127,7 @@ data CabalCompletionContext = CabalCompletionContext
123127
-- ^ the current position of the cursor in the file
124128
, completionRange :: Range
125129
-- ^ range where completion is to be inserted
126-
, completionCabalFileDir :: FilePath
130+
, completionWorkingDir :: FilePath
127131
-- ^ filepath of the handled cabal file
128132
}
129133
deriving (Eq, Show)
@@ -138,43 +142,46 @@ data CabalCompletionContext = CabalCompletionContext
138142
contextToCompleter :: Context -> Completer
139143
-- if we are in the top level of the cabal file and not in a keyword context,
140144
-- we can write any top level keywords or a stanza declaration
141-
contextToCompleter (TopLevel, None) =
145+
contextToCompleter (TopLevel, None) =
142146
constantCompleter $
143147
Map.keys (cabalVersionKeyword <> cabalKeywords) ++ Map.keys stanzaKeywordMap
144148
-- if we are in a keyword context in the top level,
145149
-- we look up that keyword in the top level context and can complete its possible values
146150
contextToCompleter (TopLevel, KeyWord kw) =
147151
case Map.lookup kw (cabalVersionKeyword <> cabalKeywords) of
148-
Nothing -> noopCompleter
152+
Nothing -> \recorder b -> do
153+
logWith recorder Warning $ LogUnknownKeyWordInContextError kw
154+
noopCompleter recorder b
149155
Just l -> l
150156
-- if we are in a stanza and not in a keyword context,
151157
-- we can write any of the stanza's keywords or a stanza declaration
152-
contextToCompleter (Stanza s, None) =
158+
contextToCompleter (Stanza s, None) =
153159
case Map.lookup s stanzaKeywordMap of
154-
Nothing -> noopCompleter
160+
Nothing -> \recorder b -> do
161+
logWith recorder Warning $ LogUnknownStanzaNameInContextError s
162+
noopCompleter recorder b
155163
Just l -> constantCompleter $ Map.keys l ++ Map.keys stanzaKeywordMap
156164
-- if we are in a stanza's keyword's context we can complete possible values of that keyword
157-
contextToCompleter (Stanza s, KeyWord kw) =
165+
contextToCompleter (Stanza s, KeyWord kw) =
158166
case Map.lookup s stanzaKeywordMap of
159-
Nothing -> noopCompleter
167+
Nothing -> \recorder b -> do
168+
logWith recorder Warning $ LogUnknownStanzaNameInContextError s
169+
noopCompleter recorder b
160170
Just m -> case Map.lookup kw m of
161-
Nothing -> noopCompleter
171+
Nothing -> \recorder b -> do
172+
logWith recorder Warning $ LogUnknownKeyWordInContextError kw
173+
noopCompleter recorder b
162174
Just l -> l
163175

164-
{- | Takes information about the current cursor position,
165-
the handled cabal file and a set of possible keywords
166-
and creates completion suggestions that fit the current input
167-
from the given list
168-
-}
169-
mkCompletionItems :: [CabalCompletionItem] -> [LSP.CompletionItem]
170-
mkCompletionItems l = map buildCompletion l
171176

172-
{- | Takes a position and a list of lines (representing a file)
173-
and returns the context of the current position
174-
can return Nothing if an error occurs
177+
178+
{- | Takes prefix info about the previously written text
179+
and a rope (representing a file), returns the corresponding context.
180+
181+
Can return Nothing if an error occurs.
175182
TODO: first line can only have cabal-version: keyword
176183
-}
177-
getContext :: MonadIO m => Recorder (WithPriority Log) -> CabalCompletionContext -> Rope -> MaybeT m Context
184+
getContext :: MonadIO m => Recorder (WithPriority Log) -> CabalPrefixInfo -> Rope -> MaybeT m Context
178185
getContext recorder ctx ls =
179186
case prevLinesM of
180187
Just prevLines -> do
@@ -206,11 +213,12 @@ getContext recorder ctx ls =
206213
-- Helper Functions
207214
-- ----------------------------------------------------------------
208215

209-
{- | Takes a position, a list of lines (representing a file)
210-
and a map of keywords and returns a keyword context if the
211-
previously written keyword matches one in the map
216+
{- | Takes prefix info about the previously written text,
217+
a list of lines (representing a file) and a map of
218+
keywords and returns a keyword context if the
219+
previously written keyword matches one in the map.
212220
-}
213-
getKeyWordContext :: CabalCompletionContext -> [T.Text] -> Map KeyWordName a -> Maybe KeyWordContext
221+
getKeyWordContext :: CabalPrefixInfo -> [T.Text] -> Map KeyWordName a -> Maybe KeyWordContext
214222
getKeyWordContext ctx ls keywords = do
215223
case lastNonEmptyLineM of
216224
Nothing -> Just None
@@ -251,21 +259,21 @@ currentLevel (cur : xs)
251259
stanza = List.find (`T.isPrefixOf` cur) (Map.keys stanzaKeywordMap)
252260

253261
{- | Returns a CabalCompletionItem with the given starting position
254-
and text to be inserted,
255-
where the displayed text is the same as the inserted text.
262+
and text to be inserted, where the displayed text is the same as the
263+
inserted text.
256264
-}
257265
makeSimpleCabalCompletionItem :: Range -> T.Text -> CabalCompletionItem
258266
makeSimpleCabalCompletionItem r txt = CabalCompletionItem txt Nothing r
259267

260268
{- | Returns a CabalCompletionItem with the given starting position,
261-
text to be inserted and text to be displayed in the completion suggestion
269+
text to be inserted and text to be displayed in the completion suggestion.
262270
-}
263-
makeCabalCompletionItem :: Range -> T.Text -> T.Text -> CabalCompletionItem
264-
makeCabalCompletionItem r insertTxt displayTxt =
271+
mkCabalCompletionItem :: Range -> T.Text -> T.Text -> CabalCompletionItem
272+
mkCabalCompletionItem r insertTxt displayTxt =
265273
CabalCompletionItem insertTxt (Just displayTxt) r
266274

267275
{- | Get all lines before the given cursor position in the given file
268-
and reverse their order to traverse backwards starting from the current position
276+
and reverse their order to traverse backwards starting from the given position.
269277
-}
270278
splitAtPosition :: Position -> Rope -> Maybe [T.Text]
271279
splitAtPosition pos ls = do
@@ -280,7 +288,7 @@ splitAtPosition pos ls = do
280288
}
281289

282290
-- | Takes a line of text and removes the last partially
283-
-- written text to be completed
291+
-- written word to be completed
284292
stripPartiallyWritten :: T.Text -> T.Text
285293
stripPartiallyWritten = T.dropWhileEnd (\y -> (y /= ' ') && (y /= ':'))
286294

@@ -297,21 +305,22 @@ stripPartiallyWritten = T.dropWhileEnd (\y -> (y /= ' ') && (y /= ':'))
297305
be used for file path completions to be written to the cabal file.
298306
-}
299307

308+
300309
{- | Takes information about the current file's file path,
301310
the current cursor position in the file
302311
and its contents; and builds a CabalCompletionItem
303312
with the prefix up to that cursor position,
304313
checks whether a suffix needs to be completed,
305314
and calculates the range in the document in which to complete.
306315
-}
307-
getCabalCompletionContext :: FilePath -> VFS.PosPrefixInfo -> CabalCompletionContext
308-
getCabalCompletionContext dir prefixInfo =
309-
CabalCompletionContext
316+
getCabalPrefixInfo :: FilePath -> VFS.PosPrefixInfo -> CabalPrefixInfo
317+
getCabalPrefixInfo dir prefixInfo =
318+
CabalPrefixInfo
310319
{ completionPrefix = filepathPrefix
311320
, completionSuffix = Just suffix
312321
, completionCursorPosition = VFS.cursorPos prefixInfo
313322
, completionRange = Range completionStart completionEnd
314-
, completionCabalFileDir = dir
323+
, completionWorkingDir = dir
315324
}
316325
where
317326
completionEnd = VFS.cursorPos prefixInfo
@@ -334,8 +343,8 @@ getCabalCompletionContext dir prefixInfo =
334343
-- otherwise we parse until a space occurs
335344
stopConditionChars = apostropheOrSpaceSeparator : [',', ':']
336345

337-
buildCompletion :: CabalCompletionItem -> LSP.CompletionItem
338-
buildCompletion completionItem =
346+
mkCompletionItem :: CabalCompletionItem -> LSP.CompletionItem
347+
mkCompletionItem completionItem =
339348
LSP.CompletionItem
340349
{ Compls._label = toDisplay
341350
, Compls._labelDetails = Nothing
@@ -395,7 +404,7 @@ filePathCompleter recorder ctx = do
395404
( \compl' -> do
396405
let compl = Fuzzy.original compl'
397406
fullFilePath <- makeFullFilePath suffix compl complInfo
398-
pure $ makeCabalCompletionItem (completionRange ctx) fullFilePath fullFilePath
407+
pure $ mkCabalCompletionItem (completionRange ctx) fullFilePath fullFilePath
399408
)
400409
where
401410
-- Takes a suffix, a completed path and a pathCompletionInfo and
@@ -422,7 +431,7 @@ directoryCompleter recorder ctx = do
422431
( \compl' -> do
423432
let compl = Fuzzy.original compl'
424433
fullDirPath <- makeFullDirPath compl complInfo
425-
pure $ makeCabalCompletionItem (completionRange ctx) fullDirPath fullDirPath
434+
pure $ mkCabalCompletionItem (completionRange ctx) fullDirPath fullDirPath
426435
)
427436
where
428437
-- Takes a directory and PathCompletionInfo and
@@ -460,17 +469,17 @@ listDirectoryCompletions recorder complInfo = do
460469
filepaths <- listFileCompletions recorder complInfo
461470
filterM (doesDirectoryExist . mkDirFromCWD complInfo) filepaths
462471

463-
pathCompletionInfoFromCompletionContext :: CabalCompletionContext -> PathCompletionInfo
472+
pathCompletionInfoFromCompletionContext :: CabalPrefixInfo -> PathCompletionInfo
464473
pathCompletionInfoFromCompletionContext ctx =
465474
PathCompletionInfo
466475
{ partialFileName = dirNamePrefix
467476
, partialFileDir = Posix.addTrailingPathSeparator $ Posix.takeDirectory prefix
468-
, cabalFileDir = dir
477+
, workingDir = dir
469478
}
470479
where
471480
prefix = T.unpack $ completionPrefix ctx
472481
dirNamePrefix = T.pack $ Posix.takeFileName prefix
473-
dir = Posix.takeDirectory $ completionCabalFileDir ctx
482+
dir = Posix.takeDirectory $ completionWorkingDir ctx
474483

475484
{- | Returns the directory, the currently handled cabal file is in.
476485
@@ -480,9 +489,11 @@ pathCompletionInfoFromCompletionContext ctx =
480489
mkCompletionDirectory :: PathCompletionInfo -> FilePath
481490
mkCompletionDirectory complInfo =
482491
FP.addTrailingPathSeparator $
483-
cabalFileDir complInfo FP.</> (FP.normalise $ partialFileDir complInfo)
492+
workingDir complInfo FP.</> (FP.normalise $ partialFileDir complInfo)
484493

485-
{- | Returns the complete filepath for the given filepath.
494+
{- | Returns the complete filepath for the given filepath,
495+
by combining the current working directory of the cabal file
496+
with the given partly written file path.
486497
487498
Since this is used for completions we use posix separators here.
488499
See Note [Using correct file path separators].
@@ -512,7 +523,7 @@ data PathCompletionInfo = PathCompletionInfo
512523
-- ^ partly written start of next part of path
513524
, partialFileDir :: FilePath
514525
-- ^ written part of path
515-
, cabalFileDir :: FilePath
526+
, workingDir :: FilePath
516527
-- ^ current working directory of the handled file
517528
}
518529
deriving (Eq, Show, Read)

0 commit comments

Comments
 (0)