Skip to content

Commit 843d7ac

Browse files
author
izuzu
committed
Return alias range at cursor for prepareRename
1 parent f23419f commit 843d7ac

2 files changed

Lines changed: 30 additions & 20 deletions

File tree

plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ prepareRenameProvider state _pluginId (PrepareRenameParams (TextDocumentIdentifi
104104
maybeAlias <- ImportAlias.resolveAliasAtPos
105105
getNamesAtPos state nfp lspPos codePointPos imports hsDecls
106106
case maybeAlias of
107-
Just _ -> pure $ InL $ PrepareRenameResult $ InR $ InR $ PrepareRenameDefaultBehavior True
107+
Just (lspRange, _importAlias) ->
108+
pure $ InL $ PrepareRenameResult $ InL $ lspRange
108109
Nothing -> do
109110
-- When this handler says that rename is invalid, VSCode shows "The element can't be renamed"
110111
-- and doesn't even allow you to create full rename request.
@@ -132,7 +133,7 @@ renameProvider state pluginId (RenameParams _prog (TextDocumentIdentifier uri) l
132133
maybeAlias <- ImportAlias.resolveAliasAtPos
133134
getNamesAtPos state nfp lspPos codePointPos imports hsDecls
134135
case maybeAlias of
135-
Just importAlias -> ImportAlias.aliasBasedRename
136+
Just (_lspRange, importAlias) -> ImportAlias.aliasBasedRename
136137
state nfp uri importAlias hsDecls newNameText
137138
Nothing ->
138139
nameBasedRename state pluginId nfp lspPos newNameText

plugins/hls-rename-plugin/src/Ide/Plugin/Rename/ImportAlias.hs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import qualified Language.LSP.Protocol.Lens as L
6060
import Language.LSP.Protocol.Message
6161
import Language.LSP.Protocol.Types hiding (Position, Range)
6262
import qualified Language.LSP.Protocol.Types as LSP
63+
import Language.LSP.VFS (codePointRangeToRange)
6364
import 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.
177186
findAliasUseAtPos ::
178187
VFS.CodePointPosition ->
179188
[LImportDecl GhcPs] ->
180189
[LHsDecl GhcPs] ->
181-
[ImportAlias]
190+
Maybe (VFS.CodePointRange, [ImportAlias])
182191
findAliasUseAtPos 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

Comments
 (0)