@@ -20,7 +20,7 @@ import Control.Monad (filterM, void)
20
20
import Control.Monad.IO.Class (liftIO )
21
21
import Data.String (IsString )
22
22
import qualified Data.Text as T
23
- import Development.IDE (IdeState , runIdeAction )
23
+ import Development.IDE (IdeState ( shakeExtras ) , runIdeAction , useWithStale )
24
24
import Distribution.PackageDescription.Quirks (patchQuirks )
25
25
import Ide.PluginUtils (mkLspCommand )
26
26
import Ide.Types (CommandFunction ,
@@ -30,7 +30,7 @@ import Language.LSP.Protocol.Types (CodeAction (Code
30
30
CodeActionKind (CodeActionKind_QuickFix ),
31
31
Diagnostic (.. ),
32
32
Null (Null ),
33
- type (|? ) (InR ))
33
+ type (|? ) (InR ), toNormalizedFilePath )
34
34
import System.Directory (doesFileExist ,
35
35
listDirectory )
36
36
@@ -43,7 +43,7 @@ import Data.List.NonEmpty (NonEmpty (..),
43
43
import Distribution.Client.Add as Add
44
44
import Distribution.Compat.Prelude (Generic )
45
45
import Distribution.PackageDescription (packageDescription ,
46
- specVersion , GenericPackageDescription )
46
+ specVersion , GenericPackageDescription ( GenericPackageDescription ) )
47
47
import Distribution.PackageDescription.Configuration (flattenPackageDescription )
48
48
import Distribution.Pretty (pretty )
49
49
import Distribution.Simple.BuildTarget (BuildTarget ,
@@ -59,7 +59,14 @@ import System.FilePath (dropFileName,
59
59
import Text.PrettyPrint (render )
60
60
import Text.Regex.TDFA
61
61
import Distribution.Simple.Utils (safeHead )
62
+ import Development.IDE.Core.Rules (runAction )
63
+ import Ide.Plugin.Cabal.Completion.Types (ParseCabalFields (.. ),
64
+ ParseCabalFile (.. ))
62
65
66
+ import Development.IDE.Core.RuleTypes (GetFileContents (.. ))
67
+ import Data.Text.Encoding (encodeUtf8 )
68
+ import Ide.Plugin.Cabal.Orphans ()
69
+ import Distribution.Fields.Field (fieldAnn )
63
70
64
71
-- | Given a path to a haskell file, returns the closest cabal file.
65
72
-- If cabal file wasn't found, dives Nothing.
@@ -134,11 +141,11 @@ data CabalAddCommandParams =
134
141
deriving anyclass (FromJSON , ToJSON )
135
142
136
143
command :: CommandFunction IdeState CabalAddCommandParams
137
- command _ _ (CabalAddCommandParams {cabalPath = path, buildTarget = target, dependency = dep, version = mbVer}) = do
144
+ command state _ (CabalAddCommandParams {cabalPath = path, buildTarget = target, dependency = dep, version = mbVer}) = do
138
145
let specifiedDep = case mbVer of
139
146
Nothing -> dep
140
147
Just ver -> dep <> " ^>=" <> ver
141
- void $ liftIO $ addDependency path target (fromList [T. unpack specifiedDep])
148
+ void $ liftIO $ addDependency state path target (fromList [T. unpack specifiedDep])
142
149
pure $ InR Null
143
150
144
151
-- | Gives cabal file's contents or throws error.
@@ -162,14 +169,29 @@ getBuildTargets gpd cabalFilePath haskellFilePath = do
162
169
--
163
170
-- Inspired by @main@ in cabal-add,
164
171
-- Distribution.Client.Main
165
- addDependency :: FilePath -> Maybe String -> NonEmpty String -> IO ()
166
- addDependency cabalFilePath buildTarget dependency = do
167
-
168
- cnfOrigContents <- readCabalFile cabalFilePath
169
-
170
- (fields, packDescr) <- case parseCabalFile cabalFilePath cnfOrigContents of
171
- Left err -> error err
172
- Right pair -> pure pair
172
+ addDependency :: IdeState -> FilePath -> Maybe String -> NonEmpty String -> IO ()
173
+ addDependency state cabalFilePath buildTarget dependency = do
174
+ (mbCnfOrigContents, mbFields, mbPackDescr) <- liftIO $ runAction " cabal.cabal-add" state $ do
175
+ contents <- useWithStale GetFileContents $ toNormalizedFilePath cabalFilePath
176
+ inFields <- useWithStale ParseCabalFields $ toNormalizedFilePath cabalFilePath
177
+ inPackDescr <- useWithStale ParseCabalFile $ toNormalizedFilePath cabalFilePath
178
+ let mbCnfOrigContents = case snd . fst <$> contents of
179
+ Just (Just txt) -> Just $ encodeUtf8 txt
180
+ _ -> Nothing
181
+ let mbFields = fst <$> inFields
182
+ let mbPackDescr :: Maybe GenericPackageDescription = fst <$> inPackDescr
183
+ pure (mbCnfOrigContents, mbFields, mbPackDescr)
184
+
185
+ (cnfOrigContents, fields, packDescr) <- liftIO $ do
186
+ cnfOrigContents <- case mbCnfOrigContents of
187
+ (Just cnfOrigContents) -> pure cnfOrigContents
188
+ Nothing -> readCabalFile cabalFilePath
189
+ let (fields, packDescr) = case (mbFields, mbPackDescr) of
190
+ (Just fields, Just packDescr) -> (fields, packDescr)
191
+ (_, _) -> case parseCabalFile cabalFilePath cnfOrigContents of
192
+ Left err -> error err
193
+ Right (_ ,gpd) -> pure gpd
194
+ pure (cnfOrigContents, fields, packDescr)
173
195
174
196
let inputs = do
175
197
let rcnfComponent = buildTarget
0 commit comments