Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit 172e8cf

Browse files
committed
Ormolu range format
1 parent 83d99ef commit 172e8cf

File tree

1 file changed

+72
-30
lines changed

1 file changed

+72
-30
lines changed
Lines changed: 72 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
1+
{-# LANGUAGE BlockArguments #-}
12
{-# LANGUAGE TypeApplications #-}
23
{-# LANGUAGE OverloadedStrings #-}
34
{-# LANGUAGE CPP #-}
45

5-
module Haskell.Ide.Engine.Plugin.Ormolu ( ormoluDescriptor ) where
6+
module Haskell.Ide.Engine.Plugin.Ormolu
7+
( ormoluDescriptor
8+
)
9+
where
610

7-
import Haskell.Ide.Engine.MonadTypes
11+
import Haskell.Ide.Engine.MonadTypes
812

913
#if __GLASGOW_HASKELL__ >= 806
10-
import Control.Exception
11-
import Control.Monad
12-
import Control.Monad.IO.Class ( liftIO , MonadIO(..) )
13-
import Data.Aeson ( Value ( Null ) )
14-
import Data.List
15-
import Data.Maybe
16-
import qualified Data.Text as T
17-
import Ormolu
18-
import Haskell.Ide.Engine.PluginUtils
19-
import HIE.Bios.Types
14+
import Control.Exception
15+
import Control.Monad
16+
import Control.Monad.IO.Class ( liftIO
17+
, MonadIO(..)
18+
)
19+
import Data.Aeson ( Value(Null) )
20+
import Data.Char
21+
import Data.List
22+
import Data.Maybe
23+
import qualified Data.Text as T
24+
import Ormolu
25+
import Haskell.Ide.Engine.PluginUtils
26+
import HIE.Bios.Types
2027
#endif
2128

2229
ormoluDescriptor :: PluginId -> PluginDescriptor
@@ -34,24 +41,59 @@ ormoluDescriptor plId = PluginDescriptor
3441

3542

3643
provider :: FormattingProvider
37-
provider _contents _uri _typ _opts =
3844
#if __GLASGOW_HASKELL__ >= 806
39-
case _typ of
40-
FormatRange _ -> return $ IdeResultFail (IdeError PluginError (T.pack "Selection formatting for Ormolu is not currently supported.") Null)
41-
FormatText -> pluginGetFile _contents _uri $ \file -> do
42-
opts <- lookupComponentOptions file
43-
let opts' = map DynOption $ filter exop $ join $ maybeToList $ componentOptions <$> opts
44-
conf = Config opts' False False True False
45-
result <- liftIO $ try @OrmoluException (ormolu conf file (T.unpack _contents))
46-
47-
case result of
48-
Left err -> return $ IdeResultFail (IdeError PluginError (T.pack $ "ormoluCmd: " ++ show err) Null)
49-
Right new -> return $ IdeResultOk [TextEdit (fullRange _contents) new]
50-
where
51-
exop s =
52-
"-X" `isPrefixOf` s
53-
|| "-fplugin=" `isPrefixOf` s
54-
|| "-pgmF=" `isPrefixOf` s
45+
provider contents uri typ _ = pluginGetFile contents uri $ \fp -> do
46+
opts <- lookupComponentOptions fp
47+
let opts' =
48+
map DynOption
49+
$ filter exop
50+
$ join
51+
$ maybeToList
52+
$ componentOptions
53+
<$> opts
54+
conf = Config opts' False False True False
55+
fmt :: T.Text -> IdeM (Either OrmoluException T.Text)
56+
fmt cont = liftIO $ try @OrmoluException (ormolu conf fp $ T.unpack cont)
57+
58+
case typ of
59+
FormatText -> ret (fullRange contents) <$> fmt contents
60+
FormatRange r ->
61+
let
62+
txt = T.lines $ extractRange r contents
63+
lineRange (Range (Position sl _) (Position el _)) =
64+
Range (Position sl 0) $ Position el $ T.length $ last txt
65+
-- Pragmas will not be picked up in a non standard location.
66+
pragmas = (takeWhile ("{-#" `T.isPrefixOf`) $ T.lines contents) <> [""]
67+
unStrip ws new =
68+
T.init $ T.unlines $ map (ws `T.append`) $ drop (length pragmas) $ T.lines new
69+
mStrip = case txt of
70+
(l : _) ->
71+
let ws = fst $ T.span isSpace l
72+
in (,) ws . T.unlines <$> traverse (T.stripPrefix ws) txt
73+
_ -> Nothing
74+
in
75+
maybe
76+
(return $ IdeResultFail
77+
(IdeError
78+
PluginError
79+
(T.pack
80+
"You must format a whole block of code. Ormolu does not support arbitrary ranges."
81+
)
82+
Null
83+
)
84+
)
85+
(\(ws, striped) ->
86+
ret (lineRange r)
87+
<$> (fmap (unStrip ws) <$> fmt (T.unlines pragmas <> striped))
88+
)
89+
mStrip
90+
where
91+
ret _ (Left err) = IdeResultFail
92+
(IdeError PluginError (T.pack $ "ormoluCmd: " ++ show err) Null)
93+
ret r (Right new) = IdeResultOk [TextEdit r new]
94+
95+
exop s =
96+
"-X" `isPrefixOf` s || "-fplugin=" `isPrefixOf` s || "-pgmF=" `isPrefixOf` s
5597
#else
56-
return $ IdeResultOk [] -- NOP formatter
98+
provider _ _ _ _ = return $ IdeResultOk [] -- NOP formatter
5799
#endif

0 commit comments

Comments
 (0)