1
1
{-# LANGUAGE DataKinds #-}
2
2
{-# LANGUAGE DuplicateRecordFields #-}
3
- {-# LANGUAGE FunctionalDependencies #-}
4
- {-# LANGUAGE MultiWayIf #-}
5
3
{-# LANGUAGE OverloadedLabels #-}
4
+ {-# LANGUAGE OverloadedRecordDot #-}
6
5
{-# LANGUAGE OverloadedStrings #-}
7
- {-# LANGUAGE TemplateHaskell #-}
8
6
{-# LANGUAGE ViewPatterns #-}
9
7
10
8
{- |
@@ -31,13 +29,9 @@ module Language.LSP.VFS (
31
29
32
30
-- * Positions and transformations
33
31
CodePointPosition (.. ),
34
- line ,
35
- character ,
36
32
codePointPositionToPosition ,
37
33
positionToCodePointPosition ,
38
34
CodePointRange (.. ),
39
- start ,
40
- end ,
41
35
codePointRangeToRange ,
42
36
rangeToCodePointRange ,
43
37
@@ -51,7 +45,6 @@ module Language.LSP.VFS (
51
45
) where
52
46
53
47
import Colog.Core (LogAction (.. ), Severity (.. ), WithSeverity (.. ), (<&) )
54
- import Control.Lens hiding (parts , (<.>) )
55
48
import Control.Monad
56
49
import Control.Monad.State
57
50
import Data.Foldable (traverse_ )
@@ -70,6 +63,9 @@ import Data.Text.Utf16.Rope.Mixed qualified as Rope
70
63
import GHC.Generics
71
64
import Language.LSP.Protocol.Message qualified as J
72
65
import Language.LSP.Protocol.Types qualified as J
66
+ import Lens.Micro
67
+ import Lens.Micro.Extras
68
+ import Lens.Micro.GHC ()
73
69
import Prettyprinter hiding (line )
74
70
import System.Directory
75
71
import System.FilePath
@@ -79,6 +75,8 @@ import System.IO
79
75
{-# ANN module ("hlint: ignore Eta reduce" :: String) #-}
80
76
{-# ANN module ("hlint: ignore Redundant do" :: String) #-}
81
77
78
+ infix 4 .= , %=
79
+
82
80
-- ---------------------------------------------------------------------
83
81
84
82
data VirtualFile = VirtualFile
@@ -137,8 +135,8 @@ emptyVFS = VFS mempty
137
135
openVFS :: (MonadState VFS m ) => LogAction m (WithSeverity VfsLog ) -> J. TMessage 'J.Method_TextDocumentDidOpen -> m ()
138
136
openVFS logger msg = do
139
137
let
140
- p = msg ^. # params
141
- J. TextDocumentItem (J. toNormalizedUri -> uri) _ version text = p ^. # textDocument
138
+ p = msg. params
139
+ J. TextDocumentItem (J. toNormalizedUri -> uri) _ version text = p. textDocument
142
140
vfile = VirtualFile version 0 (Rope. fromText text)
143
141
logger <& Opening uri `WithSeverity ` Debug
144
142
# vfsMap . at uri .= Just vfile
@@ -149,11 +147,11 @@ openVFS logger msg = do
149
147
changeFromClientVFS :: (MonadState VFS m ) => LogAction m (WithSeverity VfsLog ) -> J. TMessage 'J.Method_TextDocumentDidChange -> m ()
150
148
changeFromClientVFS logger msg = do
151
149
let
152
- J. DidChangeTextDocumentParams vid changes = msg ^. # params
150
+ J. DidChangeTextDocumentParams vid changes = msg. params
153
151
-- the client shouldn't be sending over a null version, only the server, but we just use 0 if that happens
154
152
J. VersionedTextDocumentIdentifier (J. toNormalizedUri -> uri) version = vid
155
153
vfs <- get
156
- case vfs ^. # vfsMap . at uri of
154
+ case vfs ^. # vfsMap . at @ ( Map. Map J. NormalizedUri VirtualFile ) uri of
157
155
Just (VirtualFile _ file_ver contents) -> do
158
156
contents' <- applyChanges logger contents changes
159
157
# vfsMap . at uri .= Just (VirtualFile version (file_ver + 1 ) contents')
@@ -216,7 +214,8 @@ applyDeleteFile logger (J.DeleteFile _ann _kind (J.toNormalizedUri -> uri) optio
216
214
when (options ^? _Just . # recursive . _Just == Just True ) $
217
215
logger <& CantRecursiveDelete uri `WithSeverity ` Warning
218
216
-- Remove and get the old value so we can check if it was missing
219
- old <- # vfsMap . at uri <.= Nothing
217
+ old <- gets (view $ # vfsMap . at uri)
218
+ # vfsMap . at uri .= Nothing
220
219
case old of
221
220
-- It's not entirely clear what the semantics of 'ignoreIfNotExists' are, but if it
222
221
-- doesn't exist and we're not ignoring it, let's at least log it.
@@ -232,18 +231,18 @@ applyTextDocumentEdit logger (J.TextDocumentEdit vid edits) = do
232
231
let sortedEdits = sortOn (Down . editRange) edits
233
232
changeEvents = map editToChangeEvent sortedEdits
234
233
-- TODO: is this right?
235
- vid' = J. VersionedTextDocumentIdentifier ( vid ^. # uri) (case vid ^. # version of J. InL v -> v; J. InR _ -> 0 )
234
+ vid' = J. VersionedTextDocumentIdentifier vid. uri (case vid. version of J. InL v -> v; J. InR _ -> 0 )
236
235
ps = J. DidChangeTextDocumentParams vid' changeEvents
237
236
notif = J. TNotificationMessage " " J. SMethod_TextDocumentDidChange ps
238
237
changeFromClientVFS logger notif
239
238
where
240
239
editRange :: J. TextEdit J. |? J. AnnotatedTextEdit -> J. Range
241
- editRange (J. InR e) = e ^. # range
242
- editRange (J. InL e) = e ^. # range
240
+ editRange (J. InR e) = e. range
241
+ editRange (J. InL e) = e. range
243
242
244
243
editToChangeEvent :: J. TextEdit J. |? J. AnnotatedTextEdit -> J. TextDocumentContentChangeEvent
245
- editToChangeEvent (J. InR e) = J. TextDocumentContentChangeEvent $ J. InL $ J. TextDocumentContentChangePartial {range = e ^. # range, rangeLength = Nothing , text = e ^. # newText}
246
- editToChangeEvent (J. InL e) = J. TextDocumentContentChangeEvent $ J. InL $ J. TextDocumentContentChangePartial {range = e ^. # range, rangeLength = Nothing , text = e ^. # newText}
244
+ editToChangeEvent (J. InR e) = J. TextDocumentContentChangeEvent $ J. InL $ J. TextDocumentContentChangePartial {range = e. range, rangeLength = Nothing , text = e. newText}
245
+ editToChangeEvent (J. InL e) = J. TextDocumentContentChangeEvent $ J. InL $ J. TextDocumentContentChangePartial {range = e. range, rangeLength = Nothing , text = e. newText}
247
246
248
247
applyDocumentChange :: (MonadState VFS m ) => LogAction m (WithSeverity VfsLog ) -> J. DocumentChange -> m ()
249
248
applyDocumentChange logger (J. InL change) = applyTextDocumentEdit logger change
@@ -254,7 +253,7 @@ applyDocumentChange logger (J.InR (J.InR (J.InR change))) = applyDeleteFile logg
254
253
-- | Applies the changes from a 'ApplyWorkspaceEditRequest' to the 'VFS'
255
254
changeFromServerVFS :: forall m . MonadState VFS m => LogAction m (WithSeverity VfsLog ) -> J. TMessage 'J.Method_WorkspaceApplyEdit -> m ()
256
255
changeFromServerVFS logger msg = do
257
- let J. ApplyWorkspaceEditParams _label edit = msg ^. # params
256
+ let J. ApplyWorkspaceEditParams _label edit = msg. params
258
257
J. WorkspaceEdit mChanges mDocChanges _anns = edit
259
258
case mDocChanges of
260
259
Just docChanges -> applyDocumentChanges docChanges
@@ -270,7 +269,7 @@ changeFromServerVFS logger msg = do
270
269
271
270
-- for sorting [DocumentChange]
272
271
project :: J. DocumentChange -> Maybe J. Int32
273
- project (J. InL textDocumentEdit) = case textDocumentEdit ^. # textDocument . # version of
272
+ project (J. InL textDocumentEdit) = case textDocumentEdit. textDocument. version of
274
273
J. InL v -> Just v
275
274
_ -> Nothing
276
275
project _ = Nothing
@@ -313,7 +312,7 @@ persistFileVFS logger dir vfs uri =
313
312
314
313
closeVFS :: (MonadState VFS m ) => LogAction m (WithSeverity VfsLog ) -> J. TMessage 'J.Method_TextDocumentDidClose -> m ()
315
314
closeVFS logger msg = do
316
- let J. DidCloseTextDocumentParams (J. TextDocumentIdentifier (J. toNormalizedUri -> uri)) = msg ^. # params
315
+ let J. DidCloseTextDocumentParams (J. TextDocumentIdentifier (J. toNormalizedUri -> uri)) = msg. params
317
316
logger <& Closing uri `WithSeverity ` Debug
318
317
# vfsMap . at uri .= Nothing
319
318
@@ -330,11 +329,11 @@ applyChanges logger = foldM (applyChange logger)
330
329
331
330
applyChange :: (Monad m ) => LogAction m (WithSeverity VfsLog ) -> Rope -> J. TextDocumentContentChangeEvent -> m Rope
332
331
applyChange logger str (J. TextDocumentContentChangeEvent (J. InL e))
333
- | J. Range (J. Position sl sc) (J. Position fl fc) <- e ^. # range
334
- , txt <- e ^. # text =
332
+ | J. Range (J. Position sl sc) (J. Position fl fc) <- e. range
333
+ , txt <- e. text =
335
334
changeChars logger str (Utf16. Position (fromIntegral sl) (fromIntegral sc)) (Utf16. Position (fromIntegral fl) (fromIntegral fc)) txt
336
335
applyChange _ _ (J. TextDocumentContentChangeEvent (J. InR e)) =
337
- pure $ Rope. fromText $ e ^. # text
336
+ pure $ Rope. fromText $ e. text
338
337
339
338
-- ---------------------------------------------------------------------
340
339
@@ -356,9 +355,9 @@ changeChars logger str start finish new = do
356
355
Unicode code points instead of UTF-16 code units.
357
356
-}
358
357
data CodePointPosition = CodePointPosition
359
- { _line :: J. UInt
358
+ { line :: J. UInt
360
359
-- ^ Line position in a document (zero-based).
361
- , _character :: J. UInt
360
+ , character :: J. UInt
362
361
-- ^ Character offset on a line in a document in *code points* (zero-based).
363
362
}
364
363
deriving (Show , Read , Eq , Ord )
@@ -367,16 +366,13 @@ data CodePointPosition = CodePointPosition
367
366
Unicode code points instead of UTF-16 code units.
368
367
-}
369
368
data CodePointRange = CodePointRange
370
- { _start :: CodePointPosition
369
+ { start :: CodePointPosition
371
370
-- ^ The range's start position.
372
- , _end :: CodePointPosition
371
+ , end :: CodePointPosition
373
372
-- ^ The range's end position.
374
373
}
375
374
deriving (Show , Read , Eq , Ord )
376
375
377
- makeFieldsNoPrefix ''CodePointPosition
378
- makeFieldsNoPrefix ''CodePointRange
379
-
380
376
{- Note [Converting between code points and code units]
381
377
This is inherently a somewhat expensive operation, but we take some care to minimize the cost.
382
378
In particular, we use the good asymptotics of 'Rope' to our advantage:
@@ -464,3 +460,9 @@ rangeLinesFromVfs (VirtualFile _ _ ropetext) (J.Range (J.Position lf _cf) (J.Pos
464
460
(_, s1) = Rope. splitAtLine (fromIntegral lf) ropetext
465
461
(s2, _) = Rope. splitAtLine (fromIntegral (lt - lf)) s1
466
462
r = Rope. toText s2
463
+
464
+ (.=) :: MonadState s m => ASetter s s a b -> b -> m ()
465
+ l .= b = modify (l .~ b)
466
+
467
+ (%=) :: MonadState s m => ASetter s s a b -> (a -> b ) -> m ()
468
+ l %= f = modify (l %~ f)
0 commit comments