@@ -60,6 +60,7 @@ import qualified Language.LSP.Protocol.Lens as L
6060import Language.LSP.Protocol.Message
6161import Language.LSP.Protocol.Types hiding (Position , Range )
6262import qualified Language.LSP.Protocol.Types as LSP
63+ import Language.LSP.VFS (codePointRangeToRange )
6364import qualified Language.LSP.VFS as VFS
6465
6566-- | The module name, alias name, declaration text range, and sharing status
@@ -86,10 +87,10 @@ getParsedModuleStale state nfp =
8687 runAction " rename.getParsedModuleStale" state
8788 (useWithStale GetParsedModule nfp)
8889
89- -- | Return the 'ImportAlias' being renamed at the cursor. The cursor may be on
90- -- the alias token in an import declaration or on a qualifier at a use site. If
91- -- multiple imports share the same alias, falls back to the typechecked module's
92- -- 'GlobalRdrEnv' to disambiguate.
90+ -- | Return the 'ImportAlias' and corresponding text range at the cursor. The
91+ -- cursor may be on the alias token in an import declaration or on a qualifier
92+ -- at a use site. If multiple imports share the same alias, falls back to the
93+ -- typechecked module's 'GlobalRdrEnv' to disambiguate.
9394-- Returns @Nothing@ if the cursor is not on an import alias.
9495-- HACK: The first argument is `Rename.getNamesAtPos`, parameterized to avoid a
9596-- circular dependency.
@@ -102,19 +103,27 @@ resolveAliasAtPos ::
102103 VFS. CodePointPosition ->
103104 [LImportDecl GhcPs ] ->
104105 [LHsDecl GhcPs ] ->
105- ExceptT PluginError m (Maybe ImportAlias )
106- resolveAliasAtPos getNamesAtPosFn state nfp lspPos pos imports hsDecls =
106+ ExceptT PluginError m (Maybe (LSP. Range , ImportAlias ))
107+ resolveAliasAtPos getNamesAtPosFn state nfp lspPos pos imports hsDecls = do
108+ virtualFile <- runActionE " rename.getVirtualFile" state
109+ $ handleMaybeM (PluginInternalError
110+ (" Virtual file not found: " <> T. pack (show nfp)))
111+ $ getVirtualFile nfp
112+ let toLSPRange (range, alias) = case codePointRangeToRange virtualFile range of
113+ Nothing -> Nothing
114+ Just lspRange -> Just (lspRange, alias)
107115 case findAliasDeclAtPos pos imports of
108- Just alias -> pure ( Just alias)
116+ Just alias -> pure $ toLSPRange (aliasDeclRange alias, alias)
109117 Nothing -> case findAliasUseAtPos pos imports hsDecls of
110- [] -> pure Nothing
111- [alias] -> pure (Just alias)
112- candidates -> do
118+ Nothing -> pure Nothing
119+ Just (_, [] ) -> pure Nothing
120+ Just (range, [alias]) -> pure $ toLSPRange (range, alias)
121+ Just (range, candidates) -> do
113122 tcModule <- runActionE " rename.resolveAlias" state $ useE TypeCheck nfp
114123 namesAtPos <- getNamesAtPosFn state nfp lspPos
115124 case disambiguateAliasUse tcModule namesAtPos candidates of
116125 [] -> pure Nothing
117- [alias] -> pure ( Just alias)
126+ [alias] -> pure $ toLSPRange (range, alias)
118127 aliases -> throwError $ PluginInvalidParams $
119128 ambiguousAliasErrorMessage aliases
120129
@@ -171,14 +180,14 @@ findAliasDeclAtPos pos imports = listToMaybe $ do
171180 aliasIsShared = length (filter (== aliasName) allAliases) > 1
172181 [ImportAlias {aliasModuleName, aliasName, aliasDeclRange, aliasIsShared}]
173182
174- -- | Find the 'ImportAlias' matching the name qualifier at the cursor, such as
175- -- @L@ in @L.take@.
176- -- Returns multiple values if multiple modules share the same alias.
183+ -- | Find the text range and matching 'ImportAlias' for the name qualifier at
184+ -- the cursor, such as @L@ in @L.take@.
185+ -- Returns multiple aliases if multiple modules share the same alias.
177186findAliasUseAtPos ::
178187 VFS. CodePointPosition ->
179188 [LImportDecl GhcPs ] ->
180189 [LHsDecl GhcPs ] ->
181- [ImportAlias ]
190+ Maybe ( VFS. CodePointRange , [ImportAlias ])
182191findAliasUseAtPos pos imports hsDecls =
183192 let qualifiersAtPos = do
184193 locatedRdrName :: XRec GhcPs RdrName <- listify (const True ) hsDecls
@@ -191,10 +200,10 @@ findAliasUseAtPos pos imports hsDecls =
191200 qualifierRange = qualifiedNameRange
192201 & VFS. end .~ (qualifierStart & VFS. character +~ qualifierLength)
193202 guard (rangeContainsPosition qualifierRange pos)
194- [qualifier]
203+ [(qualifierRange, qualifier) ]
195204 in case qualifiersAtPos of
196- [] -> []
197- qualifierAtPos : _ -> do
205+ [] -> Nothing
206+ (rangeAtPos, qualifierAtPos) : _ -> Just $ (,) rangeAtPos $ do
198207 let allAliases = mapMaybe (fmap unLoc . ideclAs . unLoc) imports
199208 importDecl <- map unLoc imports
200209 Just locatedAlias <- [ideclAs importDecl]
0 commit comments