@@ -28,6 +28,7 @@ import qualified Data.Map.Strict as Map
28
28
import Data.Maybe (catMaybes , fromMaybe ,
29
29
isJust )
30
30
import qualified Data.Text as T
31
+ import Data.String (fromString )
31
32
import Development.IDE hiding (pluginHandlers ,
32
33
pluginRules )
33
34
import Development.IDE.Core.PositionMapping
@@ -269,12 +270,41 @@ 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
+ -- The title of the command is ideally the minimal explicit import decl, but
286
+ -- we don't want to create a really massive code lens (and the decl can be extremely large!).
287
+ -- So we abbreviate it to fit a max column size, and indicate how many more items are in the list
288
+ -- after the abbreviation
289
+
290
+ -- For starters, we only want one line in the title
291
+ oneLineText = T. unwords $ T. lines _newText
292
+ -- Now, split at the max columns, leaving space for the suffix text we're going to add
293
+ -- (conservatively assuming we won't need to print a number larger than 100)
294
+ (prefix, suffix) = T. splitAt (maxColumns - (T. length (suffixText 100 ))) oneLineText
295
+ -- We also want to truncate the last item so we get a "clean" break, rather than half way through
296
+ -- something. The conditional here is just because 'breakOnEnd' doesn't give us quite the right thing
297
+ -- if there are actually no commas.
298
+ (actualPrefix, extraSuffix) = if T. count " ," prefix > 0 then T. breakOnEnd " ," prefix else (prefix, " " )
299
+ actualSuffix = extraSuffix <> suffix
300
+
301
+ -- The number of additional items is the number of commas+1
302
+ numAdditionalItems = T. count " ," actualSuffix + 1
303
+ -- We want to make text like this: import Foo (AImport, BImport, ... (30 more items))
304
+ -- Trailing paren is to match the opening paren from the import list
305
+ suffixText n = " ... (" <> fromString (show n) <> " more items) )"
306
+ title = if T. length oneLineText <= maxColumns then oneLineText else actualPrefix <> suffixText numAdditionalItems
307
+
278
308
-- the code lens has no extra data
279
309
_xdata = Nothing
280
310
-- an edit that replaces the whole declaration with the explicit one
0 commit comments