packages feed

haskell-language-server 2.10.0.0 → 2.11.0.0

raw patch · 47 files changed

+3016/−1108 lines, 47 filesdep −monoid-subclassesdep ~fourmoludep ~ghcidedep ~hiedb

Dependencies removed: monoid-subclasses

Dependency ranges changed: fourmolu, ghcide, hiedb, hlint, hls-graph, hls-plugin-api, hls-test-utils, ormolu, stylish-haskell

Files

ChangeLog.md view
@@ -1,5 +1,74 @@ # Changelog for haskell-language-server ++## 2.11.0.0++- Bindists for GHC 9.12.2+  - Full plugin support, inlcuding refactor plugin+- Bindists for GHC 9.10.2+- Bindists for GHC 9.8.4+- Bindists for GHC 9.6.7+- Bindists for GHC 9.4.8+- Dropped support for Centos 7 as this platform is no longer supported by ghc+- Improved import suggestions for contructors and OverloadedRecordDot fields++### Pull Requests++- Add doc for project-wide renaming+  ([#4584](https://github.com/haskell/haskell-language-server/pull/4584)) by @jian-lin+- Use hie-bios 0.15.0+  ([#4582](https://github.com/haskell/haskell-language-server/pull/4582)) by @fendor+- Allow building HLS with GHC 9.10.2+  ([#4581](https://github.com/haskell/haskell-language-server/pull/4581)) by @fendor+- Fix Plugin support table for 9.12.2+  ([#4580](https://github.com/haskell/haskell-language-server/pull/4580)) by @fendor+- Fix misplaced inlay hints by applying PositionMapping+  ([#4571](https://github.com/haskell/haskell-language-server/pull/4571)) by @jetjinser+- Enable hls-plugin-gadt for ghc-9.12+  ([#4568](https://github.com/haskell/haskell-language-server/pull/4568)) by @GuillaumedeVolpiano+- Remove no longer needed allow-newer+  ([#4566](https://github.com/haskell/haskell-language-server/pull/4566)) by @jhrcek+- Add missing golden files for GHC 9.10 config tests+  ([#4563](https://github.com/haskell/haskell-language-server/pull/4563)) by @jian-lin+- updating the plugins support table for refactor+  ([#4560](https://github.com/haskell/haskell-language-server/pull/4560)) by @GuillaumedeVolpiano+- Enable stylish-haskell for ghc-9.10 and ghc-9.12+  ([#4559](https://github.com/haskell/haskell-language-server/pull/4559)) by @GuillaumedeVolpiano+- Bump haskell-actions/setup from 2.7.10 to 2.7.11+  ([#4557](https://github.com/haskell/haskell-language-server/pull/4557)) by @dependabot[bot]+- Provide code action in hls-eval-plugin+  ([#4556](https://github.com/haskell/haskell-language-server/pull/4556)) by @jian-lin+- enable hlint for ghc-9.12+  ([#4555](https://github.com/haskell/haskell-language-server/pull/4555)) by @GuillaumedeVolpiano+- Enable fourmolu and ormolu for GHC 9.12+  ([#4554](https://github.com/haskell/haskell-language-server/pull/4554)) by @fendor+- Enable hls-cabal-gild-plugin for GHC 9.12.2+  ([#4553](https://github.com/haskell/haskell-language-server/pull/4553)) by @fendor+- Update plugin support table for GHC 9.12.2+  ([#4552](https://github.com/haskell/haskell-language-server/pull/4552)) by @fendor+- Remove allow-newer for hiedb+  ([#4551](https://github.com/haskell/haskell-language-server/pull/4551)) by @jhrcek+- Fix typo of rename plugin config+  ([#4546](https://github.com/haskell/haskell-language-server/pull/4546)) by @jian-lin+- Update the ghcup-metadata generation script+  ([#4545](https://github.com/haskell/haskell-language-server/pull/4545)) by @fendor+- porting hls-refactor to ghc-9.12+  ([#4543](https://github.com/haskell/haskell-language-server/pull/4543)) by @GuillaumedeVolpiano+- add ghcide-bench flag to .cabal file+  ([#4542](https://github.com/haskell/haskell-language-server/pull/4542)) by @juhp+- Revert "link executables dynamically to speed up linking (#4423)"+  ([#4541](https://github.com/haskell/haskell-language-server/pull/4541)) by @fendor+- Support PackageImports in hiddenPackageSuggestion+  ([#4537](https://github.com/haskell/haskell-language-server/pull/4537)) by @jian-lin+- Improve FreeBSD installation docs+  ([#4536](https://github.com/haskell/haskell-language-server/pull/4536)) by @arrowd+- reinstating ignore-plugins-ghc-bounds+  ([#4532](https://github.com/haskell/haskell-language-server/pull/4532)) by @GuillaumedeVolpiano+- Simplify FuzzySearch test (avoid dependency on /usr/share/dict/words)+  ([#4531](https://github.com/haskell/haskell-language-server/pull/4531)) by @jhrcek+- Import suggestion for missing newtype constructor, all types constructor and indirect overloadedrecorddot fields+  ([#4516](https://github.com/haskell/haskell-language-server/pull/4516)) by @guibou+ ## 2.10.0.0  - Bindists for GHC 9.12.2
+ ghcide-test/data/watched-files/reload/reload.cabal view
@@ -0,0 +1,12 @@+cabal-version:      2.4+name:               reload+version:            0.1.0.0+author:             Lin Jian+maintainer:         me@linj.tech+build-type:         Simple++library+  exposed-modules:  MyLib+  build-depends:    base+  hs-source-dirs:   src+  default-language: Haskell2010
+ ghcide-test/data/watched-files/reload/src/MyLib.hs view
@@ -0,0 +1,6 @@+module MyLib (someFunc) where++import Data.List.Split++someFunc :: IO ()+someFunc = putStrLn "someFunc"
ghcide-test/exe/FuzzySearch.hs view
@@ -1,130 +1,52 @@ module FuzzySearch (tests) where -import           Data.Char                  (toLower)-import           Data.Maybe                 (catMaybes)-import qualified Data.Monoid.Textual        as T-import           Data.Text                  (Text, inits, pack)-import qualified Data.Text                  as Text-import           Prelude                    hiding (filter)-import           System.Directory           (doesFileExist)-import           System.IO.Unsafe           (unsafePerformIO)-import           Test.QuickCheck+import           Data.Maybe            (isJust, mapMaybe)+import           Data.Text             (Text)+import qualified Data.Text             as Text+import           Prelude               hiding (filter) import           Test.Tasty-import           Test.Tasty.ExpectedFailure-import           Test.Tasty.QuickCheck      (testProperty)-import qualified Text.Fuzzy                 as Fuzzy-import           Text.Fuzzy                 (Fuzzy (..))+import           Test.Tasty.HUnit+import           Test.Tasty.QuickCheck import           Text.Fuzzy.Parallel  tests :: TestTree tests =   testGroup     "Fuzzy search"-    [ needDictionary $-        testGroup-          "match works as expected on the english dictionary"-          [ testProperty "for legit words" propLegit,-            testProperty "for prefixes" propPrefix,-            testProperty "for typos" propTypo-          ]+    [ testGroup "match"+        [ testCase "empty" $+            match "" "" @?= Just 0+        , testCase "camel case" $+            match "myImportantField" "myImportantField" @?= Just 262124+        , testCase "a" $+            mapMaybe (matchInput "a") ["", "a", "aa", "aaa", "A", "AA", "aA", "Aa"]+              @?= [("a",3),("aa",3),("aaa",3),("aA",3),("Aa",1)]+        ,  testCase "lowercase words" $+            mapMaybe (matchInput "abc") ["abc", "abcd", "axbc", "axbxc", "def"]+              @?= [("abc", 25), ("abcd", 25), ("axbc", 7), ("axbxc", 5)]+        , testCase "lower upper mix" $+            mapMaybe (matchInput "abc") ["abc", "aBc", "axbC", "axBxC", "def"]+              @?= [("abc", 25), ("aBc", 25), ("axbC", 7), ("axBxC", 5)]+        , testCase "prefixes" $+            mapMaybe (matchInput "alpha") (Text.inits "alphabet")+              @?= [("alpha", 119), ("alphab", 119), ("alphabe", 119), ("alphabet", 119)]+        , testProperty "x `isSubsequenceOf` y => match x y returns Just"+            prop_matchIfSubsequence+        ]     ]--test :: Text -> Bool-test candidate = do-  let previous =-        catMaybes-          [ (d,) . Fuzzy.score-              <$> referenceImplementation candidate d "" "" id-            | d <- dictionary-          ]-      new = catMaybes [(d,) <$> match candidate d | d <- dictionary]-  previous == new--propLegit :: Property-propLegit = forAll (elements dictionary) test--propPrefix :: Property-propPrefix = forAll (elements dictionary >>= elements . inits) test--propTypo :: Property-propTypo = forAll typoGen test--typoGen :: Gen Text-typoGen = do-  w <- elements dictionary-  l <- elements [0 .. Text.length w -1]-  let wl = Text.index w l-  c <- elements [ c | c <- ['a' .. 'z'], c /= wl]-  return $ replaceAt w l c--replaceAt :: Text -> Int -> Char -> Text-replaceAt t i c =-  let (l, r) = Text.splitAt i t-   in l <> Text.singleton c <> r--dictionaryPath :: FilePath-dictionaryPath = "/usr/share/dict/words"--{-# ANN dictionary ("HLint: ignore Avoid restricted function" :: String) #-}-{-# NOINLINE dictionary #-}-dictionary :: [Text]-dictionary = unsafePerformIO $ do-  existsDictionary <- doesFileExist dictionaryPath-  if existsDictionary-    then map pack . words <$> readFile dictionaryPath-    else pure []--referenceImplementation :: forall s t.-  (T.TextualMonoid s) =>-  -- | Pattern in lowercase except for first character-  s ->-  -- | The value containing the text to search in.-  t ->-  -- | The text to add before each match.-  s ->-  -- | The text to add after each match.-  s ->-  -- | The function to extract the text from the container.-  (t -> s) ->-  -- | The original value, rendered string and score.-  Maybe (Fuzzy t s)-referenceImplementation pat' t pre post extract =-  if null pat then Just (Fuzzy t result totalScore) else Nothing   where-    null :: (T.TextualMonoid s) => s -> Bool-    null = not . T.any (const True)+    matchInput :: Text -> Text -> Maybe (Text, Int)+    matchInput needle candidate = (candidate,) <$> match needle candidate -    s = extract t-    (totalScore, _currScore, result, pat, _) =-      T.foldl'-        undefined-        ( \(tot, cur, res, pat, isFirst) c ->-            case T.splitCharacterPrefix pat of-              Nothing -> (tot, 0, res <> T.singleton c, pat, isFirst)-              Just (x, xs) ->-                -- the case of the first character has to match-                -- otherwise use lower case since the pattern is assumed lower-                let !c' = if isFirst then c else toLower c-                 in if x == c'-                      then-                        let cur' = cur * 2 + 1-                         in ( tot + cur',-                              cur',-                              res <> pre <> T.singleton c <> post,-                              xs,-                              False-                            )-                      else (tot, 0, res <> T.singleton c, pat, isFirst)-        )-        ( 0,-          1, -- matching at the start gives a bonus (cur = 1)-          mempty,-          pat',-          True-        )-        s+prop_matchIfSubsequence :: Property+prop_matchIfSubsequence =+  forAll genNonEmptyText $ \haystack ->+    forAll (genSubsequence haystack) $ \needle ->+        isJust (match needle haystack)+  where+    genNonEmptyText =+      Text.pack <$> listOf1 (elements $ ['a'..'z'] ++ ['A'..'Z'] ++ ['0'..'9']) -needDictionary :: TestTree -> TestTree-needDictionary-  | null dictionary = ignoreTestBecause ("not found: " <> dictionaryPath)-  | otherwise = id+    genSubsequence :: Text -> Gen Text+    genSubsequence =+        fmap Text.pack . sublistOf . Text.unpack
ghcide-test/exe/UnitTests.hs view
@@ -29,8 +29,6 @@ import           System.IO.Extra                   hiding (withTempDir) import           System.Mem                        (performGC) import           Test.Hls                          (IdeState, def,-                                                    ignoreForGhcVersions,-                                                    GhcVersion(..),                                                     runSessionWithServerInTmpDir,                                                     waitForProgressDone) import           Test.Tasty
ghcide-test/exe/WatchedFileTests.hs view
@@ -3,11 +3,14 @@  module WatchedFileTests (tests) where -import           Config                          (testWithDummyPluginEmpty')+import           Config                          (mkIdeTestFs,+                                                  testWithDummyPlugin',+                                                  testWithDummyPluginEmpty') import           Control.Applicative.Combinators import           Control.Monad.IO.Class          (liftIO) import qualified Data.Aeson                      as A import qualified Data.Text                       as T+import qualified Data.Text.IO                    as T import           Development.IDE.Test            (expectDiagnostics) import           Language.LSP.Protocol.Message import           Language.LSP.Protocol.Types     hiding@@ -18,6 +21,7 @@ import           Language.LSP.Test import           System.Directory import           System.FilePath+import           Test.Hls.FileSystem import           Test.Tasty import           Test.Tasty.HUnit @@ -69,6 +73,17 @@         sendNotification SMethod_WorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams                [FileEvent (filePathToUri $ sessionDir </> "B.hs") FileChangeType_Changed ]         expectDiagnostics [("A.hs", [(DiagnosticSeverity_Error, (3, 4), "Couldn't match expected type '()' with actual type 'Int'", Just "GHC-83865")])]+      , testWithDummyPlugin' "reload HLS after .cabal file changes" (mkIdeTestFs [copyDir ("watched-files" </> "reload")]) $ \sessionDir -> do+          let hsFile = "src" </> "MyLib.hs"+          _ <- openDoc hsFile "haskell"+          expectDiagnostics [(hsFile, [(DiagnosticSeverity_Error, (2, 7), "Could not load module \8216Data.List.Split\8217", Nothing)])]+          let cabalFile = "reload.cabal"+          cabalContent <- liftIO $ T.readFile cabalFile+          let fix = T.replace "build-depends:    base" "build-depends:    base, split"+          liftIO $ T.writeFile cabalFile (fix cabalContent)+          sendNotification SMethod_WorkspaceDidChangeWatchedFiles $ DidChangeWatchedFilesParams+            [ FileEvent (filePathToUri $ sessionDir </> cabalFile) FileChangeType_Changed ]+          expectDiagnostics [(hsFile, [])]     ]   ] 
haskell-language-server.cabal view
@@ -1,7 +1,7 @@ cabal-version:      3.4 category:           Development name:               haskell-language-server-version:            2.10.0.0+version:            2.11.0.0 synopsis:           LSP server for GHC description:   Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>@@ -117,7 +117,7 @@   manual:      True  common cabalfmt-  if flag(cabalfmt)+  if flag(cabalfmt) && flag(cabal)     build-depends: haskell-language-server:hls-cabal-fmt-plugin     cpp-options: -Dhls_cabalfmt @@ -129,15 +129,15 @@  library hls-cabal-fmt-plugin   import:           defaults, pedantic, warnings-  if !flag(cabalfmt)+  if !flag(cabalfmt) || !flag(cabal)     buildable: False   exposed-modules:  Ide.Plugin.CabalFmt   hs-source-dirs:   plugins/hls-cabal-fmt-plugin/src   build-depends:     , directory     , filepath-    , ghcide          == 2.10.0.0-    , hls-plugin-api  == 2.10.0.0+    , ghcide          == 2.11.0.0+    , hls-plugin-api  == 2.11.0.0     , lens     , lsp-types     , mtl@@ -157,8 +157,8 @@     , filepath     , haskell-language-server:hls-cabal-plugin     , haskell-language-server:hls-cabal-fmt-plugin-    , hls-plugin-api        == 2.10.0.0-    , hls-test-utils        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0+    , hls-test-utils        == 2.11.0.0    if flag(isolateCabalfmtTests)     build-tool-depends: cabal-fmt:cabal-fmt ^>=0.1.12@@ -174,7 +174,7 @@   manual:      True  common cabalgild-  if flag(cabalgild) && impl(ghc < 9.11)+  if flag(cabalgild) && flag(cabal)     build-depends: haskell-language-server:hls-cabal-gild-plugin     cpp-options: -Dhls_cabalgild @@ -186,15 +186,15 @@  library hls-cabal-gild-plugin   import:           defaults, pedantic, warnings-  if !flag(cabalgild) || impl(ghc > 9.11)+  if !flag(cabalgild) || !flag(cabal)     buildable: False   exposed-modules:  Ide.Plugin.CabalGild   hs-source-dirs:   plugins/hls-cabal-gild-plugin/src   build-depends:     , directory     , filepath-    , ghcide          == 2.10.0.0-    , hls-plugin-api  == 2.10.0.0+    , ghcide          == 2.11.0.0+    , hls-plugin-api  == 2.11.0.0     , lsp-types     , text     , mtl@@ -203,7 +203,7 @@ -- The `hls-cabal-plugin` is needed for tests, as we need to install notification handlers test-suite hls-cabal-gild-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(cabalgild) || !flag(cabal) || impl(ghc > 9.11)+  if !flag(cabalgild) || !flag(cabal)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-cabal-gild-plugin/test@@ -213,8 +213,8 @@     , filepath     , haskell-language-server:hls-cabal-plugin     , haskell-language-server:hls-cabal-gild-plugin-    , hls-plugin-api        == 2.10.0.0-    , hls-test-utils        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0+    , hls-test-utils        == 2.11.0.0    if flag(isolateCabalGildTests)     -- https://github.com/tfausak/cabal-gild/issues/89@@ -269,10 +269,10 @@     , directory     , filepath     , extra                 >=1.7.4-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hashable-    , hls-plugin-api        == 2.10.0.0-    , hls-graph             == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0+    , hls-graph             == 2.11.0.0     , lens     , lsp                   ^>=2.7     , lsp-types             ^>=2.3@@ -311,7 +311,7 @@     , filepath     , ghcide     , haskell-language-server:hls-cabal-plugin-    , hls-test-utils    == 2.10.0.0+    , hls-test-utils    == 2.11.0.0     , lens     , lsp-types     , text@@ -349,9 +349,9 @@     , extra     , ghc     , ghc-exactprint  >= 1.5 && < 1.13.0.0-    , ghcide          == 2.10.0.0+    , ghcide          == 2.11.0.0     , hls-graph-    , hls-plugin-api  == 2.10.0.0+    , hls-plugin-api  == 2.11.0.0     , lens     , lsp     , mtl@@ -372,7 +372,7 @@   build-depends:     , filepath     , haskell-language-server:hls-class-plugin-    , hls-test-utils     == 2.10.0.0+    , hls-test-utils     == 2.11.0.0     , lens     , lsp-types     , text@@ -406,9 +406,9 @@     , aeson     , containers     , extra-    , ghcide                == 2.10.0.0-    , hiedb                 ^>= 0.6.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hiedb                 ^>= 0.6.0.2+    , hls-plugin-api        == 2.11.0.0     , lens     , lsp                    >=2.7     , sqlite-simple@@ -429,7 +429,7 @@     , extra     , filepath     , haskell-language-server:hls-call-hierarchy-plugin-    , hls-test-utils        == 2.10.0.0+    , hls-test-utils        == 2.11.0.0     , lens     , lsp     , lsp-test@@ -460,9 +460,9 @@   hs-source-dirs:     plugins/hls-eval-plugin/src   other-modules:     Ide.Plugin.Eval.Code-    Ide.Plugin.Eval.CodeLens     Ide.Plugin.Eval.Config     Ide.Plugin.Eval.GHC+    Ide.Plugin.Eval.Handlers     Ide.Plugin.Eval.Parse.Comments     Ide.Plugin.Eval.Parse.Option     Ide.Plugin.Eval.Rules@@ -479,9 +479,9 @@     , filepath     , ghc     , ghc-boot-th-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hls-graph-    , hls-plugin-api        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0     , lens     , lsp     , lsp-types@@ -512,7 +512,7 @@     , filepath     , haskell-language-server:hls-eval-plugin     , hls-plugin-api-    , hls-test-utils   == 2.10.0.0+    , hls-test-utils   == 2.11.0.0     , lens     , lsp-types     , text@@ -542,9 +542,9 @@     , containers     , deepseq     , ghc-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hls-graph-    , hls-plugin-api        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0     , lens     , lsp     , mtl@@ -565,7 +565,7 @@     , extra     , filepath     , haskell-language-server:hls-explicit-imports-plugin-    , hls-test-utils   == 2.10.0.0+    , hls-test-utils   == 2.11.0.0     , lens     , lsp-types     , text@@ -580,23 +580,23 @@   manual:      True  common rename-  if flag(rename) && impl(ghc < 9.11)+  if flag(rename)     build-depends: haskell-language-server:hls-rename-plugin     cpp-options: -Dhls_rename  library hls-rename-plugin   import:           defaults, pedantic, warnings-  if !flag(rename) || impl(ghc > 9.11)+  if !flag(rename)     buildable: False   exposed-modules:  Ide.Plugin.Rename   hs-source-dirs:   plugins/hls-rename-plugin/src   build-depends:     , containers-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hashable-    , hiedb                 ^>= 0.6.0.0+    , hiedb                 ^>= 0.6.0.2     , hie-compat-    , hls-plugin-api        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0     , haskell-language-server:hls-refactor-plugin     , lens     , lsp-types@@ -610,7 +610,7 @@  test-suite hls-rename-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(rename) || impl(ghc > 9.11)+  if !flag(rename)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-rename-plugin/test@@ -621,7 +621,7 @@     , filepath     , hls-plugin-api     , haskell-language-server:hls-rename-plugin-    , hls-test-utils             == 2.10.0.0+    , hls-test-utils             == 2.11.0.0     , lens     , lsp-types     , text@@ -636,13 +636,13 @@   manual:      True  common retrie-  if flag(retrie) && impl(ghc < 9.10)+  if flag(retrie) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds))     build-depends: haskell-language-server:hls-retrie-plugin     cpp-options: -Dhls_retrie  library hls-retrie-plugin   import:           defaults, pedantic, warnings-  if !(flag(retrie) && impl(ghc < 9.10))+  if !(flag(retrie) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds)))     buildable: False   exposed-modules:  Ide.Plugin.Retrie   hs-source-dirs:   plugins/hls-retrie-plugin/src@@ -652,9 +652,9 @@     , containers     , extra     , ghc-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hashable-    , hls-plugin-api        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0     , haskell-language-server:hls-refactor-plugin     , lens     , lsp@@ -673,7 +673,7 @@  test-suite hls-retrie-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !(flag(retrie) && impl(ghc < 9.10))+  if !(flag(retrie) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds)))     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-retrie-plugin/test@@ -683,7 +683,7 @@     , filepath     , hls-plugin-api     , haskell-language-server:{hls-refactor-plugin, hls-retrie-plugin}-    , hls-test-utils             == 2.10.0.0+    , hls-test-utils             == 2.11.0.0     , text  -----------------------------@@ -703,14 +703,14 @@   manual:      True  common hlint-  if flag(hlint) && impl(ghc < 9.10)+  if flag(hlint) && ((impl(ghc < 9.10) || impl(ghc > 9.11)) || flag(ignore-plugins-ghc-bounds))     build-depends: haskell-language-server:hls-hlint-plugin     cpp-options: -Dhls_hlint  library hls-hlint-plugin   import:           defaults, pedantic, warnings   -- https://github.com/ndmitchell/hlint/pull/1594-  if !(flag(hlint)) || impl(ghc > 9.10)+  if !(flag(hlint)) || ((impl(ghc >= 9.10) && impl(ghc < 9.11)) && !flag(ignore-plugins-ghc-bounds))     buildable: False   exposed-modules:  Ide.Plugin.Hlint   hs-source-dirs:   plugins/hls-hlint-plugin/src@@ -720,10 +720,10 @@     , containers     , deepseq     , filepath-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hashable-    , hlint                 >= 3.5 && < 3.9-    , hls-plugin-api        == 2.10.0.0+    , hlint                 >= 3.5 && < 3.11+    , hls-plugin-api        == 2.11.0.0     , lens     , mtl     , refact@@ -753,7 +753,7 @@  test-suite hls-hlint-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if (!flag(hlint)) || impl(ghc > 9.10)+  if !flag(hlint) || ((impl(ghc >= 9.10) && impl(ghc < 9.11)) && !flag(ignore-plugins-ghc-bounds))     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-hlint-plugin/test@@ -767,7 +767,7 @@     , filepath     , haskell-language-server:hls-hlint-plugin     , hls-plugin-api-    , hls-test-utils      == 2.10.0.0+    , hls-test-utils      == 2.11.0.0     , lens     , lsp-types     , text@@ -782,13 +782,13 @@   manual:      True  common stan-  if flag(stan) && impl(ghc < 9.11)+  if flag(stan) && (impl(ghc < 9.11) || flag(ignore-plugins-ghc-bounds))     build-depends: haskell-language-server:hls-stan-plugin     cpp-options: -Dhls_stan  library hls-stan-plugin   import:           defaults, pedantic, warnings-  if !flag(stan) || impl(ghc > 9.11)+  if !flag(stan) || (impl(ghc > 9.11) && !flag(ignore-plugins-ghc-bounds))     buildable: False   exposed-modules:    Ide.Plugin.Stan   hs-source-dirs:     plugins/hls-stan-plugin/src@@ -813,7 +813,7 @@  test-suite hls-stan-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(stan) || impl(ghc > 9.11)+  if !flag(stan) || (impl(ghc > 9.11) && !flag(ignore-plugins-ghc-bounds))     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-stan-plugin/test@@ -822,7 +822,7 @@     , filepath     , haskell-language-server:hls-stan-plugin     , hls-plugin-api-    , hls-test-utils      == 2.10.0.0+    , hls-test-utils      == 2.11.0.0     , lens     , lsp-types     , text@@ -853,8 +853,8 @@     , aeson     , containers     , filepath-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , lsp     , text     , text-rope@@ -871,7 +871,7 @@   build-depends:     , filepath     , haskell-language-server:hls-module-name-plugin-    , hls-test-utils          == 2.10.0.0+    , hls-test-utils          == 2.11.0.0  ----------------------------- -- pragmas plugin@@ -897,8 +897,8 @@     , aeson     , extra     , fuzzy-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , lens     , lens-aeson     , lsp@@ -917,7 +917,7 @@     , aeson     , filepath     , haskell-language-server:hls-pragmas-plugin-    , hls-test-utils      == 2.10.0.0+    , hls-test-utils      == 2.11.0.0     , lens     , lsp-types     , text@@ -932,13 +932,13 @@   manual:      True  common splice-  if flag(splice) && impl(ghc < 9.10)+  if flag(splice) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds))     build-depends: haskell-language-server:hls-splice-plugin     cpp-options: -Dhls_splice  library hls-splice-plugin   import:           defaults, pedantic, warnings-  if !(flag(splice) && impl(ghc < 9.10))+  if !(flag(splice) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds)))     buildable: False   exposed-modules:     Ide.Plugin.Splice@@ -950,8 +950,8 @@     , extra     , foldl     , ghc-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , haskell-language-server:hls-refactor-plugin     , lens     , lsp@@ -966,7 +966,7 @@  test-suite hls-splice-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !(flag(splice) && impl(ghc < 9.10))+  if !(flag(splice) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds)))     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-splice-plugin/test@@ -974,7 +974,7 @@   build-depends:     , filepath     , haskell-language-server:hls-splice-plugin-    , hls-test-utils == 2.10.0.0+    , hls-test-utils == 2.11.0.0     , text  -----------------------------@@ -1001,10 +1001,10 @@   build-depends:     , containers     , extra-    , ghcide               == 2.10.0.0+    , ghcide               == 2.11.0.0     , ghc-boot-th     , hls-graph-    , hls-plugin-api       == 2.10.0.0+    , hls-plugin-api       == 2.11.0.0     , lens     , lsp                  ^>=2.7     , mtl@@ -1029,7 +1029,7 @@   build-depends:     , filepath     , haskell-language-server:hls-alternate-number-format-plugin-    , hls-test-utils       == 2.10.0.0+    , hls-test-utils       == 2.11.0.0     , regex-tdfa     , tasty-quickcheck     , text@@ -1061,8 +1061,8 @@   hs-source-dirs:   plugins/hls-qualify-imported-names-plugin/src   build-depends:     , containers-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , lens     , lsp     , text@@ -1084,7 +1084,7 @@     , text     , filepath     , haskell-language-server:hls-qualify-imported-names-plugin-    , hls-test-utils             == 2.10.0.0+    , hls-test-utils             == 2.11.0.0  ----------------------------- -- code range plugin@@ -1114,9 +1114,9 @@     , containers     , deepseq     , extra-    , ghcide           == 2.10.0.0+    , ghcide           == 2.11.0.0     , hashable-    , hls-plugin-api   == 2.10.0.0+    , hls-plugin-api   == 2.11.0.0     , lens     , lsp     , mtl@@ -1138,7 +1138,7 @@     , bytestring     , filepath     , haskell-language-server:hls-code-range-plugin-    , hls-test-utils             == 2.10.0.0+    , hls-test-utils             == 2.11.0.0     , lens     , lsp     , lsp-test@@ -1166,8 +1166,8 @@   exposed-modules:  Ide.Plugin.ChangeTypeSignature   hs-source-dirs:   plugins/hls-change-type-signature-plugin/src   build-depends:-    , ghcide           == 2.10.0.0-    , hls-plugin-api   == 2.10.0.0+    , ghcide           == 2.11.0.0+    , hls-plugin-api   == 2.11.0.0     , lsp-types     , regex-tdfa     , syb@@ -1191,7 +1191,7 @@   build-depends:     , filepath     , haskell-language-server:hls-change-type-signature-plugin-    , hls-test-utils       == 2.10.0.0+    , hls-test-utils       == 2.11.0.0     , regex-tdfa     , text   default-extensions:@@ -1208,13 +1208,13 @@   manual:      True  common gadt-  if flag(gadt) && impl(ghc < 9.11)+  if flag(gadt)     build-depends: haskell-language-server:hls-gadt-plugin     cpp-options: -Dhls_gadt  library hls-gadt-plugin   import:           defaults, pedantic, warnings-  if !flag(gadt) || impl(ghc > 9.11)+  if !flag(gadt)     buildable: False   exposed-modules:  Ide.Plugin.GADT   other-modules:    Ide.Plugin.GHC@@ -1224,9 +1224,9 @@     , containers     , extra     , ghc-    , ghcide                 == 2.10.0.0+    , ghcide                 == 2.11.0.0     , ghc-exactprint-    , hls-plugin-api         == 2.10.0.0+    , hls-plugin-api         == 2.11.0.0     , haskell-language-server:hls-refactor-plugin     , lens     , lsp                    >=2.7@@ -1238,7 +1238,7 @@  test-suite hls-gadt-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(gadt) || impl(ghc > 9.11)+  if !flag(gadt)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-gadt-plugin/test@@ -1246,7 +1246,7 @@   build-depends:     , filepath     , haskell-language-server:hls-gadt-plugin-    , hls-test-utils              == 2.10.0.0+    , hls-test-utils              == 2.11.0.0     , text  -----------------------------@@ -1273,9 +1273,9 @@     , containers     , deepseq     , extra-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , hashable-    , hls-plugin-api        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0     , lsp                   >=2.7     , text @@ -1291,7 +1291,7 @@   build-depends:     , filepath     , haskell-language-server:hls-explicit-fixity-plugin-    , hls-test-utils              == 2.10.0.0+    , hls-test-utils              == 2.11.0.0     , text  -----------------------------@@ -1314,8 +1314,8 @@     buildable: False   exposed-modules:  Ide.Plugin.ExplicitFields   build-depends:-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , lsp     , lens     , hls-graph@@ -1341,7 +1341,7 @@     , text     , ghcide     , haskell-language-server:hls-explicit-record-fields-plugin-    , hls-test-utils              == 2.10.0.0+    , hls-test-utils              == 2.11.0.0  ----------------------------- -- overloaded record dot plugin@@ -1387,7 +1387,7 @@     , filepath     , text     , haskell-language-server:hls-overloaded-record-dot-plugin-    , hls-test-utils              == 2.10.0.0+    , hls-test-utils              == 2.11.0.0   -----------------------------@@ -1400,21 +1400,21 @@   manual:      True  common floskell-  if flag(floskell) && impl(ghc < 9.10)+  if flag(floskell) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds))     build-depends: haskell-language-server:hls-floskell-plugin     cpp-options: -Dhls_floskell  library hls-floskell-plugin   import:           defaults, pedantic, warnings   -- https://github.com/ennocramer/floskell/pull/82-  if !(flag(floskell) && impl(ghc < 9.10))+  if !(flag(floskell) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds)))     buildable: False   exposed-modules:  Ide.Plugin.Floskell   hs-source-dirs:   plugins/hls-floskell-plugin/src   build-depends:     , floskell        ^>=0.11.0-    , ghcide          == 2.10.0.0-    , hls-plugin-api  == 2.10.0.0+    , ghcide          == 2.11.0.0+    , hls-plugin-api  == 2.11.0.0     , lsp-types       ^>=2.3     , mtl     , text@@ -1422,7 +1422,7 @@  test-suite hls-floskell-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !(flag(floskell) && impl(ghc < 9.10))+  if !(flag(floskell) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds)))     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-floskell-plugin/test@@ -1430,7 +1430,7 @@   build-depends:     , filepath     , haskell-language-server:hls-floskell-plugin-    , hls-test-utils       == 2.10.0.0+    , hls-test-utils       == 2.11.0.0  ----------------------------- -- fourmolu plugin@@ -1442,22 +1442,22 @@   manual:      True  common fourmolu-  if flag(fourmolu) && impl(ghc < 9.11)+  if flag(fourmolu)     build-depends: haskell-language-server:hls-fourmolu-plugin     cpp-options: -Dhls_fourmolu  library hls-fourmolu-plugin   import:           defaults, pedantic, warnings-  if !flag(fourmolu) || impl(ghc > 9.11)+  if !flag(fourmolu)     buildable: False   exposed-modules:  Ide.Plugin.Fourmolu   hs-source-dirs:   plugins/hls-fourmolu-plugin/src   build-depends:     , filepath-    , fourmolu        ^>= 0.14 || ^>= 0.15 || ^>= 0.16+    , fourmolu        ^>= 0.14 || ^>= 0.15 || ^>= 0.16 || ^>=0.17 || ^>=0.18     , ghc-boot-th-    , ghcide          == 2.10.0.0-    , hls-plugin-api  == 2.10.0.0+    , ghcide          == 2.11.0.0+    , hls-plugin-api  == 2.11.0.0     , lens     , lsp     , mtl@@ -1468,7 +1468,7 @@  test-suite hls-fourmolu-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(fourmolu) || impl(ghc > 9.11)+  if !flag(fourmolu)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-fourmolu-plugin/test@@ -1483,7 +1483,7 @@     , filepath     , haskell-language-server:hls-fourmolu-plugin     , hls-plugin-api-    , hls-test-utils       == 2.10.0.0+    , hls-test-utils       == 2.11.0.0     , lsp-test  -----------------------------@@ -1496,13 +1496,13 @@   manual:      True  common ormolu-  if flag(ormolu) && impl(ghc < 9.11)+  if flag(ormolu)     build-depends: haskell-language-server:hls-ormolu-plugin     cpp-options: -Dhls_ormolu  library hls-ormolu-plugin   import:           defaults, pedantic, warnings-  if !flag(ormolu) || impl(ghc > 9.11)+  if !flag(ormolu)     buildable: False   exposed-modules:  Ide.Plugin.Ormolu   hs-source-dirs:   plugins/hls-ormolu-plugin/src@@ -1510,19 +1510,19 @@     , extra     , filepath     , ghc-boot-th-    , ghcide          == 2.10.0.0-    , hls-plugin-api  == 2.10.0.0+    , ghcide          == 2.11.0.0+    , hls-plugin-api  == 2.11.0.0     , lsp     , mtl     , process-extras  >= 0.7.1-    , ormolu          ^>=0.1.2 || ^>= 0.2 || ^>= 0.3 || ^>= 0.5 || ^>= 0.6 || ^>= 0.7+    , ormolu          ^>=0.5.3 || ^>= 0.6 || ^>= 0.7 || ^>=0.8     , text     , transformers   test-suite hls-ormolu-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(ormolu) || impl(ghc > 9.11)+  if !flag(ormolu)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-ormolu-plugin/test@@ -1537,7 +1537,7 @@     , filepath     , haskell-language-server:hls-ormolu-plugin     , hls-plugin-api-    , hls-test-utils     == 2.10.0.0+    , hls-test-utils     == 2.11.0.0     , lsp-types     , ormolu @@ -1551,14 +1551,14 @@   manual:      True  common stylishHaskell-  if flag(stylishHaskell) && impl(ghc < 9.10)+  if flag(stylishHaskell)     build-depends: haskell-language-server:hls-stylish-haskell-plugin     cpp-options: -Dhls_stylishHaskell  library hls-stylish-haskell-plugin   import:           defaults, pedantic, warnings   -- https://github.com/haskell/stylish-haskell/issues/479-  if !(flag(stylishHaskell) && impl(ghc < 9.10))+  if !flag(stylishHaskell)     buildable: False   exposed-modules:  Ide.Plugin.StylishHaskell   hs-source-dirs:   plugins/hls-stylish-haskell-plugin/src@@ -1566,17 +1566,17 @@     , directory     , filepath     , ghc-boot-th-    , ghcide           == 2.10.0.0-    , hls-plugin-api   == 2.10.0.0+    , ghcide           == 2.11.0.0+    , hls-plugin-api   == 2.11.0.0     , lsp-types     , mtl-    , stylish-haskell  ^>=0.12 || ^>=0.13 || ^>=0.14+    , stylish-haskell  >=0.12 && <0.16     , text   test-suite hls-stylish-haskell-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !(flag(stylishHaskell) && impl(ghc < 9.10))+  if !flag(stylishHaskell)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-stylish-haskell-plugin/test@@ -1584,7 +1584,7 @@   build-depends:     , filepath     , haskell-language-server:hls-stylish-haskell-plugin-    , hls-test-utils              == 2.10.0.0+    , hls-test-utils              == 2.11.0.0  ----------------------------- -- refactor plugin@@ -1596,13 +1596,13 @@   manual:      True  common refactor-  if flag(refactor) && impl(ghc < 9.11)+  if flag(refactor)     build-depends: haskell-language-server:hls-refactor-plugin     cpp-options: -Dhls_refactor  library hls-refactor-plugin   import:           defaults, pedantic, warnings-  if !flag(refactor) || impl(ghc > 9.11)+  if !flag(refactor)     buildable: False   exposed-modules:  Development.IDE.GHC.ExactPrint                     Development.IDE.GHC.Compat.ExactPrint@@ -1636,8 +1636,8 @@     , bytestring     , ghc-boot     , regex-tdfa-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , lsp     , text     , text-rope@@ -1661,7 +1661,7 @@  test-suite hls-refactor-plugin-tests   import:           defaults, pedantic, test-defaults, warnings-  if !flag(refactor) || impl(ghc > 9.11)+  if !flag(refactor)     buildable: False   type:             exitcode-stdio-1.0   hs-source-dirs:   plugins/hls-refactor-plugin/test@@ -1675,7 +1675,7 @@     , filepath     , ghcide:ghcide     , haskell-language-server:hls-refactor-plugin-    , hls-test-utils      == 2.10.0.0+    , hls-test-utils      == 2.11.0.0     , lens     , lsp-test     , lsp-types@@ -1722,8 +1722,8 @@     , extra     , text-rope     , mtl                   >= 2.2-    , ghcide                == 2.10.0.0-    , hls-plugin-api        == 2.10.0.0+    , ghcide                == 2.11.0.0+    , hls-plugin-api        == 2.11.0.0     , lens     , lsp                    >=2.6     , text@@ -1733,7 +1733,7 @@     , array     , deepseq     , dlist-    , hls-graph == 2.10.0.0+    , hls-graph == 2.11.0.0     , template-haskell     , data-default     , stm@@ -1754,10 +1754,10 @@     , containers     , data-default     , filepath-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , haskell-language-server:hls-semantic-tokens-plugin-    , hls-plugin-api        == 2.10.0.0-    , hls-test-utils        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0+    , hls-test-utils        == 2.11.0.0     , lens     , lsp     , lsp-test@@ -1787,9 +1787,9 @@   hs-source-dirs:     plugins/hls-notes-plugin/src   build-depends:     , array-    , ghcide == 2.10.0.0-    , hls-graph == 2.10.0.0-    , hls-plugin-api == 2.10.0.0+    , ghcide == 2.11.0.0+    , hls-graph == 2.11.0.0+    , hls-plugin-api == 2.11.0.0     , lens     , lsp >=2.7     , mtl >= 2.2@@ -1815,7 +1815,7 @@   build-depends:     , filepath     , haskell-language-server:hls-notes-plugin-    , hls-test-utils == 2.10.0.0+    , hls-test-utils == 2.11.0.0   default-extensions: OverloadedStrings  ----------------------------@@ -1875,10 +1875,10 @@     , extra     , filepath     , ghc-    , ghcide                == 2.10.0.0+    , ghcide                == 2.11.0.0     , githash               >=0.1.6.1     , hie-bios-    , hls-plugin-api        == 2.10.0.0+    , hls-plugin-api        == 2.11.0.0     , optparse-applicative     , optparse-simple     , prettyprinter         >= 1.7@@ -1981,7 +1981,7 @@     , ghcide:ghcide     , hashable     , hls-plugin-api-    , hls-test-utils == 2.10.0.0+    , hls-test-utils == 2.11.0.0     , lens     , lsp-test     , lsp-types@@ -2007,11 +2007,11 @@   if flag(eval)     cpp-options: -Dhls_eval -- formatters-  if flag(floskell) && impl(ghc < 9.10)+  if flag(floskell) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds))     cpp-options: -Dhls_floskell-  if flag(fourmolu) && impl(ghc < 9.11)+  if flag(fourmolu)     cpp-options: -Dhls_fourmolu-  if flag(ormolu) && impl(ghc < 9.11)+  if flag(ormolu)     cpp-options: -Dhls_ormolu  test-suite wrapper-test@@ -2025,7 +2025,7 @@    build-depends:     , extra-    , hls-test-utils              == 2.10.0.0+    , hls-test-utils              == 2.11.0.0     , process    hs-source-dirs:     test/wrapper@@ -2094,7 +2094,6 @@     , enummapset     , extra     , filepath-    , fuzzy     , ghcide     , hls-plugin-api     , lens@@ -2102,7 +2101,6 @@     , lsp     , lsp-test                ^>=0.17.1     , lsp-types-    , monoid-subclasses     , mtl     , network-uri     , QuickCheck@@ -2120,7 +2118,7 @@     , text     , text-rope     , unordered-containers-    , hls-test-utils == 2.10.0.0+    , hls-test-utils == 2.11.0.0    if impl(ghc <9.3)     build-depends: ghc-typelits-knownnat@@ -2174,9 +2172,14 @@     RecordWildCards     ViewPatterns +flag ghcide-bench+  description: Build the ghcide-bench executable+  default:     True  executable ghcide-bench     import: defaults+    if !flag(ghcide-bench)+      buildable: False     build-depends:         aeson,         bytestring,
plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/CabalAdd.hs view
@@ -190,6 +190,12 @@ -- > It is a member of the hidden package ‘split-0.2.5’. -- > Perhaps you need to add ‘split’ to the build-depends in your .cabal file." --+-- or this if PackageImports extension is used:+--+-- > "Could not find module ‘Data.List.Split’+-- > Perhaps you meant+-- >   Data.List.Split (needs flag -package-id split-0.2.5)"+-- -- It extracts mentioned package names and version numbers. -- In this example, it will be @[("split", "0.2.5")]@ --@@ -204,13 +210,18 @@     msg :: T.Text     msg = _message diag     regex :: T.Text -- TODO: Support multiple packages suggestion-    regex = "It is a member of the hidden package [\8216']([a-zA-Z0-9-]*[a-zA-Z0-9])(-([0-9\\.]*))?[\8217']"+    regex =+        let regex' = "([a-zA-Z0-9-]*[a-zA-Z0-9])(-([0-9\\.]*))?"+        in "It is a member of the hidden package [\8216']" <> regex' <> "[\8217']"+           <> "|"+           <> "needs flag -package-id " <> regex'     -- Have to do this matching because `Regex.TDFA` doesn't(?) support     -- not-capturing groups like (?:message)     getMatch :: (T.Text, T.Text, T.Text, [T.Text]) -> [(T.Text, T.Text)]     getMatch (_, _, _, []) = []-    getMatch (_, _, _, [dependency, _, cleanVersion]) = [(dependency, cleanVersion)]-    getMatch (_, _, _, _) = error "Impossible pattern matching case"+    getMatch (_, _, _, [dependency, _, cleanVersion, "", "", ""]) = [(dependency, cleanVersion)]+    getMatch (_, _, _, ["", "", "", dependency, _, cleanVersion]) = [(dependency, cleanVersion)]+    getMatch (_, _, _, _) = []  command :: Recorder (WithPriority Log) -> CommandFunction IdeState CabalAddCommandParams command recorder state _ params@(CabalAddCommandParams {cabalPath = path, verTxtDocId = verTxtDocId, buildTarget = target, dependency = dep, version = mbVer}) = do
plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Paths.hs view
@@ -7,6 +7,7 @@                                                     BuildInfo (..),                                                     CondTree (condTreeData),                                                     Executable (..),+                                                    ForeignLib (..),                                                     GenericPackageDescription (..),                                                     Library (..),                                                     UnqualComponentName,@@ -117,6 +118,10 @@ -- | Extracts the source directories of benchmark stanza with the given name. sourceDirsExtractionBenchmark :: Maybe StanzaName -> GenericPackageDescription -> [FilePath] sourceDirsExtractionBenchmark name gpd = extractRelativeDirsFromStanza name gpd condBenchmarks benchmarkBuildInfo++-- | Extracts the source directories of foreign-lib stanza with the given name.+sourceDirsExtractionForeignLib :: Maybe StanzaName -> GenericPackageDescription -> [FilePath]+sourceDirsExtractionForeignLib name gpd = extractRelativeDirsFromStanza name gpd condForeignLibs foreignLibBuildInfo  {- | Takes a possible stanza name, a GenericPackageDescription,   a function to access the stanza information we are interested in
plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs view
@@ -1,8 +1,5 @@ {-# LANGUAGE OverloadedStrings #-}-{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} -{-# HLINT ignore "Redundant bracket" #-}- module Ide.Plugin.Cabal.Completion.Data where  import           Data.Map                                       (Map)@@ -19,6 +16,17 @@ import           Ide.Plugin.Cabal.Completion.Types import           Ide.Plugin.Cabal.LicenseSuggest                (licenseNames) +-- | Ad-hoc data type for modelling the available top-level stanzas.+-- Not intended right now for anything else but to avoid string+-- comparisons in 'stanzaKeywordMap' and 'libExecTestBenchCommons'.+data TopLevelStanza+  = Library+  | Executable+  | TestSuite+  | Benchmark+  | ForeignLib+  | Common+ -- ---------------------------------------------------------------- -- Completion Data -- ----------------------------------------------------------------@@ -71,12 +79,13 @@ stanzaKeywordMap :: Map StanzaType (Map KeyWordName Completer) stanzaKeywordMap =   Map.fromList-    [ ("library", libraryFields <> libExecTestBenchCommons),-      ("executable", executableFields <> libExecTestBenchCommons),-      ("test-suite", testSuiteFields <> libExecTestBenchCommons),-      ("benchmark", benchmarkFields <> libExecTestBenchCommons),-      ("foreign-library", foreignLibraryFields <> libExecTestBenchCommons),-      ("common", libExecTestBenchCommons),+    [ ("library", libraryFields <> libExecTestBenchCommons Library),+      ("executable", executableFields <> libExecTestBenchCommons Executable),+      ("test-suite", testSuiteFields <> libExecTestBenchCommons TestSuite),+      ("benchmark", benchmarkFields <> libExecTestBenchCommons Benchmark),+      ("foreign-library", foreignLibraryFields <> libExecTestBenchCommons ForeignLib),+      ("common", libExecTestBenchCommons Library),+      ("common", libExecTestBenchCommons Common),       ("flag", flagFields),       ("source-repository", sourceRepositoryFields)     ]@@ -162,8 +171,8 @@       ("lib-version-linux:", noopCompleter)     ] -libExecTestBenchCommons :: Map KeyWordName Completer-libExecTestBenchCommons =+libExecTestBenchCommons :: TopLevelStanza -> Map KeyWordName Completer+libExecTestBenchCommons st =   Map.fromList     [ ("import:", importCompleter),       ("build-depends:", noopCompleter),@@ -183,6 +192,8 @@       ("includes:", filePathCompleter),       ("install-includes:", filePathCompleter),       ("include-dirs:", directoryCompleter),+      ("autogen-includes:", filePathCompleter),+      ("autogen-modules:", moduleCompleterByTopLevelStanza),       ("c-sources:", filePathCompleter),       ("cxx-sources:", filePathCompleter),       ("asm-sources:", filePathCompleter),@@ -203,6 +214,26 @@       ("extra-framework-dirs:", directoryCompleter),       ("mixins:", noopCompleter)     ]+  where+    --+    moduleCompleterByTopLevelStanza = case st of+      Library -> modulesCompleter sourceDirsExtractionLibrary+      Executable -> modulesCompleter sourceDirsExtractionExecutable+      TestSuite -> modulesCompleter sourceDirsExtractionTestSuite+      Benchmark -> modulesCompleter sourceDirsExtractionBenchmark+      ForeignLib -> modulesCompleter sourceDirsExtractionForeignLib+      Common ->+        -- TODO: We can't provide a module completer because we provide+        -- module completions based on the "hs-source-dirs" after parsing the file,+        -- i.e. based on the 'PackageDescription'.+        -- "common" stanzas are erased in the 'PackageDescription' representation,+        -- thus we can't provide accurate module completers right now, as we don't+        -- know what the 'hs-source-dirs' in the "common" stanza are.+        --+        -- A potential fix would be to introduce an intermediate representation that+        -- parses the '.cabal' file s.t. that we have access to the 'hs-source-dirs',+        -- but not have erased the "common" stanza.+        noopCompleter  -- | Contains a map of the most commonly used licenses, weighted by their popularity. --
plugins/hls-cabal-plugin/test/CabalAdd.hs view
@@ -33,6 +33,8 @@         (generateAddDependencyTestSession "cabal-add-lib.cabal" ("src" </> "MyLib.hs") "split" [348])     , runHaskellTestCaseSession "Code Actions - Can add hidden package to a test" ("cabal-add-testdata" </> "cabal-add-tests")         (generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" </> "Main.hs") "split" [478])+    , runHaskellTestCaseSession "Code Actions - Can add hidden package to a test with PackageImports" ("cabal-add-testdata" </> "cabal-add-tests")+        (generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" </> "MainPackageImports.hs") "split" [731])     , runHaskellTestCaseSession "Code Actions - Can add hidden package to a benchmark" ("cabal-add-testdata" </> "cabal-add-bench")         (generateAddDependencyTestSession "cabal-add-bench.cabal" ("bench" </> "Main.hs") "split" [403]) @@ -121,6 +123,23 @@                                    ]                                    [ ("3d-graphics-examples", T.empty)                                    , ("3d-graphics-examples", "1.1.6")+                                   ]+    , testHiddenPackageSuggestions "Check CabalAdd's parser, with version, with PackageImports"+                                   [ "(needs flag -package-id base-0.1.0.0)"+                                   , "(needs flag -package-id Blammo-wai-0.11.0)"+                                   , "(needs flag -package-id BlastHTTP-2.6.4.3)"+                                   , "(needs flag -package-id CC-delcont-ref-tf-0.0.0.2)"+                                   , "(needs flag -package-id 3d-graphics-examples-1.1.6)"+                                   , "(needs flag -package-id AAI-0.1)"+                                   , "(needs flag -package-id AWin32Console-1.19.1)"+                                   ]+                                   [ ("base","0.1.0.0")+                                   , ("Blammo-wai", "0.11.0")+                                   , ("BlastHTTP", "2.6.4.3")+                                   , ("CC-delcont-ref-tf", "0.0.0.2")+                                   , ("3d-graphics-examples", "1.1.6")+                                   , ("AAI", "0.1")+                                   , ("AWin32Console", "1.19.1")                                    ]     ]  where
plugins/hls-cabal-plugin/test/Completer.hs view
@@ -7,6 +7,7 @@  import           Control.Lens                                   ((^.), (^?)) import           Control.Lens.Prism+import           Control.Monad                                  (forM_) import qualified Data.ByteString                                as ByteString import qualified Data.ByteString.Char8                          as BS8 import           Data.Maybe                                     (mapMaybe)@@ -40,7 +41,8 @@       completionHelperTests,       filePathExposedModulesTests,       exposedModuleCompleterTests,-      importCompleterTests+      importCompleterTests,+      autogenFieldCompletionTests     ]  basicCompleterTests :: TestTree@@ -335,6 +337,26 @@           (Syntax.Name (Syntax.Position row col) "common")           [Syntax.SecArgName (Syntax.Position row (col + 7)) (BS8.pack name)]           []++autogenFieldCompletionTests :: TestTree+autogenFieldCompletionTests =+  testGroup "Autogen Field Completer Tests"+    [ testAutogenField "library"         "completion/autogen-completion.cabal" (Position 6 9)  ["autogen-modules:", "autogen-includes:"]+    , testAutogenField "executable"      "completion/autogen-completion.cabal" (Position 11 9) ["autogen-modules:", "autogen-includes:"]+    , testAutogenField "test-suite"      "completion/autogen-completion.cabal" (Position 16 9) ["autogen-modules:", "autogen-includes:"]+    , testAutogenField "benchmark"       "completion/autogen-completion.cabal" (Position 21 9) ["autogen-modules:", "autogen-includes:"]+    , testAutogenField "common"          "completion/autogen-completion.cabal" (Position 24 9) ["autogen-modules:", "autogen-includes:"]+    ]++  where+    testAutogenField :: String -> FilePath -> Position -> [T.Text] -> TestTree+    testAutogenField section file pos expected = runCabalTestCaseSession ("autogen-modules completion in " <> section) "" $ do+      doc <- openDoc file "cabal"+      items <- getCompletions doc pos+      let labels = map (^. L.label) items+      liftIO $ forM_ expected $ \expect ->+        assertBool (T.unpack expect <> " not found in " <> section) $+          any (expect `T.isInfixOf`) labels  simpleCompleterData :: Maybe StanzaName -> FilePath -> T.Text -> CompleterData simpleCompleterData sName dir pref = do
plugins/hls-cabal-plugin/test/Main.hs view
@@ -131,29 +131,6 @@                 expectNoMoreDiagnostics 1 hsDoc "typechecking"                 cabalDoc <- openDoc "simple-cabal.cabal" "cabal"                 expectNoMoreDiagnostics 1 cabalDoc "parsing"-            , runCabalTestCaseSession "Diagnostics in .hs files from invalid .cabal file" "simple-cabal" $ do-                    hsDoc <- openDoc "A.hs" "haskell"-                    expectNoMoreDiagnostics 1 hsDoc "typechecking"-                    cabalDoc <- openDoc "simple-cabal.cabal" "cabal"-                    expectNoMoreDiagnostics 1 cabalDoc "parsing"-                    let theRange = Range (Position 3 20) (Position 3 23)-                    -- Invalid license-                    changeDoc-                        cabalDoc-                        [ TextDocumentContentChangeEvent $-                            InL TextDocumentContentChangePartial-                                { _range = theRange-                                , _rangeLength = Nothing-                                , _text = "MIT3"-                                }-                        ]-                    cabalDiags <- waitForDiagnosticsFrom cabalDoc-                    unknownLicenseDiag <- liftIO $ inspectDiagnostic cabalDiags ["Unknown SPDX license identifier: 'MIT3'"]-                    expectNoMoreDiagnostics 1 hsDoc "typechecking"-                    liftIO $ do-                        length cabalDiags @?= 1-                        unknownLicenseDiag ^. L.range @?= Range (Position 3 24) (Position 4 0)-                        unknownLicenseDiag ^. L.severity @?= Just DiagnosticSeverity_Error             ]         ] -- ----------------------------------------------------------------------------
plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal view
@@ -16,3 +16,11 @@     hs-source-dirs:   test     main-is:          Main.hs     build-depends:    base++test-suite cabal-add-tests-test-package-imports+    import:           warnings+    default-language: Haskell2010+    type:             exitcode-stdio-1.0+    hs-source-dirs:   test+    main-is:          MainPackageImports.hs+    build-depends:    base
+ plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs view
@@ -0,0 +1,8 @@+{-# LANGUAGE PackageImports #-}++module Main (main) where++import "split" Data.List.Split++main :: IO ()+main = putStrLn "Test suite not yet implemented."
+ plugins/hls-cabal-plugin/test/testdata/completion/autogen-completion.cabal view
@@ -0,0 +1,25 @@+cabal-version: 3.0+name: autogen-completion+version: 0.1.0.0++library+  hs-source-dirs: src+  autogen-++executable autoexe+  main-is: Main.hs+  hs-source-dirs: src+  autogen-++test-suite autotest+  type: exitcode-stdio-1.0+  hs-source-dirs: src+  autogen-++benchmark autobench+  type: exitcode-stdio-1.0+  hs-source-dirs: src+  autogen-++common defaults+  autogen-
plugins/hls-eval-plugin/src/Ide/Plugin/Eval.hs view
@@ -13,8 +13,8 @@  import           Development.IDE               (IdeState) import           Ide.Logger                    (Recorder, WithPriority)-import qualified Ide.Plugin.Eval.CodeLens      as CL import           Ide.Plugin.Eval.Config+import qualified Ide.Plugin.Eval.Handlers      as Handlers import           Ide.Plugin.Eval.Rules         (rules) import qualified Ide.Plugin.Eval.Types         as Eval import           Ide.Types                     (ConfigDescriptor (..),@@ -27,9 +27,12 @@ -- |Plugin descriptor descriptor :: Recorder (WithPriority Eval.Log) -> PluginId -> PluginDescriptor IdeState descriptor recorder plId =-    (defaultPluginDescriptor plId "Provies a code lens to evaluate expressions in doctest comments")-        { pluginHandlers = mkPluginHandler SMethod_TextDocumentCodeLens (CL.codeLens recorder)-        , pluginCommands = [CL.evalCommand recorder plId]+    (defaultPluginDescriptor plId "Provies code action and lens to evaluate expressions in doctest comments")+        { pluginHandlers = mconcat+            [ mkPluginHandler SMethod_TextDocumentCodeAction (Handlers.codeAction recorder)+            , mkPluginHandler SMethod_TextDocumentCodeLens (Handlers.codeLens recorder)+            ]+        , pluginCommands = [Handlers.evalCommand recorder plId]         , pluginRules = rules recorder         , pluginConfigDescriptor = defaultConfigDescriptor                                    { configCustomConfig = mkCustomConfig properties
− plugins/hls-eval-plugin/src/Ide/Plugin/Eval/CodeLens.hs
@@ -1,675 +0,0 @@-{-# LANGUAGE CPP                       #-}-{-# LANGUAGE DuplicateRecordFields     #-}-{-# LANGUAGE ExtendedDefaultRules      #-}-{-# LANGUAGE NoMonomorphismRestriction #-}-{-# LANGUAGE OverloadedStrings         #-}-{-# LANGUAGE RecordWildCards           #-}-{-# LANGUAGE ViewPatterns              #-}-{-# OPTIONS_GHC -Wno-type-defaults #-}--{- |-A plugin inspired by the REPLoid feature of <https://github.com/jyp/dante Dante>, <https://www.haskell.org/haddock/doc/html/ch03s08.html#idm140354810775744 Haddock>'s Examples and Properties and <https://hackage.haskell.org/package/doctest Doctest>.--For a full example see the "Ide.Plugin.Eval.Tutorial" module.--}-module Ide.Plugin.Eval.CodeLens (-    codeLens,-    evalCommand,-) where--import           Control.Applicative                          (Alternative ((<|>)))-import           Control.Arrow                                (second)-import           Control.Exception                            (bracket_)-import qualified Control.Exception                            as E-import           Control.Lens                                 (ix, (%~), (^.))-import           Control.Monad                                (guard, void,-                                                               when)-import           Control.Monad.IO.Class                       (MonadIO (liftIO))-import           Control.Monad.Trans.Except                   (ExceptT (..),-                                                               runExceptT)-import           Data.Aeson                                   (toJSON)-import           Data.Char                                    (isSpace)-import           Data.Foldable                                (toList)-import           Data.List                                    (dropWhileEnd,-                                                               find,-                                                               intercalate,-                                                               intersperse)-import qualified Data.Map                                     as Map-import           Data.Maybe                                   (catMaybes)-import           Data.String                                  (IsString)-import           Data.Text                                    (Text)-import qualified Data.Text                                    as T-import qualified Data.Text.Utf16.Rope.Mixed                   as Rope-import           Development.IDE.Core.FileStore               (getUriContents)-import           Development.IDE.Core.Rules                   (IdeState,-                                                               runAction)-import           Development.IDE.Core.RuleTypes               (LinkableResult (linkableHomeMod),-                                                               TypeCheck (..),-                                                               tmrTypechecked)-import           Development.IDE.Core.Shake                   (useNoFile_, use_,-                                                               uses_)-import           Development.IDE.GHC.Compat                   hiding (typeKind,-                                                               unitState)-import           Development.IDE.GHC.Compat.Util              (OverridingBool (..))-import           Development.IDE.GHC.Util                     (evalGhcEnv,-                                                               modifyDynFlags)-import           Development.IDE.Import.DependencyInformation (transitiveDeps,-                                                               transitiveModuleDeps)-import           Development.IDE.Types.Location               (toNormalizedFilePath')-import           GHC                                          (ClsInst,-                                                               ExecOptions (execLineNumber, execSourceFile),-                                                               FamInst,-                                                               GhcMonad,-                                                               NamedThing (getName),-                                                               defaultFixity,-                                                               execOptions,-                                                               exprType,-                                                               getInfo,-                                                               getInteractiveDynFlags,-                                                               isImport, isStmt,-                                                               parseName,-                                                               pprFamInst,-                                                               pprInstance,-                                                               typeKind)---import           Development.IDE.Core.RuleTypes               (GetLinkable (GetLinkable),-                                                               GetModSummary (GetModSummary),-                                                               GetModuleGraph (GetModuleGraph),-                                                               GhcSessionDeps (GhcSessionDeps),-                                                               ModSummaryResult (msrModSummary))-import           Development.IDE.Core.Shake                   (VFSModified (VFSUnmodified))-import qualified Development.IDE.GHC.Compat.Core              as Compat (InteractiveImport (IIModule))-import qualified Development.IDE.GHC.Compat.Core              as SrcLoc (unLoc)-import           Development.IDE.Types.HscEnvEq               (HscEnvEq (hscEnv))-import qualified GHC.LanguageExtensions.Type                  as LangExt (Extension (..))--import           Development.IDE.Core.FileStore               (setSomethingModified)-import           Development.IDE.Core.PluginUtils-import           Development.IDE.Types.Shake                  (toKey)-import           GHC.Types.SrcLoc                             (UnhelpfulSpanReason (UnhelpfulInteractive))-import           Ide.Logger                                   (Priority (..),-                                                               Recorder,-                                                               WithPriority,-                                                               logWith)-import           Ide.Plugin.Error                             (PluginError (PluginInternalError),-                                                               handleMaybeM)-import           Ide.Plugin.Eval.Code                         (Statement,-                                                               asStatements,-                                                               myExecStmt,-                                                               propSetup,-                                                               resultRange,-                                                               testCheck,-                                                               testRanges)-import           Ide.Plugin.Eval.Config                       (EvalConfig (..),-                                                               getEvalConfig)-import           Ide.Plugin.Eval.GHC                          (addImport,-                                                               addPackages,-                                                               hasPackage,-                                                               setSessionAndInteractiveDynFlags)-import           Ide.Plugin.Eval.Parse.Comments               (commentsToSections)-import           Ide.Plugin.Eval.Parse.Option                 (parseSetFlags)-import           Ide.Plugin.Eval.Rules                        (queueForEvaluation,-                                                               unqueueForEvaluation)-import           Ide.Plugin.Eval.Types-import           Ide.Plugin.Eval.Util                         (gStrictTry,-                                                               isLiterate,-                                                               prettyWarnings,-                                                               response', timed)-import           Ide.Types-import qualified Language.LSP.Protocol.Lens                   as L-import           Language.LSP.Protocol.Message-import           Language.LSP.Protocol.Types-import           Language.LSP.Server-#if MIN_VERSION_ghc(9,11,0)-import           GHC.Unit.Module.ModIface                     (IfaceTopEnv (..))-#endif---{- | Code Lens provider- NOTE: Invoked every time the document is modified, not just when the document is saved.--}-codeLens :: Recorder (WithPriority Log) -> PluginMethodHandler IdeState Method_TextDocumentCodeLens-codeLens recorder st plId CodeLensParams{_textDocument} =-    let dbg = logWith recorder Debug-        perf = timed (\lbl duration -> dbg $ LogExecutionTime lbl duration)-     in perf "codeLens" $-            do-                let TextDocumentIdentifier uri = _textDocument-                fp <- uriToFilePathE uri-                let nfp = toNormalizedFilePath' fp-                    isLHS = isLiterate fp-                dbg $ LogCodeLensFp fp-                (comments, _) <--                    runActionE "eval.GetParsedModuleWithComments" st $ useWithStaleE GetEvalComments nfp-                dbg $ LogCodeLensComments comments--                -- Extract tests from source code-                let Sections{..} = commentsToSections isLHS comments-                    tests = testsBySection nonSetupSections-                    cmd = mkLspCommand plId evalCommandName "Evaluate=..." (Just [])-                let lenses =-                        [ CodeLens testRange (Just cmd') Nothing-                        | (section, ident, test) <- tests-                        , let (testRange, resultRange) = testRanges test-                              args = EvalParams (setupSections ++ [section]) _textDocument ident-                              cmd' =-                                (cmd :: Command)-                                    { _arguments = Just [toJSON args]-                                    , _title =-                                        if trivial resultRange-                                            then "Evaluate..."-                                            else "Refresh..."-                                    }-                        ]--                perf "tests" $-                    dbg $ LogTests-                            (length tests)-                            (length nonSetupSections)-                            (length setupSections)-                            (length lenses)--                return $ InL lenses-  where-    trivial (Range p p') = p == p'--evalCommandName :: CommandId-evalCommandName = "evalCommand"--evalCommand :: Recorder (WithPriority Log) -> PluginId -> PluginCommand IdeState-evalCommand recorder plId = PluginCommand evalCommandName "evaluate" (runEvalCmd recorder plId)--type EvalId = Int--runEvalCmd :: Recorder (WithPriority Log) -> PluginId -> CommandFunction IdeState EvalParams-runEvalCmd recorder plId st mtoken EvalParams{..} =-    let dbg = logWith recorder Debug-        perf = timed (\lbl duration -> dbg $ LogExecutionTime lbl duration)-        cmd :: ExceptT PluginError (HandlerM Config) WorkspaceEdit-        cmd = do-            let tests = map (\(a,_,b) -> (a,b)) $ testsBySection sections--            let TextDocumentIdentifier{_uri} = module_-            fp <- uriToFilePathE _uri-            let nfp = toNormalizedFilePath' fp-            mdlText <- moduleText st _uri--            -- enable codegen for the module which we need to evaluate.-            final_hscEnv <- liftIO $ bracket_-              (setSomethingModified VFSUnmodified st "Eval" $ do-                queueForEvaluation st nfp-                return [toKey IsEvaluating nfp]-                )-              (setSomethingModified VFSUnmodified st "Eval" $ do-                unqueueForEvaluation st nfp-                return [toKey IsEvaluating nfp]-                )-              (initialiseSessionForEval (needsQuickCheck tests) st nfp)--            evalCfg <- liftIO $ runAction "eval: config" st $ getEvalConfig plId--            -- Perform the evaluation of the command-            edits <--                perf "edits" $-                    liftIO $-                        evalGhcEnv final_hscEnv $ do-                            runTests recorder evalCfg fp tests--            let workspaceEditsMap = Map.singleton _uri (addFinalReturn mdlText edits)-            let workspaceEdits = WorkspaceEdit (Just workspaceEditsMap) Nothing Nothing--            return workspaceEdits-     in perf "evalCmd" $ ExceptT $-            pluginWithIndefiniteProgress "Evaluating" mtoken Cancellable $ \_updater ->-                runExceptT $ response' cmd---- | Create an HscEnv which is suitable for performing interactive evaluation.--- All necessary home modules will have linkables and the current module will--- also be loaded into the environment.------ The interactive context and interactive dynamic flags are also set appropiately.-initialiseSessionForEval :: Bool -> IdeState -> NormalizedFilePath -> IO HscEnv-initialiseSessionForEval needs_quickcheck st nfp = do-  (ms, env1) <- runAction "runEvalCmd" st $ do--    ms <- msrModSummary <$> use_ GetModSummary nfp-    deps_hsc <- hscEnv <$> use_ GhcSessionDeps nfp--    linkables_needed <- transitiveDeps <$> useNoFile_ GetModuleGraph <*> pure nfp-    linkables <- uses_ GetLinkable (nfp : maybe [] transitiveModuleDeps linkables_needed)-    -- We unset the global rdr env in mi_globals when we generate interfaces-    -- See Note [Clearing mi_globals after generating an iface]-    -- However, the eval plugin (setContext specifically) requires the rdr_env-    -- for the current module - so get it from the Typechecked Module and add-    -- it back to the iface for the current module.-    tm <- tmrTypechecked <$> use_ TypeCheck nfp-    let rdr_env = tcg_rdr_env tm-    let linkable_hsc = loadModulesHome (map (addRdrEnv . linkableHomeMod) linkables) deps_hsc-        addRdrEnv hmi-          | iface <- hm_iface hmi-          , ms_mod ms == mi_module iface-#if MIN_VERSION_ghc(9,11,0)-          = hmi { hm_iface = set_mi_top_env (Just $ IfaceTopEnv (forceGlobalRdrEnv (globalRdrEnvLocal rdr_env)) (mkIfaceImports $ tcg_import_decls tm)) iface}-#else-          = hmi { hm_iface = iface { mi_globals = Just $!-#if MIN_VERSION_ghc(9,8,0)-                    forceGlobalRdrEnv-#endif-                      rdr_env-                }}-#endif-          | otherwise = hmi--    return (ms, linkable_hsc)-  -- Bit awkward we need to use evalGhcEnv here but setContext requires to run-  -- in the Ghc monad-  env2 <- liftIO $ evalGhcEnv env1 $ do-            setContext [Compat.IIModule (moduleName (ms_mod ms))]-            let df = flip xopt_set    LangExt.ExtendedDefaultRules-                   . flip xopt_unset  LangExt.MonomorphismRestriction-                   . flip gopt_set    Opt_ImplicitImportQualified-                   . flip gopt_unset  Opt_DiagnosticsShowCaret-                   . setBackend ghciBackend-                   $ (ms_hspp_opts ms) {-                        useColor = Never-                      , canUseColor = False }-            modifyDynFlags (const df)-            when needs_quickcheck $ void $ addPackages ["QuickCheck"]-            getSession-  return env2--#if MIN_VERSION_ghc(9,11,0)-mkIfaceImports :: [ImportUserSpec] -> [IfaceImport]-mkIfaceImports = map go-  where-    go (ImpUserSpec decl ImpUserAll) = IfaceImport decl ImpIfaceAll-    go (ImpUserSpec decl (ImpUserExplicit env)) = IfaceImport decl (ImpIfaceExplicit (forceGlobalRdrEnv env))-    go (ImpUserSpec decl (ImpUserEverythingBut ns)) = IfaceImport decl (ImpIfaceEverythingBut ns)-#endif--addFinalReturn :: Text -> [TextEdit] -> [TextEdit]-addFinalReturn mdlText edits-    | not (null edits) && not (T.null mdlText) && T.last mdlText /= '\n' =-        finalReturn mdlText : edits-    | otherwise = edits--finalReturn :: Text -> TextEdit-finalReturn txt =-    let ls = T.lines txt-        l = fromIntegral $ length ls -1-        c = fromIntegral $ T.length . last $ ls-        p = Position l c-     in TextEdit (Range p p) "\n"--moduleText :: IdeState -> Uri -> ExceptT PluginError (HandlerM config) Text-moduleText state uri = do-    contents <--        handleMaybeM (PluginInternalError "mdlText") $-            liftIO $-                runAction "eval.getUriContents" state $-                    getUriContents $-                        toNormalizedUri uri-    pure $ Rope.toText contents--testsBySection :: [Section] -> [(Section, EvalId, Test)]-testsBySection sections =-    [(section, ident, test)-    | (ident, section) <- zip [0..] sections-    , test <- sectionTests section-    ]--type TEnv = String--- |GHC declarations required for expression evaluation-evalSetup :: Ghc ()-evalSetup = do-    preludeAsP <- parseImportDecl "import qualified Prelude as P"-    context <- getContext-    setContext (IIDecl preludeAsP : context)--runTests :: Recorder (WithPriority Log) -> EvalConfig -> TEnv -> [(Section, Test)] -> Ghc [TextEdit]-runTests recorder EvalConfig{..} e tests = do-    df <- getInteractiveDynFlags-    evalSetup-    when (hasQuickCheck df && needsQuickCheck tests) $ void $ evals recorder True e df propSetup--    mapM (processTest e df) tests-  where-    processTest :: TEnv -> DynFlags -> (Section, Test) -> Ghc TextEdit-    processTest fp df (section, test) = do-        let dbg = logWith recorder Debug-        let pad = pad_ $ (if isLiterate fp then ("> " `T.append`) else id) $ padPrefix (sectionFormat section)-        rs <- runTest e df test-        dbg $ LogRunTestResults rs--        let checkedResult = testCheck eval_cfg_diff (section, test) rs-        let resultLines = concatMap T.lines checkedResult--        let edit = asEdit (sectionFormat section) test (map pad resultLines)-        dbg $ LogRunTestEdits edit-        return edit--    -- runTest :: String -> DynFlags -> Loc Test -> Ghc [Text]-    runTest _ df test-        | not (hasQuickCheck df) && isProperty test =-            return $-                singleLine-                    "Add QuickCheck to your cabal dependencies to run this test."-    runTest e df test = evals recorder (eval_cfg_exception && not (isProperty test)) e df (asStatements test)--asEdit :: Format -> Test -> [Text] -> TextEdit-asEdit (MultiLine commRange) test resultLines-    -- A test in a block comment, ending with @-\}@ without newline in-between.-    | testRange test ^. L.end . L.line == commRange ^. L.end . L.line-    =-    TextEdit-        (Range-            (testRange test ^. L.end)-            (resultRange test ^. L.end)-        )-        ("\n" <> T.unlines (resultLines <> ["-}"]))-asEdit _ test resultLines =-    TextEdit (resultRange test) (T.unlines resultLines)--{- |-The result of evaluating a test line can be:-* a value-* nothing-* a (possibly multiline) error message--A value is returned for a correct expression.--Either a pure value:->>> 'h' :"askell"-"haskell"--Or an 'IO a' (output on stdout/stderr is ignored):->>> print "OK" >> return "ABC"-"ABC"--Nothing is returned for a correct directive:-->>>:set -XFlexibleInstances->>> import Data.Maybe--Nothing is returned for a correct declaration (let..,x=, data, class)-->>> let x = 11->>> y = 22->>> data B = T | F->>> class C a--Nothing is returned for an empty line:-->>>--A, possibly multi line, error is returned for a wrong declaration, directive or value or an exception thrown by the evaluated code:-->>>:set -XNonExistent-Some flags have not been recognized: -XNonExistent-->>> cls C-Variable not in scope: cls :: t0 -> t-Data constructor not in scope: C-->>> "A-lexical error in string/character literal at end of input--Exceptions are shown as if printed, but it can be configured to include prefix like-in GHCi or doctest. This allows it to be used as a hack to simulate print until we-get proper IO support. See #1977-->>> 3 `div` 0-divide by zero-->>> error "Something went wrong\nbad times" :: E.SomeException-Something went wrong-bad times--Or for a value that does not have a Show instance and can therefore not be displayed:->>> data V = V->>> V-No instance for (Show V) arising from a use of ‘evalPrint’--}-evals :: Recorder (WithPriority Log) -> Bool -> TEnv -> DynFlags -> [Statement] -> Ghc [Text]-evals recorder mark_exception fp df stmts = do-    er <- gStrictTry $ mapM eval stmts-    return $ case er of-        Left err -> errorLines err-        Right rs -> concat . catMaybes $ rs-  where-    dbg = logWith recorder Debug-    eval :: Statement -> Ghc (Maybe [Text])-    eval (Located l stmt)-        | -- GHCi flags-          Just (words -> flags) <- parseSetFlags stmt = do-            dbg $ LogEvalFlags flags-            ndf <- getInteractiveDynFlags-            dbg $ LogEvalPreSetDynFlags ndf-            eans <--                liftIO $ try @GhcException $-                parseDynamicFlagsCmdLine ndf-                (map (L $ UnhelpfulSpan unhelpfulReason) flags)-            dbg $ LogEvalParsedFlags eans-            case eans of-                Left err -> pure $ Just $ errorLines $ show err-                Right (df', ignoreds, warns) -> do-                    let warnings = do-                            guard $ not $ null warns-                            pure $ errorLines $-                                prettyWarnings warns-                        igns = do-                            guard $ not $ null ignoreds-                            pure-                                ["Some flags have not been recognized: "-                                <> T.pack (intercalate ", " $ map SrcLoc.unLoc ignoreds)-                                ]-                    dbg $ LogEvalPostSetDynFlags df'-                    setSessionAndInteractiveDynFlags df'-                    pure $ warnings <> igns-        | -- A type/kind command-          Just (cmd, arg) <- parseGhciLikeCmd $ T.pack stmt =-            evalGhciLikeCmd cmd arg-        | -- A statement-          isStmt pf stmt =-            do-                dbg $ LogEvalStmtStart stmt-                res <- exec stmt l-                let r = case res of-                        Left err -> Just . (if mark_exception then exceptionLines else errorLines) $ err-                        Right x  -> singleLine <$> x-                dbg $ LogEvalStmtResult r-                return r-        | -- An import-          isImport pf stmt =-            do-                dbg $ LogEvalImport stmt-                _ <- addImport stmt-                return Nothing-        | -- A declaration-          otherwise =-            do-                dbg $ LogEvalDeclaration stmt-                void $ runDecls stmt-                return Nothing-    pf = initParserOpts df-    unhelpfulReason = UnhelpfulInteractive-    exec stmt l =-        let opts = execOptions{execSourceFile = fp, execLineNumber = l}-         in myExecStmt stmt opts--needsQuickCheck :: [(Section, Test)] -> Bool-needsQuickCheck = any (isProperty . snd)--hasQuickCheck :: DynFlags -> Bool-hasQuickCheck df = hasPackage df "QuickCheck"--singleLine :: String -> [Text]-singleLine s = [T.pack s]--{- |- Convert error messages to a list of text lines- Remove unnecessary information.--}-errorLines :: String -> [Text]-errorLines =-        dropWhileEnd T.null-        . takeWhile (not . (\x -> "CallStack" `T.isPrefixOf` x || "HasCallStack" `T.isPrefixOf` x))-        . T.lines-        . T.pack--{- |- Convert exception messages to a list of text lines- Remove unnecessary information and mark it as exception.- We use '*** Exception:' to make it identical to doctest- output, see #2353.--}-exceptionLines :: String -> [Text]-exceptionLines = (ix 0 %~ ("*** Exception: " <>)) . errorLines--{- |->>> map (pad_ (T.pack "--")) (map T.pack ["2+2",""])-["--2+2","--<BLANKLINE>"]--}-pad_ :: Text -> Text -> Text-pad_ prefix = (prefix `T.append`) . convertBlank--convertBlank :: Text -> Text-convertBlank x-    | T.null x = "<BLANKLINE>"-    | otherwise = x--padPrefix :: IsString p => Format -> p-padPrefix SingleLine = "-- "-padPrefix _          = ""--{- | Resulting @Text@ MUST NOT prefix each line with @--@-   Such comment-related post-process will be taken place-   solely in 'evalGhciLikeCmd'.--}-type GHCiLikeCmd = DynFlags -> Text -> Ghc (Maybe Text)---- Should we use some sort of trie here?-ghciLikeCommands :: [(Text, GHCiLikeCmd)]-ghciLikeCommands =-    [ ("info", doInfoCmd False)-    , ("info!", doInfoCmd True)-    , ("kind", doKindCmd False)-    , ("kind!", doKindCmd True)-    , ("type", doTypeCmd)-    ]--evalGhciLikeCmd :: Text -> Text -> Ghc (Maybe [Text])-evalGhciLikeCmd cmd arg = do-    df <- getSessionDynFlags-    case lookup cmd ghciLikeCommands-        <|> snd-        <$> find (T.isPrefixOf cmd . fst) ghciLikeCommands of-        Just hndler ->-            fmap-                T.lines-                <$> hndler df arg-        _ -> E.throw $ GhciLikeCmdNotImplemented cmd arg--doInfoCmd :: Bool -> DynFlags -> Text -> Ghc (Maybe Text)-doInfoCmd allInfo dflags s = do-    sdocs <- mapM infoThing (T.words s)-    pure $ Just $ T.pack $ showSDoc dflags (vcat sdocs)-    where-        infoThing :: GHC.GhcMonad m => Text -> m SDoc-        infoThing (T.unpack -> str) = do-            names     <- GHC.parseName str-            mb_stuffs <- mapM (GHC.getInfo allInfo) names-            let filtered = filterOutChildren (\(t,_f,_ci,_fi,_sd) -> t)-                                            (catMaybes $ toList mb_stuffs)-            return $ vcat (intersperse (text "") $ map pprInfo filtered)--        filterOutChildren :: (a -> TyThing) -> [a] -> [a]-        filterOutChildren get_thing xs-            = filter (not . has_parent) xs-            where-                all_names = mkNameSet (map (getName . get_thing) xs)-                has_parent x = case tyThingParent_maybe (get_thing x) of-                                Just p  -> getName p `elemNameSet` all_names-                                Nothing -> False--        pprInfo :: (TyThing, Fixity, [GHC.ClsInst], [GHC.FamInst], SDoc) -> SDoc-        pprInfo (thing, fixity, cls_insts, fam_insts, docs)-            =  docs-            $$ pprTyThingInContextLoc thing-            $$ showFixity thing fixity-            $$ vcat (map GHC.pprInstance cls_insts)-            $$ vcat (map GHC.pprFamInst  fam_insts)--        pprTyThingInContextLoc :: TyThing -> SDoc-        pprTyThingInContextLoc tyThing-            = showWithLoc (pprDefinedAt (getName tyThing))-                          (pprTyThingInContext showToHeader tyThing)--        showWithLoc :: SDoc -> SDoc -> SDoc-        showWithLoc loc doc-            = hang doc 2 (text "\t--" <+> loc)--        showFixity :: TyThing -> Fixity -> SDoc-        showFixity thing fixity-            | fixity /= GHC.defaultFixity || isSymOcc (getOccName thing)-                = ppr fixity <+> pprInfixName (GHC.getName thing)-            | otherwise = empty--doKindCmd :: Bool -> DynFlags -> Text -> Ghc (Maybe Text)-doKindCmd False df arg = do-    let input = T.strip arg-    (_, kind) <- typeKind False $ T.unpack input-    let kindText = text (T.unpack input) <+> "::" <+> pprSigmaType kind-    pure $ Just $ T.pack (showSDoc df kindText)-doKindCmd True df arg = do-    let input = T.strip arg-    (ty, kind) <- typeKind True $ T.unpack input-    let kindDoc = text (T.unpack input) <+> "::" <+> pprSigmaType kind-        tyDoc = "=" <+> pprSigmaType ty-    pure $ Just $ T.pack (showSDoc df $ kindDoc $$ tyDoc)--doTypeCmd :: DynFlags -> Text -> Ghc (Maybe Text)-doTypeCmd dflags arg = do-    let (emod, expr) = parseExprMode arg-    ty <- GHC.exprType emod $ T.unpack expr-    let rawType = T.strip $ T.pack $ showSDoc dflags $ pprSigmaType ty-        broken = T.any (\c -> c == '\r' || c == '\n') rawType-    pure $-        Just $-            if broken-                then-                    T.pack $-                        showSDoc dflags $-                            text (T.unpack expr)-                                $$ nest 2 ("::" <+> pprSigmaType ty)-                else expr <> " :: " <> rawType <> "\n"--parseExprMode :: Text -> (TcRnExprMode, T.Text)-parseExprMode rawArg = case T.break isSpace rawArg of-    ("+d", rest) -> (TM_Default, T.strip rest)-    _            -> (TM_Inst, rawArg)--data GhciLikeCmdException = GhciLikeCmdNotImplemented-    { ghciCmdName :: Text-    , ghciCmdArg  :: Text-    }--instance Show GhciLikeCmdException where-    showsPrec _ GhciLikeCmdNotImplemented{..} =-        showString "unknown command '"-            . showString (T.unpack ghciCmdName)-            . showChar '\''--instance E.Exception GhciLikeCmdException--{-->>> parseGhciLikeCmd (T.pack ":kind! N + M + 1")-Just ("kind!","N + M + 1")->>> parseGhciLikeCmd (T.pack ":kind a")-Just ("kind","a")--}-parseGhciLikeCmd :: Text -> Maybe (Text, Text)-parseGhciLikeCmd input = do-    (':', rest) <- T.uncons $ T.stripStart input-    pure $ second T.strip $ T.break isSpace rest
+ plugins/hls-eval-plugin/src/Ide/Plugin/Eval/Handlers.hs view
@@ -0,0 +1,695 @@+{-# LANGUAGE CPP                       #-}+{-# LANGUAGE DuplicateRecordFields     #-}+{-# LANGUAGE ExtendedDefaultRules      #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+{-# LANGUAGE OverloadedStrings         #-}+{-# LANGUAGE RecordWildCards           #-}+{-# LANGUAGE ViewPatterns              #-}+{-# OPTIONS_GHC -Wno-type-defaults #-}++{- |+A plugin inspired by the REPLoid feature of <https://github.com/jyp/dante Dante>, <https://www.haskell.org/haddock/doc/html/ch03s08.html#idm140354810775744 Haddock>'s Examples and Properties and <https://hackage.haskell.org/package/doctest Doctest>.++For a full example see the "Ide.Plugin.Eval.Tutorial" module.+-}+module Ide.Plugin.Eval.Handlers (+    codeAction,+    codeLens,+    evalCommand,+) where++import           Control.Applicative                          (Alternative ((<|>)))+import           Control.Arrow                                (second)+import           Control.Exception                            (bracket_)+import qualified Control.Exception                            as E+import           Control.Lens                                 (ix, (%~), (^.))+import           Control.Monad                                (guard, void,+                                                               when)+import           Control.Monad.IO.Class                       (MonadIO (liftIO))+import           Control.Monad.Trans.Except                   (ExceptT (..),+                                                               runExceptT)+import           Data.Aeson                                   (toJSON)+import           Data.Char                                    (isSpace)+import           Data.Foldable                                (toList)+import           Data.List                                    (dropWhileEnd,+                                                               find,+                                                               intercalate,+                                                               intersperse)+import qualified Data.Map                                     as Map+import           Data.Maybe                                   (catMaybes)+import           Data.String                                  (IsString)+import           Data.Text                                    (Text)+import qualified Data.Text                                    as T+import qualified Data.Text.Utf16.Rope.Mixed                   as Rope+import           Development.IDE.Core.FileStore               (getUriContents)+import           Development.IDE.Core.Rules                   (IdeState,+                                                               runAction)+import           Development.IDE.Core.RuleTypes               (LinkableResult (linkableHomeMod),+                                                               TypeCheck (..),+                                                               tmrTypechecked)+import           Development.IDE.Core.Shake                   (useNoFile_, use_,+                                                               uses_)+import           Development.IDE.GHC.Compat                   hiding (typeKind,+                                                               unitState)+import           Development.IDE.GHC.Compat.Util              (OverridingBool (..))+import           Development.IDE.GHC.Util                     (evalGhcEnv,+                                                               modifyDynFlags)+import           Development.IDE.Import.DependencyInformation (transitiveDeps,+                                                               transitiveModuleDeps)+import           Development.IDE.Types.Location               (toNormalizedFilePath')+import           GHC                                          (ClsInst,+                                                               ExecOptions (execLineNumber, execSourceFile),+                                                               FamInst,+                                                               GhcMonad,+                                                               NamedThing (getName),+                                                               defaultFixity,+                                                               execOptions,+                                                               exprType,+                                                               getInfo,+                                                               getInteractiveDynFlags,+                                                               isImport, isStmt,+                                                               parseName,+                                                               pprFamInst,+                                                               pprInstance,+                                                               typeKind)+++import           Development.IDE.Core.RuleTypes               (GetLinkable (GetLinkable),+                                                               GetModSummary (GetModSummary),+                                                               GetModuleGraph (GetModuleGraph),+                                                               GhcSessionDeps (GhcSessionDeps),+                                                               ModSummaryResult (msrModSummary))+import           Development.IDE.Core.Shake                   (VFSModified (VFSUnmodified))+import qualified Development.IDE.GHC.Compat.Core              as Compat (InteractiveImport (IIModule))+import qualified Development.IDE.GHC.Compat.Core              as SrcLoc (unLoc)+import           Development.IDE.Types.HscEnvEq               (HscEnvEq (hscEnv))+import qualified GHC.LanguageExtensions.Type                  as LangExt (Extension (..))++import           Data.List.Extra                              (unsnoc)+import           Development.IDE.Core.FileStore               (setSomethingModified)+import           Development.IDE.Core.PluginUtils+import           Development.IDE.Types.Shake                  (toKey)+import           GHC.Types.SrcLoc                             (UnhelpfulSpanReason (UnhelpfulInteractive))+import           Ide.Logger                                   (Priority (..),+                                                               Recorder,+                                                               WithPriority,+                                                               logWith)+import           Ide.Plugin.Error                             (PluginError (PluginInternalError),+                                                               handleMaybeM)+import           Ide.Plugin.Eval.Code                         (Statement,+                                                               asStatements,+                                                               myExecStmt,+                                                               propSetup,+                                                               resultRange,+                                                               testCheck,+                                                               testRanges)+import           Ide.Plugin.Eval.Config                       (EvalConfig (..),+                                                               getEvalConfig)+import           Ide.Plugin.Eval.GHC                          (addImport,+                                                               addPackages,+                                                               hasPackage,+                                                               setSessionAndInteractiveDynFlags)+import           Ide.Plugin.Eval.Parse.Comments               (commentsToSections)+import           Ide.Plugin.Eval.Parse.Option                 (parseSetFlags)+import           Ide.Plugin.Eval.Rules                        (queueForEvaluation,+                                                               unqueueForEvaluation)+import           Ide.Plugin.Eval.Types+import           Ide.Plugin.Eval.Util                         (gStrictTry,+                                                               isLiterate,+                                                               prettyWarnings,+                                                               response', timed)+import           Ide.Types+import qualified Language.LSP.Protocol.Lens                   as L+import           Language.LSP.Protocol.Message+import           Language.LSP.Protocol.Types+import           Language.LSP.Server+#if MIN_VERSION_ghc(9,11,0)+import           GHC.Unit.Module.ModIface                     (IfaceTopEnv (..))+#endif++codeAction :: Recorder (WithPriority Log) -> PluginMethodHandler IdeState Method_TextDocumentCodeAction+codeAction recorder st plId CodeActionParams{_textDocument,_range} = do+    rangeCommands <- mkRangeCommands recorder st plId _textDocument+    pure+        $ InL+            [ InL command+            | (testRange, command) <- rangeCommands+            , _range `isSubrangeOf` testRange+            ]++{- | Code Lens provider+ NOTE: Invoked every time the document is modified, not just when the document is saved.+-}+codeLens :: Recorder (WithPriority Log) -> PluginMethodHandler IdeState Method_TextDocumentCodeLens+codeLens recorder st plId CodeLensParams{_textDocument} = do+    rangeCommands <- mkRangeCommands recorder st plId _textDocument+    pure+        $ InL+            [ CodeLens range (Just command) Nothing+            | (range, command) <- rangeCommands+            ]++mkRangeCommands :: Recorder (WithPriority Log) -> IdeState -> PluginId -> TextDocumentIdentifier -> ExceptT PluginError (HandlerM Config) [(Range, Command)]+mkRangeCommands recorder st plId textDocument =+    let dbg = logWith recorder Debug+        perf = timed (\lbl duration -> dbg $ LogExecutionTime lbl duration)+     in perf "evalMkRangeCommands" $+            do+                let TextDocumentIdentifier uri = textDocument+                fp <- uriToFilePathE uri+                let nfp = toNormalizedFilePath' fp+                    isLHS = isLiterate fp+                dbg $ LogCodeLensFp fp+                (comments, _) <-+                    runActionE "eval.GetParsedModuleWithComments" st $ useWithStaleE GetEvalComments nfp+                dbg $ LogCodeLensComments comments++                -- Extract tests from source code+                let Sections{..} = commentsToSections isLHS comments+                    tests = testsBySection nonSetupSections+                    cmd = mkLspCommand plId evalCommandName "Evaluate=..." (Just [])+                let rangeCommands =+                        [ (testRange, cmd')+                        | (section, ident, test) <- tests+                        , let (testRange, resultRange) = testRanges test+                              args = EvalParams (setupSections ++ [section]) textDocument ident+                              cmd' =+                                (cmd :: Command)+                                    { _arguments = Just [toJSON args]+                                    , _title =+                                        if trivial resultRange+                                            then "Evaluate..."+                                            else "Refresh..."+                                    }+                        ]++                perf "tests" $+                    dbg $ LogTests+                            (length tests)+                            (length nonSetupSections)+                            (length setupSections)+                            (length rangeCommands)++                pure rangeCommands+  where+    trivial (Range p p') = p == p'++evalCommandName :: CommandId+evalCommandName = "evalCommand"++evalCommand :: Recorder (WithPriority Log) -> PluginId -> PluginCommand IdeState+evalCommand recorder plId = PluginCommand evalCommandName "evaluate" (runEvalCmd recorder plId)++type EvalId = Int++runEvalCmd :: Recorder (WithPriority Log) -> PluginId -> CommandFunction IdeState EvalParams+runEvalCmd recorder plId st mtoken EvalParams{..} =+    let dbg = logWith recorder Debug+        perf = timed (\lbl duration -> dbg $ LogExecutionTime lbl duration)+        cmd :: ExceptT PluginError (HandlerM Config) WorkspaceEdit+        cmd = do+            let tests = map (\(a,_,b) -> (a,b)) $ testsBySection sections++            let TextDocumentIdentifier{_uri} = module_+            fp <- uriToFilePathE _uri+            let nfp = toNormalizedFilePath' fp+            mdlText <- moduleText st _uri++            -- enable codegen for the module which we need to evaluate.+            final_hscEnv <- liftIO $ bracket_+              (setSomethingModified VFSUnmodified st "Eval" $ do+                queueForEvaluation st nfp+                return [toKey IsEvaluating nfp]+                )+              (setSomethingModified VFSUnmodified st "Eval" $ do+                unqueueForEvaluation st nfp+                return [toKey IsEvaluating nfp]+                )+              (initialiseSessionForEval (needsQuickCheck tests) st nfp)++            evalCfg <- liftIO $ runAction "eval: config" st $ getEvalConfig plId++            -- Perform the evaluation of the command+            edits <-+                perf "edits" $+                    liftIO $+                        evalGhcEnv final_hscEnv $ do+                            runTests recorder evalCfg fp tests++            let workspaceEditsMap = Map.singleton _uri (addFinalReturn mdlText edits)+            let workspaceEdits = WorkspaceEdit (Just workspaceEditsMap) Nothing Nothing++            return workspaceEdits+     in perf "evalCmd" $ ExceptT $+            pluginWithIndefiniteProgress "Evaluating" mtoken Cancellable $ \_updater ->+                runExceptT $ response' cmd++-- | Create an HscEnv which is suitable for performing interactive evaluation.+-- All necessary home modules will have linkables and the current module will+-- also be loaded into the environment.+--+-- The interactive context and interactive dynamic flags are also set appropiately.+initialiseSessionForEval :: Bool -> IdeState -> NormalizedFilePath -> IO HscEnv+initialiseSessionForEval needs_quickcheck st nfp = do+  (ms, env1) <- runAction "runEvalCmd" st $ do++    ms <- msrModSummary <$> use_ GetModSummary nfp+    deps_hsc <- hscEnv <$> use_ GhcSessionDeps nfp++    linkables_needed <- transitiveDeps <$> useNoFile_ GetModuleGraph <*> pure nfp+    linkables <- uses_ GetLinkable (nfp : maybe [] transitiveModuleDeps linkables_needed)+    -- We unset the global rdr env in mi_globals when we generate interfaces+    -- See Note [Clearing mi_globals after generating an iface]+    -- However, the eval plugin (setContext specifically) requires the rdr_env+    -- for the current module - so get it from the Typechecked Module and add+    -- it back to the iface for the current module.+    tm <- tmrTypechecked <$> use_ TypeCheck nfp+    let rdr_env = tcg_rdr_env tm+    let linkable_hsc = loadModulesHome (map (addRdrEnv . linkableHomeMod) linkables) deps_hsc+        addRdrEnv hmi+          | iface <- hm_iface hmi+          , ms_mod ms == mi_module iface+#if MIN_VERSION_ghc(9,11,0)+          = hmi { hm_iface = set_mi_top_env (Just $ IfaceTopEnv (forceGlobalRdrEnv (globalRdrEnvLocal rdr_env)) (mkIfaceImports $ tcg_import_decls tm)) iface}+#else+          = hmi { hm_iface = iface { mi_globals = Just $!+#if MIN_VERSION_ghc(9,8,0)+                    forceGlobalRdrEnv+#endif+                      rdr_env+                }}+#endif+          | otherwise = hmi++    return (ms, linkable_hsc)+  -- Bit awkward we need to use evalGhcEnv here but setContext requires to run+  -- in the Ghc monad+  env2 <- liftIO $ evalGhcEnv env1 $ do+            setContext [Compat.IIModule (moduleName (ms_mod ms))]+            let df = flip xopt_set    LangExt.ExtendedDefaultRules+                   . flip xopt_unset  LangExt.MonomorphismRestriction+                   . flip gopt_set    Opt_ImplicitImportQualified+                   . flip gopt_unset  Opt_DiagnosticsShowCaret+                   . setBackend ghciBackend+                   $ (ms_hspp_opts ms) {+                        useColor = Never+                      , canUseColor = False }+            modifyDynFlags (const df)+            when needs_quickcheck $ void $ addPackages ["QuickCheck"]+            getSession+  return env2++#if MIN_VERSION_ghc(9,11,0)+mkIfaceImports :: [ImportUserSpec] -> [IfaceImport]+mkIfaceImports = map go+  where+    go (ImpUserSpec decl ImpUserAll) = IfaceImport decl ImpIfaceAll+    go (ImpUserSpec decl (ImpUserExplicit env)) = IfaceImport decl (ImpIfaceExplicit (forceGlobalRdrEnv env))+    go (ImpUserSpec decl (ImpUserEverythingBut ns)) = IfaceImport decl (ImpIfaceEverythingBut ns)+#endif++addFinalReturn :: Text -> [TextEdit] -> [TextEdit]+addFinalReturn mdlText edits+    | not (null edits) && not (T.null mdlText) && T.last mdlText /= '\n' =+        finalReturn mdlText : edits+    | otherwise = edits++finalReturn :: Text -> TextEdit+finalReturn txt =+    let ls = T.lines txt+        l = fromIntegral $ length ls -1+        c = fromIntegral $ T.length $ maybe T.empty snd (unsnoc ls)+        p = Position l c+     in TextEdit (Range p p) "\n"++moduleText :: IdeState -> Uri -> ExceptT PluginError (HandlerM config) Text+moduleText state uri = do+    contents <-+        handleMaybeM (PluginInternalError "mdlText") $+            liftIO $+                runAction "eval.getUriContents" state $+                    getUriContents $+                        toNormalizedUri uri+    pure $ Rope.toText contents++testsBySection :: [Section] -> [(Section, EvalId, Test)]+testsBySection sections =+    [(section, ident, test)+    | (ident, section) <- zip [0..] sections+    , test <- sectionTests section+    ]++type TEnv = String+-- |GHC declarations required for expression evaluation+evalSetup :: Ghc ()+evalSetup = do+    preludeAsP <- parseImportDecl "import qualified Prelude as P"+    context <- getContext+    setContext (IIDecl preludeAsP : context)++runTests :: Recorder (WithPriority Log) -> EvalConfig -> TEnv -> [(Section, Test)] -> Ghc [TextEdit]+runTests recorder EvalConfig{..} e tests = do+    df <- getInteractiveDynFlags+    evalSetup+    when (hasQuickCheck df && needsQuickCheck tests) $ void $ evals recorder True e df propSetup++    mapM (processTest e df) tests+  where+    processTest :: TEnv -> DynFlags -> (Section, Test) -> Ghc TextEdit+    processTest fp df (section, test) = do+        let dbg = logWith recorder Debug+        let pad = pad_ $ (if isLiterate fp then ("> " `T.append`) else id) $ padPrefix (sectionFormat section)+        rs <- runTest e df test+        dbg $ LogRunTestResults rs++        let checkedResult = testCheck eval_cfg_diff (section, test) rs+        let resultLines = concatMap T.lines checkedResult++        let edit = asEdit (sectionFormat section) test (map pad resultLines)+        dbg $ LogRunTestEdits edit+        return edit++    -- runTest :: String -> DynFlags -> Loc Test -> Ghc [Text]+    runTest _ df test+        | not (hasQuickCheck df) && isProperty test =+            return $+                singleLine+                    "Add QuickCheck to your cabal dependencies to run this test."+    runTest e df test = evals recorder (eval_cfg_exception && not (isProperty test)) e df (asStatements test)++asEdit :: Format -> Test -> [Text] -> TextEdit+asEdit (MultiLine commRange) test resultLines+    -- A test in a block comment, ending with @-\}@ without newline in-between.+    | testRange test ^. L.end . L.line == commRange ^. L.end . L.line+    =+    TextEdit+        (Range+            (testRange test ^. L.end)+            (resultRange test ^. L.end)+        )+        ("\n" <> T.unlines (resultLines <> ["-}"]))+asEdit _ test resultLines =+    TextEdit (resultRange test) (T.unlines resultLines)++{- |+The result of evaluating a test line can be:+* a value+* nothing+* a (possibly multiline) error message++A value is returned for a correct expression.++Either a pure value:+>>> 'h' :"askell"+"haskell"++Or an 'IO a' (output on stdout/stderr is ignored):+>>> print "OK" >> return "ABC"+"ABC"++Nothing is returned for a correct directive:++>>>:set -XFlexibleInstances+>>> import Data.Maybe++Nothing is returned for a correct declaration (let..,x=, data, class)++>>> let x = 11+>>> y = 22+>>> data B = T | F+>>> class C a++Nothing is returned for an empty line:++>>>++A, possibly multi line, error is returned for a wrong declaration, directive or value or an exception thrown by the evaluated code:++>>>:set -XNonExistent+Some flags have not been recognized: -XNonExistent++>>> cls C+Variable not in scope: cls :: t0 -> t+Data constructor not in scope: C++>>> "A+lexical error in string/character literal at end of input++Exceptions are shown as if printed, but it can be configured to include prefix like+in GHCi or doctest. This allows it to be used as a hack to simulate print until we+get proper IO support. See #1977++>>> 3 `div` 0+divide by zero++>>> error "Something went wrong\nbad times" :: E.SomeException+Something went wrong+bad times++Or for a value that does not have a Show instance and can therefore not be displayed:+>>> data V = V+>>> V+No instance for (Show V) arising from a use of ‘evalPrint’+-}+evals :: Recorder (WithPriority Log) -> Bool -> TEnv -> DynFlags -> [Statement] -> Ghc [Text]+evals recorder mark_exception fp df stmts = do+    er <- gStrictTry $ mapM eval stmts+    return $ case er of+        Left err -> errorLines err+        Right rs -> concat . catMaybes $ rs+  where+    dbg = logWith recorder Debug+    eval :: Statement -> Ghc (Maybe [Text])+    eval (Located l stmt)+        | -- GHCi flags+          Just (words -> flags) <- parseSetFlags stmt = do+            dbg $ LogEvalFlags flags+            ndf <- getInteractiveDynFlags+            dbg $ LogEvalPreSetDynFlags ndf+            eans <-+                liftIO $ try @GhcException $+                parseDynamicFlagsCmdLine ndf+                (map (L $ UnhelpfulSpan unhelpfulReason) flags)+            dbg $ LogEvalParsedFlags eans+            case eans of+                Left err -> pure $ Just $ errorLines $ show err+                Right (df', ignoreds, warns) -> do+                    let warnings = do+                            guard $ not $ null warns+                            pure $ errorLines $+                                prettyWarnings warns+                        igns = do+                            guard $ not $ null ignoreds+                            pure+                                ["Some flags have not been recognized: "+                                <> T.pack (intercalate ", " $ map SrcLoc.unLoc ignoreds)+                                ]+                    dbg $ LogEvalPostSetDynFlags df'+                    setSessionAndInteractiveDynFlags df'+                    pure $ warnings <> igns+        | -- A type/kind command+          Just (cmd, arg) <- parseGhciLikeCmd $ T.pack stmt =+            evalGhciLikeCmd cmd arg+        | -- A statement+          isStmt pf stmt =+            do+                dbg $ LogEvalStmtStart stmt+                res <- exec stmt l+                let r = case res of+                        Left err -> Just . (if mark_exception then exceptionLines else errorLines) $ err+                        Right x  -> singleLine <$> x+                dbg $ LogEvalStmtResult r+                return r+        | -- An import+          isImport pf stmt =+            do+                dbg $ LogEvalImport stmt+                _ <- addImport stmt+                return Nothing+        | -- A declaration+          otherwise =+            do+                dbg $ LogEvalDeclaration stmt+                void $ runDecls stmt+                return Nothing+    pf = initParserOpts df+    unhelpfulReason = UnhelpfulInteractive+    exec stmt l =+        let opts = execOptions{execSourceFile = fp, execLineNumber = l}+         in myExecStmt stmt opts++needsQuickCheck :: [(Section, Test)] -> Bool+needsQuickCheck = any (isProperty . snd)++hasQuickCheck :: DynFlags -> Bool+hasQuickCheck df = hasPackage df "QuickCheck"++singleLine :: String -> [Text]+singleLine s = [T.pack s]++{- |+ Convert error messages to a list of text lines+ Remove unnecessary information.+-}+errorLines :: String -> [Text]+errorLines =+        dropWhileEnd T.null+        . takeWhile (not . (\x -> "CallStack" `T.isPrefixOf` x || "HasCallStack" `T.isPrefixOf` x))+        . T.lines+        . T.pack++{- |+ Convert exception messages to a list of text lines+ Remove unnecessary information and mark it as exception.+ We use '*** Exception:' to make it identical to doctest+ output, see #2353.+-}+exceptionLines :: String -> [Text]+exceptionLines = (ix 0 %~ ("*** Exception: " <>)) . errorLines++{- |+>>> map (pad_ (T.pack "--")) (map T.pack ["2+2",""])+["--2+2","--<BLANKLINE>"]+-}+pad_ :: Text -> Text -> Text+pad_ prefix = (prefix `T.append`) . convertBlank++convertBlank :: Text -> Text+convertBlank x+    | T.null x = "<BLANKLINE>"+    | otherwise = x++padPrefix :: IsString p => Format -> p+padPrefix SingleLine = "-- "+padPrefix _          = ""++{- | Resulting @Text@ MUST NOT prefix each line with @--@+   Such comment-related post-process will be taken place+   solely in 'evalGhciLikeCmd'.+-}+type GHCiLikeCmd = DynFlags -> Text -> Ghc (Maybe Text)++-- Should we use some sort of trie here?+ghciLikeCommands :: [(Text, GHCiLikeCmd)]+ghciLikeCommands =+    [ ("info", doInfoCmd False)+    , ("info!", doInfoCmd True)+    , ("kind", doKindCmd False)+    , ("kind!", doKindCmd True)+    , ("type", doTypeCmd)+    ]++evalGhciLikeCmd :: Text -> Text -> Ghc (Maybe [Text])+evalGhciLikeCmd cmd arg = do+    df <- getSessionDynFlags+    case lookup cmd ghciLikeCommands+        <|> snd+        <$> find (T.isPrefixOf cmd . fst) ghciLikeCommands of+        Just hndler ->+            fmap+                T.lines+                <$> hndler df arg+        _ -> E.throw $ GhciLikeCmdNotImplemented cmd arg++doInfoCmd :: Bool -> DynFlags -> Text -> Ghc (Maybe Text)+doInfoCmd allInfo dflags s = do+    sdocs <- mapM infoThing (T.words s)+    pure $ Just $ T.pack $ showSDoc dflags (vcat sdocs)+    where+        infoThing :: GHC.GhcMonad m => Text -> m SDoc+        infoThing (T.unpack -> str) = do+            names     <- GHC.parseName str+            mb_stuffs <- mapM (GHC.getInfo allInfo) names+            let filtered = filterOutChildren (\(t,_f,_ci,_fi,_sd) -> t)+                                            (catMaybes $ toList mb_stuffs)+            return $ vcat (intersperse (text "") $ map pprInfo filtered)++        filterOutChildren :: (a -> TyThing) -> [a] -> [a]+        filterOutChildren get_thing xs+            = filter (not . has_parent) xs+            where+                all_names = mkNameSet (map (getName . get_thing) xs)+                has_parent x = case tyThingParent_maybe (get_thing x) of+                                Just p  -> getName p `elemNameSet` all_names+                                Nothing -> False++        pprInfo :: (TyThing, Fixity, [GHC.ClsInst], [GHC.FamInst], SDoc) -> SDoc+        pprInfo (thing, fixity, cls_insts, fam_insts, docs)+            =  docs+            $$ pprTyThingInContextLoc thing+            $$ showFixity thing fixity+            $$ vcat (map GHC.pprInstance cls_insts)+            $$ vcat (map GHC.pprFamInst  fam_insts)++        pprTyThingInContextLoc :: TyThing -> SDoc+        pprTyThingInContextLoc tyThing+            = showWithLoc (pprDefinedAt (getName tyThing))+                          (pprTyThingInContext showToHeader tyThing)++        showWithLoc :: SDoc -> SDoc -> SDoc+        showWithLoc loc doc+            = hang doc 2 (text "\t--" <+> loc)++        showFixity :: TyThing -> Fixity -> SDoc+        showFixity thing fixity+            | fixity /= GHC.defaultFixity || isSymOcc (getOccName thing)+                = ppr fixity <+> pprInfixName (GHC.getName thing)+            | otherwise = empty++doKindCmd :: Bool -> DynFlags -> Text -> Ghc (Maybe Text)+doKindCmd False df arg = do+    let input = T.strip arg+    (_, kind) <- typeKind False $ T.unpack input+    let kindText = text (T.unpack input) <+> "::" <+> pprSigmaType kind+    pure $ Just $ T.pack (showSDoc df kindText)+doKindCmd True df arg = do+    let input = T.strip arg+    (ty, kind) <- typeKind True $ T.unpack input+    let kindDoc = text (T.unpack input) <+> "::" <+> pprSigmaType kind+        tyDoc = "=" <+> pprSigmaType ty+    pure $ Just $ T.pack (showSDoc df $ kindDoc $$ tyDoc)++doTypeCmd :: DynFlags -> Text -> Ghc (Maybe Text)+doTypeCmd dflags arg = do+    let (emod, expr) = parseExprMode arg+    ty <- GHC.exprType emod $ T.unpack expr+    let rawType = T.strip $ T.pack $ showSDoc dflags $ pprSigmaType ty+        broken = T.any (\c -> c == '\r' || c == '\n') rawType+    pure $+        Just $+            if broken+                then+                    T.pack $+                        showSDoc dflags $+                            text (T.unpack expr)+                                $$ nest 2 ("::" <+> pprSigmaType ty)+                else expr <> " :: " <> rawType <> "\n"++parseExprMode :: Text -> (TcRnExprMode, T.Text)+parseExprMode rawArg = case T.break isSpace rawArg of+    ("+d", rest) -> (TM_Default, T.strip rest)+    _            -> (TM_Inst, rawArg)++data GhciLikeCmdException = GhciLikeCmdNotImplemented+    { ghciCmdName :: Text+    , ghciCmdArg  :: Text+    }++instance Show GhciLikeCmdException where+    showsPrec _ GhciLikeCmdNotImplemented{..} =+        showString "unknown command '"+            . showString (T.unpack ghciCmdName)+            . showChar '\''++instance E.Exception GhciLikeCmdException++{-+>>> parseGhciLikeCmd (T.pack ":kind! N + M + 1")+Just ("kind!","N + M + 1")+>>> parseGhciLikeCmd (T.pack ":kind a")+Just ("kind","a")+-}+parseGhciLikeCmd :: Text -> Maybe (Text, Text)+parseGhciLikeCmd input = do+    (':', rest) <- T.uncons $ T.stripStart input+    pure $ second T.strip $ T.break isSpace rest
plugins/hls-eval-plugin/test/Main.hs view
@@ -6,13 +6,15 @@   ) where  import           Control.Lens               (_Just, folded, preview, view, (^.),-                                             (^..))+                                             (^..), (^?))+import           Control.Monad              (join) import           Data.Aeson                 (Value (Object), fromJSON, object,                                              (.=)) import           Data.Aeson.Types           (Pair, Result (Success)) import           Data.List                  (isInfixOf) import           Data.List.Extra            (nubOrdOn) import qualified Data.Map                   as Map+import qualified Data.Maybe                 as Maybe import qualified Data.Text                  as T import           Ide.Plugin.Config          (Config) import qualified Ide.Plugin.Config          as Plugin@@ -59,6 +61,9 @@         lenses <- getCodeLenses doc         liftIO $ map (view range) lenses @?= [Range (Position 4 0) (Position 5 0)] +  , goldenWithEvalForCodeAction "Evaluation of expressions via code action" "T1" "hs"+  , goldenWithEvalForCodeAction "Reevaluation of expressions via code action" "T2" "hs"+   , goldenWithEval "Evaluation of expressions" "T1" "hs"   , goldenWithEval "Reevaluation of expressions" "T2" "hs"   , goldenWithEval "Evaluation of expressions w/ imports" "T3" "hs"@@ -221,6 +226,10 @@ goldenWithEval title path ext =   goldenWithHaskellDocInTmpDir def evalPlugin title (mkFs $ FS.directProject (path <.> ext)) path "expected" ext executeLensesBackwards +goldenWithEvalForCodeAction :: TestName -> FilePath -> FilePath -> TestTree+goldenWithEvalForCodeAction title path ext =+  goldenWithHaskellDocInTmpDir def evalPlugin title (mkFs $ FS.directProject (path <.> ext)) path "expected" ext executeCodeActionsBackwards+ goldenWithEvalAndFs :: TestName -> [FS.FileTree] -> FilePath -> FilePath -> TestTree goldenWithEvalAndFs title tree path ext =   goldenWithHaskellDocInTmpDir def evalPlugin title (mkFs tree) path  "expected" ext executeLensesBackwards@@ -239,14 +248,24 @@ -- | Execute lenses backwards, to avoid affecting their position in the source file executeLensesBackwards :: TextDocumentIdentifier -> Session () executeLensesBackwards doc = do-  codeLenses <- reverse <$> getCodeLenses doc+  codeLenses <- getCodeLenses doc   -- liftIO $ print codeLenses+  executeCmdsBackwards [c | CodeLens{_command = Just c} <- codeLenses] -  -- Execute sequentially, nubbing elements to avoid-  -- evaluating the same section with multiple tests-  -- more than twice-  mapM_ executeCmd $-    nubOrdOn actSectionId [c | CodeLens{_command = Just c} <- codeLenses]+executeCodeActionsBackwards :: TextDocumentIdentifier -> Session ()+executeCodeActionsBackwards doc = do+  codeLenses <- getCodeLenses doc+  let ranges = [_range | CodeLens{_range} <- codeLenses]+  -- getAllCodeActions cannot get our code actions because they have no diagnostics+  codeActions <- join <$> traverse (getCodeActions doc) ranges+  let cmds = Maybe.mapMaybe (^? _L) codeActions+  executeCmdsBackwards cmds++-- Execute commands backwards, nubbing elements to avoid+-- evaluating the same section with multiple tests+-- more than twice+executeCmdsBackwards :: [Command] -> Session ()+executeCmdsBackwards = mapM_ executeCmd . nubOrdOn actSectionId . reverse  actSectionId :: Command -> Int actSectionId Command{_arguments = Just [fromJSON -> Success EvalParams{..}]} = evalId
plugins/hls-explicit-imports-plugin/src/Ide/Plugin/ExplicitImports.hs view
@@ -25,7 +25,6 @@ import qualified Data.Aeson                           as A (ToJSON (toJSON)) import           Data.Aeson.Types                     (FromJSON) import           Data.Char                            (isSpace)-import           Data.Functor                         ((<&>)) import qualified Data.IntMap                          as IM (IntMap, elems,                                                              fromList, (!?)) import           Data.IORef                           (readIORef)@@ -218,16 +217,18 @@     --                  |^-_paddingLeft     --                  ^-_position     generateInlayHints :: Range -> ImportEdit -> PositionMapping -> Maybe InlayHint-    generateInlayHints (Range _ end) ie pm = mkLabel ie <&> \label ->-      InlayHint { _position = end-                , _label = InL label-                , _kind = Nothing -- neither a type nor a parameter-                , _textEdits = fmap singleton $ toTEdit pm ie-                , _tooltip = Just $ InL "Make this import explicit" -- simple enough, no need to resolve-                , _paddingLeft = Just True -- show an extra space before the inlay hint-                , _paddingRight = Nothing-                , _data_ = Nothing-                }+    generateInlayHints (Range _ end) ie pm = do+      label <- mkLabel ie+      currentEnd <- toCurrentPosition pm end+      return InlayHint { _position = currentEnd+                       , _label = InL label+                       , _kind = Nothing -- neither a type nor a parameter+                       , _textEdits = fmap singleton $ toTEdit pm ie+                       , _tooltip = Just $ InL "Make this import explicit" -- simple enough, no need to resolve+                       , _paddingLeft = Just True -- show an extra space before the inlay hint+                       , _paddingRight = Nothing+                       , _data_ = Nothing+                       }     mkLabel :: ImportEdit -> Maybe T.Text     mkLabel (ImportEdit{ieResType, ieText}) =       let title ExplicitImport = Just $ abbreviateImportTitleWithoutModule ieText
plugins/hls-explicit-record-fields-plugin/src/Ide/Plugin/ExplicitFields.hs view
@@ -43,7 +43,9 @@                                                        srcSpanToLocation,                                                        srcSpanToRange, viaShow) import           Development.IDE.Core.PluginUtils-import           Development.IDE.Core.PositionMapping (toCurrentRange)+import           Development.IDE.Core.PositionMapping (PositionMapping,+                                                       toCurrentPosition,+                                                       toCurrentRange) import           Development.IDE.Core.RuleTypes       (TcModuleResult (..),                                                        TypeCheck (..)) import qualified Development.IDE.Core.Shake           as Shake@@ -204,19 +206,19 @@                     | record <- records                     , pos <- maybeToList $ fmap _start $ recordInfoToDotDotRange record ]     defnLocsList <- lift $ sequence locations-    pure $ InL $ mapMaybe (mkInlayHint crr pragma) defnLocsList+    pure $ InL $ mapMaybe (mkInlayHint crr pragma pm) defnLocsList    where-     mkInlayHint :: CollectRecordsResult -> NextPragmaInfo -> (Maybe [(Location, Identifier)], RecordInfo) -> Maybe InlayHint-     mkInlayHint CRR {enabledExtensions, nameMap} pragma (defnLocs, record) =+     mkInlayHint :: CollectRecordsResult -> NextPragmaInfo -> PositionMapping -> (Maybe [(Location, Identifier)], RecordInfo) -> Maybe InlayHint+     mkInlayHint CRR {enabledExtensions, nameMap} pragma pm (defnLocs, record) =        let range = recordInfoToDotDotRange record            textEdits = maybeToList (renderRecordInfoAsTextEdit nameMap record)                     <> maybeToList (pragmaEdit enabledExtensions pragma)            names = renderRecordInfoAsDotdotLabelName record        in do-         end <- fmap _end range+         currentEnd <- range >>= toCurrentPosition pm . _end          names' <- names          defnLocs' <- defnLocs-         let excludeDotDot (Location _ (Range _ end')) = end' /= end+         let excludeDotDot (Location _ (Range _ end)) = end /= currentEnd              -- find location from dotdot definitions that name equal to label name              findLocation name locations =                let -- filter locations not within dotdot range@@ -227,7 +229,7 @@              valueWithLoc = [ (T.pack $ printName name, findLocation name defnLocs') | name <- names' ]              -- use `, ` to separate labels with definition location              label = intersperse (mkInlayHintLabelPart (", ", Nothing)) $ fmap mkInlayHintLabelPart valueWithLoc-         pure $ InlayHint { _position = end -- at the end of dotdot+         pure $ InlayHint { _position = currentEnd -- at the end of dotdot                           , _label = InR label                           , _kind = Nothing -- neither a type nor a parameter                           , _textEdits = Just textEdits -- same as CodeAction@@ -248,20 +250,22 @@                   | Just range <- [toCurrentRange pm visibleRange]                   , uid <- RangeMap.elementsInRange range crCodeActions                   , Just record <- [IntMap.lookup uid crCodeActionResolve] ]-    pure $ InL (concatMap (mkInlayHints nameMap) records)+    pure $ InL (concatMap (mkInlayHints nameMap pm) records)    where-     mkInlayHints :: UniqFM Name [Name] -> RecordInfo -> [InlayHint]-     mkInlayHints nameMap record@(RecordInfoApp _ (RecordAppExpr _ fla)) =+     mkInlayHints :: UniqFM Name [Name] -> PositionMapping -> RecordInfo -> [InlayHint]+     mkInlayHints nameMap pm record@(RecordInfoApp _ (RecordAppExpr _ fla)) =        let textEdits = renderRecordInfoAsTextEdit nameMap record-       in mapMaybe (mkInlayHint textEdits) fla-     mkInlayHints _       _              = []-     mkInlayHint :: Maybe TextEdit -> (Located FieldLabel, HsExpr GhcTc) -> Maybe InlayHint-     mkInlayHint te (label, _) =+       in mapMaybe (mkInlayHint textEdits pm) fla+     mkInlayHints _ _ _ = []++     mkInlayHint :: Maybe TextEdit -> PositionMapping -> (Located FieldLabel, HsExpr GhcTc) -> Maybe InlayHint+     mkInlayHint te pm (label, _) =        let (name, loc) = ((flSelector . unLoc) &&& (srcSpanToLocation . getLoc)) label            fieldDefLoc = srcSpanToLocation (nameSrcSpan name)        in do          (Location _ recRange) <- loc-         pure InlayHint { _position = _start recRange+         currentStart <- toCurrentPosition pm (_start recRange)+         pure InlayHint { _position = currentStart                         , _label = InR $ pure (mkInlayHintLabelPart name fieldDefLoc)                         , _kind = Nothing -- neither a type nor a parameter                         , _textEdits = Just (maybeToList te) -- same as CodeAction@@ -270,6 +274,7 @@                         , _paddingRight = Nothing                         , _data_ = Nothing                         }+      mkInlayHintLabelPart name loc = InlayHintLabelPart (printOutputable (pprNameUnqualified name) <> "=") Nothing loc Nothing  mkTitle :: [Extension] -> Text
plugins/hls-gadt-plugin/src/Ide/Plugin/GHC.hs view
@@ -7,16 +7,20 @@ {-# OPTIONS_GHC -Wno-overlapping-patterns #-} module Ide.Plugin.GHC where +#if !MIN_VERSION_ghc(9,11,0) import           Data.Functor                            ((<&>))+#endif import           Data.List.Extra                         (stripInfix) import qualified Data.Text                               as T import           Development.IDE import           Development.IDE.GHC.Compat import           Development.IDE.GHC.Compat.ExactPrint-import           GHC.Parser.Annotation                   (AddEpAnn (..),-                                                          DeltaPos (..),+import           GHC.Parser.Annotation                   (DeltaPos (..),                                                           EpAnn (..),                                                           EpAnnComments (EpaComments))+#if MIN_VERSION_ghc(9,11,0)+import           GHC.Parser.Annotation                   (EpToken (..))+#endif import           Ide.PluginUtils                         (subRange) import           Language.Haskell.GHC.ExactPrint.Parsers (parseDecl) @@ -44,6 +48,11 @@ import           Language.Haskell.GHC.ExactPrint.Utils   (showAst) #endif +#if MIN_VERSION_ghc(9,11,0)+import           GHC.Types.SrcLoc                        (UnhelpfulSpanReason (..))+#else+import           GHC.Parser.Annotation                   (AddEpAnn (..))+#endif  type GP = GhcPass Parsed @@ -97,7 +106,9 @@ h98ToGADTConDecl dataName tyVars ctxt = \case     ConDeclH98{..} ->         ConDeclGADT-#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)+            (AnnConDeclGADT [] [] NoEpUniTok)+#elif MIN_VERSION_ghc(9,9,0)             (NoEpUniTok, con_ext) #else             con_ext@@ -209,7 +220,11 @@         adjustDataDecl DataDecl{..} = DataDecl             { tcdDExt = adjustWhere tcdDExt             , tcdDataDefn = tcdDataDefn-                { dd_cons =+                {+#if MIN_VERSION_ghc(9,11,0)+                dd_ext = adjustDefnWhere (dd_ext tcdDataDefn),+#endif+                dd_cons =                       fmap adjustCon (dd_cons tcdDataDefn)                 }             , ..@@ -218,8 +233,12 @@          -- Make every data constructor start with a new line and 2 spaces         adjustCon :: LConDecl GP -> LConDecl GP-#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)         adjustCon (L _ r) =+            let delta = EpaDelta (UnhelpfulSpan UnhelpfulNoLocationInfo) (DifferentLine 1 2) []+            in L (EpAnn delta (AnnListItem []) (EpaComments [])) r+#elif MIN_VERSION_ghc(9,9,0)+        adjustCon (L _ r) =             let delta = EpaDelta (DifferentLine 1 3) []             in L (EpAnn delta (AnnListItem []) (EpaComments [])) r #else@@ -229,6 +248,10 @@ #endif          -- Adjust where annotation to the same line of the type constructor+#if MIN_VERSION_ghc(9,11,0)+        -- tcdDext is just a placeholder in ghc-9.12+        adjustWhere = id+#else         adjustWhere tcdDExt = tcdDExt <&> #if !MIN_VERSION_ghc(9,9,0)             map@@ -238,7 +261,16 @@                 then AddEpAnn AnnWhere d1                 else AddEpAnn ann l             )+#endif +#if MIN_VERSION_ghc(9,11,0)+        adjustDefnWhere annDataDefn+          | andd_where annDataDefn == NoEpTok = annDataDefn+          | otherwise = annDataDefn {andd_where = andd_where'}+          where+            (EpTok (EpaSpan aw)) = andd_where annDataDefn+            andd_where' = EpTok (EpaDelta aw (SameLine 1) [])+#endif         -- Remove the first extra line if exist         removeExtraEmptyLine s = case stripInfix "\n\n" s of             Just (x, xs) -> x <> "\n" <> xs@@ -257,6 +289,10 @@ #endif  pattern UserTyVar' :: LIdP pass -> HsTyVarBndr flag pass+#if MIN_VERSION_ghc(9,11,0)+pattern UserTyVar' s <- HsTvb _ _ (HsBndrVar _ s) _+#else pattern UserTyVar' s <- UserTyVar _ _ s+#endif  implicitTyVars = wrapXRec @GP mkHsOuterImplicit
plugins/hls-hlint-plugin/test/Main.hs view
@@ -276,14 +276,24 @@                              , "g = 2"                              , "#endif", ""                              ]-        expectedComments =  [ "-- comment before header"-                             , "module Comments where", ""-                             , "{-# standalone annotation #-}", ""-                             , "-- standalone comment", ""-                             , "-- | haddock comment"-                             , "f = {- inline comment -} {- inline comment inside refactored code -}1 -- ending comment", ""-                             , "-- final comment"-                             ]+        expectedComments = case ghcVersion of+                             GHC912 -> [ "-- comment before header"+                              , "module Comments where", ""+                              , "{-# standalone annotation #-}", ""+                              , "-- standalone comment", ""+                              , "-- | haddock comment"+                              , "f = {- inline comment -}{- inline comment inside refactored code -} 1 -- ending comment", ""+                              , "-- final comment"+                              ]++                             _ -> [ "-- comment before header"+                              , "module Comments where", ""+                              , "{-# standalone annotation #-}", ""+                              , "-- standalone comment", ""+                              , "-- | haddock comment"+                              , "f = {- inline comment -} {- inline comment inside refactored code -}1 -- ending comment", ""+                              , "-- final comment"+                              ]         expectedComments2 =  [ "module TwoHintsAndComment where"                              , "biggest = foldr1 max -- the line above will show two hlint hints, \"eta reduce\" and \"use maximum\""                              ]
plugins/hls-refactor-plugin/src/Development/IDE/GHC/ExactPrint.hs view
@@ -106,6 +106,9 @@                                                           deltaPos) import           GHC.Types.SrcLoc                        (generatedSrcSpan) #endif+#if MIN_VERSION_ghc(9,11,0)+import           GHC.Types.SrcLoc (UnhelpfulSpanReason(..))+#endif  #if MIN_VERSION_ghc(9,9,0) import           GHC                                     (@@ -116,6 +119,9 @@                                                           EpAnn (..),                                                           EpaLocation,                                                           EpaLocation' (..),+#if MIN_VERSION_ghc(9,11,0)+                                                          EpToken (..),+#endif                                                           NameAdornment (..),                                                           NameAnn (..),                                                           SrcSpanAnnA,@@ -124,7 +130,6 @@                                                           emptyComments,                                                           spanAsAnchor) #endif- setPrecedingLines :: #if !MIN_VERSION_ghc(9,9,0)      Default t =>@@ -168,6 +173,10 @@     (makeDeltaAst ps) #endif +#if MIN_VERSION_ghc(9,11,0)+type Anchor = EpaLocation+#endif+ ------------------------------------------------------------------------------  {- | A transformation for grafting source trees together. Use the semigroup@@ -466,8 +475,11 @@             False -> first (DL.singleton ldecl <>) <$> modifyMatchingDecl rest   modifyDeclsT' (fmap (first DL.toList) . modifyMatchingDecl) a -#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0) generatedAnchor :: DeltaPos -> Anchor+generatedAnchor dp = EpaDelta (UnhelpfulSpan UnhelpfulNoLocationInfo) dp []+#elif MIN_VERSION_ghc(9,9,0)+generatedAnchor :: DeltaPos -> Anchor generatedAnchor dp = EpaDelta dp [] #else generatedAnchor :: AnchorOperation -> Anchor@@ -766,15 +778,28 @@ addParensToCtxt :: Maybe EpaLocation -> AnnContext -> AnnContext addParensToCtxt close_dp = addOpen . addClose   where+#if MIN_VERSION_ghc(9,11,0)+      addOpen it@AnnContext{ac_open = []} = it{ac_open = [EpTok (epl 0)]}+#else       addOpen it@AnnContext{ac_open = []} = it{ac_open = [epl 0]}+#endif       addOpen other                       = other       addClose it+#if MIN_VERSION_ghc(9,11,0)+        | Just c <- close_dp = it{ac_close = [EpTok c]}+        | AnnContext{ac_close = []} <- it = it{ac_close = [EpTok (epl 0)]}+#else         | Just c <- close_dp = it{ac_close = [c]}         | AnnContext{ac_close = []} <- it = it{ac_close = [epl 0]}+#endif         | otherwise = it  epl :: Int -> EpaLocation+#if MIN_VERSION_ghc(9,11,0)+epl n = EpaDelta (UnhelpfulSpan UnhelpfulNoLocationInfo) (SameLine n) []+#else epl n = EpaDelta (SameLine n) []+#endif  epAnn :: SrcSpan -> ann -> EpAnn ann epAnn srcSpan anns = EpAnn (spanAsAnchor srcSpan) anns emptyComments@@ -803,14 +828,25 @@ #endif  addParens :: Bool -> GHC.NameAnn -> GHC.NameAnn+#if MIN_VERSION_ghc(9,11,0) addParens True it@NameAnn{} =-        it{nann_adornment = NameParens, nann_open = epl 0, nann_close = epl 0 }+        it{nann_adornment = NameParens (EpTok (epl 0)) (EpTok (epl 0)) } addParens True it@NameAnnCommas{} =-        it{nann_adornment = NameParens, nann_open = epl 0, nann_close = epl 0 }+        it{nann_adornment = NameParens (EpTok (epl 0)) (EpTok (epl 0)) } addParens True it@NameAnnOnly{} =-        it{nann_adornment = NameParens, nann_open = epl 0, nann_close = epl 0 }+        it{nann_adornment = NameParens (EpTok (epl 0)) (EpTok (epl 0)) }+addParens True it@NameAnnTrailing{} =+  NameAnn{nann_adornment = NameParens (EpTok (epl 0)) (EpTok (epl 0)), nann_name = epl 0, nann_trailing = nann_trailing it}+#else+addParens True it@NameAnn{} =+        it{nann_adornment = NameParens, nann_open=epl 0, nann_close=epl 0 }+addParens True it@NameAnnCommas{} =+        it{nann_adornment = NameParens, nann_open=epl 0, nann_close=epl 0 }+addParens True it@NameAnnOnly{} =+        it{nann_adornment = NameParens, nann_open=epl 0, nann_close=epl 0 } addParens True NameAnnTrailing{..} =-        NameAnn{nann_adornment = NameParens, nann_open = epl 0, nann_close = epl 0, nann_name = epl 0, ..}+        NameAnn{nann_adornment = NameParens, nann_open=epl 0, nann_close=epl 0, nann_name = epl 0, ..}+#endif addParens _ it = it  removeTrailingComma :: GenLocated SrcSpanAnnA ast -> GenLocated SrcSpanAnnA ast
plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction.hs view
@@ -12,7 +12,9 @@     fillHolePluginDescriptor,     extendImportPluginDescriptor,     -- * For testing-    matchRegExMultipleImports+    matchRegExMultipleImports,+    extractNotInScopeName,+    NotInScope(..)     ) where  import           Control.Applicative                               ((<|>))@@ -48,7 +50,9 @@ import           Development.IDE.Core.Shake                        hiding (Log) import           Development.IDE.GHC.Compat                        hiding                                                                    (ImplicitPrelude)+#if !MIN_VERSION_ghc(9,11,0) import           Development.IDE.GHC.Compat.Util+#endif import           Development.IDE.GHC.Error import           Development.IDE.GHC.ExactPrint import qualified Development.IDE.GHC.ExactPrint                    as E@@ -69,8 +73,7 @@ import           Development.IDE.Types.Exports import           Development.IDE.Types.Location import           Development.IDE.Types.Options-import           GHC                                               (AddEpAnn (AddEpAnn),-                                                                    AnnsModule (am_main),+import           GHC                                               (                                                                     DeltaPos (..),                                                                     EpAnn (..),                                                                     LEpaComment)@@ -105,18 +108,31 @@  #if !MIN_VERSION_ghc(9,9,0) import           Development.IDE.GHC.Compat.ExactPrint             (makeDeltaAst)-import           GHC                                               (Anchor (anchor_op),+import           GHC                                               (AddEpAnn (AddEpAnn),+                                                                    AnnsModule (am_main),+                                                                    Anchor (anchor_op),                                                                     AnchorOperation (..),                                                                     EpaLocation (..)) #endif -#if MIN_VERSION_ghc(9,9,0)-import           GHC                                               (EpaLocation,+#if MIN_VERSION_ghc(9,9,0) && !MIN_VERSION_ghc(9,11,0)+import           GHC                                               (AddEpAnn (AddEpAnn),+                                                                    AnnsModule (am_main),+                                                                    EpaLocation,                                                                     EpaLocation' (..),                                                                     HasLoc (..)) import           GHC.Types.SrcLoc                                  (srcSpanToRealSrcSpan) #endif+#if MIN_VERSION_ghc(9,11,0)+import           GHC                                               (EpaLocation,+                                                                    AnnsModule (am_where),+                                                                    EpaLocation' (..),+                                                                    HasLoc (..),+                                                                    EpToken (..))+import           GHC.Types.SrcLoc                                  (srcSpanToRealSrcSpan)+#endif + -------------------------------------------------------------------------------------------------  -- | Generate code actions.@@ -339,7 +355,11 @@         case unLoc <$> findDeclContainingLoc (_start range) lsigs of           Just sig' -> Just sig'           Nothing -> do+#if MIN_VERSION_ghc(9,11,0)+            lHsBindLR <- findDeclContainingLoc (_start range) binds+#else             lHsBindLR <- findDeclContainingLoc (_start range) (bagToList binds)+#endif             findSigOfBind range (unLoc lHsBindLR)     go _ = Nothing @@ -420,7 +440,11 @@   modName   importSpan     | occ <- mkVarOcc identifier,+#if MIN_VERSION_ghc(9,11,0)+      impModsVals <- importedByUser . concat $ M.elems imp_mods,+#else       impModsVals <- importedByUser . concat $ moduleEnvElts imp_mods,+#endif       Just rdrEnv <-         listToMaybe           [ imv_all_exports@@ -659,7 +683,11 @@         name         (L _ Match{m_grhss=GRHSs{grhssLocalBinds}}) = do         let go bag lsigs =+#if MIN_VERSION_ghc(9,11,0)+                if null bag+#else                 if isEmptyBag bag+#endif                 then []                 else concatMap (findRelatedSpanForHsBind indexedContent name lsigs) bag         case grhssLocalBinds of@@ -1572,13 +1600,34 @@         modNameP = fmap snd $ RE.withMatched $ conIDP `sepBy1` RE.sym '.'  +-- | A Backward compatible implementation of `lookupOccEnv_AllNameSpaces` for+-- GHC <=9.6+--+-- It looks for a symbol name in all known namespaces, including types,+-- variables, and fieldnames.+--+-- Note that on GHC >= 9.8, the record selectors are not in the `mkVarOrDataOcc`+-- anymore, but are in a custom namespace, see+-- https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.8#new-namespace-for-record-fields,+-- hence we need to use this "AllNamespaces" implementation, otherwise we'll+-- miss them.+lookupOccEnvAllNamespaces :: ExportsMap -> T.Text -> [IdentInfo]+#if MIN_VERSION_ghc(9,7,0)+lookupOccEnvAllNamespaces exportsMap name = Set.toList $ mconcat (lookupOccEnv_AllNameSpaces (getExportsMap exportsMap) (mkTypeOcc name))+#else+lookupOccEnvAllNamespaces exportsMap name = maybe [] Set.toList $+                            lookupOccEnv (getExportsMap exportsMap) (mkVarOrDataOcc name)+                          <> lookupOccEnv (getExportsMap exportsMap) (mkTypeOcc name) -- look up the modified unknown name in the export map+#endif++ constructNewImportSuggestions   :: ExportsMap -> (Maybe T.Text, NotInScope) -> Maybe [T.Text] -> QualifiedImportStyle -> [ImportSuggestion] constructNewImportSuggestions exportsMap (qual, thingMissing) notTheseModules qis = nubOrdBy simpleCompareImportSuggestion   [ suggestion   | Just name <- [T.stripPrefix (maybe "" (<> ".") qual) $ notInScope thingMissing] -- strip away qualified module names from the unknown name-  , identInfo <- maybe [] Set.toList $ lookupOccEnv (getExportsMap exportsMap) (mkVarOrDataOcc name)-                                    <> lookupOccEnv (getExportsMap exportsMap) (mkTypeOcc name) -- look up the modified unknown name in the export map++  , identInfo <- lookupOccEnvAllNamespaces exportsMap name -- look up the modified unknown name in the export map   , canUseIdent thingMissing identInfo                                              -- check if the identifier information retrieved can be used   , moduleNameText identInfo `notElem` fromMaybe [] notTheseModules                 -- check if the module of the identifier is allowed   , suggestion <- renderNewImport identInfo                                         -- creates a list of import suggestions for the retrieved identifier information@@ -1700,13 +1749,22 @@ #endif         EpAnn _ annsModule _ -> do             -- Find the first 'where'+#if MIN_VERSION_ghc(9,11,0)+            whereLocation <- filterWhere $ am_where annsModule+#else             whereLocation <- listToMaybe . mapMaybe filterWhere $ am_main annsModule+#endif             epaLocationToLine whereLocation #if !MIN_VERSION_ghc(9,9,0)         EpAnnNotUsed -> Nothing #endif+#if MIN_VERSION_ghc(9,11,0)+    filterWhere (EpTok loc) = Just loc+    filterWhere _ = Nothing+#else     filterWhere (AddEpAnn AnnWhere loc) = Just loc     filterWhere _                       = Nothing+#endif      epaLocationToLine :: EpaLocation -> Maybe Int #if MIN_VERSION_ghc(9,9,0)@@ -1719,12 +1777,19 @@     epaLocationToLine (EpaSpan sp)       = Just . srcLocLine . realSrcSpanEnd $ sp #endif+#if MIN_VERSION_ghc(9,11,0)+    epaLocationToLine (EpaDelta _ (SameLine _) priorComments) = Just $ sumCommentsOffset priorComments+    -- 'priorComments' contains the comments right before the current EpaLocation+    -- Summing line offset of priorComments is necessary, as 'line' is the gap between the last comment and+    -- the current AST node+    epaLocationToLine (EpaDelta _ (DifferentLine line _) priorComments) = Just (line + sumCommentsOffset priorComments)+#else     epaLocationToLine (EpaDelta (SameLine _) priorComments) = Just $ sumCommentsOffset priorComments     -- 'priorComments' contains the comments right before the current EpaLocation     -- Summing line offset of priorComments is necessary, as 'line' is the gap between the last comment and     -- the current AST node     epaLocationToLine (EpaDelta (DifferentLine line _) priorComments) = Just (line + sumCommentsOffset priorComments)-+#endif     sumCommentsOffset :: [LEpaComment] -> Int #if MIN_VERSION_ghc(9,9,0)     sumCommentsOffset = sum . fmap (\(L anchor _) -> anchorOpLine anchor)@@ -1732,9 +1797,14 @@     sumCommentsOffset = sum . fmap (\(L anchor _) -> anchorOpLine (anchor_op anchor)) #endif -#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)     anchorOpLine :: EpaLocation' a -> Int     anchorOpLine EpaSpan{}                           = 0+    anchorOpLine (EpaDelta _ (SameLine _) _)           = 0+    anchorOpLine (EpaDelta _ (DifferentLine line _) _) = line+#elif MIN_VERSION_ghc(9,9,0)+    anchorOpLine :: EpaLocation' a -> Int+    anchorOpLine EpaSpan{}                           = 0     anchorOpLine (EpaDelta (SameLine _) _)           = 0     anchorOpLine (EpaDelta (DifferentLine line _) _) = line #else@@ -1825,7 +1895,7 @@     = NotInScopeDataConstructor T.Text     | NotInScopeTypeConstructorOrClass T.Text     | NotInScopeThing T.Text-    deriving Show+    deriving (Show, Eq)  notInScope :: NotInScope -> T.Text notInScope (NotInScopeDataConstructor t)        = t@@ -1840,6 +1910,38 @@   = Just $ NotInScopeDataConstructor name   | Just [name] <- matchRegexUnifySpaces x "ot in scope: type constructor or class [^‘]*‘([^’]*)’"   = Just $ NotInScopeTypeConstructorOrClass name+  | Just [name] <- matchRegexUnifySpaces x "The data constructors of ‘([^ ]+)’ are not all in scope"+  = Just $ NotInScopeDataConstructor name+  | Just [name] <- matchRegexUnifySpaces x "of newtype ‘([^’]*)’ is not in scope"+  = Just $ NotInScopeThing name+  -- Match for HasField "foo" Bar String in the context where, e.g. x.foo is+  -- used, and x :: Bar.+  --+  -- This usually mean that the field is not in scope and the correct fix is to+  -- import (Bar(foo)) or (Bar(..)).+  --+  -- However, it is more reliable to match for the type name instead of the field+  -- name, and most of the time you'll want to import the complete type with all+  -- their fields instead of the specific field.+  --+  -- The regex is convoluted because it accounts for:+  --+  -- - Qualified (or not) `HasField`+  -- - The type bar is always qualified. If it is unqualified, it means that the+  -- parent module is already imported, and in this context it uses an hint+  -- already available in the GHC error message. However this regex accounts for+  -- qualified or not, it does not cost much and should be more robust if the+  -- hint changes in the future+  -- - Next regex will account for polymorphic types, which appears as `HasField+  -- "foo" (Bar Int)...`, e.g. see the parenthesis+  | Just [_module, name] <- matchRegexUnifySpaces x "No instance for [‘(].*HasField \"[^\"]+\" ([^ (.]+\\.)*([^ (.]+).*[’)]"+  = Just $ NotInScopeThing name+  | Just [_module, name] <- matchRegexUnifySpaces x "No instance for [‘(].*HasField \"[^\"]+\" \\(([^ .]+\\.)*([^ .]+)[^)]*\\).*[’)]"+  = Just $ NotInScopeThing name+  -- The order of the "Not in scope" is important, for example, some of the+  -- matcher may catch the "record" value instead of the value later.+  | Just [name] <- matchRegexUnifySpaces x "Not in scope: record field ‘([^’]*)’"+  = Just $ NotInScopeThing name   | Just [name] <- matchRegexUnifySpaces x "ot in scope: \\(([^‘ ]+)\\)"   = Just $ NotInScopeThing name   | Just [name] <- matchRegexUnifySpaces x "ot in scope: ([^‘ ]+)"@@ -1881,14 +1983,11 @@ --         ‘Data.Functor’ nor ‘Data.Text’ exports ‘putStrLn’. extractDoesNotExportModuleName :: T.Text -> Maybe T.Text extractDoesNotExportModuleName x-  | Just [m] <--#if MIN_VERSION_ghc(9,4,0)-    matchRegexUnifySpaces x "the module ‘([^’]*)’ does not export"-      <|> matchRegexUnifySpaces x "nor ‘([^’]*)’ export"-#else-    matchRegexUnifySpaces x "Module ‘([^’]*)’ does not export"-      <|> matchRegexUnifySpaces x "nor ‘([^’]*)’ exports"-#endif+  | Just [m] <- case ghcVersion of+                  GHC912 -> matchRegexUnifySpaces x "The module ‘([^’]*)’ does not export"+                            <|> matchRegexUnifySpaces x "nor ‘([^’]*)’ export"+                  _ ->      matchRegexUnifySpaces x "the module ‘([^’]*)’ does not export"+                            <|> matchRegexUnifySpaces x "nor ‘([^’]*)’ export"   = Just m   | otherwise   = Nothing
plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction/ExactPrint.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE GADTs        #-} {-# LANGUAGE TypeFamilies #-} module Development.IDE.Plugin.CodeAction.ExactPrint (@@ -35,10 +36,8 @@ import           Data.Bifunctor                         (first) import           Data.Maybe                             (fromMaybe, mapMaybe) import           Development.IDE.Plugin.CodeAction.Util-import           GHC                                    (AddEpAnn (..),-                                                         AnnContext (..),+import           GHC                                    (AnnContext (..),                                                          AnnList (..),-                                                         AnnParen (..),                                                          DeltaPos (SameLine),                                                          EpAnn (..),                                                          IsUnicodeSyntax (NormalSyntax),@@ -46,8 +45,17 @@                                                          TrailingAnn (AddCommaAnn),                                                          emptyComments, reAnnL) + -- See Note [Guidelines For Using CPP In GHCIDE Import Statements] +#if MIN_VERSION_ghc(9,11,0)+import GHC (EpToken (..)+           , AnnListBrackets (..)+           , EpUniToken (..))+#else+import GHC (AddEpAnn (..),+                                                         AnnParen (..))+#endif #if !MIN_VERSION_ghc(9,9,0) import           Data.Default                           (Default (..)) import           GHC                                    (addAnns, ann)@@ -179,7 +187,9 @@     -- For singleton constraints, the close Paren DP is attached to an HsPar wrapping the constraint     -- we have to reposition it manually into the AnnContext         close_dp = case ctxt of-#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)+            [L _ (HsParTy (_, (EpTok ap_close)) _)] -> Just ap_close+#elif MIN_VERSION_ghc(9,9,0)             [L _ (HsParTy AnnParen{ap_close} _)] -> Just ap_close #else             [L _ (HsParTy EpAnn{anns=AnnParen{ap_close}} _)] -> Just ap_close@@ -203,7 +213,11 @@ #else     let context = Just $ reAnnL annCtxt emptyComments $ L lContext [resetEntryDP constraint] #endif+#if MIN_VERSION_ghc(9,11,0)+        annCtxt = AnnContext (Just (EpUniTok (epl 1) NormalSyntax)) [EpTok (epl 0) | needsParens] [EpTok (epl 0) | needsParens]+#else         annCtxt = AnnContext (Just (NormalSyntax, epl 1)) [epl 0 | needsParens] [epl 0 | needsParens]+#endif         needsParens = hsTypeNeedsParens sigPrec $ unLoc constraint     ast <- pure $ setEntryDP (makeDeltaAst ast) (SameLine 1) @@ -346,7 +360,9 @@ #endif                                              childRdr           x :: LIE GhcPs = L ll' $ IEThingWith-#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)+                                     (Nothing, (EpTok d1, NoEpTok, NoEpTok, EpTok noAnn))+#elif MIN_VERSION_ghc(9,9,0)                                      (Nothing, [AddEpAnn AnnOpenP d1, AddEpAnn AnnCloseP noAnn]) #elif MIN_VERSION_ghc(9,7,0)                                      (Nothing, addAnns mempty [AddEpAnn AnnOpenP d1, AddEpAnn AnnCloseP def] emptyComments)@@ -384,6 +400,8 @@ #endif #if MIN_VERSION_ghc(9,7,0) && !MIN_VERSION_ghc(9,9,0)             newl = fmap (\ann -> ann ++ [AddEpAnn AnnDotdot d0]) <$> l'''+#elif MIN_VERSION_ghc(9,11,0)+            newl = (\(open, _, comma, close)  -> (open, EpTok d0, comma, close)) <$> l''' #else             newl = (\ann -> ann ++ [AddEpAnn AnnDotdot d0]) <$> l''' #endif@@ -427,21 +445,31 @@       parentRdr <- liftParseAST df parent       let childRdr = reLocA $ L srcChild $ mkRdrUnqual $ mkVarOcc child           isParentOperator = hasParen parent+#if MIN_VERSION_ghc(9,11,0)+      let parentLIE = reLocA $ L srcParent $ if isParentOperator then IEType (EpTok (epl 0)) parentRdr'+#else       let parentLIE = reLocA $ L srcParent $ if isParentOperator then IEType (epl 0) parentRdr'+#endif                                                else IEName #if MIN_VERSION_ghc(9,5,0)                                                       noExtField #endif                                                       parentRdr'           parentRdr' = modifyAnns parentRdr $ \case+#if MIN_VERSION_ghc(9,11,0)+              it@NameAnn{nann_adornment = NameParens _ _} -> it{nann_adornment=NameParens (EpTok (epl 1)) (EpTok (epl 0))}+#else               it@NameAnn{nann_adornment = NameParens} -> it{nann_open = epl 1, nann_close = epl 0}+#endif               other -> other           childLIE = reLocA $ L srcChild $ IEName #if MIN_VERSION_ghc(9,5,0)                                              noExtField #endif                                              childRdr-#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)+          listAnn = (Nothing, (EpTok (epl 1), NoEpTok, NoEpTok, EpTok (epl 0)))+#elif MIN_VERSION_ghc(9,9,0)           listAnn = (Nothing, [AddEpAnn AnnOpenP (epl 1), AddEpAnn AnnCloseP (epl 0)]) #elif MIN_VERSION_ghc(9,7,0)           listAnn = (Nothing, epAnn srcParent [AddEpAnn AnnOpenP (epl 1), AddEpAnn AnnCloseP (epl 0)])@@ -538,7 +566,10 @@ extendHiding symbol (L l idecls) mlies df = do   L l' lies <- case mlies of     Nothing -> do-#if MIN_VERSION_ghc(9,9,0)+#if MIN_VERSION_ghc(9,11,0)+        let ann :: EpAnn (AnnList (EpToken "hiding", [EpToken ","]))+            ann = noAnnSrcSpanDP0 +#elif MIN_VERSION_ghc(9,9,0)         let ann = noAnnSrcSpanDP0 #else         src <- uniqueSrcSpanT@@ -549,9 +580,14 @@ #else             ann' = flip (fmap.fmap) ann $ \x -> x #endif+#if MIN_VERSION_ghc(9,11,0)+                {al_rest = (EpTok (epl 1), [NoEpTok])+                ,al_brackets=ListParens (EpTok (epl 1)) (EpTok (epl 0))+#else                 {al_rest = [AddEpAnn AnnHiding (epl 1)]                 ,al_open = Just $ AddEpAnn AnnOpenP (epl 1)                 ,al_close = Just $ AddEpAnn AnnCloseP (epl 0)+#endif                 }         return $ L ann' []     Just pr -> pure pr
plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/AddArgument.hs view
@@ -50,7 +50,9 @@                                                             IsUnicodeSyntax (NormalSyntax)) import           Language.Haskell.GHC.ExactPrint           (d1, setEntryDP) #endif-+#if MIN_VERSION_ghc(9,11,0)+import GHC.Parser.Annotation (EpToken(..))+#endif  -- When GHC tells us that a variable is not bound, it will tell us either: --  - there is an unbound variable with a given type@@ -77,19 +79,28 @@ --      addArgToMatch "foo" `bar arg1 arg2 = ...` --   => (`bar arg1 arg2 foo = ...`, 2) addArgToMatch :: T.Text -> GenLocated l (Match GhcPs (LocatedA (HsExpr GhcPs))) -> (GenLocated l (Match GhcPs (LocatedA (HsExpr GhcPs))), Int)+#if MIN_VERSION_ghc(9,11,0)+addArgToMatch name (L locMatch (Match xMatch ctxMatch (L l pats) rhs)) =+#else addArgToMatch name (L locMatch (Match xMatch ctxMatch pats rhs)) =-  let unqualName = mkRdrUnqual $ mkVarOcc $ T.unpack name+#endif #if MIN_VERSION_ghc(9,9,0)+  let unqualName = mkRdrUnqual $ mkVarOcc $ T.unpack name       newPat = L noAnnSrcSpanDP1 $ VarPat NoExtField $ L noAnn unqualName       -- The intention is to move `= ...` (right-hand side with equals) to the right so there's 1 space between       -- the newly added pattern and the rest       indentRhs :: GRHSs GhcPs (LocatedA (HsExpr GhcPs)) -> GRHSs GhcPs (LocatedA (HsExpr GhcPs))       indentRhs rhs@GRHSs{grhssGRHSs} = rhs {grhssGRHSs = fmap (`setEntryDP` (SameLine 1)) grhssGRHSs } #else+  let unqualName = mkRdrUnqual $ mkVarOcc $ T.unpack name       newPat = L (noAnnSrcSpanDP1 generatedSrcSpan) $ VarPat NoExtField (noLocA unqualName)       indentRhs = id #endif+#if MIN_VERSION_ghc(9,11,0)+  in (L locMatch (Match xMatch ctxMatch (L l (pats <> [newPat])) (indentRhs rhs)), Prelude.length pats)+#else   in (L locMatch (Match xMatch ctxMatch (pats <> [newPat]) (indentRhs rhs)), Prelude.length pats)+#endif  -- Attempt to insert a binding pattern into each match for the given LHsDecl; succeeds only if the function is a FunBind. -- Also return:@@ -171,7 +182,11 @@           ( noAnn           , noExtField           , HsUnrestrictedArrow (EpUniTok d1 NormalSyntax)+#if MIN_VERSION_ghc(9,11,0)+          , L wildCardAnn $ HsWildCardTy NoEpTok+#else           , L wildCardAnn $ HsWildCardTy noExtField+#endif            ) #elif MIN_VERSION_ghc(9,4,0)         wildCardAnn = SrcSpanAnn (EpAnn genAnchor1 (AnnListItem []) emptyComments) generatedSrcSpan
plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/Diagnostic.hs view
@@ -21,6 +21,9 @@     Nothing                                                -> Nothing  -- | 'matchRegex' combined with 'unifySpaces'+--+-- >>> matchRegexUnifySpaces  "hello I'm a cow" "he(ll)o"+-- Just ["ll"] matchRegexUnifySpaces :: T.Text -> T.Text -> Maybe [T.Text] matchRegexUnifySpaces message = matchRegex (unifySpaces message) 
plugins/hls-refactor-plugin/test/Main.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP                   #-} {-# LANGUAGE AllowAmbiguousTypes   #-} {-# LANGUAGE DataKinds             #-} {-# LANGUAGE DuplicateRecordFields #-}@@ -46,6 +47,7 @@ import           Test.Hls  import qualified Development.IDE.GHC.ExactPrint+import           Development.IDE.Plugin.CodeAction        (NotInScope (..)) import qualified Development.IDE.Plugin.CodeAction        as Refactor import qualified Test.AddArgument @@ -68,6 +70,7 @@   , codeActionTests   , codeActionHelperFunctionTests   , completionTests+  , extractNotInScopeNameTests   ]  initializeTests :: TestTree@@ -300,6 +303,8 @@   , suggestImportClassMethodTests   , suggestImportTests   , suggestAddRecordFieldImportTests+  , suggestAddCoerceMissingConstructorImportTests+  , suggestAddGenericMissingConstructorImportTests   , suggestHideShadowTests   , fixConstructorImportTests   , fixModuleImportTypoTests@@ -316,6 +321,7 @@   , addImplicitParamsConstraintTests   , removeExportTests   , Test.AddArgument.tests+  , suggestAddRecordFieldUpdateImportTests   ]  insertImportTests :: TestTree@@ -1849,8 +1855,14 @@ suggestAddRecordFieldImportTests :: TestTree suggestAddRecordFieldImportTests = testGroup "suggest imports of record fields when using OverloadedRecordDot"   [ testGroup "The field is suggested when an instance resolution failure occurs"-    [ ignoreForGhcVersions [GHC94, GHC96] "Extension not present <9.2, and the assist is derived from the help message in >=9.4" theTest+    ([ ignoreForGhcVersions [GHC94, GHC96] "Extension not present <9.2, and the assist is derived from the help message in >=9.4" theTest     ]+    ++ [+        theTestIndirect qualifiedGhcRecords polymorphicType+        |+        qualifiedGhcRecords <- [False, True]+        , polymorphicType <- [False, True]+        ])   ]   where     theTest = testSessionWithExtraFiles "hover" def $ \dir -> do@@ -1871,7 +1883,145 @@       contentAfterAction <- documentContents doc       liftIO $ after @=? contentAfterAction +    theTestIndirect qualifiedGhcRecords polymorphicType = testGroup+      ((if qualifiedGhcRecords then "qualified-" else "unqualified-")+      <> ("HasField " :: String)+      <>+      (if polymorphicType then "polymorphic-" else "monomorphic-")+      <> "type ")+      . (\x -> [x]) $ testSessionWithExtraFiles "hover" def $ \dir -> do+      -- Hopefully enable project indexing?+      configureCheckProject True +      let+          before = T.unlines ["{-# LANGUAGE OverloadedRecordDot #-}", "module A where", if qualifiedGhcRecords then "" else "import GHC.Records", "import C (bar)", "spam = bar.foo"]+          after = T.unlines ["{-# LANGUAGE OverloadedRecordDot #-}", "module A where", if qualifiedGhcRecords then "" else "import GHC.Records", "import C (bar)", "import B (Foo(..))", "spam = bar.foo"]+          cradle = "cradle: {direct: {arguments: [-hide-all-packages, -package, base, -package, text, -package-env, -, A, B, C]}}"+      liftIO $ writeFileUTF8 (dir </> "hie.yaml") cradle+      liftIO $ writeFileUTF8 (dir </> "B.hs") $ unlines ["module B where", if polymorphicType then "data Foo x = Foo { foo :: x }" else "data Foo = Foo { foo :: Int }"]+      liftIO $ writeFileUTF8 (dir </> "C.hs") $ unlines ["module C where", "import B", "bar = Foo 10" ]+      doc <- createDoc "Test.hs" "haskell" before+      waitForProgressDone+      _ <- waitForDiagnostics+      let defLine = 4+          range = Range (Position defLine 0) (Position defLine maxBound)+      actions <- getCodeActions doc range+      action <- pickActionWithTitle "import B (Foo(..))" actions+      executeCodeAction action+      contentAfterAction <- documentContents doc+      liftIO $ after @=? contentAfterAction++suggestAddRecordFieldUpdateImportTests :: TestTree+suggestAddRecordFieldUpdateImportTests = testGroup "suggest imports of record fields in update"+  [ testGroup "implicit import of type" [theTest ] ]+  where+    theTest = testSessionWithExtraFiles "hover" def $ \dir -> do+      configureCheckProject True++      let+          before = T.unlines ["module C where", "import B", "biz = bar { foo = 100 }"]+          after = T.unlines ["module C where", "import B", "import A (Foo(..))", "biz = bar { foo = 100 }"]+          cradle = "cradle: {direct: {arguments: [-hide-all-packages, -package, base, -package, text, -package-env, -, A, B, C]}}"+      liftIO $ writeFileUTF8 (dir </> "hie.yaml") cradle+      liftIO $ writeFileUTF8 (dir </> "A.hs") $ unlines ["module A where", "data Foo = Foo { foo :: Int }"]+      liftIO $ writeFileUTF8 (dir </> "B.hs") $ unlines ["module B where", "import A", "bar = Foo 10" ]+      doc <- createDoc "Test.hs" "haskell" before+      waitForProgressDone+      diags <- waitForDiagnostics+      liftIO $ print diags+      let defLine = 2+          range = Range (Position defLine 0) (Position defLine maxBound)+      actions <- getCodeActions doc range+      liftIO $ print actions+      action <- pickActionWithTitle "import A (Foo(..))" actions+      executeCodeAction action+      contentAfterAction <- documentContents doc+      liftIO $ after @=? contentAfterAction++extractNotInScopeNameTests :: TestTree+extractNotInScopeNameTests =+  testGroup "extractNotInScopeName" [+      testGroup "record field" [+            testCase ">=ghc 910" $ Refactor.extractNotInScopeName "Not in scope: ‘foo’"  @=? Just (NotInScopeThing "foo"),+            testCase "<ghc 910" $ Refactor.extractNotInScopeName "Not in scope: record field ‘foo’"  @=? Just (NotInScopeThing "foo")+            ],+      testGroup "HasField" [+        testGroup "unqualified" [+          testGroup "nice ticks" [+            testCase "Simple type" $ Refactor.extractNotInScopeName "No instance for ‘HasField \"baz\" Cheval Bool’"  @=? Just (NotInScopeThing "Cheval"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘HasField \"bar\" (Hibou Int) a0’"  @=? Just (NotInScopeThing "Hibou"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘HasField \"foo\" (Tortue Int) Int’"  @=? Just (NotInScopeThing "Tortue")+            ],+          testGroup "parenthesis" [+            testCase "Simple type" $ Refactor.extractNotInScopeName "No instance for ‘HasField \"blup\" Calamar Bool’"  @=? Just (NotInScopeThing "Calamar"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘HasField \"biz\" (Ornithorink Int) a0’"  @=? Just (NotInScopeThing "Ornithorink"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘HasField \"blork\" (Salamandre Int) Int’"  @=? Just (NotInScopeThing "Salamandre")+            ]+          ],+        testGroup "qualified" [+          testGroup "nice ticks" [+            testCase "Simple type" $ Refactor.extractNotInScopeName "No instance for ‘GHC.HasField \"baz\" Cheval Bool’"  @=? Just (NotInScopeThing "Cheval"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘Record.HasField \"bar\" (Hibou Int) a0’"  @=? Just (NotInScopeThing "Hibou"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘Youpi.HasField \"foo\" (Tortue Int) Int’"  @=? Just (NotInScopeThing "Tortue")+            ],+          testGroup "parenthesis" [+            testCase "Simple type" $ Refactor.extractNotInScopeName "No instance for ‘GHC.Tortue.HasField \"blup\" Calamar Bool’"  @=? Just (NotInScopeThing "Calamar"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘Youpi.Salamandre.HasField \"biz\" (Ornithorink Int) a0’"  @=? Just (NotInScopeThing "Ornithorink"),+            testCase "Parametric type" $ Refactor.extractNotInScopeName "No instance for ‘Foo.Bar.HasField \"blork\" (Salamandre Int) Int’"  @=? Just (NotInScopeThing "Salamandre")+            ]+          ]+        ]+    ]+suggestAddCoerceMissingConstructorImportTests :: TestTree+suggestAddCoerceMissingConstructorImportTests = testGroup "suggest imports of newtype constructor when using coerce"+  [ testGroup "The newtype constructor is suggested when a matching representation error"+    [ theTest+    ]+  ]+  where+    theTest = testSessionWithExtraFiles "hover" def $ \dir -> do+      configureCheckProject False+      let before = T.unlines ["module A where", "import Data.Coerce (coerce)", "import Data.Semigroup (Sum)", "bar = coerce (10 :: Int) :: Sum Int"]+          after = T.unlines ["module A where", "import Data.Coerce (coerce)", "import Data.Semigroup (Sum)", "import Data.Semigroup (Sum(..))", "bar = coerce (10 :: Int) :: Sum Int"]+          cradle = "cradle: {direct: {arguments: [-hide-all-packages, -package, base, -package, text, -package-env, -, A]}}"+      liftIO $ writeFileUTF8 (dir </> "hie.yaml") cradle+      doc <- createDoc "Test.hs" "haskell" before+      waitForProgressDone+      _ <- waitForDiagnostics+      let defLine = 3+          range = Range (Position defLine 0) (Position defLine maxBound)+      actions <- getCodeActions doc range+      action <- pickActionWithTitle "import Data.Semigroup (Sum(..))" actions+      executeCodeAction action+      contentAfterAction <- documentContents doc+      liftIO $ after @=? contentAfterAction++suggestAddGenericMissingConstructorImportTests :: TestTree+suggestAddGenericMissingConstructorImportTests = testGroup "suggest imports of type constructors when using generic deriving"+  [ testGroup "The type constructors are suggested when not in scope"+    [ theTest+    ]+  ]+  where+    theTest = testSessionWithExtraFiles "hover" def $ \dir -> do+      configureCheckProject False+      let+          before = T.unlines ["module A where", "import GHC.Generics", "import Data.Semigroup (Sum)", "deriving instance Generic (Sum Int)"]+          after = T.unlines ["module A where", "import GHC.Generics", "import Data.Semigroup (Sum)", "import Data.Semigroup (Sum(..))", "deriving instance Generic (Sum Int)"]+          cradle = "cradle: {direct: {arguments: [-hide-all-packages, -package, base, -package, text, -package-env, -, A]}}"+      liftIO $ writeFileUTF8 (dir </> "hie.yaml") cradle+      doc <- createDoc "Test.hs" "haskell" before+      waitForProgressDone+      _ <- waitForDiagnostics+      let defLine = 3+          range = Range (Position defLine 0) (Position defLine maxBound)+      actions <- getCodeActions doc range+      action <- pickActionWithTitle "import Data.Semigroup (Sum(..))" actions+      executeCodeAction action+      contentAfterAction <- documentContents doc+      liftIO $ after @=? contentAfterAction++ suggestImportDisambiguationTests :: TestTree suggestImportDisambiguationTests = testGroup "suggest import disambiguation actions"   [ testGroup "Hiding strategy works"@@ -2538,14 +2688,14 @@           [ (DiagnosticSeverity_Warning, (6, 8), "Defaulting the following constraint", Nothing)           , (DiagnosticSeverity_Warning, (6, 16), "Defaulting the following constraint", Nothing)           ])-      "Add type annotation ‘String’ to ‘\"debug\"’"+      ("Add type annotation ‘" <> stringLit <> "’ to ‘\"debug\"’")       [ "{-# OPTIONS_GHC -Wtype-defaults #-}"       , "{-# LANGUAGE OverloadedStrings #-}"       , "module A (f) where"       , ""       , "import Debug.Trace"       , ""-      , "f = seq (\"debug\" :: String) traceShow \"debug\""+      , "f = seq (\"debug\" :: "<> stringLit <> ") traceShow \"debug\""       ]   , testSession "add default type to satisfy two constraints" $     testFor@@ -2560,14 +2710,14 @@       (if ghcVersion >= GHC94         then [ (DiagnosticSeverity_Warning, (6, 6), "Defaulting the type variable", Nothing) ]         else [ (DiagnosticSeverity_Warning, (6, 6), "Defaulting the following constraint", Nothing) ])-      "Add type annotation ‘String’ to ‘\"debug\"’"+      ("Add type annotation ‘" <> stringLit <> "’ to ‘\"debug\"’")       [ "{-# OPTIONS_GHC -Wtype-defaults #-}"       , "{-# LANGUAGE OverloadedStrings #-}"       , "module A (f) where"       , ""       , "import Debug.Trace"       , ""-      , "f a = traceShow (\"debug\" :: String) a"+      , "f a = traceShow (\"debug\" :: " <> stringLit <> ") a"       ]   , testSession "add default type to satisfy two constraints with duplicate literals" $     testFor@@ -2582,17 +2732,18 @@       (if ghcVersion >= GHC94         then [ (DiagnosticSeverity_Warning, (6, 54), "Defaulting the type variable", Nothing) ]         else [ (DiagnosticSeverity_Warning, (6, 54), "Defaulting the following constraint", Nothing) ])-      "Add type annotation ‘String’ to ‘\"debug\"’"+      ("Add type annotation ‘"<> stringLit <>"’ to ‘\"debug\"’")       [ "{-# OPTIONS_GHC -Wtype-defaults #-}"       , "{-# LANGUAGE OverloadedStrings #-}"       , "module A (f) where"       , ""       , "import Debug.Trace"       , ""-      , "f = seq (\"debug\" :: [Char]) (seq (\"debug\" :: [Char]) (traceShow (\"debug\" :: String)))"+      , "f = seq (\"debug\" :: [Char]) (seq (\"debug\" :: [Char]) (traceShow (\"debug\" :: "<> stringLit <> ")))"       ]   ]   where+    stringLit = if ghcVersion >= GHC912 then "[Char]" else "String"     testFor sourceLines diag expectedTitle expectedLines = do       docId <- createDoc "A.hs" "haskell" $ T.unlines sourceLines       expectDiagnostics [ ("A.hs", diag) ]@@ -3208,6 +3359,10 @@     executeCodeAction chosenAction     modifiedCode <- documentContents doc     liftIO $ expectedCode @=? modifiedCode+  issue806 = if ghcVersion >= GHC912 then+                  "hello = print"           >:: "hello :: GHC.Types.ZonkAny 0 -> IO ()" -- GHC now returns ZonkAny 0 instead of Any. https://gitlab.haskell.org/ghc/ghc/-/issues/25895+                else+                  "hello = print"           >:: "hello :: GHC.Types.Any -> IO ()" -- Documents current behavior outlined in #806   in   testGroup "add signature"     [ "abc = True"              >:: "abc :: Bool"@@ -3216,7 +3371,7 @@     , "(!!!) a b = a > b"       >:: "(!!!) :: Ord a => a -> a -> Bool"     , "a >>>> b = a + b"        >:: "(>>>>) :: Num a => a -> a -> a"     , "a `haha` b = a b"        >:: "haha :: (t1 -> t2) -> t1 -> t2"-    , "hello = print"           >:: "hello :: GHC.Types.Any -> IO ()" -- Documents current behavior outlined in #806+    , issue806     , "pattern Some a = Just a" >:: "pattern Some :: a -> Maybe a"     , "pattern Some a <- Just a" >:: "pattern Some :: a -> Maybe a"     , "pattern Some a <- Just a\n  where Some a = Just a" >:: "pattern Some :: a -> Maybe a"@@ -3893,8 +4048,7 @@ -- Which we need to do on macOS since the $TMPDIR can be in @/private/var@ or -- @/var@ withTempDir :: (FilePath -> IO a) -> IO a-withTempDir f = System.IO.Extra.withTempDir $ \dir ->-  canonicalizePath dir >>= f+withTempDir f = System.IO.Extra.withTempDir $ (canonicalizePath >=> f)  brokenForGHC94 :: String -> TestTree -> TestTree brokenForGHC94 = knownBrokenForGhcVersions [GHC94]
plugins/hls-refactor-plugin/test/Test/AddArgument.hs view
@@ -35,7 +35,7 @@       mkGoldenAddArgTest "AddArgFromLet" (r 2 0 2 50),       mkGoldenAddArgTest "AddArgFromWhere" (r 3 0 3 50),       -- TODO can we make this work for GHC 9.10?-      knownBrokenForGhcVersions [GHC910] "In GHC 9.10 end-of-line comment annotation is in different place" $+      knownBrokenForGhcVersions [GHC910, GHC912] "In GHC 9.10 and 9.12 end-of-line comment annotation is in different place" $           mkGoldenAddArgTest "AddArgFromWhereComments" (r 3 0 3 50),       mkGoldenAddArgTest "AddArgWithTypeSynSig" (r 2 0 2 50),       mkGoldenAddArgTest "AddArgWithTypeSynSigContravariant" (r 2 0 2 50),
plugins/hls-stylish-haskell-plugin/src/Ide/Plugin/StylishHaskell.hs view
@@ -79,10 +79,15 @@ -- If no such file has been found, return default config. loadConfigFrom :: FilePath -> IO Config loadConfigFrom file = do+#if MIN_VERSION_stylish_haskell(0,15,0)+  let configSearchStrategy = SearchFromDirectory (takeDirectory file)+  config <- loadConfig (makeVerbose False) configSearchStrategy+#else   currDir <- getCurrentDirectory   setCurrentDirectory (takeDirectory file)   config <- loadConfig (makeVerbose False) Nothing   setCurrentDirectory currDir+#endif   pure config  -- | Run stylish-haskell on the given text with the given configuration.
+ test/testdata/hieBiosError/hie.yaml view
− test/testdata/hieBiosMainIs/dist-newstyle/cache/plan.json
@@ -1,1 +0,0 @@-{"cabal-version":"3.12.1.0","cabal-lib-version":"3.12.1.0","compiler-id":"ghc-9.12.2","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.21.0.0-b7a5","pkg-name":"base","pkg-version":"4.21.0.0","depends":["ghc-internal-9.1202.0-7700","ghc-prim-0.13.0-00de"]},{"type":"pre-existing","id":"ghc-bignum-1.3-4dbb","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.13.0-00de"]},{"type":"pre-existing","id":"ghc-internal-9.1202.0-7700","pkg-name":"ghc-internal","pkg-version":"9.1202.0","depends":["ghc-bignum-1.3-4dbb","ghc-prim-0.13.0-00de","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-prim-0.13.0-00de","pkg-name":"ghc-prim","pkg-version":"0.13.0","depends":["rts-1.0.2"]},{"type":"configured","id":"hieBiosMainIs-0.1.0.0-inplace-hieBiosMainIs","pkg-name":"hieBiosMainIs","pkg-version":"0.1.0.0","flags":{},"style":"local","pkg-src":{"type":"local","path":"/home/hugin/Documents/haskell/hls/test/testdata/hieBiosMainIs/."},"dist-dir":"/home/hugin/Documents/haskell/hls/test/testdata/hieBiosMainIs/dist-newstyle/build/x86_64-linux/ghc-9.12.2/hieBiosMainIs-0.1.0.0/x/hieBiosMainIs","build-info":"/home/hugin/Documents/haskell/hls/test/testdata/hieBiosMainIs/dist-newstyle/build/x86_64-linux/ghc-9.12.2/hieBiosMainIs-0.1.0.0/x/hieBiosMainIs/build-info.json","depends":["base-4.21.0.0-b7a5"],"exe-depends":[],"component-name":"exe:hieBiosMainIs","bin-file":"/home/hugin/Documents/haskell/hls/test/testdata/hieBiosMainIs/dist-newstyle/build/x86_64-linux/ghc-9.12.2/hieBiosMainIs-0.1.0.0/x/hieBiosMainIs/build/hieBiosMainIs/hieBiosMainIs"},{"type":"pre-existing","id":"rts-1.0.2","pkg-name":"rts","pkg-version":"1.0.2","depends":[]}]}
− test/testdata/missingModuleTest/missingModule/dist-newstyle/cache/plan.json
@@ -1,1 +0,0 @@-{"cabal-version":"3.12.1.0","cabal-lib-version":"3.12.1.0","compiler-id":"ghc-9.12.2","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.21.0.0-b7a5","pkg-name":"base","pkg-version":"4.21.0.0","depends":["ghc-internal-9.1202.0-7700","ghc-prim-0.13.0-00de"]},{"type":"pre-existing","id":"ghc-bignum-1.3-4dbb","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.13.0-00de"]},{"type":"pre-existing","id":"ghc-internal-9.1202.0-7700","pkg-name":"ghc-internal","pkg-version":"9.1202.0","depends":["ghc-bignum-1.3-4dbb","ghc-prim-0.13.0-00de","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-prim-0.13.0-00de","pkg-name":"ghc-prim","pkg-version":"0.13.0","depends":["rts-1.0.2"]},{"type":"configured","id":"missingModule-0.1.0.0-inplace","pkg-name":"missingModule","pkg-version":"0.1.0.0","flags":{},"style":"local","pkg-src":{"type":"local","path":"/home/hugin/Documents/haskell/hls/test/testdata/missingModuleTest/missingModule/."},"dist-dir":"/home/hugin/Documents/haskell/hls/test/testdata/missingModuleTest/missingModule/dist-newstyle/build/x86_64-linux/ghc-9.12.2/missingModule-0.1.0.0","build-info":"/home/hugin/Documents/haskell/hls/test/testdata/missingModuleTest/missingModule/dist-newstyle/build/x86_64-linux/ghc-9.12.2/missingModule-0.1.0.0/build-info.json","depends":["base-4.21.0.0-b7a5"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"rts-1.0.2","pkg-name":"rts","pkg-version":"1.0.2","depends":[]}]}
+ test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/cache/plan.json view
@@ -0,0 +1,1 @@+{"cabal-version":"3.10.1.0","cabal-lib-version":"3.10.1.0","compiler-id":"ghc-9.6.3","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.18.1.0","pkg-name":"base","pkg-version":"4.18.1.0","depends":["ghc-bignum-1.3","ghc-prim-0.10.0","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-bignum-1.3","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.10.0"]},{"type":"pre-existing","id":"ghc-prim-0.10.0","pkg-name":"ghc-prim","pkg-version":"0.10.0","depends":["rts-1.0.2"]},{"type":"configured","id":"noPrefixMatch-0.1.0.0-inplace-testExe","pkg-name":"noPrefixMatch","pkg-version":"0.1.0.0","flags":{},"style":"local","pkg-src":{"type":"local","path":"/home/zubin/haskell-language-server-dist/test/testdata/missingModuleTest/noPrefixMatch/."},"dist-dir":"/home/zubin/haskell-language-server-dist/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/build/x86_64-linux/ghc-9.6.3/noPrefixMatch-0.1.0.0/x/testExe","build-info":"/home/zubin/haskell-language-server-dist/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/build/x86_64-linux/ghc-9.6.3/noPrefixMatch-0.1.0.0/x/testExe/build-info.json","depends":["base-4.18.1.0"],"exe-depends":[],"component-name":"exe:testExe","bin-file":"/home/zubin/haskell-language-server-dist/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/build/x86_64-linux/ghc-9.6.3/noPrefixMatch-0.1.0.0/x/testExe/build/testExe/testExe"},{"type":"pre-existing","id":"rts-1.0.2","pkg-name":"rts","pkg-version":"1.0.2","depends":[]}]}
+ test/testdata/schema/ghc910/default-config.golden.json view
@@ -0,0 +1,151 @@+{+    "cabalFormattingProvider": "cabal-gild",+    "checkParents": "CheckOnSave",+    "checkProject": true,+    "formattingProvider": "ormolu",+    "maxCompletions": 40,+    "plugin": {+        "alternateNumberFormat": {+            "globalOn": true+        },+        "cabal": {+            "codeActionsOn": true,+            "completionOn": true,+            "diagnosticsOn": true,+            "hoverOn": true,+            "symbolsOn": true+        },+        "cabal-fmt": {+            "config": {+                "path": "cabal-fmt"+            }+        },+        "cabal-gild": {+            "config": {+                "path": "cabal-gild"+            }+        },+        "cabalHaskellIntegration": {+            "globalOn": true+        },+        "callHierarchy": {+            "globalOn": true+        },+        "changeTypeSignature": {+            "globalOn": true+        },+        "class": {+            "codeActionsOn": true,+            "codeLensOn": true+        },+        "eval": {+            "codeActionsOn": true,+            "codeLensOn": true,+            "config": {+                "diff": true,+                "exception": false+            }+        },+        "explicit-fields": {+            "codeActionsOn": true,+            "inlayHintsOn": true+        },+        "explicit-fixity": {+            "globalOn": true+        },+        "fourmolu": {+            "config": {+                "external": false,+                "path": "fourmolu"+            }+        },+        "gadt": {+            "globalOn": true+        },+        "ghcide-code-actions-bindings": {+            "globalOn": true+        },+        "ghcide-code-actions-fill-holes": {+            "globalOn": true+        },+        "ghcide-code-actions-imports-exports": {+            "globalOn": true+        },+        "ghcide-code-actions-type-signatures": {+            "globalOn": true+        },+        "ghcide-completions": {+            "config": {+                "autoExtendOn": true,+                "snippetsOn": true+            },+            "globalOn": true+        },+        "ghcide-hover-and-symbols": {+            "hoverOn": true,+            "symbolsOn": true+        },+        "ghcide-type-lenses": {+            "config": {+                "mode": "always"+            },+            "globalOn": true+        },+        "importLens": {+            "codeActionsOn": true,+            "codeLensOn": true,+            "inlayHintsOn": true+        },+        "moduleName": {+            "globalOn": true+        },+        "ormolu": {+            "config": {+                "external": false+            }+        },+        "overloaded-record-dot": {+            "globalOn": true+        },+        "pragmas-completion": {+            "globalOn": true+        },+        "pragmas-disable": {+            "globalOn": true+        },+        "pragmas-suggest": {+            "globalOn": true+        },+        "qualifyImportedNames": {+            "globalOn": true+        },+        "rename": {+            "config": {+                "crossModule": false+            },+            "globalOn": true+        },+        "semanticTokens": {+            "config": {+                "classMethodToken": "method",+                "classToken": "class",+                "dataConstructorToken": "enumMember",+                "functionToken": "function",+                "moduleToken": "namespace",+                "operatorToken": "operator",+                "patternSynonymToken": "macro",+                "recordFieldToken": "property",+                "typeConstructorToken": "enum",+                "typeFamilyToken": "interface",+                "typeSynonymToken": "type",+                "typeVariableToken": "typeParameter",+                "variableToken": "variable"+            },+            "globalOn": false+        },+        "stan": {+            "globalOn": false+        }+    },+    "sessionLoading": "singleComponent"+}
+ test/testdata/schema/ghc910/vscode-extension-schema.golden.json view
@@ -0,0 +1,1028 @@+{+    "haskell.plugin.alternateNumberFormat.globalOn": {+        "default": true,+        "description": "Enables alternateNumberFormat plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.cabal-fmt.config.path": {+        "default": "cabal-fmt",+        "markdownDescription": "Set path to 'cabal-fmt' executable",+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.cabal-gild.config.path": {+        "default": "cabal-gild",+        "markdownDescription": "Set path to 'cabal-gild' executable",+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.cabal.codeActionsOn": {+        "default": true,+        "description": "Enables cabal code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.cabal.completionOn": {+        "default": true,+        "description": "Enables cabal completions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.cabal.diagnosticsOn": {+        "default": true,+        "description": "Enables cabal diagnostics",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.cabal.hoverOn": {+        "default": true,+        "description": "Enables cabal hover",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.cabal.symbolsOn": {+        "default": true,+        "description": "Enables cabal symbols",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.cabalHaskellIntegration.globalOn": {+        "default": true,+        "description": "Enables cabalHaskellIntegration plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.callHierarchy.globalOn": {+        "default": true,+        "description": "Enables callHierarchy plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.changeTypeSignature.globalOn": {+        "default": true,+        "description": "Enables changeTypeSignature plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.class.codeActionsOn": {+        "default": true,+        "description": "Enables class code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.class.codeLensOn": {+        "default": true,+        "description": "Enables class code lenses",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.codeActionsOn": {+        "default": true,+        "description": "Enables eval code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.codeLensOn": {+        "default": true,+        "description": "Enables eval code lenses",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.config.diff": {+        "default": true,+        "markdownDescription": "Enable the diff output (WAS/NOW) of eval lenses",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.config.exception": {+        "default": false,+        "markdownDescription": "Enable marking exceptions with `*** Exception:` similarly to doctest and GHCi.",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.explicit-fields.codeActionsOn": {+        "default": true,+        "description": "Enables explicit-fields code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.explicit-fields.inlayHintsOn": {+        "default": true,+        "description": "Enables explicit-fields inlay hints",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.explicit-fixity.globalOn": {+        "default": true,+        "description": "Enables explicit-fixity plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.fourmolu.config.external": {+        "default": false,+        "markdownDescription": "Call out to an external \"fourmolu\" executable, rather than using the bundled library.",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.fourmolu.config.path": {+        "default": "fourmolu",+        "markdownDescription": "Set path to executable (for \"external\" mode).",+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.gadt.globalOn": {+        "default": true,+        "description": "Enables gadt plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-bindings.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-bindings plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-fill-holes.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-fill-holes plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-imports-exports.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-imports-exports plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-type-signatures.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-type-signatures plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-completions.config.autoExtendOn": {+        "default": true,+        "markdownDescription": "Extends the import list automatically when completing a out-of-scope identifier",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-completions.config.snippetsOn": {+        "default": true,+        "markdownDescription": "Inserts snippets when using code completions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-completions.globalOn": {+        "default": true,+        "description": "Enables ghcide-completions plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-hover-and-symbols.hoverOn": {+        "default": true,+        "description": "Enables ghcide-hover-and-symbols hover",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-hover-and-symbols.symbolsOn": {+        "default": true,+        "description": "Enables ghcide-hover-and-symbols symbols",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-type-lenses.config.mode": {+        "default": "always",+        "description": "Control how type lenses are shown",+        "enum": [+            "always",+            "exported",+            "diagnostics"+        ],+        "enumDescriptions": [+            "Always displays type lenses of global bindings",+            "Only display type lenses of exported global bindings",+            "Follows error messages produced by GHC about missing signatures"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.ghcide-type-lenses.globalOn": {+        "default": true,+        "description": "Enables ghcide-type-lenses plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.importLens.codeActionsOn": {+        "default": true,+        "description": "Enables importLens code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.importLens.codeLensOn": {+        "default": true,+        "description": "Enables importLens code lenses",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.importLens.inlayHintsOn": {+        "default": true,+        "description": "Enables importLens inlay hints",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.moduleName.globalOn": {+        "default": true,+        "description": "Enables moduleName plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ormolu.config.external": {+        "default": false,+        "markdownDescription": "Call out to an external \"ormolu\" executable, rather than using the bundled library",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.overloaded-record-dot.globalOn": {+        "default": true,+        "description": "Enables overloaded-record-dot plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.pragmas-completion.globalOn": {+        "default": true,+        "description": "Enables pragmas-completion plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.pragmas-disable.globalOn": {+        "default": true,+        "description": "Enables pragmas-disable plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.pragmas-suggest.globalOn": {+        "default": true,+        "description": "Enables pragmas-suggest plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.qualifyImportedNames.globalOn": {+        "default": true,+        "description": "Enables qualifyImportedNames plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.rename.config.crossModule": {+        "default": false,+        "markdownDescription": "Enable experimental cross-module renaming",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.rename.globalOn": {+        "default": true,+        "description": "Enables rename plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.semanticTokens.config.classMethodToken": {+        "default": "method",+        "description": "LSP semantic token type to use for typeclass methods",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.classToken": {+        "default": "class",+        "description": "LSP semantic token type to use for typeclasses",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.dataConstructorToken": {+        "default": "enumMember",+        "description": "LSP semantic token type to use for data constructors",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.functionToken": {+        "default": "function",+        "description": "LSP semantic token type to use for functions",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.moduleToken": {+        "default": "namespace",+        "description": "LSP semantic token type to use for modules",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.operatorToken": {+        "default": "operator",+        "description": "LSP semantic token type to use for operators",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.patternSynonymToken": {+        "default": "macro",+        "description": "LSP semantic token type to use for pattern synonyms",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.recordFieldToken": {+        "default": "property",+        "description": "LSP semantic token type to use for record fields",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.typeConstructorToken": {+        "default": "enum",+        "description": "LSP semantic token type to use for type constructors",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.typeFamilyToken": {+        "default": "interface",+        "description": "LSP semantic token type to use for type families",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.typeSynonymToken": {+        "default": "type",+        "description": "LSP semantic token type to use for type synonyms",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.typeVariableToken": {+        "default": "typeParameter",+        "description": "LSP semantic token type to use for type variables",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.config.variableToken": {+        "default": "variable",+        "description": "LSP semantic token type to use for variables",+        "enum": [+            "namespace",+            "type",+            "class",+            "enum",+            "interface",+            "struct",+            "typeParameter",+            "parameter",+            "variable",+            "property",+            "enumMember",+            "event",+            "function",+            "method",+            "macro",+            "keyword",+            "modifier",+            "comment",+            "string",+            "number",+            "regexp",+            "operator",+            "decorator"+        ],+        "enumDescriptions": [+            "LSP Semantic Token Type: namespace",+            "LSP Semantic Token Type: type",+            "LSP Semantic Token Type: class",+            "LSP Semantic Token Type: enum",+            "LSP Semantic Token Type: interface",+            "LSP Semantic Token Type: struct",+            "LSP Semantic Token Type: typeParameter",+            "LSP Semantic Token Type: parameter",+            "LSP Semantic Token Type: variable",+            "LSP Semantic Token Type: property",+            "LSP Semantic Token Type: enumMember",+            "LSP Semantic Token Type: event",+            "LSP Semantic Token Type: function",+            "LSP Semantic Token Type: method",+            "LSP Semantic Token Type: macro",+            "LSP Semantic Token Type: keyword",+            "LSP Semantic Token Type: modifier",+            "LSP Semantic Token Type: comment",+            "LSP Semantic Token Type: string",+            "LSP Semantic Token Type: number",+            "LSP Semantic Token Type: regexp",+            "LSP Semantic Token Type: operator",+            "LSP Semantic Token Type: decorator"+        ],+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.semanticTokens.globalOn": {+        "default": false,+        "description": "Enables semanticTokens plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.stan.globalOn": {+        "default": false,+        "description": "Enables stan plugin",+        "scope": "resource",+        "type": "boolean"+    }+}
test/testdata/schema/ghc912/default-config.golden.json view
@@ -20,6 +20,11 @@                 "path": "cabal-fmt"             }         },+        "cabal-gild": {+            "config": {+                "path": "cabal-gild"+            }+        },         "cabalHaskellIntegration": {             "globalOn": true         },@@ -34,11 +39,12 @@             "codeLensOn": true         },         "eval": {+            "codeActionsOn": true,+            "codeLensOn": true,             "config": {                 "diff": true,                 "exception": false-            },-            "globalOn": true+            }         },         "explicit-fields": {             "codeActionsOn": true,@@ -47,6 +53,27 @@         "explicit-fixity": {             "globalOn": true         },+        "fourmolu": {+            "config": {+                "external": false,+                "path": "fourmolu"+            }+        },+        "gadt": {+            "globalOn": true+        },+        "ghcide-code-actions-bindings": {+            "globalOn": true+        },+        "ghcide-code-actions-fill-holes": {+            "globalOn": true+        },+        "ghcide-code-actions-imports-exports": {+            "globalOn": true+        },+        "ghcide-code-actions-type-signatures": {+            "globalOn": true+        },         "ghcide-completions": {             "config": {                 "autoExtendOn": true,@@ -64,6 +91,13 @@             },             "globalOn": true         },+        "hlint": {+            "codeActionsOn": true,+            "config": {+                "flags": []+            },+            "diagnosticsOn": true+        },         "importLens": {             "codeActionsOn": true,             "codeLensOn": true,@@ -72,6 +106,11 @@         "moduleName": {             "globalOn": true         },+        "ormolu": {+            "config": {+                "external": false+            }+        },         "overloaded-record-dot": {             "globalOn": true         },@@ -85,6 +124,12 @@             "globalOn": true         },         "qualifyImportedNames": {+            "globalOn": true+        },+        "rename": {+            "config": {+                "crossModule": false+            },             "globalOn": true         },         "semanticTokens": {
test/testdata/schema/ghc912/vscode-extension-schema.golden.json view
@@ -11,6 +11,12 @@         "scope": "resource",         "type": "string"     },+    "haskell.plugin.cabal-gild.config.path": {+        "default": "cabal-gild",+        "markdownDescription": "Set path to 'cabal-gild' executable",+        "scope": "resource",+        "type": "string"+    },     "haskell.plugin.cabal.codeActionsOn": {         "default": true,         "description": "Enables cabal code actions",@@ -71,6 +77,18 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.eval.codeActionsOn": {+        "default": true,+        "description": "Enables eval code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.codeLensOn": {+        "default": true,+        "description": "Enables eval code lenses",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.eval.config.diff": {         "default": true,         "markdownDescription": "Enable the diff output (WAS/NOW) of eval lenses",@@ -83,12 +101,6 @@         "scope": "resource",         "type": "boolean"     },-    "haskell.plugin.eval.globalOn": {-        "default": true,-        "description": "Enables eval plugin",-        "scope": "resource",-        "type": "boolean"-    },     "haskell.plugin.explicit-fields.codeActionsOn": {         "default": true,         "description": "Enables explicit-fields code actions",@@ -107,6 +119,48 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.fourmolu.config.external": {+        "default": false,+        "markdownDescription": "Call out to an external \"fourmolu\" executable, rather than using the bundled library.",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.fourmolu.config.path": {+        "default": "fourmolu",+        "markdownDescription": "Set path to executable (for \"external\" mode).",+        "scope": "resource",+        "type": "string"+    },+    "haskell.plugin.gadt.globalOn": {+        "default": true,+        "description": "Enables gadt plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-bindings.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-bindings plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-fill-holes.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-fill-holes plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-imports-exports.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-imports-exports plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.ghcide-code-actions-type-signatures.globalOn": {+        "default": true,+        "description": "Enables ghcide-code-actions-type-signatures plugin",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.ghcide-completions.config.autoExtendOn": {         "default": true,         "markdownDescription": "Extends the import list automatically when completing a out-of-scope identifier",@@ -159,6 +213,24 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.hlint.codeActionsOn": {+        "default": true,+        "description": "Enables hlint code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.hlint.config.flags": {+        "default": [],+        "markdownDescription": "Flags used by hlint",+        "scope": "resource",+        "type": "array"+    },+    "haskell.plugin.hlint.diagnosticsOn": {+        "default": true,+        "description": "Enables hlint diagnostics",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.importLens.codeActionsOn": {         "default": true,         "description": "Enables importLens code actions",@@ -183,6 +255,12 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.ormolu.config.external": {+        "default": false,+        "markdownDescription": "Call out to an external \"ormolu\" executable, rather than using the bundled library",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.overloaded-record-dot.globalOn": {         "default": true,         "description": "Enables overloaded-record-dot plugin",@@ -210,6 +288,18 @@     "haskell.plugin.qualifyImportedNames.globalOn": {         "default": true,         "description": "Enables qualifyImportedNames plugin",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.rename.config.crossModule": {+        "default": false,+        "markdownDescription": "Enable experimental cross-module renaming",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.rename.globalOn": {+        "default": true,+        "description": "Enables rename plugin",         "scope": "resource",         "type": "boolean"     },
test/testdata/schema/ghc94/default-config.golden.json view
@@ -39,11 +39,12 @@             "codeLensOn": true         },         "eval": {+            "codeActionsOn": true,+            "codeLensOn": true,             "config": {                 "diff": true,                 "exception": false-            },-            "globalOn": true+            }         },         "explicit-fields": {             "codeActionsOn": true,
test/testdata/schema/ghc94/vscode-extension-schema.golden.json view
@@ -77,6 +77,18 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.eval.codeActionsOn": {+        "default": true,+        "description": "Enables eval code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.codeLensOn": {+        "default": true,+        "description": "Enables eval code lenses",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.eval.config.diff": {         "default": true,         "markdownDescription": "Enable the diff output (WAS/NOW) of eval lenses",@@ -86,12 +98,6 @@     "haskell.plugin.eval.config.exception": {         "default": false,         "markdownDescription": "Enable marking exceptions with `*** Exception:` similarly to doctest and GHCi.",-        "scope": "resource",-        "type": "boolean"-    },-    "haskell.plugin.eval.globalOn": {-        "default": true,-        "description": "Enables eval plugin",         "scope": "resource",         "type": "boolean"     },
test/testdata/schema/ghc96/default-config.golden.json view
@@ -39,11 +39,12 @@             "codeLensOn": true         },         "eval": {+            "codeActionsOn": true,+            "codeLensOn": true,             "config": {                 "diff": true,                 "exception": false-            },-            "globalOn": true+            }         },         "explicit-fields": {             "codeActionsOn": true,
test/testdata/schema/ghc96/vscode-extension-schema.golden.json view
@@ -77,6 +77,18 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.eval.codeActionsOn": {+        "default": true,+        "description": "Enables eval code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.codeLensOn": {+        "default": true,+        "description": "Enables eval code lenses",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.eval.config.diff": {         "default": true,         "markdownDescription": "Enable the diff output (WAS/NOW) of eval lenses",@@ -86,12 +98,6 @@     "haskell.plugin.eval.config.exception": {         "default": false,         "markdownDescription": "Enable marking exceptions with `*** Exception:` similarly to doctest and GHCi.",-        "scope": "resource",-        "type": "boolean"-    },-    "haskell.plugin.eval.globalOn": {-        "default": true,-        "description": "Enables eval plugin",         "scope": "resource",         "type": "boolean"     },
test/testdata/schema/ghc98/default-config.golden.json view
@@ -39,11 +39,12 @@             "codeLensOn": true         },         "eval": {+            "codeActionsOn": true,+            "codeLensOn": true,             "config": {                 "diff": true,                 "exception": false-            },-            "globalOn": true+            }         },         "explicit-fields": {             "codeActionsOn": true,
test/testdata/schema/ghc98/vscode-extension-schema.golden.json view
@@ -77,6 +77,18 @@         "scope": "resource",         "type": "boolean"     },+    "haskell.plugin.eval.codeActionsOn": {+        "default": true,+        "description": "Enables eval code actions",+        "scope": "resource",+        "type": "boolean"+    },+    "haskell.plugin.eval.codeLensOn": {+        "default": true,+        "description": "Enables eval code lenses",+        "scope": "resource",+        "type": "boolean"+    },     "haskell.plugin.eval.config.diff": {         "default": true,         "markdownDescription": "Enable the diff output (WAS/NOW) of eval lenses",@@ -86,12 +98,6 @@     "haskell.plugin.eval.config.exception": {         "default": false,         "markdownDescription": "Enable marking exceptions with `*** Exception:` similarly to doctest and GHCi.",-        "scope": "resource",-        "type": "boolean"-    },-    "haskell.plugin.eval.globalOn": {-        "default": true,-        "description": "Enables eval plugin",         "scope": "resource",         "type": "boolean"     },
+ test/testdata/wErrorTest/dist-newstyle/cache/plan.json view
@@ -0,0 +1,1 @@+{"cabal-version":"3.8.1.0","cabal-lib-version":"3.8.1.0","compiler-id":"ghc-9.2.4","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.16.3.0","pkg-name":"base","pkg-version":"4.16.3.0","depends":["ghc-bignum-1.2","ghc-prim-0.8.0","rts"]},{"type":"pre-existing","id":"ghc-bignum-1.2","pkg-name":"ghc-bignum","pkg-version":"1.2","depends":["ghc-prim-0.8.0"]},{"type":"pre-existing","id":"ghc-prim-0.8.0","pkg-name":"ghc-prim","pkg-version":"0.8.0","depends":["rts"]},{"type":"pre-existing","id":"rts","pkg-name":"rts","pkg-version":"1.0.2","depends":[]},{"type":"configured","id":"test-0.1.0.0-inplace","pkg-name":"test","pkg-version":"0.1.0.0","flags":{},"style":"local","pkg-src":{"type":"local","path":"/home/zubin/haskell-language-server-dist/test/testdata/wErrorTest/."},"dist-dir":"/home/zubin/haskell-language-server-dist/test/testdata/wErrorTest/dist-newstyle/build/x86_64-linux/ghc-9.2.4/test-0.1.0.0","build-info":"/home/zubin/haskell-language-server-dist/test/testdata/wErrorTest/dist-newstyle/build/x86_64-linux/ghc-9.2.4/test-0.1.0.0/build-info.json","depends":["base-4.16.3.0"],"exe-depends":[],"component-name":"lib"}]}