@@ -78,6 +78,12 @@ type ModuleName = T.Text
78
78
type SymbolName = T. Text
79
79
type DatatypeName = T. Text
80
80
81
+ -- | Wrapper for a FilePath that is used as an Input file for HsImport
82
+ newtype InputFilePath = MkInputFilePath { getInput :: FilePath }
83
+
84
+ -- | Wrapper for a FilePath that is used as an Output file for HsImport
85
+ newtype OutputFilePath = MkOutputFilePath { getOutput :: FilePath }
86
+
81
87
-- | How to import a module.
82
88
-- Can be used to express to import a whole module or only specific symbols
83
89
-- from a module.
@@ -128,7 +134,11 @@ importModule uri impStyle modName =
128
134
tmpDir <- liftIO getTemporaryDirectory
129
135
(output, outputH) <- liftIO $ openTempFile tmpDir " hsimportOutput"
130
136
liftIO $ hClose outputH
131
- let args = importStyleToHsImportArgs input output modName impStyle
137
+ let args = importStyleToHsImportArgs
138
+ (MkInputFilePath input)
139
+ (MkOutputFilePath output)
140
+ modName
141
+ impStyle
132
142
-- execute hsimport on the given file and write into a temporary file.
133
143
maybeErr <- liftIO $ HsImport. hsimportWithArgs HsImport. defaultConfig args
134
144
case maybeErr of
@@ -207,12 +217,12 @@ importModule uri impStyle modName =
207
217
-- | Convert the import style arguments into HsImport arguments.
208
218
-- Takes an input and an output file as well as a module name.
209
219
importStyleToHsImportArgs
210
- :: FilePath -> FilePath -> ModuleName -> ImportStyle -> HsImport. HsImportArgs
220
+ :: InputFilePath -> OutputFilePath -> ModuleName -> ImportStyle -> HsImport. HsImportArgs
211
221
importStyleToHsImportArgs input output modName style =
212
222
let defaultArgs = -- Default args, must be set every time.
213
223
HsImport. defaultArgs { HsImport. moduleName = T. unpack modName
214
- , HsImport. inputSrcFile = input
215
- , HsImport. outputSrcFile = output
224
+ , HsImport. inputSrcFile = getInput input
225
+ , HsImport. outputSrcFile = getOutput output
216
226
}
217
227
218
228
kindToArgs :: SymbolKind -> HsImport. HsImportArgs
@@ -393,6 +403,9 @@ codeActionProvider plId docId _ context = do
393
403
--
394
404
-- >>> symName "take :: Int -> [a] -> [a]"
395
405
-- Just "take"
406
+ --
407
+ -- >>> symName "take"
408
+ -- Just "take"
396
409
symName :: T. Text -> Maybe SymbolName
397
410
symName = S. headMay . T. words
398
411
@@ -403,7 +416,7 @@ codeActionProvider plId docId _ context = do
403
416
mkImportAction modName importDiagnostic symbolType = do
404
417
cmd <- mkLspCommand plId " import" title (Just cmdParams)
405
418
return (Just (codeAction cmd))
406
- where
419
+ where
407
420
codeAction cmd = J. CodeAction title
408
421
(Just J. CodeActionQuickFix )
409
422
(Just (J. List [diagnostic importDiagnostic]))
@@ -413,6 +426,8 @@ codeActionProvider plId docId _ context = do
413
426
<> modName
414
427
<> case termType importDiagnostic of
415
428
Hiding _ -> " hiding "
429
+ -- ^ Note, that it must never happen
430
+ -- in combination with `symbolType == Nothing`
416
431
Import _ -> " "
417
432
<> case symbolType of
418
433
Just s -> case s of
@@ -442,25 +457,27 @@ codeActionProvider plId docId _ context = do
442
457
-- This looks at the error message and tries to extract the expected
443
458
-- signature of an unknown function.
444
459
-- If this is not possible, Nothing is returned.
445
- extractImportableTerm :: T. Text -> Maybe (T. Text , ( SymbolImport SymbolType ) )
460
+ extractImportableTerm :: T. Text -> Maybe (T. Text , SymbolImport SymbolType )
446
461
extractImportableTerm dirtyMsg =
447
- let extractedTerm =
448
- asum
449
- [ (\ name -> (name, Import Symbol )) <$> T. stripPrefix " Variable not in scope: " importMsg
450
- , (\ name -> (T. init name, Import Type )) <$> T. stripPrefix " Not in scope: type constructor or class ‘" importMsg
451
- , (\ name -> (name, Import Constructor )) <$> T. stripPrefix " Data constructor not in scope: " importMsg
452
- ]
462
+ let extractedTerm = asum
463
+ [ (\ name -> (name, Import Symbol ))
464
+ <$> T. stripPrefix " Variable not in scope: " importMsg
465
+ , (\ name -> (T. init name, Import Type ))
466
+ <$> T. stripPrefix
467
+ " Not in scope: type constructor or class ‘"
468
+ importMsg
469
+ , (\ name -> (name, Import Constructor ))
470
+ <$> T. stripPrefix " Data constructor not in scope: " importMsg]
453
471
in do
454
- (n, s) <- extractedTerm
455
- let n' = T. strip n
456
- return (n', s)
457
- where
458
- importMsg =
459
- head
460
- -- Get rid of the rename suggestion parts
472
+ (n, s) <- extractedTerm
473
+ let n' = T. strip n
474
+ return (n', s)
475
+ where
476
+ importMsg = head
477
+ -- Get rid of the rename suggestion parts
461
478
$ T. splitOn " Perhaps you meant "
462
479
$ T. replace " \n " " "
463
- -- Get rid of trailing/leading whitespace on each individual line
480
+ -- Get rid of trailing/leading whitespace on each individual line
464
481
$ T. unlines
465
482
$ map T. strip
466
483
$ T. lines
0 commit comments