Skip to content

Commit 6b76461

Browse files
committed
Ditch alphabetical ordering - it's incompatible with qualified completions
1 parent 275beb2 commit 6b76461

File tree

1 file changed

+10
-33
lines changed

1 file changed

+10
-33
lines changed

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

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import Language.LSP.Types
4949
import qualified Language.LSP.VFS as VFS
5050
import Text.Fuzzy.Parallel (Scored (..))
5151

52-
5352
descriptor :: PluginId -> PluginDescriptor IdeState
5453
descriptor plId = (defaultPluginDescriptor plId)
5554
{ pluginRules = produceCompletions
@@ -168,51 +167,29 @@ getCompletionsLSP ide plId
168167
Ordering is important because local/nonlocal are import aware, whereas
169168
global are not and will always insert import statements, potentially redundant.
170169
171-
On the other hand the fuzzy sort algorithm doesn't always sort in the optimal way,
172-
there is room for the LSP client to improve.
173-
174-
According to the LSP specification, if no sortText is provided, the label is used.
175-
To allow the LSP client to reorder identifiers while preserving the relative ordering
176-
of repeated occurrences we generate sortText values that include both the label and
177-
an index denoting the relative order
170+
Moreover, the order prioritizes qualifiers, for instance, given:
178171
179-
EXAMPLE OF DESIRED BEHAVIOUR
180-
We produce completions:
181-
x -- local
182-
y -- local
183-
x -- global
184-
y -- global
172+
import qualified MyModule
173+
foo = MyModule.<complete>
185174
186-
The LSP client decides to present:
187-
y -- local
188-
y -- global
189-
x -- local
190-
x -- global
175+
The identifiers defined in MyModule will be listed first, followed by other
176+
identifiers in importable modules.
191177
192-
This is fine if the LSP client thinks that 'y' is more relevant than 'x'.
193-
Importantly, the local options are presented before the global ones
194-
195-
We provide the LSP client with 3 sorting measures encoded in _sortText:
196-
1. The distance to the best fuzzy score
197-
2. The label
198-
3. The index in our original sorted list
178+
According to the LSP specification, if no sortText is provided, the label is used
179+
to sort alphabetically. Alphabetical ordering is almost never what we want,
180+
so we force the LSP client to respect our ordering by using a numbered sequence.
199181
-}
200182

201183
orderedCompletions :: [Scored CompletionItem] -> [CompletionItem]
202184
orderedCompletions [] = []
203-
orderedCompletions xx@(h:_) = zipWith addOrder [0..] xx
185+
orderedCompletions xx = zipWith addOrder [0..] xx
204186
where
205187
lxx = digits $ Prelude.length xx
206-
lm = digits maxScore
207-
maxScore = score_ h
208-
209188
digits = Prelude.length . show
210189

211190
addOrder :: Int -> Scored CompletionItem -> CompletionItem
212-
addOrder n Scored{score_, original = it@CompletionItem{_label,_sortText}} =
191+
addOrder n Scored{original = it@CompletionItem{_label,_sortText}} =
213192
it{_sortText = Just $
214-
T.pack(pad lm (maxScore - score_)) <>
215-
_label <>
216193
T.pack(pad lxx n)
217194
}
218195

0 commit comments

Comments
 (0)