Skip to content

Commit 0026fd8

Browse files
committed
sort completions
1 parent a0cd84b commit 0026fd8

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import Development.IDE.GHC.ExactPrint (Annotated (annsA)
3030
import Development.IDE.GHC.Util (prettyPrint)
3131
import Development.IDE.Graph
3232
import Development.IDE.Graph.Classes
33-
import qualified Development.IDE.Types.KnownTargets as KT
3433
import Development.IDE.Plugin.CodeAction (newImport,
3534
newImportToEdit)
3635
import Development.IDE.Plugin.CodeAction.ExactPrint
@@ -39,6 +38,7 @@ import Development.IDE.Plugin.Completions.Types
3938
import Development.IDE.Types.Exports
4039
import Development.IDE.Types.HscEnvEq (HscEnvEq (envPackageExports),
4140
hscEnv)
41+
import qualified Development.IDE.Types.KnownTargets as KT
4242
import Development.IDE.Types.Location
4343
import GHC.Exts (fromList, toList)
4444
import GHC.Generics
@@ -156,17 +156,37 @@ getCompletionsLSP ide plId
156156
let clientCaps = clientCapabilities $ shakeExtras ide
157157
config <- getCompletionsConfig plId
158158
allCompletions <- liftIO $ getCompletions plId ideOpts cci' parsedMod bindMap pfix' clientCaps config moduleExports
159-
pure $ InL (List allCompletions)
159+
pure $ InL (List $ orderedCompletions allCompletions)
160160
_ -> return (InL $ List [])
161161
_ -> return (InL $ List [])
162162
_ -> return (InL $ List [])
163163

164+
{- COMPLETION SORTING
165+
We return an ordered set of completions (local -> nonlocal -> global).
166+
Ordering is important because local/nonlocal are import aware, whereas
167+
global are not and will always insert import statements, potentially redundant.
168+
169+
On the other hand the fuzzy sort algorithm doesn't always sort in the optimal way,
170+
there is room for the LSP client to improve.
171+
172+
According to the LSP specification, if no sortText is provided, the label is used.
173+
To allow the LSP client to reorder identifiers while preserving the relative ordering
174+
of repeated occurrences we generate sortText values that include both the label and
175+
an index denoting the relative order
176+
-}
177+
orderedCompletions :: [CompletionItem] -> [CompletionItem]
178+
orderedCompletions = zipWith addOrder [0..]
179+
where
180+
addOrder :: Int -> CompletionItem -> CompletionItem
181+
addOrder n it@CompletionItem{_label} =
182+
it{_sortText = Just $ _label <> T.pack(show n)}
183+
164184
----------------------------------------------------------------------------------------------------
165185

166186
toModueNameText :: KT.Target -> T.Text
167187
toModueNameText target = case target of
168-
KT.TargetModule m -> T.pack $ moduleNameString m
169-
_ -> T.empty
188+
KT.TargetModule m -> T.pack $ moduleNameString m
189+
_ -> T.empty
170190

171191
extendImportCommand :: PluginCommand IdeState
172192
extendImportCommand =

0 commit comments

Comments
 (0)