Skip to content

Commit afb14c7

Browse files
committed
Add fix for import placement
1 parent 4b7d139 commit afb14c7

File tree

6 files changed

+73
-4
lines changed

6 files changed

+73
-4
lines changed

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ module Development.IDE.Plugin.CodeAction
2121
import Control.Applicative ((<|>))
2222
import Control.Arrow (second,
2323
(>>>))
24-
import Control.Monad (guard, join)
24+
import Control.Monad (foldM,
25+
guard, join)
2526
import Control.Monad.IO.Class
2627
import Data.Char
2728
import qualified Data.DList as DL
@@ -1323,12 +1324,32 @@ findNextPragmaPosition contents = Just ((lineNumber, 0), 0)
13231324
contents' = T.lines contents
13241325

13251326
afterPragma :: T.Text -> [T.Text] -> Int -> Int
1326-
afterPragma name contents lineNum = lastLineWithPrefix (checkPragma name) contents lineNum
1327+
afterPragma name = lastLineWithPrefixMulti (checkPragma name)
13271328

13281329
lastLineWithPrefix :: (T.Text -> Bool) -> [T.Text] -> Int -> Int
13291330
lastLineWithPrefix p contents lineNum = max lineNum next
13301331
where
1331-
next = maybe lineNum succ $ listToMaybe . reverse $ findIndices p contents
1332+
next = maybe lineNum succ $ listToMaybe $ reverse $ findIndices p contents
1333+
1334+
-- | Accounts for the case where the LANGUAGE or OPTIONS_GHC
1335+
-- pragma spans multiple lines or just a single line
1336+
lastLineWithPrefixMulti :: (T.Text -> Bool) -> [T.Text] -> Int -> Int
1337+
lastLineWithPrefixMulti p contents lineNum = max lineNum next
1338+
where
1339+
mIndex = listToMaybe . reverse $ findIndices p contents
1340+
next = case mIndex of
1341+
Nothing -> 0
1342+
Just index -> getEndOfPragmaBlock index $ drop index contents
1343+
1344+
getEndOfPragmaBlock :: Int -> [T.Text] -> Int
1345+
getEndOfPragmaBlock start contents = lineNumber
1346+
where
1347+
lineNumber = either id id lineNum
1348+
lineNum = foldM go start contents
1349+
go pos txt
1350+
| endOfBlock txt = Left $ pos + 1
1351+
| otherwise = Right $ pos + 1
1352+
endOfBlock txt = T.dropWhile (/= '}') (T.dropWhile (/= '-') txt) == "}"
13321353

13331354
checkPragma :: T.Text -> T.Text -> Bool
13341355
checkPragma name = check
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{-# OPTIONS_GHC -Wall #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE RecordWildCards,
4+
OverloadedStrings #-}
5+
{-# OPTIONS_GHC -Wno-unused-imports #-}
6+
{-# OPTIONS_GHC -Wall,
7+
-Wno-unused-imports #-}
8+
import Data.Monoid
9+
10+
11+
12+
class Semigroup a => SomeData a
13+
14+
-- | a comment
15+
instance SomeData All
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{-# OPTIONS_GHC -Wall #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE RecordWildCards,
4+
OverloadedStrings #-}
5+
{-# OPTIONS_GHC -Wno-unused-imports #-}
6+
{-# OPTIONS_GHC -Wall,
7+
-Wno-unused-imports #-}
8+
9+
10+
11+
class Semigroup a => SomeData a
12+
13+
-- | a comment
14+
instance SomeData All
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{-# LANGUAGE RecordWildCards,
2+
OverloadedStrings #-}
3+
import Data.Monoid
4+
5+
6+
class Semigroup a => SomeData a
7+
8+
-- | a comment
9+
instance SomeData All
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{-# LANGUAGE RecordWildCards,
2+
OverloadedStrings #-}
3+
4+
5+
class Semigroup a => SomeData a
6+
7+
-- | a comment
8+
instance SomeData All

ghcide/test/exe/Main.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,9 @@ watchedFilesTests = testGroup "watched files"
857857

858858
insertImportTests :: TestTree
859859
insertImportTests = testGroup "insert import"
860-
[ checkImport "above comment at top of module" "CommentAtTop.hs" "CommentAtTop.expected.hs" "import Data.Monoid"
860+
[ checkImport "after multiline pragmas and opts no module or imports" "AfterMultilineOptsPragma.hs" "AfterMultilineOptsPragma.expected.hs" "import Data.Monoid"
861+
, checkImport "after multiline pragma no module or imports" "AfterMultilinePragma.hs" "AfterMultilinePragma.expected.hs" "import Data.Monoid"
862+
, checkImport "above comment at top of module" "CommentAtTop.hs" "CommentAtTop.expected.hs" "import Data.Monoid"
861863
, checkImport "above multiple comments below" "CommentAtTopMultipleComments.hs" "CommentAtTopMultipleComments.expected.hs" "import Data.Monoid"
862864
, checkImport "above curly brace comment" "CommentCurlyBraceAtTop.hs" "CommentCurlyBraceAtTop.expected.hs" "import Data.Monoid"
863865
, checkImport "above multi-line comment" "MultiLineCommentAtTop.hs" "MultiLineCommentAtTop.expected.hs" "import Data.Monoid"

0 commit comments

Comments
 (0)