diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,62 @@
 # Changelog for haskell-language-server
 
+## 2.13.0.0
+
+- Bindists for GHC 9.14.1
+- Bindists for GHC 9.12.2
+- Bindists for GHC 9.10.3
+- Bindists for GHC 9.8.4
+- Bindists for GHC 9.6.7
+- Last release supporting GHC 9.6
+
+Support for GHC 9.14.1 is preliminary, some plugins are not yet support but will
+be in the future.
+Plugins that are expected to be supported in a later release:
+
+- `hls-hlint-plugin`
+- `hls-ormolu-plugin`
+- `hls-fourmolu-plugin`
+- `hls-stylish-haskell-plugin`
+
+### Pull Requests
+
+- 9.14 support
+  ([#4780](https://github.com/haskell/haskell-language-server/pull/4780)) by @wz1000
+- Use 9.10.2 instead of 9.10.3 for CI on windows
+  ([#4768](https://github.com/haskell/haskell-language-server/pull/4768)) by @wz1000
+- Disable the hlint plugin for GHC 9.10, for good
+  ([#4767](https://github.com/haskell/haskell-language-server/pull/4767)) by @fendor
+- Add default-extension completions in .cabal files
+  ([#4766](https://github.com/haskell/haskell-language-server/pull/4766)) by @VeryMilkyJoe
+- Use the `HscEnv` after summarising the module
+  ([#4749](https://github.com/haskell/haskell-language-server/pull/4749)) by @fendor
+- Escape dollar signs in completion snippets
+  ([#4745](https://github.com/haskell/haskell-language-server/pull/4745)) by @Soupstraw
+- update contributing.md, adding instructions for configuring eglot to use a hacked HLS executable.
+  ([#4740](https://github.com/haskell/haskell-language-server/pull/4740)) by @morphismz
+- docs(ghcide): move most of the README in hls documentation (#3639)
+  ([#4739](https://github.com/haskell/haskell-language-server/pull/4739)) by @blackheaven
+- haskell-language-server: add plugin-tutorial cabal flag
+  ([#4738](https://github.com/haskell/haskell-language-server/pull/4738)) by @juhp
+- Remove overly chatty log message
+  ([#4737](https://github.com/haskell/haskell-language-server/pull/4737)) by @fendor
+- Rely on gitignore to exclude listed files in ghcide (#4665)
+  ([#4736](https://github.com/haskell/haskell-language-server/pull/4736)) by @blackheaven
+- Bump haskell-actions/setup from 2.8.1 to 2.8.2 in /.github/actions/setup-build
+  ([#4730](https://github.com/haskell/haskell-language-server/pull/4730)) by @dependabot[bot]
+- Bump haskell-actions/setup from 2.8.1 to 2.8.2
+  ([#4729](https://github.com/haskell/haskell-language-server/pull/4729)) by @dependabot[bot]
+- Prepare release 2.12.0.0
+  ([#4728](https://github.com/haskell/haskell-language-server/pull/4728)) by @wz1000
+- Use edit-distance to fix typos in cabal fields
+  ([#4722](https://github.com/haskell/haskell-language-server/pull/4722)) by @crtschin
+- Add code action to introduce `_` in numeric literals
+  ([#4716](https://github.com/haskell/haskell-language-server/pull/4716)) by @crtschin
+- Add "Go to type" hyperlinks in the hover popup (like Rust has)
+  ([#4691](https://github.com/haskell/haskell-language-server/pull/4691)) by @dnikolovv
+- Set the XDG_CACHE_HOME for tests
+  ([#4572](https://github.com/haskell/haskell-language-server/pull/4572)) by @fendor
+
 ## 2.12.0.0
 
 - Bindists for GHC 9.12.2
@@ -56,7 +113,7 @@
   ([#4640](https://github.com/haskell/haskell-language-server/pull/4640)) by @soulomoon
 - CI: Fix hls-eval-plugin tests for GHC-9.10
   ([#4638](https://github.com/haskell/haskell-language-server/pull/4638)) by @sgillespie
-- Fix renaming data constructors with fields (resolves #2915, resolves #4083) 
+- Fix renaming data constructors with fields (resolves #2915, resolves #4083)
   ([#4635](https://github.com/haskell/haskell-language-server/pull/4635)) by @jhrcek
 - Migrate change-type-signature-plugin to use structured diagnostics
   ([#4632](https://github.com/haskell/haskell-language-server/pull/4632)) by @sgillespie
@@ -94,7 +151,7 @@
   ([#4596](https://github.com/haskell/haskell-language-server/pull/4596)) by @fendor
 - Compute Partial module graph fingerprints
   ([#4594](https://github.com/haskell/haskell-language-server/pull/4594)) by @soulomoon
-- Strip prefixes added by DuplicateRecordFields 
+- Strip prefixes added by DuplicateRecordFields
   ([#4593](https://github.com/haskell/haskell-language-server/pull/4593)) by @kozak
 - Use shorter test names in ghcide-tests
   ([#4591](https://github.com/haskell/haskell-language-server/pull/4591)) by @fendor
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -34,3 +34,4 @@
 - [Configuration](https://haskell-language-server.readthedocs.io/en/latest/configuration.html)
 - [Troubleshooting](https://haskell-language-server.readthedocs.io/en/latest/troubleshooting.html)
 - [Contributing](https://haskell-language-server.readthedocs.io/en/latest/contributing/index.html)
+- [Components](https://haskell-language-server.readthedocs.io/en/latest/components/index.html)
diff --git a/ghcide-test/data/multi/cabal.project b/ghcide-test/data/multi/cabal.project
--- a/ghcide-test/data/multi/cabal.project
+++ b/ghcide-test/data/multi/cabal.project
@@ -1,3 +1,6 @@
 packages: a b c
 
-allow-newer: base
+allow-newer: async:base,
+             hashable:base,
+             hashable:template-haskell,
+             hashable:ghc-bignum,
diff --git a/ghcide-test/data/plugin-parser/cabal.project b/ghcide-test/data/plugin-parser/cabal.project
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/cabal.project
@@ -0,0 +1,2 @@
+packages: ./plugin
+          ./usage
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/plugin-1.0.0/build/autogen/PackageInfo_plugin.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/plugin-1.0.0/build/autogen/PackageInfo_plugin.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/plugin-1.0.0/build/autogen/PackageInfo_plugin.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module PackageInfo_plugin (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+name :: String
+name = "plugin"
+version :: Version
+version = Version [1,0,0] []
+
+synopsis :: String
+synopsis = ""
+copyright :: String
+copyright = ""
+homepage :: String
+homepage = ""
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/plugin-1.0.0/build/autogen/Paths_plugin.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/plugin-1.0.0/build/autogen/Paths_plugin.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/plugin-1.0.0/build/autogen/Paths_plugin.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module Paths_plugin (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import qualified Data.List as List
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+version :: Version
+version = Version [1,0,0] []
+
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.2-d434/plugin-1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.2-d434"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.10.2-d434/plugin-1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.10.2-d434/plugin-1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "plugin_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "plugin_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "plugin_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "plugin_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "plugin_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "plugin_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir fname
+  | isPathSeparator (List.last dir) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/usage-1.0.0/build/autogen/PackageInfo_usage.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/usage-1.0.0/build/autogen/PackageInfo_usage.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/usage-1.0.0/build/autogen/PackageInfo_usage.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module PackageInfo_usage (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+name :: String
+name = "usage"
+version :: Version
+version = Version [1,0,0] []
+
+synopsis :: String
+synopsis = ""
+copyright :: String
+copyright = ""
+homepage :: String
+homepage = ""
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/usage-1.0.0/build/autogen/Paths_usage.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/usage-1.0.0/build/autogen/Paths_usage.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.2/usage-1.0.0/build/autogen/Paths_usage.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module Paths_usage (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import qualified Data.List as List
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+version :: Version
+version = Version [1,0,0] []
+
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.2-d434/usage-1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.2-d434"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.10.2-d434/usage-1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.10.2-d434/usage-1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "usage_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "usage_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "usage_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "usage_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "usage_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "usage_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir fname
+  | isPathSeparator (List.last dir) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/plugin-1.0.0/build/autogen/PackageInfo_plugin.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/plugin-1.0.0/build/autogen/PackageInfo_plugin.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/plugin-1.0.0/build/autogen/PackageInfo_plugin.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module PackageInfo_plugin (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+name :: String
+name = "plugin"
+version :: Version
+version = Version [1,0,0] []
+
+synopsis :: String
+synopsis = ""
+copyright :: String
+copyright = ""
+homepage :: String
+homepage = ""
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/plugin-1.0.0/build/autogen/Paths_plugin.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/plugin-1.0.0/build/autogen/Paths_plugin.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/plugin-1.0.0/build/autogen/Paths_plugin.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module Paths_plugin (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import qualified Data.List as List
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+version :: Version
+version = Version [1,0,0] []
+
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c/plugin-1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.10.3-415c/plugin-1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.10.3-415c/plugin-1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "plugin_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "plugin_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "plugin_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "plugin_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "plugin_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "plugin_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir fname
+  | isPathSeparator (List.last dir) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/usage-1.0.0/build/autogen/PackageInfo_usage.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/usage-1.0.0/build/autogen/PackageInfo_usage.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/usage-1.0.0/build/autogen/PackageInfo_usage.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module PackageInfo_usage (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+name :: String
+name = "usage"
+version :: Version
+version = Version [1,0,0] []
+
+synopsis :: String
+synopsis = ""
+copyright :: String
+copyright = ""
+homepage :: String
+homepage = ""
diff --git a/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/usage-1.0.0/build/autogen/Paths_usage.hs b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/usage-1.0.0/build/autogen/Paths_usage.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/dist-newstyle/build/x86_64-linux/ghc-9.10.3/usage-1.0.0/build/autogen/Paths_usage.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+module Paths_usage (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import qualified Data.List as List
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+version :: Version
+version = Version [1,0,0] []
+
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c/usage-1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.10.3-415c/usage-1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.10.3-415c/usage-1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "usage_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "usage_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "usage_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "usage_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "usage_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "usage_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir fname
+  | isPathSeparator (List.last dir) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/ghcide-test/data/plugin-parser/plugin/Plugin.hs b/ghcide-test/data/plugin-parser/plugin/Plugin.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/plugin/Plugin.hs
@@ -0,0 +1,37 @@
+{-# LANGUAGE RecordWildCards #-}
+module Plugin (plugin) where
+
+import Control.Monad.IO.Class (MonadIO (..))
+import Data.Foldable          (for_)
+import Data.List              (foldl')
+import Data.List.NonEmpty     (NonEmpty (..))
+import Data.Traversable       (for)
+
+import qualified Data.Generics as SYB
+
+import qualified GHC.Plugins  as GHC
+import           GHC
+
+plugin :: GHC.Plugin
+plugin = GHC.defaultPlugin
+    { GHC.parsedResultAction = \_cliOptions -> pluginImpl
+    }
+
+pluginImpl :: GHC.ModSummary -> GHC.ParsedResult -> GHC.Hsc GHC.ParsedResult
+pluginImpl _modSummary pm = do
+    let m = GHC.parsedResultModule pm
+    hpm_module' <- transform (GHC.hpm_module m)
+    let module' = m { GHC.hpm_module = hpm_module' }
+    return pm { GHC.parsedResultModule = module' }
+
+transform
+    :: GHC.Located (HsModule GhcPs)
+    -> GHC.Hsc (GHC.Located (HsModule GhcPs))
+transform = SYB.everywhereM (SYB.mkM transform') where
+    transform' :: LHsExpr GhcPs -> GHC.Hsc (LHsExpr GhcPs)
+    transform' expr@(L srcSpan (HsVar _ lvar)) =
+        if GHC.occNameString (GHC.occName $ GHC.unLoc lvar) == "pluginConstant"
+            then return (nlHsIntLit 0x42)
+            else return expr
+    transform' expr =
+        return expr
diff --git a/ghcide-test/data/plugin-parser/plugin/plugin.cabal b/ghcide-test/data/plugin-parser/plugin/plugin.cabal
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/plugin/plugin.cabal
@@ -0,0 +1,9 @@
+cabal-version:  1.18
+name: plugin
+version: 1.0.0
+build-type: Simple
+
+library
+  build-depends: base, ghc, syb
+  exposed-modules: Plugin
+  hs-source-dirs: .
diff --git a/ghcide-test/data/plugin-parser/usage/File1.hs b/ghcide-test/data/plugin-parser/usage/File1.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/usage/File1.hs
@@ -0,0 +1,6 @@
+{-# OPTIONS_GHC -Wall #-}
+module File1 where
+
+import File2
+
+bar = foo * foo
diff --git a/ghcide-test/data/plugin-parser/usage/File2.hs b/ghcide-test/data/plugin-parser/usage/File2.hs
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/usage/File2.hs
@@ -0,0 +1,4 @@
+module File2 where
+
+foo :: Int
+foo = pluginConstant
diff --git a/ghcide-test/data/plugin-parser/usage/usage.cabal b/ghcide-test/data/plugin-parser/usage/usage.cabal
new file mode 100644
--- /dev/null
+++ b/ghcide-test/data/plugin-parser/usage/usage.cabal
@@ -0,0 +1,10 @@
+cabal-version:  1.18
+name: usage
+version: 1.0.0
+build-type: Simple
+
+library
+  build-depends: base, plugin
+  exposed-modules: File1 File2
+  ghc-options: -fplugin Plugin
+  hs-source-dirs: .
diff --git a/ghcide-test/exe/BootTests.hs b/ghcide-test/exe/BootTests.hs
--- a/ghcide-test/exe/BootTests.hs
+++ b/ghcide-test/exe/BootTests.hs
@@ -27,25 +27,24 @@
         let cPath = dir </> "C.hs"
         cSource <- liftIO $ readFileUtf8 cPath
         -- Dirty the cache
-        liftIO $ runInDir dir $ do
-            cDoc <- createDoc cPath "haskell" cSource
-            -- We send a hover request then wait for either the hover response or
-            -- `ghcide/reference/ready` notification.
-            -- Once we receive one of the above, we wait for the other that we
-            -- haven't received yet.
-            -- If we don't wait for the `ready` notification it is possible
-            -- that the `getDefinitions` request/response in the outer ghcide
-            -- session will find no definitions.
-            let hoverParams = HoverParams cDoc (Position 4 3) Nothing
-            hoverRequestId <- sendRequest SMethod_TextDocumentHover hoverParams
-            let parseReadyMessage = isReferenceReady cPath
-            let parseHoverResponse = responseForId SMethod_TextDocumentHover hoverRequestId
-            hoverResponseOrReadyMessage <- skipManyTill anyMessage ((Left <$> parseHoverResponse) <|> (Right <$> parseReadyMessage))
-            _ <- skipManyTill anyMessage $
-              case hoverResponseOrReadyMessage of
-                Left _  -> void parseReadyMessage
-                Right _ -> void parseHoverResponse
-            closeDoc cDoc
+        cDoc <- createDoc cPath "haskell" cSource
+        -- We send a hover request then wait for either the hover response or
+        -- `ghcide/reference/ready` notification.
+        -- Once we receive one of the above, we wait for the other that we
+        -- haven't received yet.
+        -- If we don't wait for the `ready` notification it is possible
+        -- that the `getDefinitions` request/response in the outer ghcide
+        -- session will find no definitions.
+        let hoverParams = HoverParams cDoc (Position 4 3) Nothing
+        hoverRequestId <- sendRequest SMethod_TextDocumentHover hoverParams
+        let parseReadyMessage = isReferenceReady cPath
+        let parseHoverResponse = responseForId SMethod_TextDocumentHover hoverRequestId
+        hoverResponseOrReadyMessage <- skipManyTill anyMessage ((Left <$> parseHoverResponse) <|> (Right <$> parseReadyMessage))
+        _ <- skipManyTill anyMessage $
+            case hoverResponseOrReadyMessage of
+            Left _  -> void parseReadyMessage
+            Right _ -> void parseHoverResponse
+        closeDoc cDoc
         cdoc <- createDoc cPath "haskell" cSource
         locs <- getDefinitions cdoc (Position 7 4)
         let floc = mkR 9 0 9 1
diff --git a/ghcide-test/exe/CradleTests.hs b/ghcide-test/exe/CradleTests.hs
--- a/ghcide-test/exe/CradleTests.hs
+++ b/ghcide-test/exe/CradleTests.hs
@@ -3,7 +3,7 @@
 
 module CradleTests (tests) where
 
-import           Config                          (checkDefs, mkL, runInDir,
+import           Config                          (checkDefs, mkL,
                                                   runWithExtraFiles,
                                                   testWithDummyPluginEmpty')
 import           Control.Applicative.Combinators
@@ -180,12 +180,9 @@
     runWithExtraFiles variant $ \dir -> do
     let aPath = dir </> "a/A.hs"
         bPath = dir </> "b/B.hs"
-    adoc <- liftIO $ runInDir dir $ do
-      aSource <- liftIO $ readFileUtf8 aPath
-      adoc <- createDoc aPath "haskell" aSource
-      skipManyTill anyMessage $ isReferenceReady aPath
-      closeDoc adoc
-      pure adoc
+    adoc <- openDoc aPath "haskell"
+    skipManyTill anyMessage $ isReferenceReady aPath
+    closeDoc adoc
     bSource <- liftIO $ readFileUtf8 bPath
     bdoc <- createDoc bPath "haskell" bSource
     locs <- getDefinitions bdoc (Position 2 7)
diff --git a/ghcide-test/exe/FindDefinitionAndHoverTests.hs b/ghcide-test/exe/FindDefinitionAndHoverTests.hs
--- a/ghcide-test/exe/FindDefinitionAndHoverTests.hs
+++ b/ghcide-test/exe/FindDefinitionAndHoverTests.hs
@@ -146,9 +146,12 @@
   fffL14 = Position 18  7  ;
   aL20   = Position 19 15
   aaaL14 = Position 18 20  ;  aaa    = [mkR  11  0   11  3]
+  kkkL30 = Position 30 2   ;  kkkType = [ExpectHoverTextRegex "Go to \\[MyClass\\]\\(.*GotoHover\\.hs#L26\\)"]
+  bbbL16 = Position 16 7   ;  bbbType = [ExpectHoverTextRegex "Go to \\[TypeConstructor\\]\\(.*GotoHover\\.hs#L8\\)"]
+  aaaL11 = Position 11 1   ;  aaaType = [ExpectHoverTextRegex "Go to \\[TypeConstructor\\]\\(.*GotoHover\\.hs#L8\\)"]
   dcL7   = Position 11 11  ;  tcDC   = [mkR   7 23    9 16]
   dcL12  = Position 16 11  ;
-  xtcL5  = Position  9 11  ;  xtc    = [ExpectHoverText ["Int", "Defined in ", "GHC.Types", "ghc-prim"]]
+  xtcL5  = Position  9 11  ;  xtc    = [ExpectHoverText ["Int", "Defined in ", if ghcVersion >= GHC914 then "GHC.Internal.Types" else "GHC.Types", if ghcVersion >= GHC914 then "ghc-internal" else "ghc-prim"]]
   tcL6   = Position 10 11  ;  tcData = [mkR   7  0    9 16, ExpectHoverText ["TypeConstructor", "GotoHover.hs:8:1"]]
   vvL16  = Position 20 12  ;  vv     = [mkR  20  4   20  6]
   opL16  = Position 20 15  ;  op     = [mkR  21  2   21  4]
@@ -185,10 +188,10 @@
   innL48 = Position 52  5  ;  innSig = [ExpectHoverText ["inner"], mkR 53 2 53 7]; innSig' = [ExpectHoverText ["inner", "Char"], mkR 49 2 49 7]
   holeL60 = Position 62 7  ;  hleInfo = [ExpectHoverText ["_ ::"]]
   holeL65 = Position 65 8  ;  hleInfo2 = [ExpectHoverText ["_ :: a -> Maybe a"]]
-  cccL17 = Position 17 16  ;  docLink = [ExpectHoverTextRegex "\\*Defined in 'GHC.Types'\\* \\*\\(ghc-prim-[0-9.]+\\)\\*\n\n"]
+  cccL17 = Position 17 16  ;  docLink = [ExpectHoverTextRegex $ if ghcVersion >= GHC914 then "\\*Defined in 'GHC.Internal.Types'\\* \\*\\(ghc-internal-[0-9.]+\\)\\*\n\n" else "\\*Defined in 'GHC.Types'\\* \\*\\(ghc-prim-[0-9.]+\\)\\*\n\n"]
   imported = Position 56 13 ; importedSig = getDocUri "Foo.hs" >>= \foo -> return [ExpectHoverText ["foo", "Foo", "Haddock"], mkL foo 5 0 5 3]
   reexported = Position 55 14
-  reexportedSig = getDocUri "Bar.hs" >>= \bar -> return [ExpectHoverText ["Bar", "Bar", "Haddock"], if ghcVersion < GHC910 || not isWindows then mkL bar 3 5 3 8 else mkL bar 3 0 3 14]
+  reexportedSig = getDocUri "Bar.hs" >>= \bar -> return [ExpectHoverText ["Bar", "Bar", "Haddock"], mkL bar 3 0 3 14]
   thLocL57 = Position 59 10 ; thLoc = [ExpectHoverText ["Identity"]]
   cmtL68 = Position 67  0  ;  lackOfdEq = [ExpectHoverExcludeText ["$dEq"]]
   import310 = Position 3 10; pkgTxt = [ExpectHoverText ["Data.Text\n\ntext-"]]
@@ -243,6 +246,9 @@
         testM yes    yes    reexported reexportedSig "Imported symbol reexported"
   , test  no     yes       thLocL57   thLoc         "TH Splice Hover"
   , test yes yes import310 pkgTxt "show package name and its version"
+  , test  no             yes               kkkL30     kkkType       "hover shows 'Go to' link for class in constraint"
+  , test  no             yes               bbbL16     bbbType       "hover shows 'Go to' link for data constructor's type"
+  , test  no             yes               aaaL11     aaaType       "hover shows 'Go to' link for binding's underlying type"
   ]
   where yes :: (TestTree -> Maybe TestTree)
         yes = Just -- test should run and pass
diff --git a/ghcide-test/exe/PluginSimpleTests.hs b/ghcide-test/exe/PluginSimpleTests.hs
--- a/ghcide-test/exe/PluginSimpleTests.hs
+++ b/ghcide-test/exe/PluginSimpleTests.hs
@@ -2,7 +2,6 @@
 module PluginSimpleTests (tests) where
 
 import           Config
-import           Control.Monad.IO.Class      (liftIO)
 import           Development.IDE.Test        (expectDiagnostics)
 import           Language.LSP.Protocol.Types hiding (SemanticTokenAbsolute (..),
                                               SemanticTokenRelative (..),
@@ -11,37 +10,70 @@
 import           System.FilePath
 import           Test.Hls.FileSystem
 import           Test.Tasty
+import qualified Test.Hls.FileSystem as FS
 
 tests :: TestTree
-tests =
-  -- Build profile: -w ghc-9.4.2 -O1
-  -- In order, the following will be built (use -v for more details):
-  -- - ghc-typelits-natnormalise-0.7.7 (lib) (requires build)
-  -- - ghc-typelits-knownnat-0.7.7 (lib) (requires build)
-  -- - plugin-1.0.0 (lib) (first run)
-  -- Starting     ghc-typelits-natnormalise-0.7.7 (lib)
-  -- Building     ghc-typelits-natnormalise-0.7.7 (lib)
+tests = testGroup "ghc-plugins"
+  [
+    -- Build profile: -w ghc-9.4.2 -O1
+    -- In order, the following will be built (use -v for more details):
+    -- - ghc-typelits-natnormalise-0.7.7 (lib) (requires build)
+    -- - ghc-typelits-knownnat-0.7.7 (lib) (requires build)
+    -- - plugin-1.0.0 (lib) (first run)
+    -- Starting     ghc-typelits-natnormalise-0.7.7 (lib)
+    -- Building     ghc-typelits-natnormalise-0.7.7 (lib)
 
-  -- Failed to build ghc-typelits-natnormalise-0.7.7.
-  -- Build log (
-  -- C:\cabal\logs\ghc-9.4.2\ghc-typelits-_-0.7.7-3f036a52a0d9bfc3389d1852a87da2e87c6de2e4.log
-  -- ):
-  -- Preprocessing library for ghc-typelits-natnormalise-0.7.7..
-  -- Building library for ghc-typelits-natnormalise-0.7.7..
-  -- [1 of 3] Compiling GHC.TypeLits.Normalise.SOP ( src\GHC\TypeLits\Normalise\SOP.hs, dist\build\GHC\TypeLits\Normalise\SOP.o )
-  -- [2 of 3] Compiling GHC.TypeLits.Normalise.Unify ( src\GHC\TypeLits\Normalise\Unify.hs, dist\build\GHC\TypeLits\Normalise\Unify.o )
-  -- [3 of 3] Compiling GHC.TypeLits.Normalise ( src-ghc-9.4\GHC\TypeLits\Normalise.hs, dist\build\GHC\TypeLits\Normalise.o )
-  -- C:\tools\ghc-9.4.2\lib\../mingw/bin/llvm-ar.exe: error: dist\build\objs-5156\libHSghc-typelits-_-0.7.7-3f036a52a0d9bfc3389d1852a87da2e87c6de2e4.a: No such file or directory
+    -- Failed to build ghc-typelits-natnormalise-0.7.7.
+    -- Build log (
+    -- C:\cabal\logs\ghc-9.4.2\ghc-typelits-_-0.7.7-3f036a52a0d9bfc3389d1852a87da2e87c6de2e4.log
+    -- ):
+    -- Preprocessing library for ghc-typelits-natnormalise-0.7.7..
+    -- Building library for ghc-typelits-natnormalise-0.7.7..
+    -- [1 of 3] Compiling GHC.TypeLits.Normalise.SOP ( src\GHC\TypeLits\Normalise\SOP.hs, dist\build\GHC\TypeLits\Normalise\SOP.o )
+    -- [2 of 3] Compiling GHC.TypeLits.Normalise.Unify ( src\GHC\TypeLits\Normalise\Unify.hs, dist\build\GHC\TypeLits\Normalise\Unify.o )
+    -- [3 of 3] Compiling GHC.TypeLits.Normalise ( src-ghc-9.4\GHC\TypeLits\Normalise.hs, dist\build\GHC\TypeLits\Normalise.o )
+    -- C:\tools\ghc-9.4.2\lib\../mingw/bin/llvm-ar.exe: error: dist\build\objs-5156\libHSghc-typelits-_-0.7.7-3f036a52a0d9bfc3389d1852a87da2e87c6de2e4.a: No such file or directory
 
-  -- Error: cabal: Failed to build ghc-typelits-natnormalise-0.7.7 (which is
-  -- required by plugin-1.0.0). See the build log above for details.
-  testWithExtraFiles "simple plugin"  "plugin-knownnat" $ \dir -> do
-    _ <- openDoc (dir </> "KnownNat.hs") "haskell"
-    liftIO $ atomicFileWriteString (dir</>"hie.yaml")
-      "cradle: {cabal: [{path: '.', component: 'lib:plugin'}]}"
+    -- Error: cabal: Failed to build ghc-typelits-natnormalise-0.7.7 (which is
+    -- required by plugin-1.0.0). See the build log above for details.
+    testWithDummyPlugin "simple plugin" pluginKnownNatVfs $ do
+      _ <- openDoc "KnownNat.hs" "haskell"
 
-    expectDiagnostics
-      [ ( "KnownNat.hs",
-          [(DiagnosticSeverity_Error, (9, 15), "Variable not in scope: c", Just "GHC-88464")]
-          )
-      ]
+      expectDiagnostics
+        [ ( "KnownNat.hs",
+            [(DiagnosticSeverity_Error, (9, 15), "Variable not in scope: c", Just "GHC-88464")]
+            )
+        ]
+  , testWithDummyPlugin "simple parser plugin" pluginParsreVfs $ do
+      _ <- openDoc "usage/File1.hs" "haskell"
+
+      expectDiagnostics
+        [ ( ("usage" </> "File1.hs"),
+            [(DiagnosticSeverity_Warning, (5, 0), "Top-level binding with no type signature: bar :: Int", Just "GHC-38417")]
+            )
+        ]
+  ]
+
+pluginKnownNatVfs :: VirtualFileTree
+pluginKnownNatVfs = FS.mkVirtualFileTree ("ghcide-test" </> "data" </> "plugin-knownnat") $
+  FS.simpleCabalProject
+    [ "cabal.project"
+    , "KnownNat.hs"
+    , "plugin.cabal"
+    ]
+
+pluginParsreVfs :: VirtualFileTree
+pluginParsreVfs = FS.mkVirtualFileTree ("ghcide-test" </> "data" </> "plugin-parser") $
+  [ simpleCabalCradle
+  , copy "cabal.project"
+  , directory "plugin"
+    [ copy "plugin/Plugin.hs"
+    , copy "plugin/plugin.cabal"
+    ]
+  , directory "usage"
+    [ copy "usage/File1.hs"
+    , copy "usage/File2.hs"
+    , copy "usage/usage.cabal"
+    ]
+  ]
+
diff --git a/haskell-language-server.cabal b/haskell-language-server.cabal
--- a/haskell-language-server.cabal
+++ b/haskell-language-server.cabal
@@ -1,7 +1,7 @@
 cabal-version:      3.4
 category:           Development
 name:               haskell-language-server
-version:            2.12.0.0
+version:            2.13.0.0
 synopsis:           LSP server for GHC
 description:
   Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>
@@ -136,8 +136,8 @@
   build-depends:
     , directory
     , filepath
-    , ghcide          == 2.12.0.0
-    , hls-plugin-api  == 2.12.0.0
+    , ghcide          == 2.13.0.0
+    , hls-plugin-api  == 2.13.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.12.0.0
-    , hls-test-utils        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
+    , hls-test-utils        == 2.13.0.0
 
   if flag(isolateCabalfmtTests)
     build-tool-depends: cabal-fmt:cabal-fmt ^>=0.1.12
@@ -193,8 +193,8 @@
   build-depends:
     , directory
     , filepath
-    , ghcide          == 2.12.0.0
-    , hls-plugin-api  == 2.12.0.0
+    , ghcide          == 2.13.0.0
+    , hls-plugin-api  == 2.13.0.0
     , lsp-types
     , text
     , mtl
@@ -213,8 +213,8 @@
     , filepath
     , haskell-language-server:hls-cabal-plugin
     , haskell-language-server:hls-cabal-gild-plugin
-    , hls-plugin-api        == 2.12.0.0
-    , hls-test-utils        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
+    , hls-test-utils        == 2.13.0.0
 
   if flag(isolateCabalGildTests)
     -- https://github.com/tfausak/cabal-gild/issues/89
@@ -274,10 +274,10 @@
     , directory
     , filepath
     , extra                 >=1.7.4
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hashable
-    , hls-plugin-api        == 2.12.0.0
-    , hls-graph             == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
+    , hls-graph             == 2.13.0.0
     , lens
     , lsp                   ^>=2.7
     , lsp-types             ^>=2.3
@@ -316,9 +316,8 @@
     , filepath
     , ghcide
     , haskell-language-server:hls-cabal-plugin
-    , hls-test-utils    == 2.12.0.0
+    , hls-test-utils    == 2.13.0.0
     , lens
-    , lsp
     , lsp-types
     , text
 
@@ -353,10 +352,10 @@
     , deepseq
     , extra
     , ghc
-    , ghc-exactprint  >= 1.5 && < 1.13.0.0
-    , ghcide          == 2.12.0.0
+    , ghc-exactprint  >= 1.5 && < 1.15
+    , ghcide          == 2.13.0.0
     , hls-graph
-    , hls-plugin-api  == 2.12.0.0
+    , hls-plugin-api  == 2.13.0.0
     , lens
     , lsp
     , mtl
@@ -377,7 +376,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-class-plugin
-    , hls-test-utils     == 2.12.0.0
+    , hls-test-utils     == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -412,9 +411,9 @@
     , containers
     , extra
     , ghc
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hiedb                 ^>= 0.7.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , lsp                    >=2.7
     , sqlite-simple
@@ -435,7 +434,7 @@
     , extra
     , filepath
     , haskell-language-server:hls-call-hierarchy-plugin
-    , hls-test-utils        == 2.12.0.0
+    , hls-test-utils        == 2.13.0.0
     , lens
     , lsp
     , lsp-test
@@ -485,9 +484,9 @@
     , filepath
     , ghc
     , ghc-boot-th
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hls-graph
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , lsp
     , lsp-types
@@ -518,7 +517,7 @@
     , filepath
     , haskell-language-server:hls-eval-plugin
     , hls-plugin-api
-    , hls-test-utils   == 2.12.0.0
+    , hls-test-utils   == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -548,9 +547,9 @@
     , containers
     , deepseq
     , ghc
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hls-graph
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , lsp
     , mtl
@@ -571,7 +570,7 @@
     , extra
     , filepath
     , haskell-language-server:hls-explicit-imports-plugin
-    , hls-test-utils   == 2.12.0.0
+    , hls-test-utils   == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -599,10 +598,10 @@
   build-depends:
     , containers
     , ghc
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hashable
     , hiedb                 ^>= 0.7.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , haskell-language-server:hls-refactor-plugin
     , lens
     , lsp-types
@@ -627,7 +626,7 @@
     , filepath
     , hls-plugin-api
     , haskell-language-server:hls-rename-plugin
-    , hls-test-utils             == 2.12.0.0
+    , hls-test-utils             == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -658,9 +657,9 @@
     , containers
     , extra
     , ghc
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hashable
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , haskell-language-server:hls-refactor-plugin
     , lens
     , lsp
@@ -689,7 +688,7 @@
     , filepath
     , hls-plugin-api
     , haskell-language-server:{hls-refactor-plugin, hls-retrie-plugin}
-    , hls-test-utils             == 2.12.0.0
+    , hls-test-utils             == 2.13.0.0
     , text
 
 -----------------------------
@@ -709,14 +708,21 @@
   manual:      True
 
 common hlint
-  if flag(hlint)
+  -- Hlint isn't compatible with GHC 9.10, and crashes in subtle ways.
+  -- See https://github.com/haskell/haskell-language-server/issues/4674
+  -- for its wake of destruction.
+  -- hlint depends on ghc-lib-parser which doesn't support GHC 9.14
+  if flag(hlint) && !impl(ghc ==9.10.*) && !impl(ghc >= 9.14)
     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)
+  -- Hlint isn't compatible with GHC 9.10, and crashes in subtle ways.
+  -- See https://github.com/haskell/haskell-language-server/issues/4674
+  -- for its wake of destruction.
+  -- hlint depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(hlint) || impl(ghc ==9.10.*) || impl(ghc >= 9.14)
     buildable: False
   exposed-modules:  Ide.Plugin.Hlint
   hs-source-dirs:   plugins/hls-hlint-plugin/src
@@ -726,10 +732,10 @@
     , containers
     , deepseq
     , filepath
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hashable
     , hlint                 >= 3.5 && < 3.11
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , mtl
     , refact
@@ -763,7 +769,11 @@
 
 test-suite hls-hlint-plugin-tests
   import:           defaults, pedantic, test-defaults, warnings
-  if !flag(hlint)
+  -- Hlint isn't compatible with GHC 9.10, and crashes in subtle ways.
+  -- See https://github.com/haskell/haskell-language-server/issues/4674
+  -- for its wake of destruction.
+  -- hlint depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(hlint) || impl(ghc ==9.10.*) || impl(ghc >= 9.14)
     buildable: False
   type:             exitcode-stdio-1.0
   hs-source-dirs:   plugins/hls-hlint-plugin/test
@@ -778,7 +788,7 @@
     , filepath
     , haskell-language-server:hls-hlint-plugin
     , hls-plugin-api
-    , hls-test-utils      == 2.12.0.0
+    , hls-test-utils      == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -832,7 +842,7 @@
     , filepath
     , haskell-language-server:hls-stan-plugin
     , hls-plugin-api
-    , hls-test-utils      == 2.12.0.0
+    , hls-test-utils      == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -866,8 +876,8 @@
   build-depends:
     , containers
     , ghc
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lsp-types
     , text
     , transformers
@@ -883,7 +893,7 @@
   build-depends:
     , ghcide
     , haskell-language-server:hls-signature-help-plugin
-    , hls-test-utils             == 2.12.0.0
+    , hls-test-utils             == 2.13.0.0
     , lens
     , lsp-types
     , string-interpolate
@@ -916,8 +926,8 @@
     , aeson
     , containers
     , filepath
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lsp
     , text
     , text-rope
@@ -934,7 +944,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-module-name-plugin
-    , hls-test-utils          == 2.12.0.0
+    , hls-test-utils          == 2.13.0.0
 
 -----------------------------
 -- pragmas plugin
@@ -960,8 +970,8 @@
     , aeson
     , extra
     , fuzzy
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , lens-aeson
     , lsp
@@ -980,7 +990,7 @@
     , aeson
     , filepath
     , haskell-language-server:hls-pragmas-plugin
-    , hls-test-utils      == 2.12.0.0
+    , hls-test-utils      == 2.13.0.0
     , lens
     , lsp-types
     , text
@@ -1013,8 +1023,8 @@
     , extra
     , foldl
     , ghc
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , haskell-language-server:hls-refactor-plugin
     , lens
     , lsp
@@ -1037,7 +1047,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-splice-plugin
-    , hls-test-utils == 2.12.0.0
+    , hls-test-utils == 2.13.0.0
     , text
 
 -----------------------------
@@ -1064,14 +1074,13 @@
   build-depends:
     , containers
     , extra
-    , ghcide               == 2.12.0.0
+    , ghcide               == 2.13.0.0
     , ghc-boot-th
     , hls-graph
-    , hls-plugin-api       == 2.12.0.0
+    , hls-plugin-api       == 2.13.0.0
     , lens
     , lsp                  ^>=2.7
     , mtl
-    , regex-tdfa
     , syb
     , text
 
@@ -1090,9 +1099,10 @@
   main-is:          Main.hs
   ghc-options:      -fno-ignore-asserts
   build-depends:
+    , containers
     , filepath
     , haskell-language-server:hls-alternate-number-format-plugin
-    , hls-test-utils       == 2.12.0.0
+    , hls-test-utils       == 2.13.0.0
     , regex-tdfa
     , tasty-quickcheck
     , text
@@ -1125,8 +1135,8 @@
   build-depends:
     , containers
     , ghc
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , lsp
     , text
@@ -1148,7 +1158,7 @@
     , text
     , filepath
     , haskell-language-server:hls-qualify-imported-names-plugin
-    , hls-test-utils             == 2.12.0.0
+    , hls-test-utils             == 2.13.0.0
 
 -----------------------------
 -- code range plugin
@@ -1179,9 +1189,9 @@
     , deepseq
     , extra
     , ghc
-    , ghcide           == 2.12.0.0
+    , ghcide           == 2.13.0.0
     , hashable
-    , hls-plugin-api   == 2.12.0.0
+    , hls-plugin-api   == 2.13.0.0
     , lens
     , lsp
     , mtl
@@ -1203,7 +1213,7 @@
     , bytestring
     , filepath
     , haskell-language-server:hls-code-range-plugin
-    , hls-test-utils             == 2.12.0.0
+    , hls-test-utils             == 2.13.0.0
     , lens
     , lsp
     , lsp-test
@@ -1231,8 +1241,8 @@
   exposed-modules:  Ide.Plugin.ChangeTypeSignature
   hs-source-dirs:   plugins/hls-change-type-signature-plugin/src
   build-depends:
-    , ghcide           == 2.12.0.0
-    , hls-plugin-api   == 2.12.0.0
+    , ghcide           == 2.13.0.0
+    , hls-plugin-api   == 2.13.0.0
     , lens
     , lsp-types
     , regex-tdfa
@@ -1259,7 +1269,7 @@
     , filepath
     , haskell-language-server:hls-change-type-signature-plugin
     , hls-plugin-api
-    , hls-test-utils       == 2.12.0.0
+    , hls-test-utils       == 2.13.0.0
     , regex-tdfa
     , text
   default-extensions:
@@ -1292,9 +1302,9 @@
     , containers
     , extra
     , ghc
-    , ghcide                 == 2.12.0.0
+    , ghcide                 == 2.13.0.0
     , ghc-exactprint
-    , hls-plugin-api         == 2.12.0.0
+    , hls-plugin-api         == 2.13.0.0
     , haskell-language-server:hls-refactor-plugin
     , lens
     , lsp                    >=2.7
@@ -1314,7 +1324,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-gadt-plugin
-    , hls-test-utils              == 2.12.0.0
+    , hls-test-utils              == 2.13.0.0
     , text
 
 -----------------------------
@@ -1341,9 +1351,9 @@
     , containers
     , deepseq
     , extra
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , hashable
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lsp                   >=2.7
     , text
 
@@ -1359,7 +1369,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-explicit-fixity-plugin
-    , hls-test-utils              == 2.12.0.0
+    , hls-test-utils              == 2.13.0.0
     , text
 
 -----------------------------
@@ -1383,8 +1393,8 @@
   exposed-modules:  Ide.Plugin.ExplicitFields
   build-depends:
     , ghc
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lsp
     , lens
     , hls-graph
@@ -1410,7 +1420,7 @@
     , text
     , ghcide
     , haskell-language-server:hls-explicit-record-fields-plugin
-    , hls-test-utils              == 2.12.0.0
+    , hls-test-utils              == 2.13.0.0
 
 -----------------------------
 -- overloaded record dot plugin
@@ -1456,7 +1466,7 @@
     , filepath
     , text
     , haskell-language-server:hls-overloaded-record-dot-plugin
-    , hls-test-utils              == 2.12.0.0
+    , hls-test-utils              == 2.13.0.0
 
 
 -----------------------------
@@ -1482,8 +1492,8 @@
   hs-source-dirs:   plugins/hls-floskell-plugin/src
   build-depends:
     , floskell        ^>=0.11.0
-    , ghcide          == 2.12.0.0
-    , hls-plugin-api  == 2.12.0.0
+    , ghcide          == 2.13.0.0
+    , hls-plugin-api  == 2.13.0.0
     , lsp-types       ^>=2.3
     , mtl
     , text
@@ -1499,7 +1509,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-floskell-plugin
-    , hls-test-utils       == 2.12.0.0
+    , hls-test-utils       == 2.13.0.0
 
 -----------------------------
 -- fourmolu plugin
@@ -1511,13 +1521,15 @@
   manual:      True
 
 common fourmolu
-  if flag(fourmolu)
+  -- fourmolu depends on ghc-lib-parser which doesn't support GHC 9.14
+  if flag(fourmolu) && !impl(ghc >= 9.14)
     build-depends: haskell-language-server:hls-fourmolu-plugin
     cpp-options: -Dhls_fourmolu
 
 library hls-fourmolu-plugin
   import:           defaults, pedantic, warnings
-  if !flag(fourmolu)
+  -- fourmolu depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(fourmolu) || impl(ghc >= 9.14)
     buildable: False
   exposed-modules:  Ide.Plugin.Fourmolu
   hs-source-dirs:   plugins/hls-fourmolu-plugin/src
@@ -1525,8 +1537,8 @@
     , filepath
     , fourmolu        ^>= 0.14 || ^>= 0.15 || ^>= 0.16 || ^>=0.17 || ^>=0.18 || ^>=0.19
     , ghc-boot-th
-    , ghcide          == 2.12.0.0
-    , hls-plugin-api  == 2.12.0.0
+    , ghcide          == 2.13.0.0
+    , hls-plugin-api  == 2.13.0.0
     , lens
     , lsp
     , mtl
@@ -1537,7 +1549,8 @@
 
 test-suite hls-fourmolu-plugin-tests
   import:           defaults, pedantic, test-defaults, warnings
-  if !flag(fourmolu)
+  -- fourmolu depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(fourmolu) || impl(ghc >= 9.14)
     buildable: False
   type:             exitcode-stdio-1.0
   hs-source-dirs:   plugins/hls-fourmolu-plugin/test
@@ -1552,7 +1565,7 @@
     , filepath
     , haskell-language-server:hls-fourmolu-plugin
     , hls-plugin-api
-    , hls-test-utils       == 2.12.0.0
+    , hls-test-utils       == 2.13.0.0
     , lsp-test
 
 -----------------------------
@@ -1565,13 +1578,15 @@
   manual:      True
 
 common ormolu
-  if flag(ormolu)
+  -- ormolu depends on ghc-lib-parser which doesn't support GHC 9.14
+  if flag(ormolu) && !impl(ghc >= 9.14)
     build-depends: haskell-language-server:hls-ormolu-plugin
     cpp-options: -Dhls_ormolu
 
 library hls-ormolu-plugin
   import:           defaults, pedantic, warnings
-  if !flag(ormolu)
+  -- ormolu depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(ormolu) || impl(ghc >= 9.14)
     buildable: False
   exposed-modules:  Ide.Plugin.Ormolu
   hs-source-dirs:   plugins/hls-ormolu-plugin/src
@@ -1579,8 +1594,8 @@
     , extra
     , filepath
     , ghc-boot-th
-    , ghcide          == 2.12.0.0
-    , hls-plugin-api  == 2.12.0.0
+    , ghcide          == 2.13.0.0
+    , hls-plugin-api  == 2.13.0.0
     , lsp
     , mtl
     , process-extras  >= 0.7.1
@@ -1591,7 +1606,8 @@
 
 test-suite hls-ormolu-plugin-tests
   import:           defaults, pedantic, test-defaults, warnings
-  if !flag(ormolu)
+  -- ormolu depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(ormolu) || impl(ghc >= 9.14)
     buildable: False
   type:             exitcode-stdio-1.0
   hs-source-dirs:   plugins/hls-ormolu-plugin/test
@@ -1606,7 +1622,7 @@
     , filepath
     , haskell-language-server:hls-ormolu-plugin
     , hls-plugin-api
-    , hls-test-utils     == 2.12.0.0
+    , hls-test-utils     == 2.13.0.0
     , lsp-types
     , ormolu
 
@@ -1620,14 +1636,16 @@
   manual:      True
 
 common stylishHaskell
-  if flag(stylishHaskell)
+  -- stylish-haskell depends on ghc-lib-parser which doesn't support GHC 9.14
+  if flag(stylishHaskell) && !impl(ghc >= 9.14)
     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)
+  -- stylish-haskell depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(stylishHaskell) || impl(ghc >= 9.14)
     buildable: False
   exposed-modules:  Ide.Plugin.StylishHaskell
   hs-source-dirs:   plugins/hls-stylish-haskell-plugin/src
@@ -1635,8 +1653,8 @@
     , directory
     , filepath
     , ghc-boot-th
-    , ghcide           == 2.12.0.0
-    , hls-plugin-api   == 2.12.0.0
+    , ghcide           == 2.13.0.0
+    , hls-plugin-api   == 2.13.0.0
     , lsp-types
     , mtl
     , stylish-haskell  >=0.12 && <0.16
@@ -1645,7 +1663,8 @@
 
 test-suite hls-stylish-haskell-plugin-tests
   import:           defaults, pedantic, test-defaults, warnings
-  if !flag(stylishHaskell)
+  -- stylish-haskell depends on ghc-lib-parser which doesn't support GHC 9.14
+  if !flag(stylishHaskell) || impl(ghc >= 9.14)
     buildable: False
   type:             exitcode-stdio-1.0
   hs-source-dirs:   plugins/hls-stylish-haskell-plugin/test
@@ -1653,7 +1672,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-stylish-haskell-plugin
-    , hls-test-utils              == 2.12.0.0
+    , hls-test-utils              == 2.13.0.0
 
 -----------------------------
 -- refactor plugin
@@ -1705,8 +1724,8 @@
     , bytestring
     , ghc-boot
     , regex-tdfa
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lsp
     , text
     , text-rope
@@ -1744,7 +1763,7 @@
     , filepath
     , ghcide:ghcide
     , haskell-language-server:hls-refactor-plugin
-    , hls-test-utils      == 2.12.0.0
+    , hls-test-utils      == 2.13.0.0
     , lens
     , lsp-test
     , lsp-types
@@ -1792,8 +1811,8 @@
     , text-rope
     , mtl                   >= 2.2
     , ghc
-    , ghcide                == 2.12.0.0
-    , hls-plugin-api        == 2.12.0.0
+    , ghcide                == 2.13.0.0
+    , hls-plugin-api        == 2.13.0.0
     , lens
     , lsp                    >=2.6
     , text
@@ -1803,7 +1822,7 @@
     , array
     , deepseq
     , dlist
-    , hls-graph == 2.12.0.0
+    , hls-graph == 2.13.0.0
     , template-haskell
     , data-default
     , stm
@@ -1824,10 +1843,10 @@
     , containers
     , data-default
     , filepath
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , haskell-language-server:hls-semantic-tokens-plugin
-    , hls-plugin-api        == 2.12.0.0
-    , hls-test-utils        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
+    , hls-test-utils        == 2.13.0.0
     , lens
     , lsp
     , lsp-test
@@ -1857,9 +1876,9 @@
   hs-source-dirs:     plugins/hls-notes-plugin/src
   build-depends:
     , array
-    , ghcide == 2.12.0.0
-    , hls-graph == 2.12.0.0
-    , hls-plugin-api == 2.12.0.0
+    , ghcide == 2.13.0.0
+    , hls-graph == 2.13.0.0
+    , hls-plugin-api == 2.13.0.0
     , lens
     , lsp >=2.7
     , mtl >= 2.2
@@ -1885,7 +1904,7 @@
   build-depends:
     , filepath
     , haskell-language-server:hls-notes-plugin
-    , hls-test-utils == 2.12.0.0
+    , hls-test-utils == 2.13.0.0
   default-extensions: OverloadedStrings
 
 ----------------------------
@@ -1946,10 +1965,10 @@
     , extra
     , filepath
     , ghc
-    , ghcide                == 2.12.0.0
+    , ghcide                == 2.13.0.0
     , githash               >=0.1.6.1
     , hie-bios
-    , hls-plugin-api        == 2.12.0.0
+    , hls-plugin-api        == 2.13.0.0
     , optparse-applicative
     , optparse-simple
     , prettyprinter         >= 1.7
@@ -2052,7 +2071,7 @@
     , ghcide:ghcide
     , hashable
     , hls-plugin-api
-    , hls-test-utils == 2.12.0.0
+    , hls-test-utils == 2.13.0.0
     , lens
     , lsp-test
     , lsp-types
@@ -2080,9 +2099,9 @@
 -- formatters
   if flag(floskell) && (impl(ghc < 9.10) || flag(ignore-plugins-ghc-bounds))
     cpp-options: -Dhls_floskell
-  if flag(fourmolu)
+  if flag(fourmolu) && (impl(ghc < 9.14) || flag(ignore-plugins-ghc-bounds))
     cpp-options: -Dhls_fourmolu
-  if flag(ormolu)
+  if flag(ormolu) && (impl(ghc < 9.14) || flag(ignore-plugins-ghc-bounds))
     cpp-options: -Dhls_ormolu
 
 test-suite wrapper-test
@@ -2096,7 +2115,7 @@
 
   build-depends:
     , extra
-    , hls-test-utils              == 2.12.0.0
+    , hls-test-utils              == 2.13.0.0
     , process
 
   hs-source-dirs:     test/wrapper
@@ -2189,7 +2208,7 @@
     , text
     , text-rope
     , unordered-containers
-    , hls-test-utils == 2.12.0.0
+    , hls-test-utils == 2.13.0.0
 
   if impl(ghc <9.3)
     build-depends: ghc-typelits-knownnat
@@ -2337,11 +2356,16 @@
         RecordWildCards
         ViewPatterns
 
+flag plugin-tutorial
+  description: Build the plugin tutorial executable
+  default:     True
+  manual:      True
+
 executable plugin-tutorial
   import: defaults
   -- The plugin tutorial is only compatible with 9.6 and 9.8.
   -- No particular reason, just to avoid excessive CPP.
-  if (impl(ghc >= 9.6) && impl(ghc < 9.10))
+  if flag(plugin-tutorial) && (impl(ghc >= 9.6) && impl(ghc < 9.10))
     buildable: True
   else
     buildable: False
diff --git a/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/AlternateNumberFormat.hs b/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/AlternateNumberFormat.hs
--- a/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/AlternateNumberFormat.hs
+++ b/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/AlternateNumberFormat.hs
@@ -23,7 +23,7 @@
 import           GHC.Generics                     (Generic)
 import           Ide.Logger                       as Logger
 import           Ide.Plugin.Conversion            (AlternateFormat,
-                                                   ExtensionNeeded (NeedsExtension, NoExtension),
+                                                   ExtensionNeeded (..),
                                                    alternateFormat)
 import           Ide.Plugin.Error
 import           Ide.Plugin.Literals
@@ -93,7 +93,7 @@
     pure $ InL actions
     where
         mkCodeAction :: NormalizedFilePath -> Literal -> [GhcExtension] -> NextPragmaInfo -> AlternateFormat -> Command |? CodeAction
-        mkCodeAction nfp lit enabled npi af@(alt, ext) = InR CodeAction {
+        mkCodeAction nfp lit enabled npi af@(alt, ExtensionNeeded exts) = InR CodeAction {
             _title = mkCodeActionTitle lit af enabled
             , _kind = Just $ CodeActionKind_Custom "quickfix.literals.style"
             , _diagnostics = Nothing
@@ -104,10 +104,10 @@
             , _data_ = Nothing
             }
             where
-                edits =  [TextEdit (realSrcSpanToRange $ getSrcSpan lit) alt] <> pragmaEdit
-                pragmaEdit = case ext of
-                    NeedsExtension ext' -> [insertNewPragma npi ext' | needsExtension ext' enabled]
-                    NoExtension         -> []
+                edits =  [TextEdit (realSrcSpanToRange $ getSrcSpan lit) alt] <> pragmaEdit exts
+                pragmaEdit ext = case ext of
+                    ext': exts -> [insertNewPragma npi ext' | needsExtension enabled ext'] <> pragmaEdit exts
+                    []         -> []
 
         mkWorkspaceEdit :: NormalizedFilePath -> [TextEdit] -> WorkspaceEdit
         mkWorkspaceEdit nfp edits = WorkspaceEdit changes Nothing Nothing
@@ -115,17 +115,18 @@
                 changes = Just $ Map.singleton (filePathToUri $ fromNormalizedFilePath nfp) edits
 
 mkCodeActionTitle :: Literal -> AlternateFormat -> [GhcExtension] -> Text
-mkCodeActionTitle lit (alt, ext) ghcExts
-    | (NeedsExtension ext') <- ext
-    , needsExtension ext' ghcExts = title <> " (needs extension: " <> T.pack (show ext') <> ")"
-    | otherwise = title
+mkCodeActionTitle lit (alt, ExtensionNeeded exts) ghcExts
+    | null necessaryExtensions = title
+    | otherwise = title <> " (needs extensions: " <> formattedExtensions <> ")"
     where
+        formattedExtensions = T.intercalate ", " $ map (T.pack . show) necessaryExtensions
+        necessaryExtensions = filter (needsExtension ghcExts) exts
         title = "Convert " <> getSrcText lit <> " into " <> alt
 
 
 -- | Checks whether the extension given is already enabled
-needsExtension :: Extension -> [GhcExtension] -> Bool
-needsExtension ext ghcExts = ext `notElem` map unExt ghcExts
+needsExtension :: [GhcExtension] -> Extension -> Bool
+needsExtension ghcExts ext = ext `notElem` map unExt ghcExts
 
 requestLiterals :: MonadIO m => PluginId -> IdeState -> NormalizedFilePath -> ExceptT PluginError m CollectLiteralsResult
 requestLiterals (PluginId pId) state =
diff --git a/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Conversion.hs b/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Conversion.hs
--- a/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Conversion.hs
+++ b/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Conversion.hs
@@ -1,14 +1,7 @@
-{-# LANGUAGE CPP          #-}
-{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE CPP                #-}
+{-# LANGUAGE DerivingStrategies #-}
 module Ide.Plugin.Conversion (
     alternateFormat
-    , hexRegex
-    , hexFloatRegex
-    , binaryRegex
-    , octalRegex
-    , decimalRegex
-    , numDecimalRegex
-    , matchLineRegex
     , toOctal
     , toDecimal
     , toBinary
@@ -16,23 +9,28 @@
     , toFloatDecimal
     , toFloatExpDecimal
     , toHexFloat
+    , intFormats
+    , fracFormats
     , AlternateFormat
     , ExtensionNeeded(..)
+    , FormatType(..)
+    , IntFormatType(..)
+    , FracFormatType(..)
+    , UnderscoreFormatType(..)
 ) where
 
-import           Data.List                     (delete)
-import           Data.List.Extra               (enumerate, upper)
-import           Data.Maybe                    (mapMaybe)
+import           Data.List                     (intercalate)
+import           Data.List.Extra               (chunksOf, enumerate, nubOrdOn,
+                                                upper)
+import qualified Data.Map                      as Map
 import           Data.Ratio                    (denominator, numerator)
 import           Data.Text                     (Text)
 import qualified Data.Text                     as T
 import           Development.IDE.Graph.Classes (NFData)
 import           GHC.Generics                  (Generic)
 import           GHC.LanguageExtensions.Type   (Extension (..))
-import           GHC.Show                      (intToDigit)
 import           Ide.Plugin.Literals           (Literal (..), getSrcText)
 import           Numeric
-import           Text.Regex.TDFA               ((=~))
 
 data FormatType = IntFormat IntFormatType
                 | FracFormat FracFormatType
@@ -46,142 +44,130 @@
                    | OctalFormat
                    | BinaryFormat
                    | NumDecimalFormat
-                   deriving (Show, Eq, Generic, Bounded, Enum)
+                   deriving (Show, Eq, Generic, Ord, Bounded, Enum)
 
 instance NFData IntFormatType
 
 data FracFormatType = FracDecimalFormat
                     | HexFloatFormat
                     | ExponentFormat
-                    deriving (Show, Eq, Generic, Bounded, Enum)
+                    deriving (Show, Eq, Generic, Ord, Bounded, Enum)
 
 instance NFData FracFormatType
 
-data ExtensionNeeded = NoExtension
-                     | NeedsExtension Extension
+newtype ExtensionNeeded = ExtensionNeeded [Extension]
+    deriving newtype (Semigroup, Monoid)
 
 type AlternateFormat = (Text, ExtensionNeeded)
 
 -- | Generate alternate formats for a single Literal based on FormatType's given.
 alternateFormat :: Literal -> [AlternateFormat]
-alternateFormat lit = case lit of
-  IntLiteral _ _ val   -> map (alternateIntFormat val) (removeCurrentFormatInt lit)
+alternateFormat lit = nubOrdOn fst $ removeIdentical $ case lit of
+  IntLiteral _ _ val   -> alternateIntFormatsOf id val
   FracLiteral _ _  val -> if denominator val == 1 -- floats that can be integers we can represent as ints
-      then map (alternateIntFormat (numerator val)) (removeCurrentFormatInt lit)
-      else map (alternateFracFormat val) (removeCurrentFormatFrac lit)
-
-alternateIntFormat :: Integer -> IntFormatType -> AlternateFormat
-alternateIntFormat val = \case
-    IntDecimalFormat -> (T.pack $ toDecimal val, NoExtension)
-    HexFormat        -> (T.pack $ toHex val, NoExtension)
-    OctalFormat      -> (T.pack $ toOctal val, NoExtension)
-    BinaryFormat     -> (T.pack $ toBinary val, NeedsExtension BinaryLiterals)
-    NumDecimalFormat -> (T.pack $ toFloatExpDecimal (fromInteger @Double val), NeedsExtension NumDecimals)
-
-alternateFracFormat :: Rational -> FracFormatType -> AlternateFormat
-alternateFracFormat val = \case
-  FracDecimalFormat -> (T.pack $ toFloatDecimal (fromRational @Double val), NoExtension)
-  ExponentFormat    -> (T.pack $ toFloatExpDecimal (fromRational @Double val), NoExtension)
-  HexFloatFormat    -> (T.pack $ toHexFloat (fromRational @Double val), NeedsExtension HexFloatLiterals)
-
--- given a Literal compute it's current Format and delete it from the list of available formats
-removeCurrentFormat :: (Foldable t, Eq a) => [a] -> t a -> [a]
-removeCurrentFormat fmts toRemove = foldl (flip delete) fmts toRemove
-
-removeCurrentFormatInt :: Literal -> [IntFormatType]
-removeCurrentFormatInt (getSrcText -> srcText) = removeCurrentFormat intFormats (filterIntFormats $ sourceToFormatType srcText)
-
-removeCurrentFormatFrac :: Literal -> [FracFormatType]
-removeCurrentFormatFrac (getSrcText -> srcText) = removeCurrentFormat fracFormats (filterFracFormats $ sourceToFormatType srcText)
+    then alternateIntFormatsOf numerator val
+    else alternateFracFormatsOf val
+  where
+    removeIdentical = filter ((/= getSrcText lit) . fst)
+    alternateIntFormatsOf with val = [ alternateIntFormat (with val) formatType f | (formatType, formats) <- Map.toList intFormats, f <- formats]
+    alternateFracFormatsOf val = [ alternateFracFormat val formatType f | (formatType, formats) <- Map.toList fracFormats, f <- formats]
 
-filterIntFormats :: [FormatType] -> [IntFormatType]
-filterIntFormats = mapMaybe getIntFormat
-    where
-        getIntFormat (IntFormat f) = Just f
-        getIntFormat _             = Nothing
+data UnderscoreFormatType
+    = NoUnderscores
+    | UseUnderscores Int
+    deriving (Show, Eq)
 
-filterFracFormats :: [FormatType] -> [FracFormatType]
-filterFracFormats = mapMaybe getFracFormat
-    where
-        getFracFormat (FracFormat f) = Just f
-        getFracFormat _              = Nothing
+underscoreExtensions :: UnderscoreFormatType -> ExtensionNeeded
+underscoreExtensions = \case
+    NoUnderscores -> mempty
+    UseUnderscores _ -> ExtensionNeeded [NumericUnderscores]
 
-intFormats :: [IntFormatType]
-intFormats = enumerate
+alternateIntFormat :: Integer -> IntFormatType -> UnderscoreFormatType -> AlternateFormat
+alternateIntFormat val formatType underscoreFormat = case formatType of
+    IntDecimalFormat -> (T.pack $ toDecimal underscoreFormat val, underscoreExtensions underscoreFormat)
+    HexFormat        -> (T.pack $ toHex underscoreFormat val, underscoreExtensions underscoreFormat)
+    OctalFormat      -> (T.pack $ toOctal underscoreFormat val, underscoreExtensions underscoreFormat)
+    BinaryFormat     -> (T.pack $ toBinary underscoreFormat val, underscoreExtensions underscoreFormat <> ExtensionNeeded [BinaryLiterals])
+    NumDecimalFormat -> (T.pack $ toFloatExpDecimal underscoreFormat (fromInteger @Double val), underscoreExtensions underscoreFormat <> ExtensionNeeded [NumDecimals])
 
-fracFormats :: [FracFormatType]
-fracFormats = enumerate
+alternateFracFormat :: Rational -> FracFormatType -> UnderscoreFormatType -> AlternateFormat
+alternateFracFormat val formatType underscoreFormat = case formatType of
+  FracDecimalFormat -> (T.pack $ toFloatDecimal underscoreFormat (fromRational @Double val), mempty)
+  ExponentFormat    -> (T.pack $ toFloatExpDecimal underscoreFormat (fromRational @Double val), mempty)
+  HexFloatFormat    -> (T.pack $ toHexFloat underscoreFormat (fromRational @Double val), underscoreExtensions underscoreFormat <> ExtensionNeeded [HexFloatLiterals])
 
--- | Regex to match a Haskell Hex Literal
-hexRegex :: Text
-hexRegex = "0[xX][a-fA-F0-9]+"
+intFormats :: Map.Map IntFormatType [UnderscoreFormatType]
+intFormats = Map.fromList $ map (\t -> (t, intFormatUnderscore t)) enumerate
 
--- | Regex to match a Haskell Hex Float Literal
-hexFloatRegex :: Text
-hexFloatRegex = "0[xX][a-fA-F0-9]+(\\.)?[a-fA-F0-9]*(p[+-]?[0-9]+)?"
+intFormatUnderscore :: IntFormatType -> [UnderscoreFormatType]
+intFormatUnderscore formatType = NoUnderscores : map UseUnderscores (case formatType of
+    IntDecimalFormat -> [3, 4]
+    HexFormat        -> [2, 4]
+    OctalFormat      -> [2, 4, 8]
+    BinaryFormat     -> [4]
+    NumDecimalFormat -> [3, 4])
 
--- | Regex to match a Haskell Binary Literal
-binaryRegex :: Text
-binaryRegex = "0[bB][0|1]+"
+fracFormats :: Map.Map FracFormatType [UnderscoreFormatType]
+fracFormats = Map.fromList $ map (\t -> (t, fracFormatUnderscore t)) enumerate
 
--- | Regex to match a Haskell Octal Literal
-octalRegex :: Text
-octalRegex = "0[oO][0-8]+"
+fracFormatUnderscore :: FracFormatType -> [UnderscoreFormatType]
+fracFormatUnderscore formatType = NoUnderscores : map UseUnderscores (case formatType of
+  FracDecimalFormat -> [3, 4]
+  ExponentFormat    -> [3, 4]
+  HexFloatFormat    -> [2, 4])
 
--- | Regex to match a Haskell Decimal Literal (no decimal points)
-decimalRegex :: Text
-decimalRegex = "[0-9]+(\\.[0-9]+)?"
+addMinus :: (Ord n, Num n) => (n -> String) -> n -> String
+addMinus f n
+  | n < 0 = '-' : f (abs n)
+  | otherwise = f n
 
--- | Regex to match a Haskell Literal with an explicit exponent
-numDecimalRegex :: Text
-numDecimalRegex = "[0-9]+\\.[0-9]+[eE][+-]?[0-9]+"
+toBase :: (a -> ShowS) -> a -> String
+toBase conv n = upper (conv n "")
 
--- we want to be explicit in our matches
--- so we need to match the beginning/end of the source text
--- | Wraps a Regex with a beginning ("^") and end ("$") token
-matchLineRegex :: Text -> Text
-matchLineRegex regex = "^" <> regex <> "$"
+toBaseFmt :: (Ord a, Num a) => (a -> ShowS) -> [Char] -> UnderscoreFormatType ->  a -> [Char]
+toBaseFmt conv header underscoreFormat = addMinus $ \val ->
+    header ++ addUnderscoresInt underscoreFormat (toBase conv val)
 
-sourceToFormatType :: Text -> [FormatType]
-sourceToFormatType srcText
-    | srcText =~ matchLineRegex hexRegex = [IntFormat HexFormat]
-    | srcText =~ matchLineRegex hexFloatRegex = [FracFormat HexFloatFormat]
-    | srcText =~ matchLineRegex octalRegex = [IntFormat OctalFormat]
-    | srcText =~ matchLineRegex binaryRegex = [IntFormat BinaryFormat]
-    -- can either be a NumDecimal or just a regular Fractional with an exponent
-    -- otherwise we wouldn't need to return a list
-    | srcText =~ matchLineRegex numDecimalRegex  = [IntFormat NumDecimalFormat, FracFormat ExponentFormat]
-    -- just assume we are in base 10 with no decimals
-    | otherwise = [IntFormat IntDecimalFormat, FracFormat FracDecimalFormat]
+toBinary  :: Integral a => UnderscoreFormatType -> a -> String
+toBinary = toBaseFmt showBin "0b"
 
-toBase :: (Num a, Ord a) => (a -> ShowS) -> String -> a -> String
-toBase conv header n
-  | n < 0 = '-' : header <> upper (conv (abs n) "")
-  | otherwise = header <> upper (conv n "")
+toOctal  :: Integral a => UnderscoreFormatType -> a -> String
+toOctal = toBaseFmt showOct "0o"
 
-#if MIN_VERSION_base(4,17,0)
-toOctal, toBinary, toHex :: Integral a => a -> String
-#else
-toOctal, toBinary, toHex:: (Integral a, Show a) => a -> String
-#endif
+toHex :: Integral a => UnderscoreFormatType -> a -> String
+toHex = toBaseFmt showHex "0x"
 
-toBinary = toBase showBin_ "0b"
-  where
-    -- this is not defined in base < 4.16
-    showBin_ = showIntAtBase 2 intToDigit
+toDecimal :: Integral a => UnderscoreFormatType -> a -> String
+toDecimal = toBaseFmt showInt ""
 
-toOctal = toBase showOct "0o"
+addUnderscoresInt :: UnderscoreFormatType -> String -> String
+addUnderscoresInt = \case
+    NoUnderscores -> id
+    -- Chunk starting from the least significant numeral.
+    UseUnderscores n -> reverse . intercalate "_" . chunksOf n . reverse
 
-toHex = toBase showHex "0x"
+toFracFormat :: (Ord t, Num t) => (t -> String) -> String -> UnderscoreFormatType -> t -> String
+toFracFormat f header underScoreFormat = addMinus $ \val ->
+    header <> addUnderscoresFloat underScoreFormat (f val)
 
-toDecimal :: Integral a => a -> String
-toDecimal = toBase showInt ""
+toFloatDecimal :: RealFloat a => UnderscoreFormatType -> a -> String
+toFloatDecimal = toFracFormat (\v -> showFFloat Nothing (abs v) "") ""
 
-toFloatDecimal :: RealFloat a => a -> String
-toFloatDecimal val = showFFloat Nothing val ""
+toFloatExpDecimal :: RealFloat a => UnderscoreFormatType -> a -> String
+toFloatExpDecimal underscoreFormat val =
+    let (n, e) = break (=='e') $ showEFloat Nothing (abs val) ""
+    in toFracFormat (const n) "" underscoreFormat val <> e
 
-toFloatExpDecimal :: RealFloat a => a -> String
-toFloatExpDecimal val = showEFloat Nothing val ""
+toHexFloat :: RealFloat a => UnderscoreFormatType -> a -> String
+toHexFloat underscoreFormat val =
+    let (header, n) = splitAt 2 $ showHFloat (abs val) ""
+        (n', e) = break (=='p') n
+    in toFracFormat (const n') header underscoreFormat val <> e
 
-toHexFloat :: RealFloat a => a -> String
-toHexFloat val = showHFloat val ""
+addUnderscoresFloat :: UnderscoreFormatType -> String -> String
+addUnderscoresFloat = \case
+    NoUnderscores -> id
+    UseUnderscores n -> \s ->
+        let (integral, decimal) = break (=='.') s
+            addUnderscores = reverse . intercalate "_" . chunksOf n . reverse
+        in intercalate "." [addUnderscores integral, intercalate "_" $ chunksOf n $ drop 1 decimal]
diff --git a/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Literals.hs b/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Literals.hs
--- a/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Literals.hs
+++ b/plugins/hls-alternate-number-format-plugin/src/Ide/Plugin/Literals.hs
@@ -66,17 +66,21 @@
 getPattern (L (locA -> (RealSrcSpan patSpan _)) pat) = case pat of
     LitPat _ lit -> case lit of
         HsInt _ val   -> fromIntegralLit patSpan val
+#if __GLASGOW_HASKELL__ < 913
         HsRat _ val _ -> fromFractionalLit patSpan val
+#endif
         _             -> Nothing
     NPat _ (L (locA -> (RealSrcSpan sSpan _)) overLit) _ _ -> fromOverLit overLit sSpan
     NPlusKPat _ _ (L (locA -> (RealSrcSpan sSpan _)) overLit1) _ _ _ -> fromOverLit overLit1 sSpan
     _ -> Nothing
 getPattern _ = Nothing
 
-fromLit :: HsLit p -> RealSrcSpan -> Maybe Literal
+fromLit :: HsLit GhcPs -> RealSrcSpan -> Maybe Literal
 fromLit lit sSpan = case lit of
         HsInt _ val   -> fromIntegralLit sSpan val
+#if __GLASGOW_HASKELL__ < 913
         HsRat _ val _ -> fromFractionalLit sSpan val
+#endif
         _             -> Nothing
 
 fromOverLit :: HsOverLit p -> RealSrcSpan -> Maybe Literal
diff --git a/plugins/hls-alternate-number-format-plugin/test/Main.hs b/plugins/hls-alternate-number-format-plugin/test/Main.hs
--- a/plugins/hls-alternate-number-format-plugin/test/Main.hs
+++ b/plugins/hls-alternate-number-format-plugin/test/Main.hs
@@ -6,8 +6,7 @@
 import           Data.Text                        (Text)
 import qualified Data.Text                        as T
 import qualified Ide.Plugin.AlternateNumberFormat as AlternateNumberFormat
-import qualified Ide.Plugin.Conversion            as Conversion
-import           Properties.Conversion            (conversions)
+import qualified Properties.Conversion            as Conversion
 import           System.FilePath                  ((<.>), (</>))
 import           Test.Hls
 import           Text.Regex.TDFA                  ((=~))
@@ -23,29 +22,36 @@
 -- to do with how
 test :: TestTree
 test = testGroup "alternateNumberFormat" [
-    codeActionHex "TIntDtoH" 3 13
-    , codeActionOctal "TIntDtoO" 3 13
-    , codeActionBinary "TIntDtoB" 4 13
-    , codeActionNumDecimal "TIntDtoND" 5 13
-    , codeActionFracExp "TFracDtoE" 3 13
-    , codeActionFloatHex "TFracDtoHF" 4 13
-    , codeActionDecimal "TIntHtoD" 3 13
-    , codeActionDecimal "TFracHFtoD" 4 13
+    codeActionHex 0 "TIntDtoH" 3 13
+    , codeActionOctal 0 "TIntDtoO" 3 13
+    , codeActionBinary 0 "TIntDtoB" 4 13
+    , codeActionBinary 6 "TIntDtoBU0toU4MultiplePragma" 4 13
+    , codeActionNumDecimal 0 "TIntDtoND" 5 13
+    , codeActionDecimal 2 "TIntDtoDU0toU3" 4 13
+    , codeActionFracExp 0 "TFracDtoE" 3 13
+    , codeActionFracExp 3 "TFracDtoEU0toU3" 3 13
+    , codeActionFloatHex 0 "TFracDtoHF" 4 13
+    , codeActionFloatHex 6 "TFracDtoHFU0toU2" 4 13
+    , codeActionDecimal 0 "TIntHtoD" 3 13
+    , codeActionDecimal 0 "TFracHFtoD" 4 13
+    , codeActionDecimal 3 "TFracDtoDU0toU3" 3 13
+    , codeActionDecimal 2 "TFracDtoDU3toU4" 3 13
+    , codeActionDecimal 3 "TFracDtoDU3toU0" 3 13
     -- to test we don't duplicate pragmas
-    , codeActionFloatHex "TFracDtoHFWithPragma" 4 13
+    , codeActionFloatHex 0 "TFracDtoHFWithPragma" 4 13
     , codeActionProperties "TFindLiteralIntPattern" [(4, 25), (5,25)] $ \actions -> do
         liftIO $ length actions @?= 8
     , codeActionProperties "TFindLiteralIntCase" [(4, 29)] $ \actions -> do
-        liftIO $ length actions @?= 4
+        liftIO $ length actions @?= 5
     , codeActionProperties "TFindLiteralIntCase2" [(5, 21)] $ \actions -> do
-        liftIO $ length actions @?= 4
+        liftIO $ length actions @?= 5
     , codeActionProperties "TFindLiteralDoReturn" [(6, 10)] $ \actions -> do
-        liftIO $ length actions @?= 4
+        liftIO $ length actions @?= 5
     , codeActionProperties "TFindLiteralDoLet" [(6, 13), (7, 13)] $ \actions -> do
-        liftIO $ length actions @?= 8
+        liftIO $ length actions @?= 12
     , codeActionProperties "TFindLiteralList" [(4, 28)] $ \actions -> do
-        liftIO $ length actions @?= 4
-    , conversions
+        liftIO $ length actions @?= 5
+    , Conversion.conversions
     ]
 
 codeActionProperties :: TestName -> [(Int, Int)] -> ([CodeAction] -> Session ()) -> TestTree
@@ -81,26 +87,26 @@
     Just (InR x) -> executeCodeAction x
     _            -> liftIO $ assertFailure "Unable to find CodeAction"
 
-codeActionDecimal :: FilePath -> Int -> Int -> TestTree
-codeActionDecimal = codeActionTest isDecimalCodeAction
+codeActionDecimal :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionDecimal nrUnderscores = codeActionTest (isDecimalCodeAction nrUnderscores)
 
-codeActionHex :: FilePath -> Int -> Int -> TestTree
-codeActionHex = codeActionTest isHexCodeAction
+codeActionHex :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionHex nrUnderscores = codeActionTest (isHexCodeAction nrUnderscores)
 
-codeActionOctal :: FilePath -> Int -> Int -> TestTree
-codeActionOctal = codeActionTest isOctalCodeAction
+codeActionOctal :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionOctal nrUnderscores = codeActionTest (isOctalCodeAction nrUnderscores)
 
-codeActionBinary :: FilePath -> Int -> Int -> TestTree
-codeActionBinary = codeActionTest isBinaryCodeAction
+codeActionBinary :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionBinary nrUnderscores = codeActionTest (isBinaryCodeAction nrUnderscores)
 
-codeActionNumDecimal :: FilePath -> Int -> Int -> TestTree
-codeActionNumDecimal = codeActionTest isNumDecimalCodeAction
+codeActionNumDecimal :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionNumDecimal nrUnderscores = codeActionTest (isNumDecimalCodeAction nrUnderscores)
 
-codeActionFracExp :: FilePath -> Int -> Int -> TestTree
-codeActionFracExp = codeActionTest isNumDecimalCodeAction
+codeActionFracExp :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionFracExp nrUnderscores = codeActionTest (isNumDecimalCodeAction nrUnderscores)
 
-codeActionFloatHex :: FilePath -> Int -> Int -> TestTree
-codeActionFloatHex = codeActionTest isHexFloatCodeAction
+codeActionFloatHex :: Int -> FilePath -> Int -> Int -> TestTree
+codeActionFloatHex nrUnderscores = codeActionTest (isHexFloatCodeAction nrUnderscores)
 
 codeActionTitle :: (Command |? CodeAction) -> Maybe Text
 codeActionTitle (InR CodeAction {_title}) = Just _title
@@ -115,7 +121,7 @@
 convertPrefix, intoInfix, maybeExtension, hexRegex, hexFloatRegex, binaryRegex, octalRegex, numDecimalRegex, decimalRegex :: Text
 convertPrefix = "Convert (" <> T.intercalate "|" [Conversion.hexRegex, Conversion.hexFloatRegex, Conversion.binaryRegex, Conversion.octalRegex, Conversion.numDecimalRegex, Conversion.decimalRegex] <> ")"
 intoInfix = " into "
-maybeExtension = "( \\(needs extension: .*)?"
+maybeExtension = "( \\(needs extensions: .*)?"
 hexRegex = intoInfix <> Conversion.hexRegex <> maybeExtension
 hexFloatRegex = intoInfix <> Conversion.hexFloatRegex <> maybeExtension
 binaryRegex = intoInfix <> Conversion.binaryRegex <> maybeExtension
@@ -123,26 +129,31 @@
 numDecimalRegex = intoInfix <> Conversion.numDecimalRegex <> maybeExtension
 decimalRegex = intoInfix <> Conversion.decimalRegex <> maybeExtension
 
-isCodeAction :: Text -> Maybe Text -> Bool
-isCodeAction userRegex (Just txt) = txt =~ Conversion.matchLineRegex (convertPrefix <> userRegex)
-isCodeAction _ _                  = False
+isCodeAction :: Text -> Int -> Maybe Text -> Bool
+isCodeAction userRegex nrUnderscores (Just txt)
+    | matchesUnderscores txt nrUnderscores
+    = txt =~ Conversion.matchLineRegex (convertPrefix <> userRegex)
+isCodeAction _ _ _ = False
 
-isHexCodeAction :: Maybe Text -> Bool
+matchesUnderscores :: Text -> Int -> Bool
+matchesUnderscores txt nrUnderscores = T.count "_" txt == nrUnderscores
+
+isHexCodeAction :: Int -> Maybe Text -> Bool
 isHexCodeAction = isCodeAction hexRegex
 
-isHexFloatCodeAction :: Maybe Text -> Bool
+isHexFloatCodeAction :: Int -> Maybe Text -> Bool
 isHexFloatCodeAction = isCodeAction hexFloatRegex
 
-isBinaryCodeAction :: Maybe Text -> Bool
+isBinaryCodeAction :: Int -> Maybe Text -> Bool
 isBinaryCodeAction = isCodeAction binaryRegex
 
-isOctalCodeAction :: Maybe Text -> Bool
+isOctalCodeAction :: Int -> Maybe Text -> Bool
 isOctalCodeAction = isCodeAction octalRegex
 
 -- This can match EITHER an integer as NumDecimal extension or a Fractional
 -- as in 1.23e-3 (so anything with an exponent really)
-isNumDecimalCodeAction :: Maybe Text -> Bool
+isNumDecimalCodeAction :: Int -> Maybe Text -> Bool
 isNumDecimalCodeAction = isCodeAction numDecimalRegex
 
-isDecimalCodeAction :: Maybe Text -> Bool
+isDecimalCodeAction :: Int -> Maybe Text -> Bool
 isDecimalCodeAction = isCodeAction decimalRegex
diff --git a/plugins/hls-alternate-number-format-plugin/test/Properties/Conversion.hs b/plugins/hls-alternate-number-format-plugin/test/Properties/Conversion.hs
--- a/plugins/hls-alternate-number-format-plugin/test/Properties/Conversion.hs
+++ b/plugins/hls-alternate-number-format-plugin/test/Properties/Conversion.hs
@@ -1,42 +1,117 @@
 module Properties.Conversion where
 
+import qualified Data.Map              as Map
+import           Data.Maybe            (fromMaybe)
+import           Data.Text             (Text)
 import           Ide.Plugin.Conversion
 import           Test.Hls              (TestTree, testGroup)
 import           Test.Tasty.QuickCheck (testProperty)
 import           Text.Regex.TDFA       ((=~))
 
 conversions :: TestTree
-conversions = testGroup "Conversions" $
-    map (uncurry testProperty)
-    [ ("Match NumDecimal", prop_regexMatchesNumDecimal)
-    , ("Match Hex", prop_regexMatchesHex)
-    , ("Match Octal", prop_regexMatchesOctal)
-    , ("Match Binary", prop_regexMatchesBinary)
-    ]
-    <>
-    map (uncurry testProperty)
-    [ ("Match HexFloat", prop_regexMatchesHexFloat)
-    , ("Match FloatDecimal", prop_regexMatchesFloatDecimal)
-    , ("Match FloatExpDecimal", prop_regexMatchesFloatExpDecimal)
+conversions = testGroup "Conversions"
+    [ testGroup "integral literals"
+        [ testGroup "Match NumDecimal" prop_regexMatchesNumDecimal
+        , testGroup "Match Hex" prop_regexMatchesHex
+        , testGroup "Match Octal" prop_regexMatchesOctal
+        , testGroup "Match Binary" prop_regexMatchesBinary
+        ]
+    , testGroup "fractional literals"
+        [ testGroup "Match HexFloat" prop_regexMatchesHexFloat
+        , testGroup "Match FloatDecimal" prop_regexMatchesFloatDecimal
+        , testGroup "Match FloatExpDecimal" prop_regexMatchesFloatExpDecimal
+        ]
     ]
 
-prop_regexMatchesNumDecimal :: Integer -> Bool
-prop_regexMatchesNumDecimal = (=~ numDecimalRegex) . toFloatExpDecimal @Double . fromInteger
+allIntFormatOf :: IntFormatType -> [UnderscoreFormatType]
+allIntFormatOf formatType = fromMaybe [] (Map.lookup formatType intFormats)
 
-prop_regexMatchesHex :: Integer -> Bool
-prop_regexMatchesHex = (=~ hexRegex ) . toHex
+prop_regexMatchesNumDecimal :: [TestTree]
+prop_regexMatchesNumDecimal =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allIntFormatOf IntDecimalFormat ]
+  where
+    prop :: UnderscoreFormatType -> Integer -> Bool
+    prop underscoreFormat = (=~ numDecimalRegex) . toFloatExpDecimal @Double underscoreFormat . fromInteger
 
-prop_regexMatchesOctal :: Integer -> Bool
-prop_regexMatchesOctal = (=~ octalRegex) . toOctal
+prop_regexMatchesHex :: [TestTree]
+prop_regexMatchesHex =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allIntFormatOf IntDecimalFormat ]
+  where
+    prop :: UnderscoreFormatType -> Integer -> Bool
+    prop underscoreFormat = (=~ hexRegex ) . toHex underscoreFormat
 
-prop_regexMatchesBinary :: Integer -> Bool
-prop_regexMatchesBinary = (=~ binaryRegex) . toBinary
+prop_regexMatchesOctal :: [TestTree]
+prop_regexMatchesOctal =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allIntFormatOf IntDecimalFormat ]
+  where
+    prop :: UnderscoreFormatType -> Integer -> Bool
+    prop underscoreFormat = (=~ octalRegex) . toOctal underscoreFormat
 
-prop_regexMatchesHexFloat :: Double -> Bool
-prop_regexMatchesHexFloat = (=~ hexFloatRegex) . toHexFloat
+prop_regexMatchesBinary :: [TestTree]
+prop_regexMatchesBinary =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allIntFormatOf IntDecimalFormat ]
+  where
+    prop :: UnderscoreFormatType -> Integer -> Bool
+    prop underscoreFormat = (=~ binaryRegex) . toBinary underscoreFormat
 
-prop_regexMatchesFloatDecimal :: Double -> Bool
-prop_regexMatchesFloatDecimal = (=~ decimalRegex ) . toFloatDecimal
+allFracFormatOf :: FracFormatType -> [UnderscoreFormatType]
+allFracFormatOf formatType = fromMaybe [] (Map.lookup formatType fracFormats)
 
-prop_regexMatchesFloatExpDecimal :: Double -> Bool
-prop_regexMatchesFloatExpDecimal = (=~ numDecimalRegex ) . toFloatExpDecimal
+prop_regexMatchesHexFloat :: [TestTree]
+prop_regexMatchesHexFloat =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allFracFormatOf HexFloatFormat ]
+  where
+    prop :: UnderscoreFormatType -> Double -> Bool
+    prop underscoreFormat = (=~ hexFloatRegex) . toHexFloat underscoreFormat
+
+prop_regexMatchesFloatDecimal :: [TestTree]
+prop_regexMatchesFloatDecimal =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allFracFormatOf FracDecimalFormat ]
+  where
+    prop :: UnderscoreFormatType -> Double -> Bool
+    prop underscoreFormat = (=~ decimalRegex ) . toFloatDecimal underscoreFormat
+
+prop_regexMatchesFloatExpDecimal :: [TestTree]
+prop_regexMatchesFloatExpDecimal =
+    [ testProperty (show underscoreFormat) (prop underscoreFormat)
+    | underscoreFormat <- allFracFormatOf ExponentFormat ]
+  where
+    prop :: UnderscoreFormatType -> Double -> Bool
+    prop underscoreFormat = (=~ numDecimalRegex ) . toFloatExpDecimal underscoreFormat
+
+-- | Regex to match a Haskell Hex Literal
+hexRegex :: Text
+hexRegex = "0[xX][a-fA-F0-9_]+"
+
+-- | Regex to match a Haskell Hex Float Literal
+hexFloatRegex :: Text
+hexFloatRegex = "0[xX][a-fA-F0-9_]+(\\.)?[a-fA-F0-9_]*(p[+-]?[0-9]+)?"
+
+-- | Regex to match a Haskell Binary Literal
+binaryRegex :: Text
+binaryRegex = "0[bB][0|1_]+"
+
+-- | Regex to match a Haskell Octal Literal
+octalRegex :: Text
+octalRegex = "0[oO][0-8_]+"
+
+-- | Regex to match a Haskell Decimal Literal (no decimal points)
+decimalRegex :: Text
+decimalRegex = "[0-9_]+(\\.[0-9_]+)?"
+
+-- | Regex to match a Haskell Literal with an explicit exponent
+numDecimalRegex :: Text
+numDecimalRegex = "[0-9_]+\\.[0-9_]+[eE][+-]?[0-9]+"
+
+-- we want to be explicit in our matches
+-- so we need to match the beginning/end of the source text
+-- | Wraps a Regex with a beginning ("^") and end ("$") token
+matchLineRegex :: Text -> Text
+matchLineRegex regex = "^" <> regex <> "$"
+
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU0toU3.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU0toU3.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU0toU3.expected.hs
@@ -0,0 +1,3 @@
+module TFracDtoDUnderscores3 where
+
+convertMe = 12_345.678_912_3
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU0toU3.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU0toU3.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU0toU3.hs
@@ -0,0 +1,3 @@
+module TFracDtoDUnderscores3 where
+
+convertMe = 12345.6789123
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU0.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU0.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU0.expected.hs
@@ -0,0 +1,3 @@
+module TFracDtoDUnderscores3 where
+
+convertMe = 12345.6789123
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU0.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU0.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU0.hs
@@ -0,0 +1,3 @@
+module TFracDtoDUnderscores3 where
+
+convertMe = 12_345.678_912_3
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU4.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU4.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU4.expected.hs
@@ -0,0 +1,3 @@
+module TFracDtoDUnderscores3 where
+
+convertMe = 1_2345.6789_123
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU4.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU4.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoDU3toU4.hs
@@ -0,0 +1,3 @@
+module TFracDtoDUnderscores3 where
+
+convertMe = 12345.6789123
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoEU0toU3.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoEU0toU3.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoEU0toU3.expected.hs
@@ -0,0 +1,3 @@
+module TFracDtoE where
+
+convertMe = 1.234_567_890_123e2
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoEU0toU3.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoEU0toU3.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoEU0toU3.hs
@@ -0,0 +1,3 @@
+module TFracDtoE where
+
+convertMe = 1.234567890123e2
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoHFU0toU2.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoHFU0toU2.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoHFU0toU2.expected.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE HexFloatLiterals #-}
+{-# LANGUAGE NumericUnderscores #-}
+module TFracDtoHF where
+
+convertMe = 0x1.ee_cc_cc_cc_cc_cc_dp6
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoHFU0toU2.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoHFU0toU2.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TFracDtoHFU0toU2.hs
@@ -0,0 +1,4 @@
+{-# LANGUAGE Haskell2010 #-}
+module TFracDtoHF where
+
+convertMe = 123.7
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoBU0toU4MultiplePragma.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoBU0toU4MultiplePragma.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoBU0toU4MultiplePragma.expected.hs
@@ -0,0 +1,6 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE BinaryLiterals #-}
+{-# LANGUAGE NumericUnderscores #-}
+module TIntDtoB where
+
+convertMe = 0b111_0101_1011_1100_1101_0001_0101
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoBU0toU4MultiplePragma.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoBU0toU4MultiplePragma.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoBU0toU4MultiplePragma.hs
@@ -0,0 +1,4 @@
+{-# LANGUAGE Haskell2010 #-}
+module TIntDtoB where
+
+convertMe = 123456789
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoDU0toU3.expected.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoDU0toU3.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoDU0toU3.expected.hs
@@ -0,0 +1,5 @@
+{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE NumericUnderscores #-}
+module TIntDtoB where
+
+convertMe = 12_345_678
diff --git a/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoDU0toU3.hs b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoDU0toU3.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-alternate-number-format-plugin/test/testdata/TIntDtoDU0toU3.hs
@@ -0,0 +1,4 @@
+{-# LANGUAGE Haskell2010 #-}
+module TIntDtoB where
+
+convertMe = 12345678
diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs
--- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs
+++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal.hs
@@ -2,7 +2,6 @@
 {-# LANGUAGE DuplicateRecordFields #-}
 {-# LANGUAGE LambdaCase            #-}
 {-# LANGUAGE OverloadedStrings     #-}
-{-# LANGUAGE PatternSynonyms       #-}
 {-# LANGUAGE TypeFamilies          #-}
 
 module Ide.Plugin.Cabal (descriptor, haskellInteractionDescriptor, Log (..)) where
@@ -55,6 +54,8 @@
 import qualified Language.LSP.Protocol.Message                 as LSP
 import           Language.LSP.Protocol.Types
 import qualified Language.LSP.VFS                              as VFS
+import qualified Text.Fuzzy.Levenshtein                        as Fuzzy
+import qualified Text.Fuzzy.Parallel                           as Fuzzy
 import           Text.Regex.TDFA
 
 data Log
@@ -234,7 +235,9 @@
       fakeLspCursorPosition = Position lineNr (col + fromIntegral (T.length fieldName))
       lspPrefixInfo = Ghcide.getCompletionPrefixFromRope fakeLspCursorPosition fileContents
       cabalPrefixInfo = Completions.getCabalPrefixInfo fp lspPrefixInfo
-    completions <- liftIO $ computeCompletionsAt recorder ide cabalPrefixInfo fp cabalFields
+    completions <- liftIO $ computeCompletionsAt recorder ide cabalPrefixInfo fp cabalFields $
+      CompleterTypes.Matcher $
+        Fuzzy.levenshteinScored Fuzzy.defChunkSize
     let completionTexts = fmap (^. JL.label) completions
     pure $ FieldSuggest.fieldErrorAction uri fieldName completionTexts _range
 
@@ -365,12 +368,21 @@
         Just (fields, _) -> do
           let lspPrefInfo = Ghcide.getCompletionPrefixFromRope position cnts
               cabalPrefInfo = Completions.getCabalPrefixInfo path lspPrefInfo
-          let res = computeCompletionsAt recorder ide cabalPrefInfo path fields
+              res = computeCompletionsAt recorder ide cabalPrefInfo path fields $
+                CompleterTypes.Matcher $
+                  Fuzzy.simpleFilter Fuzzy.defChunkSize Fuzzy.defMaxResults
           liftIO $ fmap InL res
     Nothing -> pure . InR $ InR Null
 
-computeCompletionsAt :: Recorder (WithPriority Log) -> IdeState -> Types.CabalPrefixInfo -> FilePath -> [Syntax.Field Syntax.Position] -> IO [CompletionItem]
-computeCompletionsAt recorder ide prefInfo fp fields = do
+computeCompletionsAt
+  :: Recorder (WithPriority Log)
+  -> IdeState
+  -> Types.CabalPrefixInfo
+  -> FilePath
+  -> [Syntax.Field Syntax.Position]
+  -> CompleterTypes.Matcher T.Text
+  -> IO [CompletionItem]
+computeCompletionsAt recorder ide prefInfo fp fields matcher = do
   runMaybeT (context fields) >>= \case
     Nothing -> pure []
     Just ctx -> do
@@ -390,6 +402,7 @@
                   case fst ctx of
                     Types.Stanza _ name -> name
                     _                   -> Nothing
+              , matcher = matcher
               }
       completions <- completer completerRecorder completerData
       pure completions
diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Module.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Module.hs
--- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Module.hs
+++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Module.hs
@@ -33,8 +33,7 @@
   case mGPD of
     Just gpd -> do
       let sourceDirs = extractionFunction sName gpd
-      filePathCompletions <-
-        filePathsForExposedModules recorder sourceDirs prefInfo
+      filePathCompletions <- filePathsForExposedModules recorder sourceDirs prefInfo (matcher cData)
       pure $ map (\compl -> mkSimpleCompletionItem (completionRange prefInfo) compl) filePathCompletions
     Nothing -> do
       logWith recorder Debug LogUseWithStaleFastNoResult
@@ -45,8 +44,13 @@
 
 -- | Takes a list of source directories and returns a list of path completions
 --  relative to any of the passed source directories which fit the passed prefix info.
-filePathsForExposedModules :: Recorder (WithPriority Log) -> [FilePath] -> CabalPrefixInfo -> IO [T.Text]
-filePathsForExposedModules recorder srcDirs prefInfo = do
+filePathsForExposedModules
+  :: Recorder (WithPriority Log)
+  -> [FilePath]
+  -> CabalPrefixInfo
+  -> Matcher T.Text
+  -> IO [T.Text]
+filePathsForExposedModules recorder srcDirs prefInfo matcher = do
   concatForM
     srcDirs
     ( \dir' -> do
@@ -55,9 +59,8 @@
         completions <- listFileCompletions recorder pathInfo
         validExposedCompletions <- filterM (isValidExposedModulePath pathInfo) completions
         let toMatch = pathSegment pathInfo
-            scored = Fuzzy.simpleFilter
-              Fuzzy.defChunkSize
-              Fuzzy.defMaxResults
+            scored = runMatcher
+              matcher
               toMatch
               (map T.pack validExposedCompletions)
         forM
diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Simple.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Simple.hs
--- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Simple.hs
+++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Simple.hs
@@ -41,7 +41,7 @@
 constantCompleter :: [T.Text] -> Completer
 constantCompleter completions _ cData = do
   let prefInfo = cabalPrefixInfo cData
-      scored = Fuzzy.simpleFilter Fuzzy.defChunkSize Fuzzy.defMaxResults (completionPrefix prefInfo) completions
+      scored = runMatcher (matcher cData) (completionPrefix prefInfo) completions
       range = completionRange prefInfo
   pure $ map (mkSimpleCompletionItem range . Fuzzy.original) scored
 
@@ -68,7 +68,7 @@
 -- it is just forbidden on hackage.
 nameCompleter :: Completer
 nameCompleter _ cData = do
-  let scored = Fuzzy.simpleFilter Fuzzy.defChunkSize Fuzzy.defMaxResults (completionPrefix prefInfo) [completionFileName prefInfo]
+  let scored = runMatcher (matcher cData) (completionPrefix prefInfo) [completionFileName prefInfo]
       prefInfo = cabalPrefixInfo cData
       range = completionRange prefInfo
   pure $ map (mkSimpleCompletionItem range . Fuzzy.original) scored
@@ -85,6 +85,7 @@
   let scored =
         if perfectScore > 0
           then
+            -- TODO: Would be nice to use to be able to use the matcher in `cData`
             fmap Fuzzy.original $
               Fuzzy.simpleFilter' Fuzzy.defChunkSize Fuzzy.defMaxResults prefix completions customMatch
           else topTenByWeight
diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Types.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Types.hs
--- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Types.hs
+++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Completer/Types.hs
@@ -2,17 +2,23 @@
 
 module Ide.Plugin.Cabal.Completion.Completer.Types where
 
+import           Data.Text                         (Text)
+import qualified Data.Text                         as T
 import           Development.IDE                   as D
 import qualified Distribution.Fields               as Syntax
 import           Distribution.PackageDescription   (GenericPackageDescription)
 import qualified Distribution.Parsec.Position      as Syntax
 import           Ide.Plugin.Cabal.Completion.Types
 import           Language.LSP.Protocol.Types       (CompletionItem)
+import           Text.Fuzzy.Parallel
 
 -- | Takes information needed to build possible completion items
 -- and returns the list of possible completion items
 type Completer = Recorder (WithPriority Log) -> CompleterData -> IO [CompletionItem]
 
+-- | Type signature of completion functions ranking texts against a pattern.
+newtype Matcher a = Matcher { runMatcher :: T.Text -> [T.Text] -> [Scored a] }
+
 -- | Contains information to be used by completers.
 data CompleterData = CompleterData
   { -- | Access to the latest available generic package description for the handled cabal file,
@@ -24,5 +30,7 @@
     -- | Prefix info to be used for constructing completion items
     cabalPrefixInfo        :: CabalPrefixInfo,
     -- | The name of the stanza in which the completer is applied
-    stanzaName             :: Maybe StanzaName
+    stanzaName             :: Maybe StanzaName,
+    -- | The matcher that'll be used to rank the texts against the pattern.
+    matcher                :: Matcher Text
   }
diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs
--- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs
+++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Completion/Data.hs
@@ -8,6 +8,7 @@
 import           Development.IDE.GHC.Compat.Core                (flagsForCompletion)
 import           Distribution.CabalSpecVersion                  (CabalSpecVersion (CabalSpecV2_2),
                                                                  showCabalSpecVersion)
+import           Distribution.Pretty                            (prettyShow)
 import           Ide.Plugin.Cabal.Completion.Completer.FilePath
 import           Ide.Plugin.Cabal.Completion.Completer.Module
 import           Ide.Plugin.Cabal.Completion.Completer.Paths
@@ -15,7 +16,7 @@
 import           Ide.Plugin.Cabal.Completion.Completer.Types    (Completer)
 import           Ide.Plugin.Cabal.Completion.Types
 import           Ide.Plugin.Cabal.LicenseSuggest                (licenseNames)
-
+import           Language.Haskell.Extension
 -- | 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'.
@@ -177,8 +178,8 @@
     [ ("import:", importCompleter),
       ("build-depends:", noopCompleter),
       ("hs-source-dirs:", directoryCompleter),
-      ("default-extensions:", noopCompleter),
-      ("other-extensions:", noopCompleter),
+      ("default-extensions:", constantCompleter $ map (T.pack . prettyShow) allExtensions),
+      ("other-extensions:", constantCompleter $ map (T.pack . prettyShow) allExtensions),
       ("default-language:", constantCompleter ["GHC2021", "Haskell2010", "Haskell98"]),
       ("other-languages:", noopCompleter),
       ("build-tool-depends:", noopCompleter),
@@ -234,6 +235,19 @@
         -- parses the '.cabal' file s.t. that we have access to the 'hs-source-dirs',
         -- but not have erased the "common" stanza.
         noopCompleter
+
+-- | Returns all possible language extensions including disabled ones.
+allExtensions :: [Extension]
+allExtensions =
+  concatMap
+    ( \e ->
+        -- These pragmas cannot be negated as they are not reversible
+        -- by prepending "No".
+        if e `notElem` [Unsafe, Trustworthy, Safe]
+          then [EnableExtension e, DisableExtension e]
+          else [EnableExtension e]
+    )
+    knownExtensions
 
 -- | Contains a map of the most commonly used licenses, weighted by their popularity.
 --
diff --git a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Definition.hs b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Definition.hs
--- a/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Definition.hs
+++ b/plugins/hls-cabal-plugin/src/Ide/Plugin/Cabal/Definition.hs
@@ -198,9 +198,10 @@
 -- better ways to get the path.
 --
 -- Examples: (output is system dependent)
---   >>> toHaskellFile "My.Module.Lib"
---   "My/Module/Lib.hs"
---   >>> toHaskellFile "Main"
---   "Main.hs"
+--
+-- >>> toHaskellFile "My.Module.Lib"
+-- "My/Module/Lib.hs"
+-- >>> toHaskellFile "Main"
+-- "Main.hs"
 toHaskellFile :: T.Text -> FilePath
 toHaskellFile moduleName = joinPath (map T.unpack $ T.splitOn "." moduleName) <.> ".hs"
diff --git a/plugins/hls-cabal-plugin/test/CabalAdd.hs b/plugins/hls-cabal-plugin/test/CabalAdd.hs
--- a/plugins/hls-cabal-plugin/test/CabalAdd.hs
+++ b/plugins/hls-cabal-plugin/test/CabalAdd.hs
@@ -83,30 +83,29 @@
 cabalAddDependencyTests =
   testGroup
     "Add dependency"
-    [ runHaskellTestCaseSession "Add to executable" ("cabal-add-testdata" </> "cabal-add-exe")
-        (generateAddDependencyTestSession "cabal-add-exe.cabal" ("src" </> "Main.hs") "split" [253])
-    , runHaskellTestCaseSession "Add to library" ("cabal-add-testdata" </> "cabal-add-lib")
-        (generateAddDependencyTestSession "cabal-add-lib.cabal" ("src" </> "MyLib.hs") "split" [348])
-    , runHaskellTestCaseSession "Add to testsuite" ("cabal-add-testdata" </> "cabal-add-tests")
-        (generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" </> "Main.hs") "split" [478])
-    , runHaskellTestCaseSession "Add to testsuite with PackageImports" ("cabal-add-testdata" </> "cabal-add-tests")
-        (generateAddDependencyTestSession "cabal-add-tests.cabal" ("test" </> "MainPackageImports.hs") "split" [731])
-    , runHaskellTestCaseSession "Add to benchmark" ("cabal-add-testdata" </> "cabal-add-bench")
-        (generateAddDependencyTestSession "cabal-add-bench.cabal" ("bench" </> "Main.hs") "split" [403])
-
-    , runHaskellTestCaseSession "Add to executable, multiple targets" ("cabal-add-testdata" </> "cabal-add-multitarget")
-        (generateAddDependencyTestSession "cabal-add-multitarget.cabal" ("src" </> "Main.hs") "split" [269])
-    , runHaskellTestCaseSession "Add to library, multiple targets" ("cabal-add-testdata" </> "cabal-add-multitarget")
-        (generateAddDependencyTestSession "cabal-add-multitarget.cabal" ("lib" </> "MyLib.hs") "split" [413])
-    , runHaskellTestCaseSession "Add to internal library, multiple targets" ("cabal-add-testdata" </> "cabal-add-multitarget")
-        (generateAddDependencyTestSession "cabal-add-multitarget.cabal" ("lib" </> "InternalLib.hs") "split" [413])
-    , runHaskellTestCaseSession "Add to testsuite, multiple targets" ("cabal-add-testdata" </> "cabal-add-multitarget")
-        (generateAddDependencyTestSession "cabal-add-multitarget.cabal" ("test" </> "Main.hs") "split" [655])
-    , runHaskellTestCaseSession "Add to benchmark, multiple targets" ("cabal-add-testdata" </> "cabal-add-multitarget")
-        (generateAddDependencyTestSession "cabal-add-multitarget.cabal" ("bench" </> "Main.hs") "split" [776])
+    [ runHaskellTestCaseSession "Add to executable" ("cabal-add-testdata" </> "exe")
+        (generateAddDependencyTestSession "exe.cabal" ("src" </> "Main.hs") "split" [253])
+    , runHaskellTestCaseSession "Add to library" ("cabal-add-testdata" </> "lib")
+        (generateAddDependencyTestSession "lib.cabal" ("src" </> "MyLib.hs") "split" [348])
+    , runHaskellTestCaseSession "Add to testsuite" ("cabal-add-testdata" </> "tests")
+        (generateAddDependencyTestSession "tests.cabal" ("test" </> "Main.hs") "split" [478])
+    , runHaskellTestCaseSession "Add to testsuite with PackageImports" ("cabal-add-testdata" </> "tests")
+        (generateAddDependencyTestSession "tests.cabal" ("test" </> "MainPackageImports.hs") "split" [731])
+    , runHaskellTestCaseSession "Add to benchmark" ("cabal-add-testdata" </> "bench")
+        (generateAddDependencyTestSession "bench.cabal" ("bench" </> "Main.hs") "split" [403])
 
+    , runHaskellTestCaseSession "Add to executable, multiple targets" ("cabal-add-testdata" </> "multitarget")
+        (generateAddDependencyTestSession "multitarget.cabal" ("src" </> "Main.hs") "split" [269])
+    , runHaskellTestCaseSession "Add to library, multiple targets" ("cabal-add-testdata" </> "multitarget")
+        (generateAddDependencyTestSession "multitarget.cabal" ("lib" </> "MyLib.hs") "split" [413])
+    , runHaskellTestCaseSession "Add to internal library, multiple targets" ("cabal-add-testdata" </> "multitarget")
+        (generateAddDependencyTestSession "multitarget.cabal" ("lib" </> "InternalLib.hs") "split" [413])
+    , runHaskellTestCaseSession "Add to testsuite, multiple targets" ("cabal-add-testdata" </> "multitarget")
+        (generateAddDependencyTestSession "multitarget.cabal" ("test" </> "Main.hs") "split" [655])
+    , runHaskellTestCaseSession "Add to benchmark, multiple targets" ("cabal-add-testdata" </> "multitarget")
+        (generateAddDependencyTestSession "multitarget.cabal" ("bench" </> "Main.hs") "split" [776])
 
-    , runHaskellTestCaseSession "Guard against HPack" ("cabal-add-testdata" </> "cabal-add-packageYaml")
+    , runHaskellTestCaseSession "Guard against HPack" ("cabal-add-testdata" </> "packageYaml")
         (generatePackageYAMLTestSession ("src" </> "Main.hs"))
 
     , testHiddenPackageSuggestions "Check CabalAdd's parser, no version"
diff --git a/plugins/hls-cabal-plugin/test/Completer.hs b/plugins/hls-cabal-plugin/test/Completer.hs
--- a/plugins/hls-cabal-plugin/test/Completer.hs
+++ b/plugins/hls-cabal-plugin/test/Completer.hs
@@ -12,6 +12,7 @@
 import qualified Data.ByteString.Char8                          as BS8
 import           Data.Maybe                                     (mapMaybe)
 import qualified Data.Text                                      as T
+import           Development.IDE.Plugin.Completions.Types       (cursorPos)
 import qualified Development.IDE.Plugin.Completions.Types       as Ghcide
 import qualified Distribution.Fields                            as Syntax
 import           Distribution.PackageDescription                (GenericPackageDescription)
@@ -21,13 +22,18 @@
 import           Ide.Plugin.Cabal.Completion.Completer.Module
 import           Ide.Plugin.Cabal.Completion.Completer.Paths
 import           Ide.Plugin.Cabal.Completion.Completer.Simple   (importCompleter)
-import           Ide.Plugin.Cabal.Completion.Completer.Types    (CompleterData (..))
+import           Ide.Plugin.Cabal.Completion.Completer.Types    (CompleterData (..),
+                                                                 Matcher (..))
 import           Ide.Plugin.Cabal.Completion.Completions
 import           Ide.Plugin.Cabal.Completion.Types              (CabalPrefixInfo (..),
                                                                  StanzaName)
 import qualified Language.LSP.Protocol.Lens                     as L
 import           System.FilePath
 import           Test.Hls
+import           Test.Hls.FileSystem                            (file,
+                                                                 mkVirtualFileTree,
+                                                                 text)
+import qualified Text.Fuzzy.Parallel                            as Fuzzy
 import           Utils
 
 completerTests :: TestTree
@@ -71,7 +77,20 @@
         let complTexts = getTextEditTexts compls
         liftIO $ assertBool "suggests f2" $ "f2.hs" `elem` complTexts
         liftIO $ assertBool "does not suggest" $ "Content.hs" `notElem` complTexts
-    ]
+    , parameterisedCursorTestM "extensions completion" libraryStanzaData
+        [ \_ actual -> assertBool "suggests FieldSelectors" $ "FieldSelectors" `elem` actual
+        , \_ actual -> assertBool "suggests OverloadedStrings" $ "OverloadedStrings" `elem` actual
+        , \_ actual -> assertBool "suggests something" $ not . null $ actual
+        , \_ actual -> assertBool "suggests NoLambdaCase" $ "NoLambdaCase" `elem` actual
+        , \_ actual -> assertBool "suggests RecordWildCards" $ "RecordWildCards" `elem` actual
+        ]
+        $ \fileContent posPrefInfo -> do
+            let vFileTree = mkVirtualFileTree "" $ [file "cabalFile.cabal" $ text fileContent]
+            runCabalSessionVft vFileTree $ do
+              doc <- openDoc "cabalFile.cabal" "cabal"
+              compls <- getCompletions doc (cursorPos posPrefInfo)
+              let complTexts = getTextEditTexts compls
+              pure complTexts]
     where
       getTextEditTexts :: [CompletionItem] -> [T.Text]
       getTextEditTexts compls = mapMaybe (^? L.textEdit . _Just . _L . L.newText) compls
@@ -270,7 +289,7 @@
     callFilePathsForExposedModules :: [FilePath] -> IO [T.Text]
     callFilePathsForExposedModules srcDirs = do
       let prefInfo = simpleCabalPrefixInfoFromFp "" exposedTestDir
-      filePathsForExposedModules mempty srcDirs prefInfo
+      filePathsForExposedModules mempty srcDirs prefInfo $ Matcher $ Fuzzy.simpleFilter Fuzzy.defChunkSize Fuzzy.defMaxResults
 
 exposedModuleCompleterTests :: TestTree
 exposedModuleCompleterTests =
@@ -366,11 +385,19 @@
         cabalContents <- ByteString.readFile $ testDataDir </> "exposed.cabal"
         pure $ parseGenericPackageDescriptionMaybe cabalContents,
       getCabalCommonSections = undefined,
-      stanzaName = sName
+      stanzaName = sName,
+      matcher = Matcher $ Fuzzy.simpleFilter Fuzzy.defChunkSize Fuzzy.defMaxResults
     }
 
 mkCompleterData :: CabalPrefixInfo -> CompleterData
-mkCompleterData prefInfo = CompleterData {getLatestGPD = undefined, getCabalCommonSections = undefined, cabalPrefixInfo = prefInfo, stanzaName = Nothing}
+mkCompleterData prefInfo =
+  CompleterData
+    { getLatestGPD = undefined,
+      getCabalCommonSections = undefined,
+      cabalPrefixInfo = prefInfo,
+      stanzaName = Nothing,
+      matcher = Matcher $ Fuzzy.simpleFilter Fuzzy.defChunkSize Fuzzy.defMaxResults
+    }
 
 exposedTestDir :: FilePath
 exposedTestDir = addTrailingPathSeparator $ testDataDir </> "src-modules"
@@ -391,40 +418,27 @@
   Just (InL v) -> v ^. L.newText
   _            -> error ""
 
-importTestData :: T.Text
-importTestData = [__i|
-  cabal-version:      3.0
-  name:               hls-cabal-plugin
-  version:            0.1.0.0
-  synopsis:
-  homepage:
-  license:            MIT
-  license-file:       LICENSE
-  author:             Fendor
-  maintainer:         fendor@posteo.de
-  category:           Development
-  extra-source-files: CHANGELOG.md
-
-  common defaults
-    default-language: GHC2021
-    -- Should have been in GHC2021, an oversight
-    default-extensions: ExplicitNamespaces
-
-  common test-defaults
-    ghc-options: -threaded -rtsopts -with-rtsopts=-N
-
-  library
-      import:
-              ^
-      exposed-modules:  IDE.Plugin.Cabal
-      build-depends:    base ^>=4.14.3.0
-      hs-source-dirs:   src
-      default-language: Haskell2010
-
-  common notForLib
-    default-language: GHC2021
+-- ------------------------------------------------------------------------
+-- Test Data
+-- ------------------------------------------------------------------------
 
-  test-suite tests
-    import:
-            ^
+libraryStanzaData :: T.Text
+libraryStanzaData = [__i|
+    cabal-version:      3.0
+    name:               simple-cabal
+    common mylib
+      default-extensions: Field
+                               ^
+    library
+        default-extensions: Ov
+                              ^
+    test-suite mysuite
+        default-extensions:
+                            ^
+    executable myexe
+        default-extensions: NoLam
+                                 ^
+    benchmark mybench
+        other-extensions: RecordW
+                                 ^
 |]
diff --git a/plugins/hls-cabal-plugin/test/Definition.hs b/plugins/hls-cabal-plugin/test/Definition.hs
--- a/plugins/hls-cabal-plugin/test/Definition.hs
+++ b/plugins/hls-cabal-plugin/test/Definition.hs
@@ -6,8 +6,6 @@
 
 import           Control.Lens                ((^.))
 import           Data.List.Extra             (isSuffixOf)
-import qualified Data.Text                   as T
-import           Ide.Plugin.Cabal.Definition (toHaskellFile)
 import qualified Language.LSP.Protocol.Lens  as L
 import qualified Language.LSP.Protocol.Types as LSP
 import           System.FilePath
@@ -24,38 +22,35 @@
 gotoModuleDefinitionTests :: TestTree
 gotoModuleDefinitionTests = testGroup "Goto Module Definition"
     [ testGoToDefinitionLink "simple cabal test" "simple-cabal" "simple-cabal.cabal"
-                             (Position 8 23) (toTestHaskellPath "" "A")
+                             (Position 8 23) "A.hs"
 
     , testGoToDefinitionLink "library start of exposed-modules" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 6 22) (toTestHaskellPath "src" "Library.Lib")
+                             (Position 6 22) ("src" </> "Library" </> "Lib.hs")
     , testGoToDefinitionLink "library middle of exposed-modules" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 6 29) (toTestHaskellPath "src" "Library.Lib")
+                             (Position 6 29) ("src" </> "Library" </> "Lib.hs")
     , testGoToDefinitionLink "library end of exposed-modules" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 6 33) (toTestHaskellPath "src" "Library.Lib")
+                             (Position 6 33) ("src" </> "Library" </> "Lib.hs")
     , testGoToDefinitionLink "library start of other-modules" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 9 22) (toTestHaskellPath "src" "Library.Other.OtherLib")
+                             (Position 9 22) ("src" </> "Library" </> "Other" </> "OtherLib.hs")
     , testGoToDefinitionLink "library end of other-modules" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 9 44) (toTestHaskellPath "src" "Library.Other.OtherLib")
+                             (Position 9 44) ("src" </> "Library" </> "Other" </> "OtherLib.hs")
 
     , testGoToDefinitionLink "executable other-modules" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 22 10) (toTestHaskellPath ("src" </> "exe") "Config")
+                             (Position 22 10) ("src" </> "exe" </> "Config.hs")
 
     , testGoToDefinitionLink "test-suite other-modules Config" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 31 10) (toTestHaskellPath ("src" </> "test") "Config")
+                             (Position 31 10) ("src" </> "test"</> "Config.hs")
     , testGoToDefinitionLink "test-suite other-modules Library" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 34 10) (toTestHaskellPath ("src" </> "test") "Library")
+                             (Position 34 10) ("src" </> "test" </> "Library.hs")
 
     , testGoToDefinitionLink "benchmark other-modules Config" ("goto-definition" </> "modules") "module-examples.cabal"
-                             (Position 45 30) (toTestHaskellPath ("src" </> "bench") "Config")
+                             (Position 45 30) ("src" </> "bench" </> "Config.hs")
 
     , testGoToDefinitionLinkNoLocation "not existent module" ("goto-definition" </> "modules") "module-examples.cabal" (Position 48 25)
     , testGoToDefinitionLinkNoLocation "behind module" ("goto-definition" </> "modules") "module-examples.cabal" (Position 9 20)
     , testGoToDefinitionLinkNoLocation "after module" ("goto-definition" </> "modules") "module-examples.cabal" (Position 9 50)
     ]
     where
-        toTestHaskellPath :: FilePath -> T.Text -> FilePath
-        toTestHaskellPath dir moduleName = dir </> toHaskellFile moduleName
-
         getUriFromDefinition :: Show b => (Definition |? b) -> Uri
         getUriFromDefinition (InL (Definition (InL loc))) = loc^.L.uri
         getUriFromDefinition unk = error $ "Unexpected pattern '" ++ show unk ++ "' , expected '(InL (Definition (InL loc))'"
@@ -66,13 +61,12 @@
                 doc <- openDoc cabalFile "cabal"
                 definitions <- getDefinitions doc cursorPos
                 let uri = getUriFromDefinition definitions
-                    mFilePath = (testDir </>) <$> uriToFilePath uri
-                case mFilePath of
+                case uriToFilePath uri of
                     Nothing -> error $ "Not possible to convert Uri " <> show uri <> " to FilePath"
                     Just filePath -> do
-                        let filePathWithDir = testDir </> expectedFilePath
-                            isCorrectPath = filePathWithDir `isSuffixOf` filePath
-                        liftIO $ isCorrectPath @? ("Absolute path expected to end on " <> filePathWithDir <>
+                        let
+                            isCorrectPath = expectedFilePath `isSuffixOf` filePath
+                        liftIO $ isCorrectPath @? ("Absolute path expected to end on " <> filePath <>
                                                    " but " <> filePath <> " was given.")
 
         testGoToDefinitionLinkNoLocation :: TestName -> FilePath -> FilePath -> Position -> TestTree
diff --git a/plugins/hls-cabal-plugin/test/Main.hs b/plugins/hls-cabal-plugin/test/Main.hs
--- a/plugins/hls-cabal-plugin/test/Main.hs
+++ b/plugins/hls-cabal-plugin/test/Main.hs
@@ -14,10 +14,9 @@
 import           Context                         (contextTests)
 import           Control.Lens                    ((^.))
 import           Control.Lens.Fold               ((^?))
-import           Control.Monad                   (guard)
+import           Control.Monad                   (forM_, guard)
 import qualified Data.ByteString                 as BS
 import           Data.Either                     (isRight)
-import           Data.List.Extra                 (nubOrdOn)
 import qualified Data.Maybe                      as Maybe
 import           Data.Text                       (Text)
 import qualified Data.Text                       as T
@@ -26,6 +25,7 @@
 import           Development.IDE.Test
 import           Ide.Plugin.Cabal.LicenseSuggest (licenseErrorSuggestion)
 import qualified Ide.Plugin.Cabal.Parse          as Lib
+import           Language.LSP.Protocol.Lens      (HasRange (..))
 import qualified Language.LSP.Protocol.Lens      as L
 import qualified Language.LSP.Protocol.Message   as L
 import           Outline                         (outlineTests)
@@ -191,32 +191,29 @@
                     , "    build-depends:    base"
                     , "    default-language: Haskell2010"
                     ]
-    , runCabalGoldenSession "Code Actions - Can fix field names" "code-actions" "FieldSuggestions" $ \doc -> do
-        _ <- waitForDiagnosticsFrom doc
-        cas <- Maybe.mapMaybe (^? _R) <$> getAllCodeActions doc
-        -- Filter out the code actions we want to invoke.
-        -- We only want to invoke Code Actions with certain titles, and
-        -- we want to invoke them only once, not once for each cursor request.
-        -- 'getAllCodeActions' iterates over each cursor position and requests code actions.
-        let selectedCas = nubOrdOn (^. L.title) $ filter
-                (\ca -> (ca ^. L.title) `elem`
-                    [ "Replace with license"
-                    , "Replace with build-type"
-                    , "Replace with extra-doc-files"
-                    , "Replace with ghc-options"
-                    , "Replace with location"
-                    , "Replace with default-language"
-                    , "Replace with import"
-                    , "Replace with build-depends"
-                    , "Replace with main-is"
-                    , "Replace with hs-source-dirs"
-                    ]) cas
-        mapM_ executeCodeAction selectedCas
-        pure ()
+    , runCabalGoldenSession
+        "Code Actions - Can complete field names"
+        "code-actions"
+        "FieldSuggestions"
+        executeFirstActionPerDiagnostic
+    , runCabalGoldenSession
+        "Code Actions - Can fix field typos"
+        "code-actions"
+        "FieldSuggestionsTypos"
+        executeFirstActionPerDiagnostic
     , cabalAddDependencyTests
     , cabalAddModuleTests
     ]
   where
+    executeFirstActionPerDiagnostic doc = do
+      _ <- waitForDiagnosticsFrom doc
+      diagnotics <- getCurrentDiagnostics doc
+      -- Execute the first code action at each diagnostic point
+      forM_ diagnotics $ \diagnostic -> do
+        codeActions <- getCodeActions doc (diagnostic ^. range)
+        case codeActions of
+          []     -> pure ()
+          ca : _ -> mapM_ executeCodeAction (ca ^? _R)
     getLicenseAction :: T.Text -> [Command |? CodeAction] -> [CodeAction]
     getLicenseAction license codeActions = do
         InR action@CodeAction{_title} <- codeActions
diff --git a/plugins/hls-cabal-plugin/test/Utils.hs b/plugins/hls-cabal-plugin/test/Utils.hs
--- a/plugins/hls-cabal-plugin/test/Utils.hs
+++ b/plugins/hls-cabal-plugin/test/Utils.hs
@@ -14,7 +14,7 @@
 import           Ide.Plugin.Cabal.Completion.Types
 import           System.FilePath
 import           Test.Hls
-import           Test.Hls.FileSystem               (VirtualFileTree)
+import qualified Test.Hls.FileSystem               as FS
 
 
 cabalPlugin :: PluginTestDescriptor Ide.Plugin.Cabal.Log
@@ -52,22 +52,22 @@
 runCabalTestCaseSession title subdir = testCase title . runCabalSession subdir
 
 runHaskellTestCaseSession :: TestName -> FilePath -> Session () -> TestTree
-runHaskellTestCaseSession title subdir = testCase title . runHaskellAndCabalSession subdir
+runHaskellTestCaseSession title subdir = testCase title . runHaskellAndCabalSession (FS.mkVirtualFileTree testDataDir [FS.copyDir subdir])
 
 runCabalSession :: FilePath -> Session a -> IO a
 runCabalSession subdir =
-    failIfSessionTimeout . runSessionWithServer def cabalPlugin (testDataDir </> subdir)
+    failIfSessionTimeout . runSessionWithServerInTmpDir def cabalPlugin (FS.mkVirtualFileTree testDataDir [FS.copyDir subdir])
 
-runCabalTestCaseSessionVft :: TestName -> VirtualFileTree -> Session () -> TestTree
+runCabalTestCaseSessionVft :: TestName -> FS.VirtualFileTree -> Session () -> TestTree
 runCabalTestCaseSessionVft title vft = testCase title . runCabalSessionVft vft
 
-runCabalSessionVft :: VirtualFileTree -> Session a -> IO a
+runCabalSessionVft :: FS.VirtualFileTree -> Session a -> IO a
 runCabalSessionVft vft =
     failIfSessionTimeout . runSessionWithServerInTmpDir def cabalPlugin vft
 
-runHaskellAndCabalSession :: FilePath -> Session a -> IO a
-runHaskellAndCabalSession subdir =
-    failIfSessionTimeout . runSessionWithServer def (cabalPlugin <> cabalHaskellPlugin) (testDataDir </> subdir)
+runHaskellAndCabalSession :: FS.VirtualFileTree -> Session a -> IO a
+runHaskellAndCabalSession vft =
+    failIfSessionTimeout . runSessionWithServerInTmpDir def (cabalPlugin <> cabalHaskellPlugin) vft
 
 runCabalGoldenSession :: TestName -> FilePath -> FilePath -> (TextDocumentIdentifier -> Session ()) -> TestTree
 runCabalGoldenSession title subdir fp act = goldenWithCabalDoc def cabalPlugin title testDataDir (subdir </> fp) "golden" "cabal" act
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/bench.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/bench.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/bench.cabal
@@ -0,0 +1,17 @@
+cabal-version:      2.4
+name:               cabal-add-bench
+version:            0.1.0.0
+license:            NONE
+author:             George Gerasev
+maintainer:         george30032002@gmail.com
+build-type:         Simple
+
+common warnings
+    ghc-options: -Wall
+
+benchmark benchmark
+    type: exitcode-stdio-1.0
+    ghc-options: -threaded
+    main-is: Main.hs
+    hs-source-dirs: bench
+    build-depends: base
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/bench/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/bench/Main.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Data.List.Split
+
+main :: IO ()
+main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/cabal.project
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/cabal.project
@@ -0,0 +1,1 @@
+packages: ./
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/hie.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/bench/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-bench/bench/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-bench/bench/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-bench/bench/Main.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Main (main) where
-
-import Data.List.Split
-
-main :: IO ()
-main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-bench/cabal-add-bench.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-bench/cabal-add-bench.cabal
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-bench/cabal-add-bench.cabal
+++ /dev/null
@@ -1,17 +0,0 @@
-cabal-version:      2.4
-name:               cabal-add-bench
-version:            0.1.0.0
-license:            NONE
-author:             George Gerasev
-maintainer:         george30032002@gmail.com
-build-type:         Simple
-
-common warnings
-    ghc-options: -Wall
-
-benchmark benchmark
-    type: exitcode-stdio-1.0
-    ghc-options: -threaded
-    main-is: Main.hs
-    hs-source-dirs: bench
-    build-depends: base
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-exe/cabal-add-exe.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-exe/cabal-add-exe.cabal
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-exe/cabal-add-exe.cabal
+++ /dev/null
@@ -1,15 +0,0 @@
-cabal-version:       2.4
-name:                cabal-add-exe
-version:             0.1.0.0
-build-type:          Simple
-
-executable cabal-add-exe
-  main-is:             Main.hs
-  hs-source-dirs:      src
-  ghc-options:         -Wall
-  build-depends:       base
-  default-language:    Haskell2010
-
-library
-  build-depends:   base >= 4 && < 5
-  ghc-options:     -Wall
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-exe/src/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-exe/src/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-exe/src/Main.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Main where
-
-import Data.List.Split
-
-main = putStrLn "Hello, Haskell!"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-lib/cabal-add-lib.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-lib/cabal-add-lib.cabal
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-lib/cabal-add-lib.cabal
+++ /dev/null
@@ -1,17 +0,0 @@
-cabal-version:      2.4
-name:               cabal-add-lib
-version:            0.1.0.0
-license:            NONE
-author:             George Gerasev
-maintainer:         george30032002@gmail.com
-build-type:         Simple
-
-common warnings
-    ghc-options: -Wall
-
-library
-    import:           warnings
-    exposed-modules:  MyLib
-    build-depends:    base
-    hs-source-dirs:   src
-    default-language: Haskell2010
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-lib/src/MyLib.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-lib/src/MyLib.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-lib/src/MyLib.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module MyLib (someFunc) where
-
-import Data.List.Split
-
-someFunc :: IO ()
-someFunc = putStrLn "someFunc"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/bench/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/bench/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/bench/Main.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Main (main) where
-
-import Data.List.Split
-
-main :: IO ()
-main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/cabal-add-multitarget.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/cabal-add-multitarget.cabal
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/cabal-add-multitarget.cabal
+++ /dev/null
@@ -1,33 +0,0 @@
-cabal-version:       2.4
-name:                cabal-add-multitarget
-version:             0.1.0.0
-build-type:          Simple
-
-executable cabal-add-exe
-    main-is:             Main.hs
-    hs-source-dirs:      src
-    ghc-options:         -Wall
-    build-depends:       base
-    default-language:    Haskell2010
-
-library
-    exposed-modules:     MyLib
-    other-modules:       InternalLib
-    build-depends:       base >= 4 && < 5
-    hs-source-dirs:      lib
-    ghc-options:         -Wall
-
-test-suite cabal-add-tests-test
-    main-is:             Main.hs
-    hs-source-dirs:      test
-    type:                exitcode-stdio-1.0
-    build-depends:       base
-    default-language:    Haskell2010
-
-benchmark benchmark
-    main-is:             Main.hs
-    build-depends:       base
-    hs-source-dirs:      bench
-    type:                exitcode-stdio-1.0
-    ghc-options:         -threaded
-
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/lib/InternalLib.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/lib/InternalLib.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/lib/InternalLib.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module InternalLib (internalFunc) where
-
-import Data.List.Split
-
-internalFunc :: IO ()
-internalFunc = putStrLn "internalFunc"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/lib/MyLib.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/lib/MyLib.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/lib/MyLib.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module MyLib (someFunc) where
-
-import Data.List.Split
-
-someFunc :: IO ()
-someFunc = putStrLn "someFunc"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/src/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/src/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/src/Main.hs
+++ /dev/null
@@ -1,5 +0,0 @@
-module Main where
-
-import Data.List.Split
-
-main = putStrLn "Hello, Haskell!"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/test/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/test/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-multitarget/test/Main.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Main (main) where
-
-import Data.List.Split
-
-main :: IO ()
-main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/cabal-add-packageYaml.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/cabal-add-packageYaml.cabal
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/cabal-add-packageYaml.cabal
+++ /dev/null
@@ -1,17 +0,0 @@
-cabal-version:      2.4
-name:               cabal-add-packageYaml
-version:            0.1.0.0
-license:            NONE
-author:             George Gerasev
-maintainer:         george30032002@gmail.com
-build-type:         Simple
-
-common warnings
-    ghc-options: -Wall
-
-benchmark benchmark-packageYaml
-    type: exitcode-stdio-1.0
-    ghc-options: -threaded
-    main-is: Main.hs
-    hs-source-dirs: bench
-    build-depends: base
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/package.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/package.yaml
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/package.yaml
+++ /dev/null
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/src/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/src/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-packageYaml/src/Main.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Main (main) where
-
-import Data.List.Split
-
-main :: IO ()
-main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/cabal-add-tests.cabal
+++ /dev/null
@@ -1,26 +0,0 @@
-cabal-version:      2.4
-name:               cabal-add-tests
-version:            0.1.0.0
-license:            NONE
-author:             George Gerasev
-maintainer:         george30032002@gmail.com
-build-type:         Simple
-
-common warnings
-    ghc-options: -Wall
-
-test-suite cabal-add-tests-test
-    import:           warnings
-    default-language: Haskell2010
-    type:             exitcode-stdio-1.0
-    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
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/Main.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/Main.hs
+++ /dev/null
@@ -1,6 +0,0 @@
-module Main (main) where
-
-import Data.List.Split
-
-main :: IO ()
-main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal-add-tests/test/MainPackageImports.hs
+++ /dev/null
@@ -1,8 +0,0 @@
-{-# LANGUAGE PackageImports #-}
-
-module Main (main) where
-
-import "split" Data.List.Split
-
-main :: IO ()
-main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal.project
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/cabal.project
+++ /dev/null
@@ -1,6 +0,0 @@
-packages: cabal-add-exe
-          cabal-add-lib
-          cabal-add-tests
-          cabal-add-bench
-          cabal-add-multitarget
-          cabal-add-packageYaml
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/cabal.project
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/cabal.project
@@ -0,0 +1,1 @@
+packages: ./
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/exe.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/exe.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/exe.cabal
@@ -0,0 +1,15 @@
+cabal-version:       2.4
+name:                cabal-add-exe
+version:             0.1.0.0
+build-type:          Simple
+
+executable cabal-add-exe
+  main-is:             Main.hs
+  hs-source-dirs:      src
+  ghc-options:         -Wall
+  build-depends:       base
+  default-language:    Haskell2010
+
+library
+  build-depends:   base >= 4 && < 5
+  ghc-options:     -Wall
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/hie.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/src/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/exe/src/Main.hs
@@ -0,0 +1,5 @@
+module Main where
+
+import Data.List.Split
+
+main = putStrLn "Hello, Haskell!"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/hie.yaml
deleted file mode 100644
--- a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/hie.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-cradle:
-  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/cabal.project
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/cabal.project
@@ -0,0 +1,1 @@
+packages: ./
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/hie.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/lib.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/lib.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/lib.cabal
@@ -0,0 +1,17 @@
+cabal-version:      2.4
+name:               cabal-add-lib
+version:            0.1.0.0
+license:            NONE
+author:             George Gerasev
+maintainer:         george30032002@gmail.com
+build-type:         Simple
+
+common warnings
+    ghc-options: -Wall
+
+library
+    import:           warnings
+    exposed-modules:  MyLib
+    build-depends:    base
+    hs-source-dirs:   src
+    default-language: Haskell2010
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/src/MyLib.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/src/MyLib.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/lib/src/MyLib.hs
@@ -0,0 +1,6 @@
+module MyLib (someFunc) where
+
+import Data.List.Split
+
+someFunc :: IO ()
+someFunc = putStrLn "someFunc"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/bench/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/bench/Main.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Data.List.Split
+
+main :: IO ()
+main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/cabal.project
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/cabal.project
@@ -0,0 +1,1 @@
+packages: ./
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/hie.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/lib/InternalLib.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/lib/InternalLib.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/lib/InternalLib.hs
@@ -0,0 +1,6 @@
+module InternalLib (internalFunc) where
+
+import Data.List.Split
+
+internalFunc :: IO ()
+internalFunc = putStrLn "internalFunc"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/lib/MyLib.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/lib/MyLib.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/lib/MyLib.hs
@@ -0,0 +1,6 @@
+module MyLib (someFunc) where
+
+import Data.List.Split
+
+someFunc :: IO ()
+someFunc = putStrLn "someFunc"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/multitarget.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/multitarget.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/multitarget.cabal
@@ -0,0 +1,33 @@
+cabal-version:       2.4
+name:                cabal-add-multitarget
+version:             0.1.0.0
+build-type:          Simple
+
+executable cabal-add-exe
+    main-is:             Main.hs
+    hs-source-dirs:      src
+    ghc-options:         -Wall
+    build-depends:       base
+    default-language:    Haskell2010
+
+library
+    exposed-modules:     MyLib
+    other-modules:       InternalLib
+    build-depends:       base >= 4 && < 5
+    hs-source-dirs:      lib
+    ghc-options:         -Wall
+
+test-suite cabal-add-tests-test
+    main-is:             Main.hs
+    hs-source-dirs:      test
+    type:                exitcode-stdio-1.0
+    build-depends:       base
+    default-language:    Haskell2010
+
+benchmark benchmark
+    main-is:             Main.hs
+    build-depends:       base
+    hs-source-dirs:      bench
+    type:                exitcode-stdio-1.0
+    ghc-options:         -threaded
+
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/src/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/src/Main.hs
@@ -0,0 +1,5 @@
+module Main where
+
+import Data.List.Split
+
+main = putStrLn "Hello, Haskell!"
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/test/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/multitarget/test/Main.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Data.List.Split
+
+main :: IO ()
+main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/cabal.project
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/cabal.project
@@ -0,0 +1,1 @@
+packages: ./
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/hie.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/package.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/package.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/package.yaml
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/packageYaml.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/packageYaml.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/packageYaml.cabal
@@ -0,0 +1,17 @@
+cabal-version:      2.4
+name:               cabal-add-packageYaml
+version:            0.1.0.0
+license:            NONE
+author:             George Gerasev
+maintainer:         george30032002@gmail.com
+build-type:         Simple
+
+common warnings
+    ghc-options: -Wall
+
+benchmark benchmark-packageYaml
+    type: exitcode-stdio-1.0
+    ghc-options: -threaded
+    main-is: Main.hs
+    hs-source-dirs: bench
+    build-depends: base
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/src/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/src/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/packageYaml/src/Main.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Data.List.Split
+
+main :: IO ()
+main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/cabal.project b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/cabal.project
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/cabal.project
@@ -0,0 +1,1 @@
+packages: ./
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/hie.yaml b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/hie.yaml
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/hie.yaml
@@ -0,0 +1,2 @@
+cradle:
+  cabal:
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/test/Main.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/test/Main.hs
@@ -0,0 +1,6 @@
+module Main (main) where
+
+import Data.List.Split
+
+main :: IO ()
+main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/test/MainPackageImports.hs b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/test/MainPackageImports.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/test/MainPackageImports.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE PackageImports #-}
+
+module Main (main) where
+
+import "split" Data.List.Split
+
+main :: IO ()
+main = putStrLn "Test suite not yet implemented."
diff --git a/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/tests.cabal b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/tests.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/cabal-add-testdata/tests/tests.cabal
@@ -0,0 +1,26 @@
+cabal-version:      2.4
+name:               cabal-add-tests
+version:            0.1.0.0
+license:            NONE
+author:             George Gerasev
+maintainer:         george30032002@gmail.com
+build-type:         Simple
+
+common warnings
+    ghc-options: -Wall
+
+test-suite cabal-add-tests-test
+    import:           warnings
+    default-language: Haskell2010
+    type:             exitcode-stdio-1.0
+    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
diff --git a/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.cabal b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.cabal
--- a/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.cabal
+++ b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.cabal
@@ -21,9 +21,8 @@
   loc: fake
 
 library
-    default-lang: Haskell2010
-    -- Import isn't supported right now.
     impor: warnings
+    default-lang: Haskell2010
     build-dep: base
 
 executable my-exe
diff --git a/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.golden.cabal b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.golden.cabal
--- a/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.golden.cabal
+++ b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestions.golden.cabal
@@ -21,9 +21,8 @@
   location: fake
 
 library
-    default-language: Haskell2010
-    -- Import isn't supported right now.
     import: warnings
+    default-language: Haskell2010
     build-depends: base
 
 executable my-exe
diff --git a/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestionsTypos.cabal b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestionsTypos.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestionsTypos.cabal
@@ -0,0 +1,35 @@
+cabal-version: 3.0
+name: FieldSuggestions
+version: 0.1.0
+liqns:            BSD-3-Clause
+
+quil-type: Simple
+
+qqxtra-doc-fils:
+    ChangeLog
+
+-- Default warnings in HLS
+common warnings
+  ghq-option: -Wall
+               -Wredundant-constraints
+               -Wunused-packages
+               -Wno-name-shadowing
+               -Wno-unticked-promoted-constructors
+
+source-repository head
+  type:     git
+  locqt: fake
+
+library
+    iqqor: warnings
+    qqjfault-lang: Haskell2010
+    bqqld-dep: base
+
+executable my-exe
+    mbn-is: Main.hs
+
+test-suite Test
+    type: exitcode-stdio-1.0
+    main-is: Test.hs
+    hqqqsource-drs:
+
diff --git a/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestionsTypos.golden.cabal b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestionsTypos.golden.cabal
new file mode 100644
--- /dev/null
+++ b/plugins/hls-cabal-plugin/test/testdata/code-actions/FieldSuggestionsTypos.golden.cabal
@@ -0,0 +1,35 @@
+cabal-version: 3.0
+name: FieldSuggestions
+version: 0.1.0
+license:            BSD-3-Clause
+
+build-type: Simple
+
+extra-doc-files:
+    ChangeLog
+
+-- Default warnings in HLS
+common warnings
+  ghc-options: -Wall
+               -Wredundant-constraints
+               -Wunused-packages
+               -Wno-name-shadowing
+               -Wno-unticked-promoted-constructors
+
+source-repository head
+  type:     git
+  location: fake
+
+library
+    import: warnings
+    default-language: Haskell2010
+    build-depends: base
+
+executable my-exe
+    main-is: Main.hs
+
+test-suite Test
+    type: exitcode-stdio-1.0
+    main-is: Test.hs
+    hs-source-dirs:
+
diff --git a/plugins/hls-change-type-signature-plugin/src/Ide/Plugin/ChangeTypeSignature.hs b/plugins/hls-change-type-signature-plugin/src/Ide/Plugin/ChangeTypeSignature.hs
--- a/plugins/hls-change-type-signature-plugin/src/Ide/Plugin/ChangeTypeSignature.hs
+++ b/plugins/hls-change-type-signature-plugin/src/Ide/Plugin/ChangeTypeSignature.hs
@@ -42,6 +42,10 @@
 import           Generics.SYB                      (extQ, something)
 import           GHC.Tc.Errors.Types               (ErrInfo (..),
                                                     TcRnMessageDetailed (..))
+#if MIN_VERSION_ghc(9,13,0)
+import           GHC.Tc.Errors.Ppr                 (pprErrCtxtMsg)
+import           GHC.Utils.Outputable              (vcat)
+#endif
 import qualified Ide.Logger                        as Logger
 import           Ide.Plugin.Error                  (PluginError,
                                                     getNormalizedFilePathE)
@@ -61,8 +65,13 @@
 
 instance Pretty Log where
     pretty = \case
+#if MIN_VERSION_ghc(9,13,0)
+        LogErrInfoCtxt (ErrInfo ctxt _ _) ->
+            fromSDoc (vcat $ map pprErrCtxtMsg ctxt)
+#else
         LogErrInfoCtxt (ErrInfo ctxt suppl) ->
             Logger.vcat [fromSDoc ctxt, fromSDoc suppl]
+#endif
         LogFindSigLocFailure name ->
             pretty ("Lookup signature location failure: " <> name)
         where
@@ -175,7 +184,11 @@
         unwrapMatch (_, _, _, [name]) = Just name
         unwrapMatch _                 = Nothing
 
+#if MIN_VERSION_ghc(9,13,0)
+        errInfoTxt = printOutputable (vcat $ map pprErrCtxtMsg errInfoContext)
+#else
         errInfoTxt = printOutputable errInfoContext
+#endif
 
 -- | List of regexes that match various Error Messages
 errorMessageRegexes :: [Text]
diff --git a/plugins/hls-change-type-signature-plugin/test/Main.hs b/plugins/hls-change-type-signature-plugin/test/Main.hs
--- a/plugins/hls-change-type-signature-plugin/test/Main.hs
+++ b/plugins/hls-change-type-signature-plugin/test/Main.hs
@@ -41,7 +41,7 @@
 test = testGroup "changeTypeSignature" [
         testRegexes
         , codeActionTest "TExpectedActual" 4 11
-        , knownBrokenForGhcVersions [GHC96 .. GHC912] "Error Message in 9.6+ does not provide enough info" $
+        , knownBrokenForGhcVersions [GHC96 .. GHC914] "Error Message in 9.6+ does not provide enough info" $
             codeActionTest "TRigidType" 4 14
         , codeActionTest "TRigidType2" 4 8
         , codeActionTest "TLocalBinding" 7 22
diff --git a/plugins/hls-class-plugin/src/Ide/Plugin/Class/CodeAction.hs b/plugins/hls-class-plugin/src/Ide/Plugin/Class/CodeAction.hs
--- a/plugins/hls-class-plugin/src/Ide/Plugin/Class/CodeAction.hs
+++ b/plugins/hls-class-plugin/src/Ide/Plugin/Class/CodeAction.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP             #-}
 {-# LANGUAGE GADTs           #-}
 {-# LANGUAGE LambdaCase      #-}
 {-# LANGUAGE OverloadedLists #-}
@@ -225,14 +226,18 @@
 signatureToName sig = T.drop (T.length bindingPrefix) (printOutputable (bindName sig))
 
 -- Return [groupName text, [(methodName text, signature text)]]
-minDefToMethodGroups :: HscEnv -> TcGblEnv -> Range -> [InstanceBindTypeSig] -> BooleanFormula Name -> [MethodGroup]
+minDefToMethodGroups :: HscEnv -> TcGblEnv -> Range -> [InstanceBindTypeSig] -> ClassMinimalDef -> [MethodGroup]
 minDefToMethodGroups hsc gblEnv range sigs minDef = makeMethodGroup <$> go minDef
     where
         makeMethodGroup methodDefinitions =
             let name = mconcat $ intersperse "," $ (\x -> "'" <> x <> "'") . fst <$> methodDefinitions
             in  (name, methodDefinitions)
 
+#if __GLASGOW_HASKELL__ >= 913
+        go (Var lmn)  = pure $ makeMethodDefinitions hsc gblEnv range $ filter ((==) (printOutputable (unLoc lmn)) . signatureToName) sigs
+#else
         go (Var mn)   = pure $ makeMethodDefinitions hsc gblEnv range $ filter ((==) (printOutputable mn) . signatureToName) sigs
+#endif
         go (Or ms)    = concatMap (go . unLoc) ms
         go (And ms)   = foldr (liftA2 (<>) . go . unLoc) [[]] ms
         go (Parens m) = go (unLoc m)
diff --git a/plugins/hls-class-plugin/test/Main.hs b/plugins/hls-class-plugin/test/Main.hs
--- a/plugins/hls-class-plugin/test/Main.hs
+++ b/plugins/hls-class-plugin/test/Main.hs
@@ -11,6 +11,7 @@
                                                 (^..), (^?))
 import           Control.Monad                 (void)
 import           Data.Foldable                 (find)
+import qualified Data.List                     as List
 import           Data.Maybe
 import qualified Data.Text                     as T
 import qualified Ide.Plugin.Class              as Class
@@ -109,9 +110,9 @@
             doc <- openDoc "CodeLensSimple.hs" "haskell"
             lens <- getAndResolveCodeLenses doc
             let titles = map (^. L.title) $ mapMaybe (^. L.command) lens
-            liftIO $ titles @?=
-                [ "(==) :: B -> B -> Bool"
-                , "(==) :: A -> A -> Bool"
+            liftIO $ List.sort titles @?=
+                [ "(==) :: A -> A -> Bool"
+                , "(==) :: B -> B -> Bool"
                 ]
     , testCase "No lens for TH" $ do
         runSessionWithServer def classPlugin testDataDir $ do
@@ -129,7 +130,7 @@
             liftIO $ length lens > 0 @?= True
         `catch` \(e :: SessionException) -> do
           liftIO $ assertFailure $ "classPluginTestError: "++ show e
-    , goldenCodeLens "Apply code lens" "CodeLensSimple" 1
+    , goldenCodeLens "Apply code lens" "CodeLensSimple" 0
     , goldenCodeLens "Apply code lens for local class" "LocalClassDefine" 0
     , goldenCodeLens "Apply code lens on the same line" "Inline" 0
     , goldenCodeLens "Don't insert pragma while existing" "CodeLensWithPragma" 0
@@ -155,7 +156,7 @@
 goldenCodeLens title path idx =
     goldenWithHaskellDoc def classPlugin title testDataDir path "expected" "hs" $ \doc -> do
         lens <- getAndResolveCodeLenses doc
-        executeCommand $ fromJust $ (lens !! idx) ^. L.command
+        executeCommand $ fromJust $ (List.sort lens !! idx) ^. L.command
         void $ skipManyTill anyMessage (message SMethod_WorkspaceApplyEdit)
 
 goldenWithClass ::TestName -> FilePath -> FilePath -> ([CodeAction] -> Session CodeAction) -> TestTree
diff --git a/plugins/hls-eval-plugin/src/Ide/Plugin/Eval/Handlers.hs b/plugins/hls-eval-plugin/src/Ide/Plugin/Eval/Handlers.hs
--- a/plugins/hls-eval-plugin/src/Ide/Plugin/Eval/Handlers.hs
+++ b/plugins/hls-eval-plugin/src/Ide/Plugin/Eval/Handlers.hs
@@ -87,6 +87,12 @@
 import           Development.IDE.Core.PluginUtils
 import           Development.IDE.Types.Shake                  (toKey)
 import           GHC.Types.SrcLoc                             (UnhelpfulSpanReason (UnhelpfulInteractive))
+#if MIN_VERSION_ghc(9,13,0)
+import           GHC.Types.Avail                              (DetOrdAvails (DefinitelyDeterministicAvails),
+                                                               sortAvails)
+import           GHC.Tc.Types                                 (tcg_exports)
+import           GHC.Types.Name.Set                           (nameSetElemsStable)
+#endif
 import           Ide.Logger                                   (Priority (..),
                                                                Recorder,
                                                                WithPriority,
@@ -262,11 +268,12 @@
     -- 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)
+#if MIN_VERSION_ghc(9,13,0)
+          = hmi { hm_iface = set_mi_top_env (IfaceTopEnv (sortAvails $ gresToAvailInfo $ globalRdrEnvElts $ globalRdrEnvLocal rdr_env) (mkIfaceImports $ tcg_import_decls tm)) iface}
+#elif 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 $!
@@ -277,12 +284,20 @@
                 }}
 #endif
           | otherwise = hmi
-
+#if MIN_VERSION_ghc(9,13,0)
+    linkable_hsc <- liftIO $ loadModulesHome (map (addRdrEnv . linkableHomeMod) linkables) deps_hsc
+#else
+    let linkable_hsc = loadModulesHome (map (addRdrEnv . linkableHomeMod) linkables) deps_hsc
+#endif
     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
+#if MIN_VERSION_ghc(9,13,0)
+            setContext [Compat.IIModule (ms_mod ms)]
+#else
             setContext [Compat.IIModule (moduleName (ms_mod ms))]
+#endif
             let df = flip xopt_set    LangExt.ExtendedDefaultRules
                    . flip xopt_unset  LangExt.MonomorphismRestriction
                    . flip gopt_set    Opt_ImplicitImportQualified
@@ -296,11 +311,18 @@
             getSession
   return env2
 
-#if MIN_VERSION_ghc(9,11,0)
+#if MIN_VERSION_ghc(9,13,0)
 mkIfaceImports :: [ImportUserSpec] -> [IfaceImport]
 mkIfaceImports = map go
   where
     go (ImpUserSpec decl ImpUserAll) = IfaceImport decl ImpIfaceAll
+    go (ImpUserSpec decl (ImpUserExplicit avails parents)) = IfaceImport decl (ImpIfaceExplicit (DefinitelyDeterministicAvails avails) (nameSetElemsStable parents))
+    go (ImpUserSpec decl (ImpUserEverythingBut ns)) = IfaceImport decl (ImpIfaceEverythingBut (nameSetElemsStable ns))
+#elif 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
@@ -463,10 +485,18 @@
             dbg $ LogEvalFlags flags
             ndf <- getInteractiveDynFlags
             dbg $ LogEvalPreSetDynFlags ndf
+#if MIN_VERSION_ghc(9,13,0)
+            hsc_env <- getSession
             eans <-
                 liftIO $ try @GhcException $
+                parseDynamicFlagsCmdLine (hsc_logger hsc_env) ndf
+                    (map (L $ UnhelpfulSpan unhelpfulReason) flags)
+#else
+            eans <-
+                liftIO $ try @GhcException $
                 parseDynamicFlagsCmdLine ndf
                 (map (L $ UnhelpfulSpan unhelpfulReason) flags)
+#endif
             dbg $ LogEvalParsedFlags eans
             case eans of
                 Left err -> pure $ Just $ errorLines $ show err
diff --git a/plugins/hls-eval-plugin/test/Main.hs b/plugins/hls-eval-plugin/test/Main.hs
--- a/plugins/hls-eval-plugin/test/Main.hs
+++ b/plugins/hls-eval-plugin/test/Main.hs
@@ -133,6 +133,7 @@
   , knownBrokenInWindowsBeforeGHC912 "The output has path separators in it, which on Windows look different. Just skip it there" $
       goldenWithEvalAndFs' "Property checking with exception" cabalProjectFS "TPropertyError" "hs" $
         case ghcVersion of
+          GHC914 -> "ghc914.expected"
           GHC912 -> "ghc912.expected"
           GHC910 -> "ghc910.expected"
           GHC98  -> "ghc98.expected"
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/info-util-0.1.0.0/build/autogen/PackageInfo_info_util.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/info-util-0.1.0.0/build/autogen/PackageInfo_info_util.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/info-util-0.1.0.0/build/autogen/PackageInfo_info_util.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : PackageInfo_info_util
+Description : Contents of some of the package's Cabal file's fields.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports values that record information from some of the fields of
+the package's Cabal package description file (Cabal file).
+
+For further information about the fields in a Cabal file, see the Cabal User
+Guide.
+-}
+
+module PackageInfo_info_util (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+-- |The content of the @name@ field of the package's Cabal file, but with any
+-- hyphen characters replaced by underscore characters.
+name :: String
+name = "info_util"
+-- |The content of the @version@ field of the package's Cabal file.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |The content of the @synopsis@ field of the package's Cabal file.
+synopsis :: String
+synopsis = ""
+-- |The content of the @copyright@ field of the package's Cabal file.
+copyright :: String
+copyright = "2017 Author name here"
+-- |The content of the @homepage@ field of the package's Cabal file.
+homepage :: String
+homepage = ""
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/info-util-0.1.0.0/build/autogen/Paths_info_util.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/info-util-0.1.0.0/build/autogen/Paths_info_util.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/info-util-0.1.0.0/build/autogen/Paths_info_util.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : Paths_info_util
+Description : Data file location, and package version and installation
+              directories.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports a function to locate data files, and values that record
+the version of the package and some directories which the package has been
+configured to be installed into.
+
+For further information about Cabal's options for its configuration step, and
+their default values, see the Cabal User Guide.
+-}
+
+module Paths_info_util (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+-- |The package version.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |If the argument is a filename, the result is the name of a corresponding
+-- file on the system on which the program is running, if the file were listed
+-- in the @data-files@ field of the package's Cabal package description file.
+-- No check is performed that the given filename is listed in that field.
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable info_util_bindir.
+getBinDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable info_util_libdir.
+getLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable info_util_dynlibdir.
+getDynLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable info_util_datadir.
+getDataDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable info_util_libexedir.
+getLibexecDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable info_util_sysconfdir.
+getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c/info-util-0.1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.10.3-415c/info-util-0.1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.10.3-415c/info-util-0.1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "info_util_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "info_util_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "info_util_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "info_util_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "info_util_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "info_util_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir@(c:cs) fname
+  | isPathSeparator (lastChar c cs) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+ where
+  -- We do not use Data.List.NonEmpty.last, as that would limit the module to
+  -- base >= 4.9.0.0 (GHC >= 8.0.1).
+  lastChar x [] = x
+  lastChar _ (x:xs) = lastChar x xs
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/test-0.1.0.0/build/autogen/PackageInfo_test.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/test-0.1.0.0/build/autogen/PackageInfo_test.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/test-0.1.0.0/build/autogen/PackageInfo_test.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : PackageInfo_test
+Description : Contents of some of the package's Cabal file's fields.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports values that record information from some of the fields of
+the package's Cabal package description file (Cabal file).
+
+For further information about the fields in a Cabal file, see the Cabal User
+Guide.
+-}
+
+module PackageInfo_test (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+-- |The content of the @name@ field of the package's Cabal file, but with any
+-- hyphen characters replaced by underscore characters.
+name :: String
+name = "test"
+-- |The content of the @version@ field of the package's Cabal file.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |The content of the @synopsis@ field of the package's Cabal file.
+synopsis :: String
+synopsis = ""
+-- |The content of the @copyright@ field of the package's Cabal file.
+copyright :: String
+copyright = "2017 Author name here"
+-- |The content of the @homepage@ field of the package's Cabal file.
+homepage :: String
+homepage = ""
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/test-0.1.0.0/build/autogen/Paths_test.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/test-0.1.0.0/build/autogen/Paths_test.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.10.3/test-0.1.0.0/build/autogen/Paths_test.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : Paths_test
+Description : Data file location, and package version and installation
+              directories.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports a function to locate data files, and values that record
+the version of the package and some directories which the package has been
+configured to be installed into.
+
+For further information about Cabal's options for its configuration step, and
+their default values, see the Cabal User Guide.
+-}
+
+module Paths_test (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+-- |The package version.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |If the argument is a filename, the result is the name of a corresponding
+-- file on the system on which the program is running, if the file were listed
+-- in the @data-files@ field of the package's Cabal package description file.
+-- No check is performed that the given filename is listed in that field.
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable test_bindir.
+getBinDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable test_libdir.
+getLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable test_dynlibdir.
+getDynLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable test_datadir.
+getDataDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable test_libexedir.
+getLibexecDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable test_sysconfdir.
+getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c/test-0.1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.10.3-415c"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.10.3-415c/test-0.1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.10.3-415c/test-0.1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "test_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "test_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "test_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "test_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "test_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "test_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir@(c:cs) fname
+  | isPathSeparator (lastChar c cs) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+ where
+  -- We do not use Data.List.NonEmpty.last, as that would limit the module to
+  -- base >= 4.9.0.0 (GHC >= 8.0.1).
+  lastChar x [] = x
+  lastChar _ (x:xs) = lastChar x xs
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/info-util-0.1.0.0/build/autogen/PackageInfo_info_util.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/info-util-0.1.0.0/build/autogen/PackageInfo_info_util.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/info-util-0.1.0.0/build/autogen/PackageInfo_info_util.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : PackageInfo_info_util
+Description : Contents of some of the package's Cabal file's fields.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports values that record information from some of the fields of
+the package's Cabal package description file (Cabal file).
+
+For further information about the fields in a Cabal file, see the Cabal User
+Guide.
+-}
+
+module PackageInfo_info_util (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+-- |The content of the @name@ field of the package's Cabal file, but with any
+-- hyphen characters replaced by underscore characters.
+name :: String
+name = "info_util"
+-- |The content of the @version@ field of the package's Cabal file.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |The content of the @synopsis@ field of the package's Cabal file.
+synopsis :: String
+synopsis = ""
+-- |The content of the @copyright@ field of the package's Cabal file.
+copyright :: String
+copyright = "2017 Author name here"
+-- |The content of the @homepage@ field of the package's Cabal file.
+homepage :: String
+homepage = ""
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/info-util-0.1.0.0/build/autogen/Paths_info_util.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/info-util-0.1.0.0/build/autogen/Paths_info_util.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/info-util-0.1.0.0/build/autogen/Paths_info_util.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : Paths_info_util
+Description : Data file location, and package version and installation
+              directories.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports a function to locate data files, and values that record
+the version of the package and some directories which the package has been
+configured to be installed into.
+
+For further information about Cabal's options for its configuration step, and
+their default values, see the Cabal User Guide.
+-}
+
+module Paths_info_util (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+-- |The package version.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |If the argument is a filename, the result is the name of a corresponding
+-- file on the system on which the program is running, if the file were listed
+-- in the @data-files@ field of the package's Cabal package description file.
+-- No check is performed that the given filename is listed in that field.
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable info_util_bindir.
+getBinDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable info_util_libdir.
+getLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable info_util_dynlibdir.
+getDynLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable info_util_datadir.
+getDataDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable info_util_libexedir.
+getLibexecDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable info_util_sysconfdir.
+getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.14.1-ade7/info-util-0.1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.14.1-ade7"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.14.1-ade7/info-util-0.1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.14.1-ade7/info-util-0.1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "info_util_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "info_util_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "info_util_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "info_util_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "info_util_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "info_util_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir@(c:cs) fname
+  | isPathSeparator (lastChar c cs) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+ where
+  -- We do not use Data.List.NonEmpty.last, as that would limit the module to
+  -- base >= 4.9.0.0 (GHC >= 8.0.1).
+  lastChar x [] = x
+  lastChar _ (x:xs) = lastChar x xs
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/test-0.1.0.0/build/autogen/PackageInfo_test.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/test-0.1.0.0/build/autogen/PackageInfo_test.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/test-0.1.0.0/build/autogen/PackageInfo_test.hs
@@ -0,0 +1,46 @@
+{-# LANGUAGE NoRebindableSyntax #-}
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : PackageInfo_test
+Description : Contents of some of the package's Cabal file's fields.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports values that record information from some of the fields of
+the package's Cabal package description file (Cabal file).
+
+For further information about the fields in a Cabal file, see the Cabal User
+Guide.
+-}
+
+module PackageInfo_test (
+    name,
+    version,
+    synopsis,
+    copyright,
+    homepage,
+  ) where
+
+import Data.Version (Version(..))
+import Prelude
+
+-- |The content of the @name@ field of the package's Cabal file, but with any
+-- hyphen characters replaced by underscore characters.
+name :: String
+name = "test"
+-- |The content of the @version@ field of the package's Cabal file.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |The content of the @synopsis@ field of the package's Cabal file.
+synopsis :: String
+synopsis = ""
+-- |The content of the @copyright@ field of the package's Cabal file.
+copyright :: String
+copyright = "2017 Author name here"
+-- |The content of the @homepage@ field of the package's Cabal file.
+homepage :: String
+homepage = ""
diff --git a/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/test-0.1.0.0/build/autogen/Paths_test.hs b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/test-0.1.0.0/build/autogen/Paths_test.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/dist-newstyle/build/x86_64-linux/ghc-9.14.1/test-0.1.0.0/build/autogen/Paths_test.hs
@@ -0,0 +1,132 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE NoRebindableSyntax #-}
+#if __GLASGOW_HASKELL__ >= 810
+{-# OPTIONS_GHC -Wno-prepositive-qualified-module #-}
+#endif
+{-# OPTIONS_GHC -Wno-missing-import-lists #-}
+{-# OPTIONS_GHC -w #-}
+
+{-|
+Module      : Paths_test
+Description : Data file location, and package version and installation
+              directories.
+
+WARNING: This module was generated by Cabal. Any modifications will be
+overwritten if the module is regenerated.
+
+This module exports a function to locate data files, and values that record
+the version of the package and some directories which the package has been
+configured to be installed into.
+
+For further information about Cabal's options for its configuration step, and
+their default values, see the Cabal User Guide.
+-}
+
+module Paths_test (
+    version,
+    getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,
+    getDataFileName, getSysconfDir
+  ) where
+
+
+import qualified Control.Exception as Exception
+import Data.Version (Version(..))
+import System.Environment (getEnv)
+import Prelude
+
+
+#if defined(VERSION_base)
+
+#if MIN_VERSION_base(4,0,0)
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#else
+catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a
+#endif
+
+#else
+catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a
+#endif
+catchIO = Exception.catch
+
+-- |The package version.
+version :: Version
+version = Version [0,1,0,0] []
+
+-- |If the argument is a filename, the result is the name of a corresponding
+-- file on the system on which the program is running, if the file were listed
+-- in the @data-files@ field of the package's Cabal package description file.
+-- No check is performed that the given filename is listed in that field.
+getDataFileName :: FilePath -> IO FilePath
+getDataFileName name = do
+  dir <- getDataDir
+  return (dir `joinFileName` name)
+
+-- |The location of the directory specified by Cabal's @--bindir@ option (where
+-- executables that the user might invoke are installed). This can be overridden
+-- at runtime using the environment variable test_bindir.
+getBinDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libdir@ option (where
+-- object libraries are installed). This can be overridden at runtime using the
+-- environment variable test_libdir.
+getLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--dynlibdir@ option
+-- (where dynamic libraries are installed). This can be overridden at runtime
+-- using the environment variable test_dynlibdir.
+getDynLibDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--datadir@ option (where
+-- architecture-independent data files are installed). This can be overridden at
+-- runtime using the environment variable test_datadir.
+getDataDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--libexedir@ option
+-- (where executables that are not expected to be invoked directly by the user
+-- are installed). This can be overridden at runtime using the environment
+-- variable test_libexedir.
+getLibexecDir :: IO FilePath
+
+-- |The location of the directory specified by Cabal's @--sysconfdir@ option
+-- (where configuration files are installed). This can be overridden at runtime
+-- using the environment variable test_sysconfdir.
+getSysconfDir :: IO FilePath
+
+
+
+
+bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath
+bindir     = "/home/hugin/.cabal/bin"
+libdir     = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.14.1-ade7/test-0.1.0.0-inplace"
+dynlibdir  = "/home/hugin/.cabal/lib/x86_64-linux-ghc-9.14.1-ade7"
+datadir    = "/home/hugin/.cabal/share/x86_64-linux-ghc-9.14.1-ade7/test-0.1.0.0"
+libexecdir = "/home/hugin/.cabal/libexec/x86_64-linux-ghc-9.14.1-ade7/test-0.1.0.0"
+sysconfdir = "/home/hugin/.cabal/etc"
+
+getBinDir     = catchIO (getEnv "test_bindir")     (\_ -> return bindir)
+getLibDir     = catchIO (getEnv "test_libdir")     (\_ -> return libdir)
+getDynLibDir  = catchIO (getEnv "test_dynlibdir")  (\_ -> return dynlibdir)
+getDataDir    = catchIO (getEnv "test_datadir")    (\_ -> return datadir)
+getLibexecDir = catchIO (getEnv "test_libexecdir") (\_ -> return libexecdir)
+getSysconfDir = catchIO (getEnv "test_sysconfdir") (\_ -> return sysconfdir)
+
+
+
+joinFileName :: String -> String -> FilePath
+joinFileName ""  fname = fname
+joinFileName "." fname = fname
+joinFileName dir ""    = dir
+joinFileName dir@(c:cs) fname
+  | isPathSeparator (lastChar c cs) = dir ++ fname
+  | otherwise                       = dir ++ pathSeparator : fname
+ where
+  -- We do not use Data.List.NonEmpty.last, as that would limit the module to
+  -- base >= 4.9.0.0 (GHC >= 8.0.1).
+  lastChar x [] = x
+  lastChar _ (x:xs) = lastChar x xs
+
+pathSeparator :: Char
+pathSeparator = '/'
+
+isPathSeparator :: Char -> Bool
+isPathSeparator c = c == '/'
diff --git a/plugins/hls-eval-plugin/test/testdata/TPropertyError.ghc914.expected.hs b/plugins/hls-eval-plugin/test/testdata/TPropertyError.ghc914.expected.hs
new file mode 100644
--- /dev/null
+++ b/plugins/hls-eval-plugin/test/testdata/TPropertyError.ghc914.expected.hs
@@ -0,0 +1,6 @@
+-- Support for property checking
+module TProperty where
+
+-- prop> \(l::[Bool]) -> head l
+-- *** Failed! Exception: 'Prelude.head: empty list' (after 1 test):
+-- []
diff --git a/plugins/hls-explicit-fixity-plugin/src/Ide/Plugin/ExplicitFixity.hs b/plugins/hls-explicit-fixity-plugin/src/Ide/Plugin/ExplicitFixity.hs
--- a/plugins/hls-explicit-fixity-plugin/src/Ide/Plugin/ExplicitFixity.hs
+++ b/plugins/hls-explicit-fixity-plugin/src/Ide/Plugin/ExplicitFixity.hs
@@ -75,8 +75,10 @@
 instance NFData FixityMap where
   rnf (FixityMap xs) = rnf xs
 
+#if __GLASGOW_HASKELL__ < 913
 instance NFData Fixity where
   rnf = rwhnf
+#endif
 
 newtype Log = LogShake Shake.Log
 
diff --git a/plugins/hls-gadt-plugin/src/Ide/Plugin/GHC.hs b/plugins/hls-gadt-plugin/src/Ide/Plugin/GHC.hs
--- a/plugins/hls-gadt-plugin/src/Ide/Plugin/GHC.hs
+++ b/plugins/hls-gadt-plugin/src/Ide/Plugin/GHC.hs
@@ -117,6 +117,9 @@
 #endif
             -- Ignore all existential type variable since GADT not needed
             implicitTyVars
+#if MIN_VERSION_ghc(9,13,0)
+            []  -- con_inner_bndrs (new in 9.13)
+#endif
             (mergeContext ctxt con_mb_cxt)
             (renderDetails con_args)
             renderResultTy
@@ -125,19 +128,17 @@
     where
         -- Parameters in the data constructor
         renderDetails :: HsConDeclH98Details GP -> HsConDeclGADTDetails GP
-#if MIN_VERSION_ghc(9,9,0)
+#if MIN_VERSION_ghc(9,13,0)
+        renderDetails (PrefixCon args)     = PrefixConGADT noExtField args
+        renderDetails (InfixCon arg1 arg2) = PrefixConGADT noExtField [arg1, arg2]
+        renderDetails (RecCon recs)        = RecConGADT NoEpUniTok recs
+#elif MIN_VERSION_ghc(9,9,0)
         renderDetails (PrefixCon _ args)   = PrefixConGADT noExtField args
-#else
-        renderDetails (PrefixCon _ args)   = PrefixConGADT args
-#endif
-#if MIN_VERSION_ghc(9,9,0)
         renderDetails (InfixCon arg1 arg2) = PrefixConGADT noExtField [arg1, arg2]
-#else
-        renderDetails (InfixCon arg1 arg2) = PrefixConGADT [arg1, arg2]
-#endif
-#if MIN_VERSION_ghc(9,9,0)
         renderDetails (RecCon recs)        = RecConGADT NoEpUniTok recs
 #else
+        renderDetails (PrefixCon _ args)   = PrefixConGADT args
+        renderDetails (InfixCon arg1 arg2) = PrefixConGADT [arg1, arg2]
         renderDetails (RecCon recs)        = RecConGADT recs noHsUniTok
 #endif
 
@@ -257,12 +258,10 @@
 #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) [])
+        adjustDefnWhere annDataDefn = case andd_where annDataDefn of
+            NoEpTok -> annDataDefn
+            EpTok (EpaSpan aw) -> annDataDefn {andd_where = EpTok (EpaDelta aw (SameLine 1) [])}
+            EpTok (EpaDelta {}) -> annDataDefn  -- already adjusted
 #endif
         -- Remove the first extra line if exist
         removeExtraEmptyLine s = case stripInfix "\n\n" s of
diff --git a/plugins/hls-overloaded-record-dot-plugin/src/Ide/Plugin/OverloadedRecordDot.hs b/plugins/hls-overloaded-record-dot-plugin/src/Ide/Plugin/OverloadedRecordDot.hs
--- a/plugins/hls-overloaded-record-dot-plugin/src/Ide/Plugin/OverloadedRecordDot.hs
+++ b/plugins/hls-overloaded-record-dot-plugin/src/Ide/Plugin/OverloadedRecordDot.hs
@@ -47,7 +47,11 @@
                                                        getLoc, hs_valds,
                                                        parenthesizeHsExpr,
                                                        pattern RealSrcSpan,
-                                                       unLoc)
+                                                       unLoc
+#if __GLASGOW_HASKELL__ >= 913
+                                                       , unLocWithUserRdr
+#endif
+                                                       )
 import           Development.IDE.GHC.Util             (getExtensions,
                                                        printOutputable)
 import           Development.IDE.Graph                (RuleResult)
@@ -300,14 +304,22 @@
       | RealSrcSpan realSpan' _ <- [ getLoc e ] ], False )
 -- Record selection where the field is being applied with the "$" operator:
 -- "selector $ record"
-#if __GLASGOW_HASKELL__ >= 911
+#if __GLASGOW_HASKELL__ >= 913
 getRecSels e@(unLoc -> OpApp _ se@(unLoc -> XExpr (HsRecSelRn _))
+                        (unLoc -> HsVar _ (unLocWithUserRdr -> d)) re) | d == dollarName =
+    ( [ RecordSelectorExpr (realSrcSpanToRange realSpan')  se re
+      | RealSrcSpan realSpan' _ <- [ getLoc e ] ], False )
+#elif __GLASGOW_HASKELL__ >= 911
+getRecSels e@(unLoc -> OpApp _ se@(unLoc -> XExpr (HsRecSelRn _))
+                        (unLoc -> HsVar _ (unLoc -> d)) re) | d == dollarName =
+    ( [ RecordSelectorExpr (realSrcSpanToRange realSpan')  se re
+      | RealSrcSpan realSpan' _ <- [ getLoc e ] ], False )
 #else
 getRecSels e@(unLoc -> OpApp _ se@(unLoc -> HsRecSel _ _)
-#endif
                         (unLoc -> HsVar _ (unLoc -> d)) re) | d == dollarName =
     ( [ RecordSelectorExpr (realSrcSpanToRange realSpan')  se re
       | RealSrcSpan realSpan' _ <- [ getLoc e ] ], False )
+#endif
 getRecSels _ = ([], False)
 
 collectRecSelResult :: MonadIO m => IdeState -> NormalizedFilePath
diff --git a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction.hs b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction.hs
--- a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction.hs
+++ b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction.hs
@@ -1872,11 +1872,11 @@
 --         ‘Data.Functor’ nor ‘Data.Text’ exports ‘putStrLn’.
 extractDoesNotExportModuleName :: T.Text -> Maybe T.Text
 extractDoesNotExportModuleName x
-  | 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] <- if ghcVersion >= GHC912
+                  then matchRegexUnifySpaces x "The module ‘([^’]*)’ does not export"
+                       <|> matchRegexUnifySpaces x "nor ‘([^’]*)’ export"
+                  else matchRegexUnifySpaces x "the module ‘([^’]*)’ does not export"
+                       <|> matchRegexUnifySpaces x "nor ‘([^’]*)’ export"
   = Just m
   | otherwise
   = Nothing
diff --git a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction/ExactPrint.hs b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction/ExactPrint.hs
--- a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction/ExactPrint.hs
+++ b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction/ExactPrint.hs
@@ -43,7 +43,11 @@
                                                          IsUnicodeSyntax (NormalSyntax),
                                                          NameAdornment (NameParens),
                                                          TrailingAnn (AddCommaAnn),
-                                                         emptyComments, reAnnL)
+                                                         emptyComments
+#if !MIN_VERSION_ghc(9,13,0)
+                                                        , reAnnL
+#endif
+                                                        )
 
 
 -- See Note [Guidelines For Using CPP In GHCIDE Import Statements]
@@ -64,6 +68,13 @@
 #if MIN_VERSION_ghc(9,9,0)
 import           GHC                                    (NoAnn (..))
 import           GHC                                    (EpAnnComments (..))
+#endif
+
+#if MIN_VERSION_ghc(9,13,0)
+import           GHC                                    (spanAsAnchor)
+
+reAnnL :: ann -> EpAnnComments -> Located e -> GenLocated (EpAnn ann) e
+reAnnL anns cs (L l a) = L (EpAnn (spanAsAnchor l) anns cs) a
 #endif
 
 ------------------------------------------------------------------------------
diff --git a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/AddArgument.hs b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/AddArgument.hs
--- a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/AddArgument.hs
+++ b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/AddArgument.hs
@@ -49,6 +49,11 @@
 import           GHC.Parser.Annotation                     (EpToken (..))
 #endif
 
+#if MIN_VERSION_ghc(9,13,0)
+-- HsArrow was renamed to HsMultAnn in GHC 9.13
+type HsArrow pass = HsMultAnn pass
+#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
 --  - there is an unbound variable (GHC provides no type suggestion)
@@ -177,7 +182,15 @@
 addTyHoleToTySigArg :: Int -> LHsSigType GhcPs -> LHsSigType GhcPs
 addTyHoleToTySigArg loc (L annHsSig (HsSig xHsSig tyVarBndrs lsigTy)) =
     let (args, res) = hsTypeToFunTypeAsList lsigTy
-#if MIN_VERSION_ghc(9,9,0)
+#if MIN_VERSION_ghc(9,13,0)
+        wildCardAnn = noAnnSrcSpanDP1
+        newArg =
+          ( noAnn
+          , noExtField
+          , HsUnannotated (EpArrow (EpUniTok d1 NormalSyntax))
+          , L wildCardAnn $ HsWildCardTy NoEpTok
+          )
+#elif MIN_VERSION_ghc(9,9,0)
         wildCardAnn = noAnnSrcSpanDP1
         newArg =
           ( noAnn
diff --git a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillTypeWildcard.hs b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillTypeWildcard.hs
--- a/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillTypeWildcard.hs
+++ b/plugins/hls-refactor-plugin/src/Development/IDE/Plugin/Plugins/FillTypeWildcard.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 module Development.IDE.Plugin.Plugins.FillTypeWildcard
   ( suggestFillTypeWildcard
   ) where
@@ -14,6 +15,10 @@
 import           GHC.Tc.Errors.Types               (ErrInfo (..))
 import           Language.LSP.Protocol.Types       (Diagnostic (..),
                                                     TextEdit (TextEdit))
+#if MIN_VERSION_ghc(9,13,0)
+import           GHC.Tc.Errors.Ppr                 (pprErrCtxtMsg)
+import           GHC.Utils.Outputable              (vcat)
+#endif
 
 suggestFillTypeWildcard :: FileDiagnostic -> [(T.Text, TextEdit)]
 suggestFillTypeWildcard diag@FileDiagnostic{fdLspDiagnostic = Diagnostic {..}}
@@ -83,9 +88,13 @@
                 . _TcRnMessageWithCtx
                 . _TcRnMessageWithInfo
     let TcRnMessageDetailed err _ = detailedMsg
+#if MIN_VERSION_ghc(9,13,0)
+        ErrInfo errInfoCtx _ _ = err
+    Just (printOutputable (vcat $ map pprErrCtxtMsg errInfoCtx))
+#else
         ErrInfo errInfoCtx _ = err
-
     Just (printOutputable errInfoCtx)
+#endif
 
 -- | Detect whether user wrote something like @foo :: _@ or @foo :: Maybe _@.
 -- The former is considered toplevel case for which the function returns 'True',
diff --git a/plugins/hls-refactor-plugin/test/Main.hs b/plugins/hls-refactor-plugin/test/Main.hs
--- a/plugins/hls-refactor-plugin/test/Main.hs
+++ b/plugins/hls-refactor-plugin/test/Main.hs
@@ -3379,7 +3379,9 @@
     executeCodeAction chosenAction
     modifiedCode <- documentContents doc
     liftIO $ expectedCode @=? modifiedCode
-  issue806 = if ghcVersion >= GHC910 then
+  issue806 = if ghcVersion >= GHC914 then
+                  "hello = print"           >:: "hello :: GHC.Internal.Types.ZonkAny 0 -> IO ()" -- GHC 9.14 moved to GHC.Internal.Types
+                else if ghcVersion >= GHC910 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
diff --git a/plugins/hls-refactor-plugin/test/Test/AddArgument.hs b/plugins/hls-refactor-plugin/test/Test/AddArgument.hs
--- a/plugins/hls-refactor-plugin/test/Test/AddArgument.hs
+++ b/plugins/hls-refactor-plugin/test/Test/AddArgument.hs
@@ -34,8 +34,8 @@
       mkGoldenAddArgTest "AddArgWithSigAndDocs" (r 8 0 8 50),
       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, GHC912] "In GHC 9.10 and 9.12 end-of-line comment annotation is in different place" $
+      -- TODO can we make this work for GHC 9.10+?
+      knownBrokenForGhcVersions [GHC910, GHC912, GHC914] "In GHC 9.10+ 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),
diff --git a/test/testdata/hieBiosMainIs/dist-newstyle/cache/plan.json b/test/testdata/hieBiosMainIs/dist-newstyle/cache/plan.json
deleted file mode 100644
--- a/test/testdata/hieBiosMainIs/dist-newstyle/cache/plan.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"cabal-version":"3.10.2.0","cabal-lib-version":"3.10.2.1","compiler-id":"ghc-9.8.1","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.19.0.0-c1f2","pkg-name":"base","pkg-version":"4.19.0.0","depends":["ghc-bignum-1.3-d2d5","ghc-prim-0.11.0-b1d6","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-bignum-1.3-d2d5","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.11.0-b1d6"]},{"type":"pre-existing","id":"ghc-prim-0.11.0-b1d6","pkg-name":"ghc-prim","pkg-version":"0.11.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/zubin/haskell-language-server/test/testdata/hieBiosMainIs/."},"dist-dir":"/home/zubin/haskell-language-server/test/testdata/hieBiosMainIs/dist-newstyle/build/x86_64-linux/ghc-9.8.1/hieBiosMainIs-0.1.0.0/x/hieBiosMainIs","build-info":"/home/zubin/haskell-language-server/test/testdata/hieBiosMainIs/dist-newstyle/build/x86_64-linux/ghc-9.8.1/hieBiosMainIs-0.1.0.0/x/hieBiosMainIs/build-info.json","depends":["base-4.19.0.0-c1f2"],"exe-depends":[],"component-name":"exe:hieBiosMainIs","bin-file":"/home/zubin/haskell-language-server/test/testdata/hieBiosMainIs/dist-newstyle/build/x86_64-linux/ghc-9.8.1/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":[]}]}
diff --git a/test/testdata/missingModuleTest/missingModule/dist-newstyle/cache/plan.json b/test/testdata/missingModuleTest/missingModule/dist-newstyle/cache/plan.json
deleted file mode 100644
--- a/test/testdata/missingModuleTest/missingModule/dist-newstyle/cache/plan.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"cabal-version":"3.10.2.0","cabal-lib-version":"3.10.2.1","compiler-id":"ghc-9.8.1","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.19.0.0-c1f2","pkg-name":"base","pkg-version":"4.19.0.0","depends":["ghc-bignum-1.3-d2d5","ghc-prim-0.11.0-b1d6","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-bignum-1.3-d2d5","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.11.0-b1d6"]},{"type":"pre-existing","id":"ghc-prim-0.11.0-b1d6","pkg-name":"ghc-prim","pkg-version":"0.11.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/zubin/haskell-language-server/test/testdata/missingModuleTest/missingModule/."},"dist-dir":"/home/zubin/haskell-language-server/test/testdata/missingModuleTest/missingModule/dist-newstyle/build/x86_64-linux/ghc-9.8.1/missingModule-0.1.0.0","build-info":"/home/zubin/haskell-language-server/test/testdata/missingModuleTest/missingModule/dist-newstyle/build/x86_64-linux/ghc-9.8.1/missingModule-0.1.0.0/build-info.json","depends":["base-4.19.0.0-c1f2"],"exe-depends":[],"component-name":"lib"},{"type":"pre-existing","id":"rts-1.0.2","pkg-name":"rts","pkg-version":"1.0.2","depends":[]}]}
diff --git a/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/cache/plan.json b/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/cache/plan.json
deleted file mode 100644
--- a/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/cache/plan.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"cabal-version":"3.10.2.0","cabal-lib-version":"3.10.2.1","compiler-id":"ghc-9.8.1","os":"linux","arch":"x86_64","install-plan":[{"type":"pre-existing","id":"base-4.19.0.0-c1f2","pkg-name":"base","pkg-version":"4.19.0.0","depends":["ghc-bignum-1.3-d2d5","ghc-prim-0.11.0-b1d6","rts-1.0.2"]},{"type":"pre-existing","id":"ghc-bignum-1.3-d2d5","pkg-name":"ghc-bignum","pkg-version":"1.3","depends":["ghc-prim-0.11.0-b1d6"]},{"type":"pre-existing","id":"ghc-prim-0.11.0-b1d6","pkg-name":"ghc-prim","pkg-version":"0.11.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/test/testdata/missingModuleTest/noPrefixMatch/."},"dist-dir":"/home/zubin/haskell-language-server/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/build/x86_64-linux/ghc-9.8.1/noPrefixMatch-0.1.0.0/x/testExe","build-info":"/home/zubin/haskell-language-server/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/build/x86_64-linux/ghc-9.8.1/noPrefixMatch-0.1.0.0/x/testExe/build-info.json","depends":["base-4.19.0.0-c1f2"],"exe-depends":[],"component-name":"exe:testExe","bin-file":"/home/zubin/haskell-language-server/test/testdata/missingModuleTest/noPrefixMatch/dist-newstyle/build/x86_64-linux/ghc-9.8.1/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":[]}]}
diff --git a/test/testdata/schema/ghc910/default-config.golden.json b/test/testdata/schema/ghc910/default-config.golden.json
--- a/test/testdata/schema/ghc910/default-config.golden.json
+++ b/test/testdata/schema/ghc910/default-config.golden.json
@@ -91,13 +91,6 @@
             },
             "globalOn": true
         },
-        "hlint": {
-            "codeActionsOn": true,
-            "config": {
-                "flags": []
-            },
-            "diagnosticsOn": true
-        },
         "importLens": {
             "codeActionsOn": true,
             "codeLensOn": true,
diff --git a/test/testdata/schema/ghc910/vscode-extension-schema.golden.json b/test/testdata/schema/ghc910/vscode-extension-schema.golden.json
--- a/test/testdata/schema/ghc910/vscode-extension-schema.golden.json
+++ b/test/testdata/schema/ghc910/vscode-extension-schema.golden.json
@@ -213,24 +213,6 @@
         "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",
diff --git a/test/testdata/schema/ghc914/default-config.golden.json b/test/testdata/schema/ghc914/default-config.golden.json
new file mode 100644
--- /dev/null
+++ b/test/testdata/schema/ghc914/default-config.golden.json
@@ -0,0 +1,140 @@
+{
+    "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
+        },
+        "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
+        },
+        "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
+        },
+        "signatureHelp": {
+            "globalOn": true
+        }
+    },
+    "sessionLoading": "singleComponent"
+}
diff --git a/test/testdata/schema/ghc914/vscode-extension-schema.golden.json b/test/testdata/schema/ghc914/vscode-extension-schema.golden.json
new file mode 100644
--- /dev/null
+++ b/test/testdata/schema/ghc914/vscode-extension-schema.golden.json
@@ -0,0 +1,1010 @@
+{
+    "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.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.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.signatureHelp.globalOn": {
+        "default": true,
+        "description": "Enables signatureHelp plugin",
+        "scope": "resource",
+        "type": "boolean"
+    }
+}
