7
7
module Haskell.Ide.Engine.Plugin.HaRe where
8
8
9
9
import Control.Lens.Operators
10
- import Control.Lens.Setter ((%~) )
11
- import Control.Lens.Traversal (traverseOf )
12
10
import Control.Monad.State
13
11
import Control.Monad.Trans.Control
14
12
import Data.Aeson
@@ -24,14 +22,12 @@ import qualified Data.Text.IO as T
24
22
import Exception
25
23
import GHC.Generics (Generic )
26
24
import qualified GhcMod.Error as GM
27
- import qualified GhcMod.Exe.CaseSplit as GM
28
25
import qualified GhcMod.Monad as GM
29
26
import qualified GhcMod.Utils as GM
30
27
import Haskell.Ide.Engine.ArtifactMap
31
28
import Haskell.Ide.Engine.MonadFunctions
32
29
import Haskell.Ide.Engine.MonadTypes
33
30
import Haskell.Ide.Engine.PluginUtils
34
- import Haskell.Ide.Engine.Plugin.GhcMod (runGhcModCommand )
35
31
import qualified Haskell.Ide.Engine.Plugin.HieExtras as Hie
36
32
import Language.Haskell.GHC.ExactPrint.Print
37
33
import qualified Language.Haskell.LSP.Core as Core
@@ -70,7 +66,7 @@ hareDescriptor plId = PluginDescriptor
70
66
genApplicativeCommand
71
67
72
68
, PluginCommand " casesplit" " Generate a pattern match for a binding under (LINE,COL)"
73
- splitCaseCmd
69
+ Hie. splitCaseCmd
74
70
]
75
71
, pluginCodeActionProvider = Just codeActionProvider
76
72
, pluginDiagnosticProvider = Nothing
@@ -80,29 +76,16 @@ hareDescriptor plId = PluginDescriptor
80
76
81
77
-- ---------------------------------------------------------------------
82
78
83
- customOptions :: Int -> J. Options
84
- customOptions n = J. defaultOptions { J. fieldLabelModifier = J. camelTo2 ' _' . drop n}
85
-
86
- data HarePoint =
87
- HP { hpFile :: Uri
88
- , hpPos :: Position
89
- } deriving (Eq ,Generic ,Show )
90
-
91
- instance FromJSON HarePoint where
92
- parseJSON = genericParseJSON $ customOptions 2
93
- instance ToJSON HarePoint where
94
- toJSON = genericToJSON $ customOptions 2
95
-
96
79
data HarePointWithText =
97
80
HPT { hptFile :: Uri
98
81
, hptPos :: Position
99
82
, hptText :: T. Text
100
83
} deriving (Eq ,Generic ,Show )
101
84
102
85
instance FromJSON HarePointWithText where
103
- parseJSON = genericParseJSON $ customOptions 3
86
+ parseJSON = genericParseJSON $ Hie. customOptions 3
104
87
instance ToJSON HarePointWithText where
105
- toJSON = genericToJSON $ customOptions 3
88
+ toJSON = genericToJSON $ Hie. customOptions 3
106
89
107
90
data HareRange =
108
91
HR { hrFile :: Uri
@@ -111,14 +94,14 @@ data HareRange =
111
94
} deriving (Eq ,Generic ,Show )
112
95
113
96
instance FromJSON HareRange where
114
- parseJSON = genericParseJSON $ customOptions 2
97
+ parseJSON = genericParseJSON $ Hie. customOptions 2
115
98
instance ToJSON HareRange where
116
- toJSON = genericToJSON $ customOptions 2
99
+ toJSON = genericToJSON $ Hie. customOptions 2
117
100
118
101
-- ---------------------------------------------------------------------
119
102
120
- demoteCmd :: CommandFunc HarePoint WorkspaceEdit
121
- demoteCmd = CmdSync $ \ _ (HP uri pos) ->
103
+ demoteCmd :: CommandFunc Hie. HarePoint WorkspaceEdit
104
+ demoteCmd = CmdSync $ \ _ (Hie. HP uri pos) ->
122
105
demoteCmd' uri pos
123
106
124
107
demoteCmd' :: Uri -> Position -> IdeGhcM (IdeResult WorkspaceEdit )
@@ -156,8 +139,8 @@ iftocaseCmd' uri (Range startPos endPos) =
156
139
157
140
-- ---------------------------------------------------------------------
158
141
159
- liftonelevelCmd :: CommandFunc HarePoint WorkspaceEdit
160
- liftonelevelCmd = CmdSync $ \ _ (HP uri pos) ->
142
+ liftonelevelCmd :: CommandFunc Hie. HarePoint WorkspaceEdit
143
+ liftonelevelCmd = CmdSync $ \ _ (Hie. HP uri pos) ->
161
144
liftonelevelCmd' uri pos
162
145
163
146
liftonelevelCmd' :: Uri -> Position -> IdeGhcM (IdeResult WorkspaceEdit )
@@ -169,8 +152,8 @@ liftonelevelCmd' uri pos =
169
152
170
153
-- ---------------------------------------------------------------------
171
154
172
- lifttotoplevelCmd :: CommandFunc HarePoint WorkspaceEdit
173
- lifttotoplevelCmd = CmdSync $ \ _ (HP uri pos) ->
155
+ lifttotoplevelCmd :: CommandFunc Hie. HarePoint WorkspaceEdit
156
+ lifttotoplevelCmd = CmdSync $ \ _ (Hie. HP uri pos) ->
174
157
lifttotoplevelCmd' uri pos
175
158
176
159
lifttotoplevelCmd' :: Uri -> Position -> IdeGhcM (IdeResult WorkspaceEdit )
@@ -195,8 +178,8 @@ renameCmd' uri pos name =
195
178
196
179
-- ---------------------------------------------------------------------
197
180
198
- deleteDefCmd :: CommandFunc HarePoint WorkspaceEdit
199
- deleteDefCmd = CmdSync $ \ _ (HP uri pos) ->
181
+ deleteDefCmd :: CommandFunc Hie. HarePoint WorkspaceEdit
182
+ deleteDefCmd = CmdSync $ \ _ (Hie. HP uri pos) ->
200
183
deleteDefCmd' uri pos
201
184
202
185
deleteDefCmd' :: Uri -> Position -> IdeGhcM (IdeResult WorkspaceEdit )
@@ -208,8 +191,8 @@ deleteDefCmd' uri pos =
208
191
209
192
-- ---------------------------------------------------------------------
210
193
211
- genApplicativeCommand :: CommandFunc HarePoint WorkspaceEdit
212
- genApplicativeCommand = CmdSync $ \ _ (HP uri pos) ->
194
+ genApplicativeCommand :: CommandFunc Hie. HarePoint WorkspaceEdit
195
+ genApplicativeCommand = CmdSync $ \ _ (Hie. HP uri pos) ->
213
196
genApplicativeCommand' uri pos
214
197
215
198
genApplicativeCommand' :: Uri -> Position -> IdeGhcM (IdeResult WorkspaceEdit )
@@ -220,64 +203,6 @@ genApplicativeCommand' uri pos =
220
203
221
204
-- ---------------------------------------------------------------------
222
205
223
- splitCaseCmd :: CommandFunc HarePoint WorkspaceEdit
224
- splitCaseCmd = CmdSync $ \ _ (HP uri pos) -> splitCaseCmd' uri pos
225
-
226
- splitCaseCmd' :: Uri -> Position -> IdeGhcM (IdeResult WorkspaceEdit )
227
- splitCaseCmd' uri newPos =
228
- pluginGetFile " splitCaseCmd: " uri $ \ path -> do
229
- origText <- GM. withMappedFile path $ liftIO . T. readFile
230
- ifCachedModule path (IdeResultOk mempty ) $ \ tm info -> runGhcModCommand $
231
- case newPosToOld info newPos of
232
- Just oldPos -> do
233
- let (line, column) = unPos oldPos
234
- splitResult' <- GM. splits' path tm line column
235
- case splitResult' of
236
- Just splitResult -> do
237
- wEdit <- liftToGhc $ splitResultToWorkspaceEdit origText splitResult
238
- return $ oldToNewPositions info wEdit
239
- Nothing -> return mempty
240
- Nothing -> return mempty
241
- where
242
-
243
- -- | Transform all ranges in a WorkspaceEdit from old to new positions.
244
- oldToNewPositions :: CachedInfo -> WorkspaceEdit -> WorkspaceEdit
245
- oldToNewPositions info wsEdit =
246
- wsEdit
247
- & J. documentChanges %~ (>>= traverseOf (traverse . J. edits . traverse . J. range) (oldRangeToNew info))
248
- & J. changes %~ (>>= traverseOf (traverse . traverse . J. range) (oldRangeToNew info))
249
-
250
- -- | Given the range and text to replace, construct a 'WorkspaceEdit'
251
- -- by diffing the change against the current text.
252
- splitResultToWorkspaceEdit :: T. Text -> GM. SplitResult -> IdeM WorkspaceEdit
253
- splitResultToWorkspaceEdit originalText (GM. SplitResult replaceFromLine replaceFromCol replaceToLine replaceToCol replaceWith) =
254
- diffText (uri, originalText) newText IncludeDeletions
255
- where
256
- before = takeUntil (toPos (replaceFromLine, replaceFromCol)) originalText
257
- after = dropUntil (toPos (replaceToLine, replaceToCol)) originalText
258
- newText = before <> replaceWith <> after
259
-
260
- -- | Take the first part of text until the given position.
261
- -- Returns all characters before the position.
262
- takeUntil :: Position -> T. Text -> T. Text
263
- takeUntil (Position l c) txt =
264
- T. unlines takeLines <> takeCharacters
265
- where
266
- textLines = T. lines txt
267
- takeLines = take l textLines
268
- takeCharacters = T. take c (textLines !! c)
269
-
270
- -- | Drop the first part of text until the given position.
271
- -- Returns all characters after and including the position.
272
- dropUntil :: Position -> T. Text -> T. Text
273
- dropUntil (Position l c) txt = dropCharacters
274
- where
275
- textLines = T. lines txt
276
- dropLines = drop l textLines
277
- dropCharacters = T. drop c (T. unlines dropLines)
278
-
279
- -- ---------------------------------------------------------------------
280
-
281
206
getRefactorResult :: [ApplyRefacResult ] -> [(FilePath ,T. Text )]
282
207
getRefactorResult = map getNewFile . filter fileModified
283
208
where fileModified ((_,m),_) = m == RefacModified
@@ -382,25 +307,25 @@ codeActionProvider pId docId _ _ (J.Range pos _) _ =
382
307
383
308
where
384
309
mkLiftOneAction name = do
385
- let args = [J. toJSON $ HP (docId ^. J. uri) pos]
310
+ let args = [J. toJSON $ Hie. HP (docId ^. J. uri) pos]
386
311
title = " Lift " <> name <> " one level"
387
312
liftCmd <- mkLspCommand pId " liftonelevel" title (Just args)
388
313
return $ J. CodeAction title (Just J. CodeActionRefactorExtract ) mempty Nothing (Just liftCmd)
389
314
390
315
mkLiftTopAction name = do
391
- let args = [J. toJSON $ HP (docId ^. J. uri) pos]
316
+ let args = [J. toJSON $ Hie. HP (docId ^. J. uri) pos]
392
317
title = " Lift " <> name <> " to top level"
393
318
liftCmd <- mkLspCommand pId " lifttotoplevel" title (Just args)
394
319
return $ J. CodeAction title (Just J. CodeActionRefactorExtract ) mempty Nothing (Just liftCmd)
395
320
396
321
mkDemoteAction name = do
397
- let args = [J. toJSON $ HP (docId ^. J. uri) pos]
322
+ let args = [J. toJSON $ Hie. HP (docId ^. J. uri) pos]
398
323
title = " Demote " <> name <> " one level"
399
324
demCmd <- mkLspCommand pId " demote" title (Just args)
400
325
return $ J. CodeAction title (Just J. CodeActionRefactorInline ) mempty Nothing (Just demCmd)
401
326
402
327
mkDeleteAction name = do
403
- let args = [J. toJSON $ HP (docId ^. J. uri) pos]
328
+ let args = [J. toJSON $ Hie. HP (docId ^. J. uri) pos]
404
329
title = " Delete definition of " <> name
405
330
delCmd <- mkLspCommand pId " deletedef" title (Just args)
406
331
return $ J. CodeAction title (Just J. CodeActionRefactor ) mempty Nothing (Just delCmd)
@@ -412,7 +337,7 @@ codeActionProvider pId docId _ _ (J.Range pos _) _ =
412
337
return $ J. CodeAction title (Just J. CodeActionRefactor ) mempty Nothing (Just dupCmd)
413
338
414
339
mkCaseSplitAction name = do
415
- let args = [J. toJSON $ HP (docId ^. J. uri) pos]
340
+ let args = [J. toJSON $ Hie. HP (docId ^. J. uri) pos]
416
341
title = " Case split on " <> name
417
342
splCmd <- mkLspCommand pId " casesplit" title (Just args)
418
343
return $ J. CodeAction title (Just J. CodeActionRefactorRewrite ) mempty Nothing (Just splCmd)
0 commit comments