@@ -103,13 +103,16 @@ data CompItem = CI
103
103
, importedFrom :: T. Text
104
104
, thingType :: Maybe Type
105
105
, label :: T. Text
106
+ , isInfix :: Maybe Backtick
106
107
}
107
108
109
+ data Backtick = Surrounded | LeftSide
110
+
108
111
instance Eq CompItem where
109
- ( CI n1 _ _ _) == ( CI n2 _ _ _) = n1 == n2
112
+ ci1 == ci2 = origName ci1 == origName ci2
110
113
111
114
instance Ord CompItem where
112
- compare ( CI n1 _ _ _) ( CI n2 _ _ _) = compare n1 n2
115
+ compare ci1 ci2 = origName ci1 ` compare` origName ci2
113
116
114
117
occNameToComKind :: OccName -> J. CompletionItemKind
115
118
occNameToComKind oc
@@ -125,16 +128,21 @@ mkQuery name importedFrom = name <> " module:" <> importedFrom
125
128
<> " is:exact"
126
129
127
130
mkCompl :: CompItem -> J. CompletionItem
128
- mkCompl CI {origName,importedFrom,thingType,label} =
131
+ mkCompl CI {origName,importedFrom,thingType,label,isInfix } =
129
132
J. CompletionItem label kind (Just $ maybe " " (<> " \n " ) typeText <> importedFrom)
130
133
Nothing Nothing Nothing Nothing Nothing (Just insertText) (Just J. Snippet )
131
134
Nothing Nothing Nothing Nothing hoogleQuery
132
135
where kind = Just $ occNameToComKind $ occName origName
133
136
hoogleQuery = Just $ toJSON $ mkQuery label importedFrom
134
137
argTypes = maybe [] getArgs thingType
135
- insertText
136
- | [] <- argTypes = label
137
- | otherwise = label <> " " <> argText
138
+ insertText = case isInfix of
139
+ Nothing -> case argTypes of
140
+ [] -> label
141
+ _ -> label <> " " <> argText
142
+ Just LeftSide -> label <> " `"
143
+
144
+ Just Surrounded -> label
145
+
138
146
argText :: T. Text
139
147
argText = mconcat $ List. intersperse " " $ zipWith snippet [1 .. ] argTypes
140
148
stripForall t
@@ -224,17 +232,20 @@ instance ModuleCache CachedCompletions where
224
232
225
233
typeEnv = md_types $ snd $ tm_internals_ tm
226
234
toplevelVars = mapMaybe safeTyThingId $ typeEnvElts typeEnv
227
- varToCompl var = CI name (showModName curMod) typ label
235
+
236
+ varToCompl :: Var -> CompItem
237
+ varToCompl var = CI name (showModName curMod) typ label Nothing
228
238
where
229
239
typ = Just $ varType var
230
240
name = Var. varName var
231
241
label = T. pack $ showGhc name
232
242
243
+ toplevelCompls :: [CompItem ]
233
244
toplevelCompls = map varToCompl toplevelVars
234
245
235
246
toCompItem :: ModuleName -> Name -> CompItem
236
247
toCompItem mn n =
237
- CI n (showModName mn) Nothing (T. pack $ showGhc n)
248
+ CI n (showModName mn) Nothing (T. pack $ showGhc n) Nothing
238
249
239
250
allImportsInfo :: [(Bool , T. Text , ModuleName , Maybe (Bool , [Name ]))]
240
251
allImportsInfo = map getImpInfo importDeclerations
@@ -369,6 +380,26 @@ getCompletions uri prefixInfo (WithSnippets withSnippets) =
369
380
d = T. length fullLine - T. length (stripTypeStuff partialLine)
370
381
in Position l (c - d)
371
382
383
+ hasTrailingBacktick =
384
+ if T. length fullLine <= trailingBacktickIndex
385
+ then False
386
+ else (fullLine `T.index` trailingBacktickIndex) == ' `'
387
+
388
+ trailingBacktickIndex = let Position _ cursorColumn = VFS. cursorPos prefixInfo in cursorColumn
389
+
390
+ isUsedAsInfix = if backtickIndex < 0
391
+ then False
392
+ else (fullLine `T.index` backtickIndex) == ' `'
393
+
394
+ backtickIndex =
395
+ let Position _ cursorColumn = VFS. cursorPos prefixInfo
396
+ prefixLength = T. length prefixText
397
+ moduleLength = if prefixModule == " "
398
+ then 0
399
+ else T. length prefixModule + 1 {- Because of "." -}
400
+ in
401
+ cursorColumn - (prefixLength + moduleLength) - 1 {- Points to the first letter of either the module or prefix text -}
402
+
372
403
filtModNameCompls =
373
404
map mkModCompl
374
405
$ mapMaybe (T. stripPrefix enteredQual)
@@ -378,13 +409,23 @@ getCompletions uri prefixInfo (WithSnippets withSnippets) =
378
409
where
379
410
isTypeCompl = isTcOcc . occName . origName
380
411
-- completions specific to the current context
381
- ctxCompls = case context of
412
+ ctxCompls' = case context of
382
413
TypeContext -> filter isTypeCompl compls
383
414
ValueContext -> filter (not . isTypeCompl) compls
415
+ -- Add whether the text to insert has backticks
416
+ ctxCompls = map (\ comp -> comp { isInfix = infixCompls }) ctxCompls'
417
+
418
+ infixCompls :: Maybe Backtick
419
+ infixCompls = case (isUsedAsInfix, hasTrailingBacktick) of
420
+ (True , False ) -> Just LeftSide
421
+ (True , True ) -> Just Surrounded
422
+ _ -> Nothing
423
+
384
424
compls = if T. null prefixModule
385
425
then unqualCompls
386
426
else Map. findWithDefault [] prefixModule qualCompls
387
427
428
+
388
429
mkImportCompl label = (J. detail ?~ label) . mkModCompl $ fromMaybe
389
430
" "
390
431
(T. stripPrefix enteredQual label)
0 commit comments