@@ -14,6 +14,7 @@ module Ide.Plugin.ExplicitImports
14
14
, descriptorForModules
15
15
, extractMinimalImports
16
16
, within
17
+ , abbreviateImportTitle
17
18
, Log (.. )
18
19
) where
19
20
@@ -28,6 +29,7 @@ import qualified Data.Map.Strict as Map
28
29
import Data.Maybe (catMaybes , fromMaybe ,
29
30
isJust )
30
31
import qualified Data.Text as T
32
+ import Data.String (fromString )
31
33
import Development.IDE hiding (pluginHandlers ,
32
34
pluginRules )
33
35
import Development.IDE.Core.PositionMapping
@@ -252,7 +254,6 @@ extractMinimalImports (Just hsc) (Just TcModuleResult {..}) = do
252
254
notExported [] _ = True
253
255
notExported exports (L _ ImportDecl {ideclName = L _ name}) =
254
256
not $ any (\ e -> (" module " ++ moduleNameString name) == e) exports
255
- notExported _ _ = False
256
257
extractMinimalImports _ _ = return ([] , Nothing )
257
258
258
259
mkExplicitEdit :: (ModuleName -> Bool ) -> PositionMapping -> LImportDecl GhcRn -> T. Text -> Maybe TextEdit
@@ -269,12 +270,19 @@ mkExplicitEdit pred posMapping (L (locA -> src) imp) explicit
269
270
| otherwise =
270
271
Nothing
271
272
273
+ -- This number is somewhat arbitrarily chosen. Ideally the protocol would tell us these things,
274
+ -- but at the moment I don't believe we know it.
275
+ -- 80 columns is traditional, but Haskellers tend to use longer lines (citation needed) and it's
276
+ -- probably not too bad if the lens is a *bit* longer than normal lines.
277
+ maxColumns :: Int
278
+ maxColumns = 120
279
+
272
280
-- | Given an import declaration, generate a code lens unless it has an
273
281
-- explicit import list or it's qualified
274
282
generateLens :: PluginId -> Uri -> TextEdit -> IO (Maybe CodeLens )
275
283
generateLens pId uri importEdit@ TextEdit {_range, _newText} = do
276
- -- The title of the command is just the minimal explicit import decl
277
- let title = _newText
284
+ let
285
+ title = abbreviateImportTitle _newText
278
286
-- the code lens has no extra data
279
287
_xdata = Nothing
280
288
-- an edit that replaces the whole declaration with the explicit one
@@ -287,6 +295,38 @@ generateLens pId uri importEdit@TextEdit {_range, _newText} = do
287
295
-- create and return the code lens
288
296
return $ Just CodeLens {.. }
289
297
298
+ -- | The title of the command is ideally the minimal explicit import decl, but
299
+ -- we don't want to create a really massive code lens (and the decl can be extremely large!).
300
+ -- So we abbreviate it to fit a max column size, and indicate how many more items are in the list
301
+ -- after the abbreviation
302
+ abbreviateImportTitle :: T. Text -> T. Text
303
+ abbreviateImportTitle input =
304
+ let
305
+ -- For starters, we only want one line in the title
306
+ oneLineText = T. unwords $ T. lines input
307
+ -- Now, split at the max columns, leaving space for the summary text we're going to add
308
+ -- (conservatively assuming we won't need to print a number larger than 100)
309
+ (prefix, suffix) = T. splitAt (maxColumns - (T. length (summaryText 100 ))) oneLineText
310
+ -- We also want to truncate the last item so we get a "clean" break, rather than half way through
311
+ -- something. The conditional here is just because 'breakOnEnd' doesn't give us quite the right thing
312
+ -- if there are actually no commas.
313
+ (actualPrefix, extraSuffix) = if T. count " ," prefix > 0 then T. breakOnEnd " ," prefix else (prefix, " " )
314
+ actualSuffix = extraSuffix <> suffix
315
+
316
+ -- The number of additional items is the number of commas+1
317
+ numAdditionalItems = T. count " ," actualSuffix + 1
318
+ -- We want to make text like this: import Foo (AImport, BImport, ... (30 items))
319
+ -- We also want it to look sensible if we end up splitting in the module name itself,
320
+ summaryText n = " ... (" <> fromString (show n) <> " items)"
321
+ -- so we only add a trailing paren if we've split in the export list
322
+ suffixText = summaryText numAdditionalItems <> if T. count " (" prefix > 0 then " )" else " "
323
+ title =
324
+ -- If the original text fits, just use it
325
+ if T. length oneLineText <= maxColumns
326
+ then oneLineText
327
+ else actualPrefix <> suffixText
328
+ in title
329
+
290
330
--------------------------------------------------------------------------------
291
331
292
332
-- | A helper to run ide actions
0 commit comments