Skip to content

Commit

Permalink
Add fix for import placement
Browse files Browse the repository at this point in the history
  • Loading branch information
nini-faroux committed Nov 25, 2021
1 parent 4b7d139 commit 73b2bfd
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 4 deletions.
28 changes: 25 additions & 3 deletions ghcide/src/Development/IDE/Plugin/CodeAction.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ module Development.IDE.Plugin.CodeAction
import Control.Applicative ((<|>))
import Control.Arrow (second,
(>>>))
import Control.Monad (guard, join)
import Control.Monad (foldM,
guard, join)
import Control.Monad.IO.Class
import Data.Char
import qualified Data.DList as DL
import Data.Either.Extra (fromEither)
import Data.Function
import Data.Functor
import qualified Data.HashMap.Strict as Map
Expand Down Expand Up @@ -1323,12 +1325,32 @@ findNextPragmaPosition contents = Just ((lineNumber, 0), 0)
contents' = T.lines contents

afterPragma :: T.Text -> [T.Text] -> Int -> Int
afterPragma name contents lineNum = lastLineWithPrefix (checkPragma name) contents lineNum
afterPragma name = lastLineWithPrefixMulti (checkPragma name)

lastLineWithPrefix :: (T.Text -> Bool) -> [T.Text] -> Int -> Int
lastLineWithPrefix p contents lineNum = max lineNum next
where
next = maybe lineNum succ $ listToMaybe . reverse $ findIndices p contents
next = maybe lineNum succ $ listToMaybe $ reverse $ findIndices p contents

-- | Accounts for the case where the LANGUAGE or OPTIONS_GHC
-- pragma spans multiple lines or just a single line
lastLineWithPrefixMulti :: (T.Text -> Bool) -> [T.Text] -> Int -> Int
lastLineWithPrefixMulti p contents lineNum = max lineNum next
where
mIndex = listToMaybe . reverse $ findIndices p contents
next = case mIndex of
Nothing -> 0
Just index -> getEndOfPragmaBlock index $ drop index contents

getEndOfPragmaBlock :: Int -> [T.Text] -> Int
getEndOfPragmaBlock start contents = lineNumber
where
lineNumber = fromEither lineNum
lineNum = foldM go start contents
go pos txt
| endOfBlock txt = Left $ pos + 1
| otherwise = Right $ pos + 1
endOfBlock txt = T.dropWhile (/= '}') (T.dropWhile (/= '-') txt) == "}"

checkPragma :: T.Text -> T.Text -> Bool
checkPragma name = check
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards,
OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_GHC -Wall,
-Wno-unused-imports #-}
import Data.Monoid



class Semigroup a => SomeData a

-- | a comment
instance SomeData All
14 changes: 14 additions & 0 deletions ghcide/test/data/import-placement/AfterMultilineOptsPragma.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards,
OverloadedStrings #-}
{-# OPTIONS_GHC -Wno-unused-imports #-}
{-# OPTIONS_GHC -Wall,
-Wno-unused-imports #-}



class Semigroup a => SomeData a

-- | a comment
instance SomeData All
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{-# LANGUAGE RecordWildCards,
OverloadedStrings #-}
import Data.Monoid


class Semigroup a => SomeData a

-- | a comment
instance SomeData All
8 changes: 8 additions & 0 deletions ghcide/test/data/import-placement/AfterMultilinePragma.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{-# LANGUAGE RecordWildCards,
OverloadedStrings #-}


class Semigroup a => SomeData a

-- | a comment
instance SomeData All
4 changes: 3 additions & 1 deletion ghcide/test/exe/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -857,7 +857,9 @@ watchedFilesTests = testGroup "watched files"

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

0 comments on commit 73b2bfd

Please sign in to comment.