@@ -8,56 +8,59 @@ module Ide.Plugin.Cabal (descriptor, Log (..)) where
8
8
9
9
import Control.Concurrent.Strict
10
10
import Control.DeepSeq
11
- import Control.Lens ((^.) )
11
+ import Control.Lens ((^.) )
12
12
import Control.Monad.Extra
13
13
import Control.Monad.IO.Class
14
14
import Control.Monad.Trans.Class
15
- import Control.Monad.Trans.Maybe (runMaybeT )
16
- import qualified Data.ByteString as BS
15
+ import Control.Monad.Trans.Maybe (runMaybeT )
16
+ import qualified Data.ByteString as BS
17
17
import Data.Hashable
18
- import Data.HashMap.Strict (HashMap )
19
- import qualified Data.HashMap.Strict as HashMap
20
- import Data.List (find )
21
- import qualified Data.List.NonEmpty as NE
22
- import qualified Data.Maybe as Maybe
23
- import qualified Data.Text as T
24
- import qualified Data.Text.Encoding as Encoding
18
+ import Data.HashMap.Strict (HashMap )
19
+ import qualified Data.HashMap.Strict as HashMap
20
+ import Data.List (find )
21
+ import qualified Data.List.NonEmpty as NE
22
+ import qualified Data.Maybe as Maybe
23
+ import qualified Data.Text as T
24
+ import qualified Data.Text.Encoding as Encoding
25
25
import Data.Typeable
26
- import Development.IDE as D
26
+ import Debug.Trace
27
+ import Development.IDE as D
27
28
import Development.IDE.Core.PluginUtils
28
- import Development.IDE.Core.Shake (restartShakeSession )
29
- import qualified Development.IDE.Core.Shake as Shake
30
- import Development.IDE.Graph (Key , alwaysRerun )
31
- import qualified Development.IDE.Plugin.Completions.Logic as Ghcide
32
- import Development.IDE.Types.Shake (toKey )
33
- import qualified Distribution.Fields as Syntax
34
- import qualified Distribution.Parsec.Position as Syntax
29
+ import Development.IDE.Core.Shake (restartShakeSession )
30
+ import qualified Development.IDE.Core.Shake as Shake
31
+ import Development.IDE.Graph (Key ,
32
+ alwaysRerun )
33
+ import Development.IDE.LSP.HoverDefinition (foundHover )
34
+ import qualified Development.IDE.Plugin.Completions.Logic as Ghcide
35
+ import Development.IDE.Types.Shake (toKey )
36
+ import qualified Distribution.Fields as Syntax
37
+ import Distribution.Package (Dependency )
38
+ import Distribution.PackageDescription (allBuildDepends ,
39
+ depPkgName ,
40
+ unPackageName )
41
+ import Distribution.PackageDescription.Configuration (flattenPackageDescription )
42
+ import qualified Distribution.Parsec.Position as Syntax
35
43
import GHC.Generics
36
- import Ide.Plugin.Cabal.Completion.CabalFields as CabalFields
37
- import qualified Ide.Plugin.Cabal.Completion.Completer.Types as CompleterTypes
38
- import qualified Ide.Plugin.Cabal.Completion.Completions as Completions
39
- import Ide.Plugin.Cabal.Completion.Types (ParseCabalCommonSections (ParseCabalCommonSections ),
40
- ParseCabalFields (.. ),
41
- ParseCabalFile (.. ))
42
- import qualified Ide.Plugin.Cabal.Completion.Types as Types
43
- import qualified Ide.Plugin.Cabal.Diagnostics as Diagnostics
44
- import qualified Ide.Plugin.Cabal.FieldSuggest as FieldSuggest
45
- import qualified Ide.Plugin.Cabal.LicenseSuggest as LicenseSuggest
46
- import Ide.Plugin.Cabal.Orphans ()
44
+ import Ide.Plugin.Cabal.Completion.CabalFields as CabalFields
45
+ import qualified Ide.Plugin.Cabal.Completion.Completer.Types as CompleterTypes
46
+ import qualified Ide.Plugin.Cabal.Completion.Completions as Completions
47
+ import Ide.Plugin.Cabal.Completion.Types (ParseCabalCommonSections (ParseCabalCommonSections ),
48
+ ParseCabalFields (.. ),
49
+ ParseCabalFile (.. ))
50
+ import qualified Ide.Plugin.Cabal.Completion.Types as Types
51
+ import qualified Ide.Plugin.Cabal.Diagnostics as Diagnostics
52
+ import qualified Ide.Plugin.Cabal.FieldSuggest as FieldSuggest
53
+ import qualified Ide.Plugin.Cabal.LicenseSuggest as LicenseSuggest
54
+ import Ide.Plugin.Cabal.Orphans ()
47
55
import Ide.Plugin.Cabal.Outline
48
- import qualified Ide.Plugin.Cabal.Parse as Parse
56
+ import qualified Ide.Plugin.Cabal.Parse as Parse
49
57
import Ide.Plugin.Error
50
58
import Ide.Types
51
- import qualified Language.LSP.Protocol.Lens as JL
52
- import qualified Language.LSP.Protocol.Message as LSP
59
+ import qualified Language.LSP.Protocol.Lens as JL
60
+ import qualified Language.LSP.Protocol.Message as LSP
53
61
import Language.LSP.Protocol.Types
54
- import qualified Language.LSP.VFS as VFS
55
- import Distribution.PackageDescription.Configuration (flattenPackageDescription )
56
- import Distribution.Package (Dependency ())
57
- import Distribution.PackageDescription (depPkgName , unPackageName , allBuildDepends )
58
- import Development.IDE.LSP.HoverDefinition (foundHover )
62
+ import qualified Language.LSP.VFS as VFS
59
63
import Text.Regex.TDFA
60
- import Debug.Trace
61
64
62
65
63
66
data Log
@@ -299,67 +302,67 @@ fieldSuggestCodeAction recorder ide _ (CodeActionParams _ _ (TextDocumentIdentif
299
302
-- TODO: Support more definitions than sections.
300
303
gotoDefinition :: PluginMethodHandler IdeState LSP. Method_TextDocumentDefinition
301
304
gotoDefinition ideState _ msgParam = do
302
- nfp <- getNormalizedFilePathE uri
303
- cabalFields <- runActionE " cabal-plugin.commonSections" ideState $ useE ParseCabalFields nfp
304
- case CabalFields. findTextWord cursor cabalFields of
305
- Nothing ->
306
- pure $ InR $ InR Null
307
- Just cursorText -> do
308
- commonSections <- runActionE " cabal-plugin.commonSections" ideState $ useE ParseCabalCommonSections nfp
309
- case find (isSectionArgName cursorText) commonSections of
310
- Nothing ->
311
- pure $ InR $ InR Null
312
- Just commonSection -> do
313
- pure $ InL $ Definition $ InL $ Location uri $ CabalFields. getFieldLSPRange commonSection
314
- where
315
- cursor = Types. lspPositionToCabalPosition (msgParam ^. JL. position)
316
- uri = msgParam ^. JL. textDocument . JL. uri
317
- isSectionArgName name (Syntax. Section _ sectionArgName _) = name == CabalFields. onelineSectionArgs sectionArgName
318
- isSectionArgName _ _ = False
319
-
320
- -- | CodeActions for hover messages.
305
+ nfp <- getNormalizedFilePathE uri
306
+ cabalFields <- runActionE " cabal-plugin.commonSections" ideState $ useE ParseCabalFields nfp
307
+ case CabalFields. findTextWord cursor cabalFields of
308
+ Nothing ->
309
+ pure $ InR $ InR Null
310
+ Just cursorText -> do
311
+ commonSections <- runActionE " cabal-plugin.commonSections" ideState $ useE ParseCabalCommonSections nfp
312
+ case find (isSectionArgName cursorText) commonSections of
313
+ Nothing ->
314
+ pure $ InR $ InR Null
315
+ Just commonSection -> do
316
+ pure $ InL $ Definition $ InL $ Location uri $ CabalFields. getFieldLSPRange commonSection
317
+ where
318
+ cursor = Types. lspPositionToCabalPosition (msgParam ^. JL. position)
319
+ uri = msgParam ^. JL. textDocument . JL. uri
320
+ isSectionArgName name (Syntax. Section _ sectionArgName _) = name == CabalFields. onelineSectionArgs sectionArgName
321
+ isSectionArgName _ _ = False
322
+
323
+ -- | Handler for hover messages.
321
324
--
322
- -- Provides a CodeAction for displaying message on hover.
325
+ -- Provides a Handler for displaying message on hover.
323
326
-- If found that the filtered hover message is a dependency,
324
327
-- adds a Documentation link.
325
328
hover :: PluginMethodHandler IdeState LSP. Method_TextDocumentHover
326
329
hover ide _ msgParam = do
327
- nfp <- getNormalizedFilePathE uri
328
- (cabalFields, _) <- runActionE " cabal.cabal-hover" ide $ useWithStaleE ParseCabalFields nfp
329
- let mCursorText = CabalFields. findTextWord cursor cabalFields
330
- case mCursorText of
331
- Nothing ->
332
- pure $ InR Null
333
- Just cursorText -> do
334
- (gpd, _) <- runActionE " cabal.GPD" ide $ useWithStaleE ParseCabalFile nfp
335
- let depsNames = map dependencyName $ allBuildDepends $ flattenPackageDescription gpd
336
- mText = filterVersion cursorText
337
- case mText of
338
- Nothing -> pure $ foundHover ( Nothing , [cursorText])
339
- Just txt ->
340
- if txt `elem` depsNames
341
- then pure $ foundHover (Nothing , [txt <> " \n " , documentationText txt])
342
- else pure $ foundHover ( Nothing , [txt])
330
+ nfp <- getNormalizedFilePathE uri
331
+ (cabalFields, _) <- runActionE " cabal.cabal-hover" ide $ useWithStaleE ParseCabalFields nfp
332
+ let mCursorText = CabalFields. findTextWord cursor cabalFields
333
+ case mCursorText of
334
+ Nothing ->
335
+ pure $ InR Null
336
+ Just cursorText -> do
337
+ (gpd, _) <- runActionE " cabal.GPD" ide $ useWithStaleE ParseCabalFile nfp
338
+ let depsNames = map dependencyName $ allBuildDepends $ flattenPackageDescription gpd
339
+ mText = filterVersion cursorText
340
+ case mText of
341
+ Nothing -> pure $ InR Null
342
+ Just txt ->
343
+ if txt `elem` depsNames
344
+ then pure $ foundHover (Nothing , [txt <> " \n " , documentationText txt])
345
+ else pure $ InR Null
343
346
where
344
- cursor = Types. lspPositionToCabalPosition (msgParam ^. JL. position)
345
- uri = msgParam ^. JL. textDocument . JL. uri
347
+ cursor = Types. lspPositionToCabalPosition (msgParam ^. JL. position)
348
+ uri = msgParam ^. JL. textDocument . JL. uri
346
349
347
- dependencyName :: Dependency -> T. Text
348
- dependencyName dep = T. pack $ unPackageName $ depPkgName dep
350
+ dependencyName :: Dependency -> T. Text
351
+ dependencyName dep = T. pack $ unPackageName $ depPkgName dep
349
352
350
- filterVersion :: T. Text -> Maybe T. Text
351
- filterVersion msg = getMatch (msg =~ regex)
352
- where
353
- regex :: T. Text
354
- regex = " ([a-zA-Z0-9-]*[a-zA-Z0-9]).* "
353
+ filterVersion :: T. Text -> Maybe T. Text
354
+ filterVersion msg = getMatch (msg =~ regex)
355
+ where
356
+ regex :: T. Text
357
+ regex = " ([a-zA-Z0-9-]*[a-zA-Z0-9])"
355
358
356
- getMatch :: (T. Text , T. Text , T. Text , [T. Text ]) -> Maybe T. Text
357
- getMatch (_, _, _, [] ) = Nothing
358
- getMatch (_, _, _, [dependency]) = Just dependency
359
- getMatch (_, _, _, _) = Nothing -- impossible case
359
+ getMatch :: (T. Text , T. Text , T. Text , [T. Text ]) -> Maybe T. Text
360
+ getMatch (_, _, _, [] ) = Nothing
361
+ getMatch (_, _, _, [dependency]) = Just dependency
362
+ getMatch (_, _, _, _) = Nothing -- impossible case
360
363
361
- documentationText :: T. Text -> T. Text
362
- documentationText package = " [Documentation](https://hackage.haskell.org/package/" <> package <> " )"
364
+ documentationText :: T. Text -> T. Text
365
+ documentationText package = " [Documentation](https://hackage.haskell.org/package/" <> package <> " )"
363
366
364
367
-- ----------------------------------------------------------------
365
368
-- Cabal file of Interest rules and global variable
0 commit comments