Skip to content

Commit 982c50c

Browse files
committed
Fix bugs in completion help text
This fixes the ugly "Imported from 'Just B'" and other inconsistencies
1 parent 6b76461 commit 982c50c

File tree

2 files changed

+44
-33
lines changed

2 files changed

+44
-33
lines changed

ghcide/src/Development/IDE/Plugin/Completions/Logic.hs

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ mkCompl
166166
{ compKind,
167167
isInfix,
168168
insertText,
169-
importedFrom,
169+
provenance,
170170
typeText,
171171
label,
172172
docs,
@@ -195,26 +195,28 @@ mkCompl
195195

196196
where kind = Just compKind
197197
docs' = imported : spanDocToMarkdown docs
198-
isImported = isNothing additionalTextEdits
199-
definedOrImported = if isImported then "*Imported from '" else "*Defined in '"
200-
imported = case importedFrom of
201-
Left pos -> "*Defined at '" <> ppr pos <> "'*\n'"
202-
Right mod -> definedOrImported <> mod <> "'*\n"
198+
imported = case provenance of
199+
Local pos -> "*Defined at " <> pprLineCol (srcSpanStart pos) <> " in this module*\n'"
200+
ImportedFrom mod -> "*Imported from '" <> mod <> "'*\n"
201+
DefinedIn mod -> "*Defined in '" <> mod <> "'*\n"
203202
colon = if optNewColonConvention then ": " else ":: "
204203
documentation = Just $ CompletionDocMarkup $
205204
MarkupContent MkMarkdown $
206205
T.intercalate sectionSeparator docs'
206+
pprLineCol :: SrcLoc -> T.Text
207+
pprLineCol (UnhelpfulLoc fs) = T.pack $ unpackFS fs
208+
pprLineCol (RealSrcLoc loc) =
209+
"line " <> ppr(srcLocLine loc) <> ", column " <> ppr(srcLocCol loc)
207210

208211

209212
mkAdditionalEditsCommand :: PluginId -> ExtendImport -> Command
210213
mkAdditionalEditsCommand pId edits =
211214
mkLspCommand pId (CommandId extendImportCommandId) "extend import" (Just [toJSON edits])
212215

213-
mkNameCompItem :: Uri -> Maybe T.Text -> OccName -> ModuleName -> Maybe Type -> Maybe Backtick -> SpanDoc -> Maybe (LImportDecl GhcPs) -> CompItem
214-
mkNameCompItem doc thingParent origName origMod thingType isInfix docs !imp = CI {..}
216+
mkNameCompItem :: Uri -> Maybe T.Text -> OccName -> Provenance -> Maybe Type -> Maybe Backtick -> SpanDoc -> Maybe (LImportDecl GhcPs) -> CompItem
217+
mkNameCompItem doc thingParent origName provenance thingType isInfix docs !imp = CI {..}
215218
where
216219
compKind = occNameToComKind typeText origName
217-
importedFrom = Right $ showModName origMod
218220
isTypeCompl = isTcOcc origName
219221
label = stripPrefix $ showGhc origName
220222
insertText = case isInfix of
@@ -309,7 +311,7 @@ fromIdentInfo :: Uri -> IdentInfo -> Maybe T.Text -> CompItem
309311
fromIdentInfo doc IdentInfo{..} q = CI
310312
{ compKind= occNameToComKind Nothing name
311313
, insertText=rendered
312-
, importedFrom=Right moduleNameText
314+
, provenance = DefinedIn moduleNameText
313315
, typeText=Nothing
314316
, label=rendered
315317
, isInfix=Nothing
@@ -330,6 +332,7 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do
330332
let
331333
packageState = hscEnv env
332334
curModName = moduleName curMod
335+
curModNameText = ppr curModName
333336

334337
importMap = Map.fromList [ (l, imp) | imp@(L (RealSrcSpan l _) _) <- limports ]
335338

@@ -356,7 +359,7 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do
356359

357360
getComplsForOne :: GlobalRdrElt -> IO ([CompItem],QualCompls)
358361
getComplsForOne (GRE n par True _) =
359-
(, mempty) <$> toCompItem par curMod curModName n Nothing
362+
(, mempty) <$> toCompItem par curMod curModNameText n Nothing
360363
getComplsForOne (GRE n par False prov) =
361364
flip foldMapM (map is_decl prov) $ \spec -> do
362365
let originalImportDecl = do
@@ -365,7 +368,7 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do
365368
-- or if it doesn't have a real location
366369
loc <- realSpan $ is_dloc spec
367370
Map.lookup loc importMap
368-
compItem <- toCompItem par curMod (is_mod spec) n originalImportDecl
371+
compItem <- toCompItem par curMod (ppr $ is_mod spec) n originalImportDecl
369372
let unqual
370373
| is_qual spec = []
371374
| otherwise = compItem
@@ -376,7 +379,7 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do
376379
origMod = showModName (is_mod spec)
377380
return (unqual,QualCompls qual)
378381

379-
toCompItem :: Parent -> Module -> ModuleName -> Name -> Maybe (LImportDecl GhcPs) -> IO [CompItem]
382+
toCompItem :: Parent -> Module -> T.Text -> Name -> Maybe (LImportDecl GhcPs) -> IO [CompItem]
380383
toCompItem par m mn n imp' = do
381384
docs <- getDocumentationTryGhc packageState curMod n
382385
let (mbParent, originName) = case par of
@@ -392,10 +395,10 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do
392395

393396
let recordCompls = case record_ty of
394397
Just (ctxStr, flds) | not (null flds) ->
395-
[mkRecordSnippetCompItem uri mbParent ctxStr flds (ppr mn) docs imp']
398+
[mkRecordSnippetCompItem uri mbParent ctxStr flds (ImportedFrom mn) docs imp']
396399
_ -> []
397400

398-
return $ mkNameCompItem uri mbParent originName mn ty Nothing docs imp'
401+
return $ mkNameCompItem uri mbParent originName (ImportedFrom mn) ty Nothing docs imp'
399402
: recordCompls
400403

401404
(unquals,quals) <- getCompls rdrElts
@@ -413,7 +416,7 @@ cacheDataProducer uri env curMod globalEnv inScopeEnv limports = do
413416

414417
-- | Produces completions from the top level declarations of a module.
415418
localCompletionsForParsedModule :: Uri -> ParsedModule -> CachedCompletions
416-
localCompletionsForParsedModule uri pm@ParsedModule{pm_parsed_source = L _ HsModule{hsmodDecls, hsmodName}} =
419+
localCompletionsForParsedModule uri pm@ParsedModule{pm_parsed_source = L _ HsModule{hsmodDecls}} =
417420
CC { allModNamesAsNS = mempty
418421
, unqualCompls = compls
419422
, qualCompls = mempty
@@ -449,7 +452,7 @@ localCompletionsForParsedModule uri pm@ParsedModule{pm_parsed_source = L _ HsMod
449452
| id <- listify (\(_ :: Located(IdP GhcPs)) -> True) x
450453
, let cl = occNameToComKind Nothing (rdrNameOcc $ unLoc id)]
451454
-- here we only have to look at the outermost type
452-
recordCompls = findRecordCompl uri pm thisModName x
455+
recordCompls = findRecordCompl uri pm (Local pos) x
453456
in
454457
-- the constructors and snippets will be duplicated here giving the user 2 choices.
455458
generalCompls ++ recordCompls
@@ -458,18 +461,17 @@ localCompletionsForParsedModule uri pm@ParsedModule{pm_parsed_source = L _ HsMod
458461
ForD _ ForeignExport{fd_name,fd_sig_ty} ->
459462
[mkComp fd_name CiVariable (Just $ ppr fd_sig_ty)]
460463
_ -> []
461-
| L _ decl <- hsmodDecls
464+
| L pos decl <- hsmodDecls,
465+
let mkComp = mkLocalComp pos
462466
]
463467

464-
mkComp n ctyp ty =
465-
CI ctyp pn (Right thisModName) ty pn Nothing doc (ctyp `elem` [CiStruct, CiInterface]) Nothing
468+
mkLocalComp pos n ctyp ty =
469+
CI ctyp pn (Local pos) ty pn Nothing doc (ctyp `elem` [CiStruct, CiInterface]) Nothing
466470
where
467471
pn = ppr n
468472
doc = SpanDocText (getDocumentation [pm] n) (SpanDocUris Nothing Nothing)
469473

470-
thisModName = ppr hsmodName
471-
472-
findRecordCompl :: Uri -> ParsedModule -> T.Text -> TyClDecl GhcPs -> [CompItem]
474+
findRecordCompl :: Uri -> ParsedModule -> Provenance -> TyClDecl GhcPs -> [CompItem]
473475
findRecordCompl uri pmod mn DataDecl {tcdLName, tcdDataDefn} = result
474476
where
475477
result = [mkRecordSnippetCompItem uri (Just $ showNameWithoutUniques $ unLoc tcdLName)
@@ -590,9 +592,7 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
590592
ctyp = occNameToComKind Nothing occ
591593
pn = ppr name
592594
ty = ppr <$> typ
593-
thisModName = case nameModule_maybe name of
594-
Nothing -> Left $ nameSrcSpan name
595-
Just m -> Right $ ppr m
595+
thisModName = Local $ nameSrcSpan name
596596

597597
compls = if T.null prefixModule
598598
then localCompls ++ unqualCompls ++ (($Nothing) <$> anyQualCompls)
@@ -639,8 +639,8 @@ getCompletions plId ideOpts CC {allModNamesAsNS, anyQualCompls, unqualCompls, qu
639639

640640
uniqueCompl :: CompItem -> CompItem -> Ordering
641641
uniqueCompl x y =
642-
case compare (label x, importedFrom x, compKind x)
643-
(label y, importedFrom y, compKind y) of
642+
case compare (label x, importedFrom (provenance x), compKind x)
643+
(label y, importedFrom (provenance x), compKind y) of
644644
EQ ->
645645
-- preserve completions for duplicate record fields where the only difference is in the type
646646
-- remove redundant completions with less type info
@@ -650,6 +650,11 @@ uniqueCompl x y =
650650
then EQ
651651
else compare (insertText x) (insertText y)
652652
other -> other
653+
where
654+
importedFrom :: Provenance -> T.Text
655+
importedFrom (ImportedFrom m) = m
656+
importedFrom (DefinedIn m) = m
657+
importedFrom (Local _) = "local"
653658

654659
-- ---------------------------------------------------------------------
655660
-- helper functions for infix backticks
@@ -755,13 +760,13 @@ safeTyThingForRecord (AConLike dc) =
755760
Just (ctxStr, field_names)
756761
safeTyThingForRecord _ = Nothing
757762

758-
mkRecordSnippetCompItem :: Uri -> Maybe T.Text -> T.Text -> [T.Text] -> T.Text -> SpanDoc -> Maybe (LImportDecl GhcPs) -> CompItem
759-
mkRecordSnippetCompItem uri parent ctxStr compl mn docs imp = r
763+
mkRecordSnippetCompItem :: Uri -> Maybe T.Text -> T.Text -> [T.Text] -> Provenance -> SpanDoc -> Maybe (LImportDecl GhcPs) -> CompItem
764+
mkRecordSnippetCompItem uri parent ctxStr compl importedFrom docs imp = r
760765
where
761766
r = CI {
762767
compKind = CiSnippet
763768
, insertText = buildSnippet
764-
, importedFrom = importedFrom
769+
, provenance = importedFrom
765770
, typeText = Nothing
766771
, label = ctxStr
767772
, isInfix = Nothing
@@ -781,7 +786,6 @@ mkRecordSnippetCompItem uri parent ctxStr compl mn docs imp = r
781786
snippet_parts = map (\(x, i) -> x <> "=${" <> T.pack (show i) <> ":_" <> x <> "}") placeholder_pairs
782787
snippet = T.intercalate (T.pack ", ") snippet_parts
783788
buildSnippet = ctxStr <> " {" <> snippet <> "}"
784-
importedFrom = Right mn
785789

786790
getImportQual :: LImportDecl GhcPs -> Maybe T.Text
787791
getImportQual (L _ imp)

ghcide/src/Development/IDE/Plugin/Completions/Types.hs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import qualified Data.Text as T
1313
import Data.Aeson (FromJSON, ToJSON)
1414
import Data.Text (Text)
1515
import Development.IDE.GHC.Compat
16+
import Development.IDE.GHC.Compat (ModuleName)
1617
import Development.IDE.Spans.Common
1718
import GHC.Generics (Generic)
1819
import Ide.Plugin.Config (Config)
@@ -66,10 +67,16 @@ data ExtendImport = ExtendImport
6667
deriving (Eq, Show, Generic)
6768
deriving anyclass (FromJSON, ToJSON)
6869

70+
data Provenance
71+
= ImportedFrom Text
72+
| DefinedIn Text
73+
| Local SrcSpan
74+
deriving (Eq, Ord, Show)
75+
6976
data CompItem = CI
7077
{ compKind :: CompletionItemKind
7178
, insertText :: T.Text -- ^ Snippet for the completion
72-
, importedFrom :: Either SrcSpan T.Text -- ^ From where this item is imported from.
79+
, provenance :: Provenance -- ^ From where this item is imported from.
7380
, typeText :: Maybe T.Text -- ^ Available type information.
7481
, label :: T.Text -- ^ Label to display to the user.
7582
, isInfix :: Maybe Backtick -- ^ Did the completion happen

0 commit comments

Comments
 (0)