diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,19 @@
-# Revision history for haskell-lsp
+# Revision history for haskell-lsp-types
 
+## 0.4.0.0  -- 2018-07-10
+
+* CodeAction support as per v3.8 of the specification, by @Bubba
+* Update VersionedTextDocumentIdentifier to match specification, by @Bubba.
+
+## 0.3.0.0
+
+* Handle TextDocumentSync fallbacks with new TDS type.
+
+## 0.2.3.0
+
+* GHC 8.4.3 support
+* Introduce additional error codes as per the LSP spec. By @Bubba
+
 ## 0.2.2.0  -- 2018-05-04
 
 * Make Diagnostic relatedInformation optional, as per the LSP Spec. By @Bubba.
@@ -9,4 +23,3 @@
 * Broken out from the haskell-lsp package, to simplify development
   by not having to run massive TH processes when working on the
   framework.
-
diff --git a/haskell-lsp-types.cabal b/haskell-lsp-types.cabal
--- a/haskell-lsp-types.cabal
+++ b/haskell-lsp-types.cabal
@@ -1,5 +1,5 @@
 name:                haskell-lsp-types
-version:             0.2.2.0
+version:             0.4.0.0
 synopsis:            Haskell library for the Microsoft Language Server Protocol, data types
 
 description:         An implementation of the types to allow language implementors to
@@ -10,7 +10,7 @@
 license-file:        LICENSE
 author:              Alan Zimmerman
 maintainer:          alan.zimm@gmail.com
-copyright:           Alan Zimmerman, 2016-2017
+copyright:           Alan Zimmerman, 2016-2018
 category:            Development
 build-type:          Simple
 extra-source-files:  ChangeLog.md, README.md
@@ -20,9 +20,18 @@
   exposed-modules:     Language.Haskell.LSP.TH.ClientCapabilities
                      , Language.Haskell.LSP.TH.Constants
                      , Language.Haskell.LSP.TH.DataTypesJSON
-                     , Language.Haskell.LSP.TH.Messages
+                     , Language.Haskell.LSP.TH.MessageFuncs
                      , Language.Haskell.LSP.TH.Utils
-  -- other-modules:
+  other-modules:       Language.Haskell.LSP.TH.Command
+                     , Language.Haskell.LSP.TH.CodeAction
+                     , Language.Haskell.LSP.TH.Diagnostic
+                     , Language.Haskell.LSP.TH.List
+                     , Language.Haskell.LSP.TH.Location
+                     , Language.Haskell.LSP.TH.Message
+                     , Language.Haskell.LSP.TH.Symbol
+                     , Language.Haskell.LSP.TH.TextDocumentIdentifier
+                     , Language.Haskell.LSP.TH.Uri
+                     , Language.Haskell.LSP.TH.WorkspaceEdit
  -- other-extensions:
   ghc-options:         -Wall
   -- ghc-options:         -Werror
diff --git a/src/Language/Haskell/LSP/TH/ClientCapabilities.hs b/src/Language/Haskell/LSP/TH/ClientCapabilities.hs
--- a/src/Language/Haskell/LSP/TH/ClientCapabilities.hs
+++ b/src/Language/Haskell/LSP/TH/ClientCapabilities.hs
@@ -1,19 +1,13 @@
-{-# LANGUAGE DeriveGeneric         #-}
 {-# LANGUAGE DuplicateRecordFields #-}
-{-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE TemplateHaskell       #-}
-{-# LANGUAGE TypeSynonymInstances  #-}
 
 module Language.Haskell.LSP.TH.ClientCapabilities where
 
 import           Data.Aeson.TH
--- import           Data.Aeson.Types
 import qualified Data.Aeson as A
--- import qualified Data.HashMap.Strict as H
--- import qualified Data.Text as T
-
 import Language.Haskell.LSP.TH.Constants
--- import Language.Haskell.LSP.Utility
+import Language.Haskell.LSP.TH.CodeAction
+import Language.Haskell.LSP.TH.List
 import Data.Default
 
 -- ---------------------------------------------------------------------
@@ -496,9 +490,37 @@
 
 -- -------------------------------------
 
+data CodeActionKindValueSet =
+  CodeActionKindValueSet
+   { _valueSet :: List CodeActionKind
+   } deriving (Show, Read, Eq)
+
+instance Default CodeActionKindValueSet where
+  def = CodeActionKindValueSet (List allKinds)
+    where allKinds = [ CodeActionQuickFix
+                     , CodeActionRefactor
+                     , CodeActionRefactorExtract
+                     , CodeActionRefactorInline
+                     , CodeActionRefactorRewrite
+                     , CodeActionSource
+                     , CodeActionSourceOrganizeImports
+                     ]
+
+$(deriveJSON lspOptions ''CodeActionKindValueSet)
+
+data CodeActionLiteralSupport =
+  CodeActionLiteralSupport
+    { _codeActionKind :: CodeActionKindValueSet -- ^ The code action kind is support with the following value set.
+    } deriving (Show, Read, Eq)
+
+$(deriveJSON lspOptions ''CodeActionLiteralSupport)
+
 data CodeActionClientCapabilities =
   CodeActionClientCapabilities
-    { _dynamicRegistration :: Maybe Bool
+    { _dynamicRegistration      :: Maybe Bool -- ^ Whether code action supports dynamic registration.
+    , _codeActionLiteralSupport :: Maybe CodeActionLiteralSupport -- ^ The client support code action literals as a valid response
+                                                                 -- of the `textDocument/codeAction` request.
+                                                                 -- Since 3.8.0
     } deriving (Show, Read, Eq)
 
 $(deriveJSON lspOptions ''CodeActionClientCapabilities)
diff --git a/src/Language/Haskell/LSP/TH/CodeAction.hs b/src/Language/Haskell/LSP/TH/CodeAction.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/CodeAction.hs
@@ -0,0 +1,294 @@
+{-# LANGUAGE DuplicateRecordFields      #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TemplateHaskell            #-}
+module Language.Haskell.LSP.TH.CodeAction where
+
+import           Control.Applicative
+import qualified Data.Aeson                    as A
+import           Data.Aeson.TH
+import           Data.Aeson.Types
+import           Data.Text                      ( Text )
+import           Language.Haskell.LSP.TH.Command
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.Diagnostic
+import           Language.Haskell.LSP.TH.List
+import           Language.Haskell.LSP.TH.Location
+import           Language.Haskell.LSP.TH.Message
+import           Language.Haskell.LSP.TH.TextDocumentIdentifier
+import           Language.Haskell.LSP.TH.WorkspaceEdit
+
+
+{-
+Code Action Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#code-action-request
+
+The code action request is sent from the client to the server tocompute commands
+for a given text document and range. These commands are typically code fixes to
+either fix problems or to beautify/refactor code. The result of a
+textDocument/codeAction request is an array of Command literals which are
+typically presented in the user interface. When the command is selected the
+server should be contacted again (via the workspace/executeCommand) request to
+execute the command.
+
+Since version 3.8.0: support for CodeAction litarals to enable the following
+scenarios:
+
+the ability to directly return a workspace edit from e code action request. This
+avoids having another server roundtrip to execute an actual code action. However
+server providers should be aware that if the code action is expensive to compute
+or the edits are huge it might still be beneficial if the result is imply a
+command and the actual edit is only computed when needed. the ability to group
+code actions using a kind. Clients are allowed to ignore that information.
+However it allows them to better group code action for example into
+corresponding menus (e.g. all refactor code actions into a refactor menu).
+Clients need to announce there support code action literals and code action
+kinds via the corresponding client capability
+textDocument.codeAction.codeActionLiteralSupport.
+
+Request
+
+    method: 'textDocument/codeAction'
+    params: CodeActionParams defined as follows:
+
+/**
+ * Params for the CodeActionRequest
+ */
+interface CodeActionParams {
+	/**
+	 * The document in which the command was invoked.
+	 */
+	textDocument: TextDocumentIdentifier;
+
+	/**
+	 * The range for which the command was invoked.
+	 */
+	range: Range;
+
+	/**
+	 * Context carrying additional information.
+	 */
+	context: CodeActionContext;
+}
+
+/**
+ * The kind of a code action.
+ *
+ * Kinds are a hierarchical list of identifiers separated by `.`, e.g. `"refactor.extract.function"`.
+ *
+ * The set of kinds is open and client needs to announce the kinds it supports to the server during
+ * initialization.
+ */
+export type CodeActionKind = string;
+
+/**
+ * A set of predefined code action kinds
+ */
+export namespace CodeActionKind {
+	/**
+	 * Base kind for quickfix actions: 'quickfix'
+	 */
+	export const QuickFix: CodeActionKind = 'quickfix';
+
+	/**
+	 * Base kind for refactoring actions: 'refactor'
+	 */
+	export const Refactor: CodeActionKind = 'refactor';
+
+	/**
+	 * Base kind for refactoring extraction actions: 'refactor.extract'
+	 *
+	 * Example extract actions:
+	 *
+	 * - Extract method
+	 * - Extract function
+	 * - Extract variable
+	 * - Extract interface from class
+	 * - ...
+	 */
+	export const RefactorExtract: CodeActionKind = 'refactor.extract';
+
+	/**
+	 * Base kind for refactoring inline actions: 'refactor.inline'
+	 *
+	 * Example inline actions:
+	 *
+	 * - Inline function
+	 * - Inline variable
+	 * - Inline constant
+	 * - ...
+	 */
+	export const RefactorInline: CodeActionKind = 'refactor.inline';
+
+	/**
+	 * Base kind for refactoring rewrite actions: 'refactor.rewrite'
+	 *
+	 * Example rewrite actions:
+	 *
+	 * - Convert JavaScript function to class
+	 * - Add or remove parameter
+	 * - Encapsulate field
+	 * - Make method static
+	 * - Move method to base class
+	 * - ...
+	 */
+	export const RefactorRewrite: CodeActionKind = 'refactor.rewrite';
+
+	/**
+	 * Base kind for source actions: `source`
+	 *
+	 * Source code actions apply to the entire file.
+	 */
+	export const Source: CodeActionKind = 'source';
+
+	/**
+	 * Base kind for an organize imports source action: `source.organizeImports`
+	 */
+	export const SourceOrganizeImports: CodeActionKind = 'source.organizeImports';
+}
+
+/**
+ * Contains additional diagnostic information about the context in which
+ * a code action is run.
+ */
+interface CodeActionContext {
+	/**
+	 * An array of diagnostics.
+	 */
+	diagnostics: Diagnostic[];
+
+	/**
+	 * Requested kind of actions to return.
+	 *
+	 * Actions not of this kind are filtered out by the client before being shown. So servers
+	 * can omit computing them.
+	 */
+	only?: CodeActionKind[];
+}
+
+Response
+
+    result: (Command | CodeAction)[] | null where CodeAction is defined as follows:
+        /**
+    * A code action represents a change that can be performed in code, e.g. to fix a problem or
+    * to refactor code.
+    *
+    * A CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed.
+    */
+    export interface CodeAction {
+
+        /**
+        * A short, human-readable, title for this code action.
+        */
+        title: string;
+
+        /**
+        * The kind of the code action.
+        *
+        * Used to filter code actions.
+        */
+        kind?: CodeActionKind;
+
+        /**
+        * The diagnostics that this code action resolves.
+        */
+        diagnostics?: Diagnostic[];
+
+        /**
+        * The workspace edit this code action performs.
+        */
+        edit?: WorkspaceEdit;
+
+        /**
+        * A command this code action executes. If a code action
+        * provides an edit and a command, first the edit is
+        * executed and then the command.
+        */
+        command?: Command;
+    }
+    error: code and message set in case an exception happens during the code
+           action request.
+
+-}
+
+data CodeActionKind = CodeActionQuickFix
+                    | CodeActionRefactor
+                    | CodeActionRefactorExtract
+                    | CodeActionRefactorInline
+                    | CodeActionRefactorRewrite
+                    | CodeActionSource
+                    | CodeActionSourceOrganizeImports
+                    | CodeActionUnknown Text
+  deriving (Read,Show,Eq)
+
+instance ToJSON CodeActionKind where
+  toJSON CodeActionQuickFix                   = String "quickfix"
+  toJSON CodeActionRefactor                   = String "refactor"
+  toJSON CodeActionRefactorExtract            = String "refactor.extract"
+  toJSON CodeActionRefactorInline             = String "refactor.inline"
+  toJSON CodeActionRefactorRewrite            = String "refactor.rewrite"
+  toJSON CodeActionSource                     = String "source"
+  toJSON CodeActionSourceOrganizeImports      = String "source.organizeImports"
+  toJSON (CodeActionUnknown s)                = String s
+
+instance FromJSON CodeActionKind where
+  parseJSON (String "quickfix")               = pure CodeActionQuickFix
+  parseJSON (String "refactor")               = pure CodeActionRefactor
+  parseJSON (String "refactor.extract")       = pure CodeActionRefactorExtract
+  parseJSON (String "refactor.inline")        = pure CodeActionRefactorInline
+  parseJSON (String "refactor.rewrite")       = pure CodeActionRefactorRewrite
+  parseJSON (String "source")                 = pure CodeActionSource
+  parseJSON (String "source.organizeImports") = pure CodeActionSourceOrganizeImports
+  parseJSON (String s)                        = pure (CodeActionUnknown s)
+  parseJSON _                                 = mempty
+
+data CodeActionContext =
+  CodeActionContext
+    { _diagnostics :: List Diagnostic
+    , only         :: Maybe (List CodeActionKind)
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CodeActionContext
+
+
+data CodeActionParams =
+  CodeActionParams
+    { _textDocument :: TextDocumentIdentifier
+    , _range        :: Range
+    , _context      :: CodeActionContext
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CodeActionParams
+
+data CodeAction =
+  -- | A code action represents a change that can be performed in code, e.g. to fix a problem or
+  -- to refactor code.
+  --
+  -- A CodeAction must set either '_edit' and/or a '_command'. If both are supplied,
+  -- the '_edit' is applied first, then the '_command' is executed.
+  CodeAction
+    { _title       :: Text -- ^ A short, human-readable, title for this code action.
+    , _kind        :: Maybe CodeActionKind -- ^ The kind of the code action. Used to filter code actions.
+    , _diagnostics :: Maybe (List Diagnostic) -- ^ The diagnostics that this code action resolves.
+    , _edit        :: Maybe WorkspaceEdit -- ^ The workspace edit this code action performs.
+    , _command     :: Maybe Command -- ^ A command this code action executes. If a code action
+                                    -- provides an edit and a command, first the edit is
+                                    -- executed and then the command.
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CodeAction
+
+data CommandOrCodeAction = CommandOrCodeActionCommand Command
+                         | CommandOrCodeActionCodeAction CodeAction
+  deriving (Read,Show,Eq)
+
+instance FromJSON CommandOrCodeAction where
+  parseJSON x = CommandOrCodeActionCommand <$> parseJSON x
+              <|> CommandOrCodeActionCodeAction <$> parseJSON x
+
+instance ToJSON CommandOrCodeAction where
+  toJSON (CommandOrCodeActionCommand x) = toJSON x
+  toJSON (CommandOrCodeActionCodeAction x) = toJSON x
+
+type CodeActionRequest  = RequestMessage ClientMethod CodeActionParams (List CommandOrCodeAction)
+type CodeActionResponse = ResponseMessage (List CommandOrCodeAction)
diff --git a/src/Language/Haskell/LSP/TH/Command.hs b/src/Language/Haskell/LSP/TH/Command.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/Command.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE TemplateHaskell            #-}
+
+module Language.Haskell.LSP.TH.Command where
+
+import           Data.Aeson
+import           Data.Aeson.TH
+import           Data.Text
+import           Language.Haskell.LSP.TH.Constants
+-- ---------------------------------------------------------------------
+{-
+Command
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#command
+
+Represents a reference to a command. Provides a title which will be used to
+represent a command in the UI. Commands are identitifed using a string
+identifier and the protocol currently doesn't specify a set of well known
+commands. So executing a command requires some tool extension code.
+
+interface Command {
+    /**
+     * Title of the command, like `save`.
+     */
+    title: string;
+    /**
+     * The identifier of the actual command handler.
+     */
+    command: string;
+    /**
+     * Arguments that the command handler should be
+     * invoked with.
+     */
+    arguments?: any[];
+}
+-}
+
+data Command =
+  Command
+    { _title     :: Text
+    , _command   :: Text
+    , _arguments :: Maybe Value
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''Command
diff --git a/src/Language/Haskell/LSP/TH/DataTypesJSON.hs b/src/Language/Haskell/LSP/TH/DataTypesJSON.hs
--- a/src/Language/Haskell/LSP/TH/DataTypesJSON.hs
+++ b/src/Language/Haskell/LSP/TH/DataTypesJSON.hs
@@ -10,4256 +10,3201 @@
 {-# LANGUAGE TemplateHaskell            #-}
 {-# LANGUAGE TypeSynonymInstances       #-}
 
-module Language.Haskell.LSP.TH.DataTypesJSON where
-
-import           Control.Lens.TH                            (makeFieldsNoPrefix)
-import qualified Data.Aeson                                 as A
-import           Data.Aeson.TH
-import           Data.Aeson.Types
-import           Data.Hashable
-import qualified Data.HashMap.Strict                        as H
-import           Data.Monoid                                ((<>))
-import           Data.Text                                  (Text)
-import qualified Data.Text                                  as T
-import           Network.URI
-import qualified System.FilePath.Posix                      as FPP
-import qualified System.FilePath.Windows                    as FPW
-import qualified System.Info
-import           System.IO                                  (FilePath)
-
-import           Language.Haskell.LSP.TH.ClientCapabilities
-import           Language.Haskell.LSP.TH.Constants
-import           Language.Haskell.LSP.TH.Utils
-
--- ---------------------------------------------------------------------
-
--- | This data type is used to host a FromJSON instance for the encoding used by
--- elisp, where an empty list shows up as "null"
-newtype List a = List [a]
-                deriving (Show,Read,Eq,Ord,Monoid,Functor,Foldable,Traversable)
-
-instance (A.ToJSON a) => A.ToJSON (List a) where
-  toJSON (List ls) = toJSON ls
-
-instance (A.FromJSON a) => A.FromJSON (List a) where
-  parseJSON A.Null = return (List [])
-  parseJSON v      = List <$> parseJSON v
-
-#if __GLASGOW_HASKELL__ >= 804
-instance Semigroup (List a) where
-  (<>) = mappend
-#endif
-
--- ---------------------------------------------------------------------
-
-newtype Uri = Uri { getUri :: Text }
-  deriving (Eq,Ord,Read,Show,A.FromJSON,A.ToJSON,Hashable,A.ToJSONKey,A.FromJSONKey)
-
-fileScheme :: String
-fileScheme = "file:"
-
-windowsOS :: String
-windowsOS = "mingw32"
-
-type SystemOS = String
-
-uriToFilePath :: Uri -> Maybe FilePath
-uriToFilePath = platformAwareUriToFilePath System.Info.os
-
-platformAwareUriToFilePath :: String -> Uri -> Maybe FilePath
-platformAwareUriToFilePath systemOS (Uri uri) = do
-  parsedUri <- parseURI $ T.unpack uri
-  if uriScheme parsedUri == fileScheme
-    then return $ (platformAdjustFromUriPath systemOS . unEscapeString . uriPath) parsedUri
-    else Nothing
-
-platformAdjustFromUriPath :: SystemOS -> String -> FilePath
-platformAdjustFromUriPath systemOS srcPath =
-  if systemOS /= windowsOS then srcPath
-    else let
-      firstSegment:rest = (FPP.splitDirectories . tail) srcPath  -- Drop leading '/' for absolute Windows paths
-      drive = if FPW.isDrive firstSegment then FPW.addTrailingPathSeparator firstSegment else firstSegment
-      in FPW.joinDrive drive $ FPW.joinPath rest
-
-filePathToUri :: FilePath -> Uri
-filePathToUri = platformAwareFilePathToUri System.Info.os
-
-platformAwareFilePathToUri :: SystemOS -> FilePath -> Uri
-platformAwareFilePathToUri systemOS fp = Uri . T.pack . show $ URI
-  { uriScheme = fileScheme
-  , uriAuthority = Just $ URIAuth "" "" ""
-  , uriPath = platformAdjustToUriPath systemOS fp
-  , uriQuery = ""
-  , uriFragment = ""
-  }
-
-platformAdjustToUriPath :: SystemOS -> FilePath -> String
-platformAdjustToUriPath systemOS srcPath =
-  if systemOS /= windowsOS then srcPath
-    else let
-      drive:rest = FPW.splitDirectories srcPath
-      leaveCharUnescaped = (/= ':')
-      removePathSeparator = filter (not . FPW.isPathSeparator)
-      escapedDrive = removePathSeparator $ escapeURIString leaveCharUnescaped drive
-      in '/' : FPP.joinPath (escapedDrive : rest)
-
--- ---------------------------------------------------------------------
-
--- | Id used for a request, Can be either a String or an Int
-data LspId = IdInt Int | IdString Text
-            deriving (Show,Read,Eq,Ord)
-
-instance A.ToJSON LspId where
-  toJSON (IdInt i)    = toJSON i
-  toJSON (IdString s) = toJSON s
-
-instance A.FromJSON LspId where
-  parseJSON v@(A.Number _) = IdInt <$> parseJSON v
-  parseJSON  (A.String  s) = return (IdString s)
-  parseJSON _              = mempty
-
--- ---------------------------------------------------------------------
-
--- | Id used for a response, Can be either a String or an Int, or Null. If a
--- request doesn't provide a result value the receiver of a request still needs
--- to return a response message to conform to the JSON RPC specification. The
--- result property of the ResponseMessage should be set to null in this case to
--- signal a successful request.
-data LspIdRsp = IdRspInt Int | IdRspString Text | IdRspNull
-            deriving (Show,Read,Eq)
-
-instance A.ToJSON LspIdRsp where
-  toJSON (IdRspInt i)    = toJSON i
-  toJSON (IdRspString s) = toJSON s
-  toJSON IdRspNull       = A.Null
-
-instance A.FromJSON LspIdRsp where
-  parseJSON v@(A.Number _) = IdRspInt <$> parseJSON v
-  parseJSON  (A.String  s) = return $ IdRspString s
-  parseJSON  A.Null        = return IdRspNull
-  parseJSON _              = mempty
-
-responseId :: LspId -> LspIdRsp
-responseId (IdInt    i) = (IdRspInt i)
-responseId (IdString s) = (IdRspString s)
-
--- ---------------------------------------------------------------------
-
--- Client Methods
-data ClientMethod =
- -- General
-   Initialize
- | Initialized
- | Shutdown
- | Exit
- | CancelRequest
- -- Workspace
- | WorkspaceDidChangeConfiguration
- | WorkspaceDidChangeWatchedFiles
- | WorkspaceSymbol
- | WorkspaceExecuteCommand
- -- Document
- | TextDocumentDidOpen
- | TextDocumentDidChange
- | TextDocumentWillSave
- | TextDocumentWillSaveWaitUntil
- | TextDocumentDidSave
- | TextDocumentDidClose
- | TextDocumentCompletion
- | CompletionItemResolve
- | TextDocumentHover
- | TextDocumentSignatureHelp
- | TextDocumentReferences
- | TextDocumentDocumentHighlight
- | TextDocumentDocumentSymbol
- | TextDocumentFormatting
- | TextDocumentRangeFormatting
- | TextDocumentOnTypeFormatting
- | TextDocumentDefinition
- | TextDocumentCodeAction
- | TextDocumentCodeLens
- | CodeLensResolve
- | TextDocumentDocumentLink
- | DocumentLinkResolve
- | TextDocumentRename
- -- Messages of the form $/message
- -- Implementation Dependent, can be ignored
- | Misc Text
-   deriving (Eq,Ord,Read,Show)
-
-instance A.FromJSON ClientMethod where
-  -- General
-  parseJSON (A.String "initialize")                       = return Initialize
-  parseJSON (A.String "initialized")                      = return Initialized
-  parseJSON (A.String "shutdown")                         = return Shutdown
-  parseJSON (A.String "exit")                             = return Exit
-  parseJSON (A.String "$/cancelRequest")                  = return CancelRequest
- -- Workspace
-  parseJSON (A.String "workspace/didChangeConfiguration") = return WorkspaceDidChangeConfiguration
-  parseJSON (A.String "workspace/didChangeWatchedFiles")  = return WorkspaceDidChangeWatchedFiles
-  parseJSON (A.String "workspace/symbol")                 = return WorkspaceSymbol
-  parseJSON (A.String "workspace/executeCommand")         = return WorkspaceExecuteCommand
- -- Document
-  parseJSON (A.String "textDocument/didOpen")             = return TextDocumentDidOpen
-  parseJSON (A.String "textDocument/didChange")           = return TextDocumentDidChange
-  parseJSON (A.String "textDocument/willSave")            = return TextDocumentWillSave
-  parseJSON (A.String "textDocument/willSaveWaitUntil")   = return TextDocumentWillSaveWaitUntil
-  parseJSON (A.String "textDocument/didSave")             = return TextDocumentDidSave
-  parseJSON (A.String "textDocument/didClose")            = return TextDocumentDidClose
-  parseJSON (A.String "textDocument/completion")          = return TextDocumentCompletion
-  parseJSON (A.String "completionItem/resolve")           = return CompletionItemResolve
-  parseJSON (A.String "textDocument/hover")               = return TextDocumentHover
-  parseJSON (A.String "textDocument/signatureHelp")       = return TextDocumentSignatureHelp
-  parseJSON (A.String "textDocument/references")          = return TextDocumentReferences
-  parseJSON (A.String "textDocument/documentHighlight")   = return TextDocumentDocumentHighlight
-  parseJSON (A.String "textDocument/documentSymbol")      = return TextDocumentDocumentSymbol
-  parseJSON (A.String "textDocument/formatting")          = return TextDocumentFormatting
-  parseJSON (A.String "textDocument/rangeFormatting")     = return TextDocumentRangeFormatting
-  parseJSON (A.String "textDocument/onTypeFormatting")    = return TextDocumentOnTypeFormatting
-  parseJSON (A.String "textDocument/definition")          = return TextDocumentDefinition
-  parseJSON (A.String "textDocument/codeAction")          = return TextDocumentCodeAction
-  parseJSON (A.String "textDocument/codeLens")            = return TextDocumentCodeLens
-  parseJSON (A.String "codeLens/resolve")                 = return CodeLensResolve
-  parseJSON (A.String "textDocument/documentLink")        = return TextDocumentDocumentLink
-  parseJSON (A.String "documentLink/resolve")             = return DocumentLinkResolve
-  parseJSON (A.String "textDocument/rename")              = return TextDocumentRename
-  parseJSON (A.String x)                                  = if T.isPrefixOf "$/" x
-                                                               then return $ Misc (T.drop 2 x)
-                                                            else mempty
-  parseJSON _                                             = mempty
-
-instance A.ToJSON ClientMethod where
-  -- General
-  toJSON Initialize                      = A.String "initialize"
-  toJSON Initialized                     = A.String "initialized"
-  toJSON Shutdown                        = A.String "shutdown"
-  toJSON Exit                            = A.String "exit"
-  toJSON CancelRequest                   = A.String "$/cancelRequest"
-  -- Workspace
-  toJSON WorkspaceDidChangeConfiguration = A.String "workspace/didChangeConfiguration"
-  toJSON WorkspaceDidChangeWatchedFiles  = A.String "workspace/didChangeWatchedFiles"
-  toJSON WorkspaceSymbol                 = A.String "workspace/symbol"
-  toJSON WorkspaceExecuteCommand         = A.String "workspace/executeCommand"
-  -- Document
-  toJSON TextDocumentDidOpen             = A.String "textDocument/didOpen"
-  toJSON TextDocumentDidChange           = A.String "textDocument/didChange"
-  toJSON TextDocumentWillSave            = A.String "textDocument/willSave"
-  toJSON TextDocumentWillSaveWaitUntil   = A.String "textDocument/willSaveWaitUntil"
-  toJSON TextDocumentDidSave             = A.String "textDocument/didSave"
-  toJSON TextDocumentDidClose            = A.String "textDocument/didClose"
-  toJSON TextDocumentCompletion          = A.String "textDocument/completion"
-  toJSON CompletionItemResolve           = A.String "completionItem/resolve"
-  toJSON TextDocumentHover               = A.String "textDocument/hover"
-  toJSON TextDocumentSignatureHelp       = A.String "textDocument/signatureHelp"
-  toJSON TextDocumentReferences          = A.String "textDocument/references"
-  toJSON TextDocumentDocumentHighlight   = A.String "textDocument/documentHighlight"
-  toJSON TextDocumentDocumentSymbol      = A.String "textDocument/documentSymbol"
-  toJSON TextDocumentFormatting          = A.String "textDocument/formatting"
-  toJSON TextDocumentRangeFormatting     = A.String "textDocument/rangeFormatting"
-  toJSON TextDocumentOnTypeFormatting    = A.String "textDocument/onTypeFormatting"
-  toJSON TextDocumentDefinition          = A.String "textDocument/definition"
-  toJSON TextDocumentCodeAction          = A.String "textDocument/codeAction"
-  toJSON TextDocumentCodeLens            = A.String "textDocument/codeLens"
-  toJSON CodeLensResolve                 = A.String "codeLens/resolve"
-  toJSON TextDocumentRename              = A.String "textDocument/rename"
-  toJSON TextDocumentDocumentLink        = A.String "textDocument/documentLink"
-  toJSON DocumentLinkResolve             = A.String "documentLink/resolve"
-  toJSON (Misc xs)                       = A.String $ "$/" <> xs
-
-data ServerMethod =
-  -- Window
-    WindowShowMessage
-  | WindowShowMessageRequest
-  | WindowLogMessage
-  | TelemetryEvent
-  -- Client
-  | ClientRegisterCapability
-  | ClientUnregisterCapability
-  -- Workspace
-  | WorkspaceApplyEdit
-  -- Document
-  | TextDocumentPublishDiagnostics
-   deriving (Eq,Ord,Read,Show)
-
-instance A.FromJSON ServerMethod where
-  -- Window
-  parseJSON (A.String "window/showMessage")              = return WindowShowMessage
-  parseJSON (A.String "window/showMessageRequest")       = return WindowShowMessageRequest
-  parseJSON (A.String "window/logMessage")               = return WindowLogMessage
-  parseJSON (A.String "telemetry/event")                 = return TelemetryEvent
-  -- Client
-  parseJSON (A.String "client/registerCapability")       = return ClientRegisterCapability
-  parseJSON (A.String "client/unregisterCapability")     = return ClientUnregisterCapability
-  -- Workspace
-  parseJSON (A.String "workspace/applyEdit")             = return WorkspaceApplyEdit
-  -- Document
-  parseJSON (A.String "textDocument/publishDiagnostics") = return TextDocumentPublishDiagnostics
-  parseJSON _                                            = mempty
-
-instance A.ToJSON ServerMethod where
-  -- Window
-  toJSON WindowShowMessage = A.String "window/showMessage"
-  toJSON WindowShowMessageRequest = A.String "window/showMessageRequest"
-  toJSON WindowLogMessage = A.String "window/logMessage"
-  toJSON TelemetryEvent = A.String "telemetry/event"
-  -- Client
-  toJSON ClientRegisterCapability = A.String "client/registerCapability"
-  toJSON ClientUnregisterCapability = A.String "client/unregisterCapability"
-  -- Workspace
-  toJSON WorkspaceApplyEdit = A.String "workspace/applyEdit"
-  -- Document
-  toJSON TextDocumentPublishDiagnostics = A.String "textDocument/publishDiagnostics"
-
-data RequestMessage m req resp =
-  RequestMessage
-    { _jsonrpc :: Text
-    , _id      :: LspId
-    , _method  :: m
-    , _params  :: req
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''RequestMessage
-makeFieldsNoPrefix ''RequestMessage
-
--- ---------------------------------------------------------------------
-{-
-interface ResponseError<D> {
-    /**
-     * A number indicating the error type that occurred.
-     */
-    code: number;
-
-    /**
-     * A string providing a short description of the error.
-     */
-    message: string;
-
-    /**
-     * A Primitive or Structured value that contains additional
-     * information about the error. Can be omitted.
-     */
-    data?: D;
-}
-
-export namespace ErrorCodes {
-        // Defined by JSON RPC
-        export const ParseError: number = -32700;
-        export const InvalidRequest: number = -32600;
-        export const MethodNotFound: number = -32601;
-        export const InvalidParams: number = -32602;
-        export const InternalError: number = -32603;
-        export const serverErrorStart: number = -32099;
-        export const serverErrorEnd: number = -32000;
-        export const ServerNotInitialized: number = -32002;
-        export const UnknownErrorCode: number = -32001;
-
-        // Defined by the protocol.
-        export const RequestCancelled: number = -32800;
-}
--}
-
-data ErrorCode = ParseError
-               | InvalidRequest
-               | MethodNotFound
-               | InvalidParams
-               | InternalError
-               -- ^ Note: server error codes are reserved from -32099 to -32000
-               deriving (Read,Show,Eq)
-
-instance A.ToJSON ErrorCode where
-  toJSON ParseError     = A.Number (-32700)
-  toJSON InvalidRequest = A.Number (-32600)
-  toJSON MethodNotFound = A.Number (-32601)
-  toJSON InvalidParams  = A.Number (-32602)
-  toJSON InternalError  = A.Number (-32603)
-
-instance A.FromJSON ErrorCode where
-  parseJSON (A.Number (-32700)) = pure ParseError
-  parseJSON (A.Number (-32600)) = pure InvalidRequest
-  parseJSON (A.Number (-32601)) = pure MethodNotFound
-  parseJSON (A.Number (-32602)) = pure InvalidParams
-  parseJSON (A.Number (-32603)) = pure InternalError
-  parseJSON _                   = mempty
-
--- -------------------------------------
-
-data ResponseError =
-  ResponseError
-    { _code    :: ErrorCode
-    , _message :: Text
-    , _xdata   :: Maybe A.Value
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ResponseError
-makeFieldsNoPrefix ''ResponseError
-
--- ---------------------------------------------------------------------
-
-data ResponseMessage a =
-  ResponseMessage
-    { _jsonrpc :: Text
-    , _id      :: LspIdRsp
-    , _result  :: Maybe a
-    , _error   :: Maybe ResponseError
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''ResponseMessage
-makeFieldsNoPrefix ''ResponseMessage
-
-type ErrorResponse = ResponseMessage ()
-
--- ---------------------------------------------------------------------
-
-type BareResponseMessage = ResponseMessage A.Value
-
--- ---------------------------------------------------------------------
-{-
-$ Notifications and Requests
-
-Notification and requests ids starting with '$/' are messages which are protocol
-implementation dependent and might not be implementable in all clients or
-servers. For example if the server implementation uses a single threaded
-synchronous programming language then there is little a server can do to react
-to a '$/cancelRequest'. If a server or client receives notifications or requests
-starting with '$/' it is free to ignore them if they are unknown.
--}
-
-data NotificationMessage m a =
-  NotificationMessage
-    { _jsonrpc :: Text
-    , _method  :: m
-    , _params  :: a
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''NotificationMessage
-makeFieldsNoPrefix ''NotificationMessage
-
--- ---------------------------------------------------------------------
-{-
-Cancellation Support
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#cancellation-support
-
-    New: The base protocol now offers support for request cancellation. To
-    cancel a request, a notification message with the following properties is
-    sent:
-
-Notification:
-
-    method: '$/cancelRequest'
-    params: CancelParams defined as follows:
-
-interface CancelParams {
-    /**
-     * The request id to cancel.
-     */
-    id: number | string;
-}
-
-A request that got canceled still needs to return from the server and send a
-response back. It can not be left open / hanging. This is in line with the JSON
-RPC protocol that requires that every request sends a response back. In addition
-it allows for returning partial results on cancel.
--}
-
-data CancelParams =
-  CancelParams
-    { _id :: LspId
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''CancelParams
-makeFieldsNoPrefix ''CancelParams
-
-type CancelNotification = NotificationMessage ClientMethod CancelParams
-
--- ---------------------------------------------------------------------
-
-{-
-The current protocol is talored for textual documents which content can be
-represented as a string. There is currently no support for binary documents.
-Positions inside a document (see Position definition below) are expressed as a
-zero-based line and character offset. To ensure that both client and server
-split the string into the same line representation the protocol specs the
-following end of line sequences: '\n', '\r\n' and '\r'.
-
-export const EOL: string[] = ['\n', '\r\n', '\r'];
--}
-{-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#position
-
-Position in a text document expressed as zero-based line and character offset. A
-position is between two characters like an 'insert' cursor in a editor.
-
-interface Position {
-    /**
-     * Line position in a document (zero-based).
-     */
-    line: number;
-
-    /**
-     * Character offset on a line in a document (zero-based).
-     */
-    character: number;
-}
--}
-data Position =
-  Position
-    { _line      :: Int
-    , _character :: Int
-    } deriving (Show, Read, Eq, Ord)
-
-deriveJSON lspOptions ''Position
-makeFieldsNoPrefix ''Position
-
--- ---------------------------------------------------------------------
-{-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#range
-
-A range in a text document expressed as (zero-based) start and end positions. A
-range is comparable to a selection in an editor. Therefore the end position is
-exclusive.
-
-interface Range {
-    /**
-     * The range's start position.
-     */
-    start: Position;
-
-    /**
-     * The range's end position.
-     */
-    end: Position;
-}
--}
-
-data Range =
-  Range
-    { _start :: Position
-    , _end   :: Position
-    } deriving (Show, Read, Eq, Ord)
-
-deriveJSON lspOptions ''Range
-makeFieldsNoPrefix ''Range
-
--- ---------------------------------------------------------------------
-{-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#location
-
-Represents a location inside a resource, such as a line inside a text file.
-
-interface Location {
-    uri: string;
-    range: Range;
-}
--}
-
-data Location =
-  Location
-    { _uri   :: Uri
-    , _range :: Range
-    } deriving (Show, Read, Eq, Ord)
-
-deriveJSON lspOptions ''Location
-makeFieldsNoPrefix ''Location
-
--- ---------------------------------------------------------------------
-{-
-The protocol currently supports the following diagnostic severities:
-
-enum DiagnosticSeverity {
-    /**
-     * Reports an error.
-     */
-    Error = 1,
-    /**
-     * Reports a warning.
-     */
-    Warning = 2,
-    /**
-     * Reports an information.
-     */
-    Information = 3,
-    /**
-     * Reports a hint.
-     */
-    Hint = 4
-}
--}
-data DiagnosticSeverity
-  = DsError   -- ^ Error = 1,
-  | DsWarning -- ^ Warning = 2,
-  | DsInfo    -- ^ Info = 3,
-  | DsHint    -- ^ Hint = 4
-  deriving (Eq,Ord,Show,Read)
-
-instance A.ToJSON DiagnosticSeverity where
-  toJSON DsError   = A.Number 1
-  toJSON DsWarning = A.Number 2
-  toJSON DsInfo    = A.Number 3
-  toJSON DsHint    = A.Number 4
-
-instance A.FromJSON DiagnosticSeverity where
-  parseJSON (A.Number 1) = pure DsError
-  parseJSON (A.Number 2) = pure DsWarning
-  parseJSON (A.Number 3) = pure DsInfo
-  parseJSON (A.Number 4) = pure DsHint
-  parseJSON _            = mempty
-
--- ---------------------------------------------------------------------
-{-
-Represents a related message and source code location for a diagnostic. This should be
-used to point to code locations that cause or related to a diagnostics, e.g when duplicating
-a symbol in a scope.
-
-export interface DiagnosticRelatedInformation {
-  /**
-   * The location of this related diagnostic information.
-   */
-  location: Location;
-
-  /**
-   * The message of this related diagnostic information.
-   */
-  message: string;
-}
--}
-
-data DiagnosticRelatedInformation =
-  DiagnosticRelatedInformation
-    { _location :: Location
-    , _message  :: Text
-    } deriving (Show, Read, Eq, Ord)
-
-deriveJSON lspOptions ''DiagnosticRelatedInformation
-makeFieldsNoPrefix ''DiagnosticRelatedInformation
-
--- ---------------------------------------------------------------------
-{-
-Diagnostic
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#diagnostic
-
-Represents a diagnostic, such as a compiler error or warning. Diagnostic objects
-are only valid in the scope of a resource.
-
-interface Diagnostic {
-    /**
-     * The range at which the message applies.
-     */
-    range: Range;
-
-    /**
-     * The diagnostic's severity. Can be omitted. If omitted it is up to the
-     * client to interpret diagnostics as error, warning, info or hint.
-     */
-    severity?: number;
-
-    /**
-     * The diagnostic's code. Can be omitted.
-     */
-    code?: number | string;
-
-    /**
-     * A human-readable string describing the source of this
-     * diagnostic, e.g. 'typescript' or 'super lint'.
-     */
-    source?: string;
-
-    /**
-     * The diagnostic's message.
-     */
-    message: string;
-
-    /**
-     * An array of related diagnostic information, e.g. when symbol-names within
-     * a scope collide all definitions can be marked via this property.
-     */
-    relatedInformation?: DiagnosticRelatedInformation[];
-}
--}
-
-type DiagnosticSource = Text
-data Diagnostic =
-  Diagnostic
-    { _range              :: Range
-    , _severity           :: Maybe DiagnosticSeverity
-    , _code               :: Maybe Text -- Note: Protocol allows Int too.
-    , _source             :: Maybe DiagnosticSource
-    , _message            :: Text
-    , _relatedInformation :: Maybe (List DiagnosticRelatedInformation)
-    } deriving (Show, Read, Eq, Ord)
-
-deriveJSON lspOptions ''Diagnostic
-makeFieldsNoPrefix ''Diagnostic
-
--- ---------------------------------------------------------------------
-{-
-Command
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#command
-
-Represents a reference to a command. Provides a title which will be used to
-represent a command in the UI. Commands are identitifed using a string
-identifier and the protocol currently doesn't specify a set of well known
-commands. So executing a command requires some tool extension code.
-
-interface Command {
-    /**
-     * Title of the command, like `save`.
-     */
-    title: string;
-    /**
-     * The identifier of the actual command handler.
-     */
-    command: string;
-    /**
-     * Arguments that the command handler should be
-     * invoked with.
-     */
-    arguments?: any[];
-}
--}
-
-data Command =
-  Command
-    { _title     :: Text
-    , _command   :: Text
-    , _arguments :: Maybe A.Value
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''Command
-makeFieldsNoPrefix ''Command
-
--- ---------------------------------------------------------------------
-{-
-TextEdit
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textedit
-
-A textual edit applicable to a text document.
-
-interface TextEdit {
-    /**
-     * The range of the text document to be manipulated. To insert
-     * text into a document create a range where start === end.
-     */
-    range: Range;
-
-    /**
-     * The string to be inserted. For delete operations use an
-     * empty string.
-     */
-    newText: string;
-}
-
-
--}
-
-data TextEdit =
-  TextEdit
-    { _range   :: Range
-    , _newText :: Text
-    } deriving (Show,Read,Eq)
-
-deriveJSON lspOptions ''TextEdit
-makeFieldsNoPrefix ''TextEdit
-
--- ---------------------------------------------------------------------
-{-
-VersionedTextDocumentIdentifier
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#versionedtextdocumentidentifier
-
-    New: An identifier to denote a specific version of a text document.
-
-interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
-    /**
-     * The version number of this document.
-     */
-    version: number;
--}
-
-type TextDocumentVersion = Int
-
-data VersionedTextDocumentIdentifier =
-  VersionedTextDocumentIdentifier
-    { _uri     :: Uri
-    , _version :: TextDocumentVersion
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''VersionedTextDocumentIdentifier
-makeFieldsNoPrefix ''VersionedTextDocumentIdentifier
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-TextDocumentEdit
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#new-textdocumentedit
-
-If multiple TextEdits are applied to a text document, all text edits describe
-changes made to the initial document version. Execution wise text edits should
-applied from the bottom to the top of the text document. Overlapping text edits
-are not supported.
-
-export interface TextDocumentEdit {
-        /**
-         * The text document to change.
-         */
-        textDocument: VersionedTextDocumentIdentifier;
-
-        /**
-         * The edits to be applied.
-         */
-        edits: TextEdit[];
-}
-
--}
-
-data TextDocumentEdit =
-  TextDocumentEdit
-    { _textDocument :: VersionedTextDocumentIdentifier
-    , _edits        :: List TextEdit
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentEdit
-makeFieldsNoPrefix ''TextDocumentEdit
-
--- ---------------------------------------------------------------------
-{-
-Changed in 3.0
---------------
-
-WorkspaceEdit
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#workspaceedit
-
-
-Changed A workspace edit represents changes to many resources managed in the
-workspace. The edit should either provide changes or documentChanges. If
-documentChanges are present they are preferred over changes if the client can
-handle versioned document edits.
-
-export interface WorkspaceEdit {
-        /**
-         * Holds changes to existing resources.
-         */
-        changes?: { [uri: string]: TextEdit[]; };
-
-        /**
-         * An array of `TextDocumentEdit`s to express changes to specific a specific
-         * version of a text document. Whether a client supports versioned document
-         * edits is expressed via `WorkspaceClientCapabilities.versionedWorkspaceEdit`.
-         */
-        documentChanges?: TextDocumentEdit[];
-}
--}
-
-type WorkspaceEditMap = H.HashMap Uri (List TextEdit)
-
-data WorkspaceEdit =
-  WorkspaceEdit
-    { _changes         :: Maybe WorkspaceEditMap
-    , _documentChanges :: Maybe (List TextDocumentEdit)
-    } deriving (Show, Read, Eq)
-
-instance Monoid WorkspaceEdit where
-  mempty = WorkspaceEdit Nothing Nothing
-  mappend (WorkspaceEdit a b) (WorkspaceEdit c d) = WorkspaceEdit (a <> c) (b <> d)
-
-deriveJSON lspOptions ''WorkspaceEdit
-makeFieldsNoPrefix ''WorkspaceEdit
-
-#if __GLASGOW_HASKELL__ >= 804
-instance Semigroup WorkspaceEdit where
-  (<>) = mappend
-#endif
-
--- ---------------------------------------------------------------------
-{-
-TextDocumentIdentifier
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textdocumentidentifier
-
-Text documents are identified using a URI. On the protocol level, URIs are
-passed as strings. The corresponding JSON structure looks like this:
-
-interface TextDocumentIdentifier {
-    /**
-     * The text document's URI.
-     */
-    uri: string;
-}
--}
-data TextDocumentIdentifier =
-  TextDocumentIdentifier
-    { _uri :: Uri
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentIdentifier
-makeFieldsNoPrefix ''TextDocumentIdentifier
-
--- ---------------------------------------------------------------------
-
-{-
-TextDocumentItem
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textdocumentitem
-
-    New: An item to transfer a text document from the client to the server.
-
-interface TextDocumentItem {
-    /**
-     * The text document's URI.
-     */
-    uri: string;
-
-    /**
-     * The text document's language identifier.
-     */
-    languageId: string;
-
-    /**
-     * The version number of this document (it will strictly increase after each
-     * change, including undo/redo).
-     */
-    version: number;
-
-    /**
-     * The content of the opened text document.
-     */
-    text: string;
-}
--}
-
-data TextDocumentItem =
-  TextDocumentItem {
-    _uri        :: Uri
-  , _languageId :: Text
-  , _version    :: Int
-  , _text       :: Text
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentItem
-makeFieldsNoPrefix ''TextDocumentItem
-
--- ---------------------------------------------------------------------
-{-
-TextDocumentPositionParams
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textdocumentpositionparams
-
-    Changed: Was TextDocumentPosition in 1.0 with inlined parameters
-
-
-interface TextDocumentPositionParams {
-    /**
-     * The text document.
-     */
-    textDocument: TextDocumentIdentifier;
-
-    /**
-     * The position inside the text document.
-     */
-    position: Position;
-}
-
--}
-data TextDocumentPositionParams =
-  TextDocumentPositionParams
-    { _textDocument :: TextDocumentIdentifier
-    , _position     :: Position
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentPositionParams
-makeFieldsNoPrefix ''TextDocumentPositionParams
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-DocumentFilter
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#new-documentfilter
-
-A document filter denotes a document through properties like language, schema or
-pattern. Examples are a filter that applies to TypeScript files on disk or a
-filter the applies to JSON files with name package.json:
-
-    { language: 'typescript', scheme: 'file' }
-    { language: 'json', pattern: '**/package.json' }
-
-export interface DocumentFilter {
-        /**
-         * A language id, like `typescript`.
-         */
-        language?: string;
-
-        /**
-         * A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
-         */
-        scheme?: string;
-
-        /**
-         * A glob pattern, like `*.{ts,js}`.
-         */
-        pattern?: string;
-}
--}
-data DocumentFilter =
-  DocumentFilter
-    { _language :: Text
-    , _scheme   :: Text
-    , _pattern  :: Maybe Text
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''DocumentFilter
-makeFieldsNoPrefix ''DocumentFilter
-
-{-
-A document selector is the combination of one or many document filters.
-
-export type DocumentSelector = DocumentFilter[];
--}
-type DocumentSelector = List DocumentFilter
-
--- =====================================================================
--- ACTUAL PROTOCOL -----------------------------------------------------
--- =====================================================================
-
--- ---------------------------------------------------------------------
--- Initialize Request
--- ---------------------------------------------------------------------
-{-
-Initialize Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#initialize-request
-
-The initialize request is sent as the first request from the client to the server.
-
-Request
-
-    method: 'initialize'
-    params: InitializeParams defined as follows:
-
-interface InitializeParams {
-        /**
-         * The process Id of the parent process that started
-         * the server. Is null if the process has not been started by another process.
-         * If the parent process is not alive then the server should exit (see exit notification) its process.
-         */
-        processId: number | null;
-
-        /**
-         * The rootPath of the workspace. Is null
-         * if no folder is open.
-         *
-         * @deprecated in favour of rootUri.
-         */
-        rootPath?: string | null;
-
-        /**
-         * The rootUri of the workspace. Is null if no
-         * folder is open. If both `rootPath` and `rootUri` are set
-         * `rootUri` wins.
-         */
-        rootUri: DocumentUri | null;
-
-        /**
-         * User provided initialization options.
-         */
-        initializationOptions?: any;
-
-        /**
-         * The capabilities provided by the client (editor or tool)
-         */
-        capabilities: ClientCapabilities;
-
-        /**
-         * The initial trace setting. If omitted trace is disabled ('off').
-         */
-        trace?: 'off' | 'messages' | 'verbose';
-}
--}
-
-data Trace = TraceOff | TraceMessages | TraceVerbose
-           deriving (Show, Read, Eq)
-
-instance A.ToJSON Trace where
-  toJSON TraceOff      = A.String (T.pack "off")
-  toJSON TraceMessages = A.String (T.pack "messages")
-  toJSON TraceVerbose  = A.String (T.pack "verbose")
-
-instance A.FromJSON Trace where
-  parseJSON (A.String s) = case T.unpack s of
-    "off"      -> return TraceOff
-    "messages" -> return TraceMessages
-    "verbose"  -> return TraceVerbose
-    _          -> mempty
-  parseJSON _                               = mempty
-
-data InitializeParams =
-  InitializeParams {
-    _processId             :: Maybe Int
-  , _rootPath              :: Maybe Text -- ^ Deprecated in favour of _rootUri
-  , _rootUri               :: Maybe Uri
-  , _initializationOptions :: Maybe A.Value
-  , _capabilities          :: ClientCapabilities
-  , _trace                 :: Maybe Trace
-  } deriving (Show, Read, Eq)
-
-
-deriveJSON lspOptions ''InitializeParams
-makeFieldsNoPrefix ''InitializeParams
-
--- ---------------------------------------------------------------------
--- Initialize Response
--- ---------------------------------------------------------------------
-{-
-
-    error.data:
-
-interface InitializeError {
-    /**
-     * Indicates whether the client should retry to send the
-     * initilize request after showing the message provided
-     * in the ResponseError.
-     */
-    retry: boolean;
--
--}
-data InitializeError =
-  InitializeError
-    { _retry :: Bool
-    } deriving (Read, Show, Eq)
-
-deriveJSON lspOptions ''InitializeError
-makeFieldsNoPrefix ''InitializeError
-
--- ---------------------------------------------------------------------
-{-
-The server can signal the following capabilities:
-
-/**
- * Defines how the host (editor) should sync document changes to the language server.
- */
-enum TextDocumentSyncKind {
-    /**
-     * Documents should not be synced at all.
-     */
-    None = 0,
-    /**
-     * Documents are synced by always sending the full content of the document.
-     */
-    Full = 1,
-    /**
-     * Documents are synced by sending the full content on open. After that only incremental
-     * updates to the document are sent.
-     */
-    Incremental = 2
-}
--}
-
--- ^ Note: Omitting this parameter from the capabilities is effectively a fourth
--- state, where DidSave events are generated without sending document contents.
-data TextDocumentSyncKind = TdSyncNone
-                          | TdSyncFull
-                          | TdSyncIncremental
-       deriving (Read,Eq,Show)
-
-instance A.ToJSON TextDocumentSyncKind where
-  toJSON TdSyncNone        = A.Number 0
-  toJSON TdSyncFull        = A.Number 1
-  toJSON TdSyncIncremental = A.Number 2
-
-instance A.FromJSON TextDocumentSyncKind where
-  parseJSON (A.Number 0) = pure TdSyncNone
-  parseJSON (A.Number 1) = pure TdSyncFull
-  parseJSON (A.Number 2) = pure TdSyncIncremental
-  parseJSON _            = mempty
-
--- ---------------------------------------------------------------------
-{-
-/**
- * Completion options.
- */
-interface CompletionOptions {
-    /**
-     * The server provides support to resolve additional information for a completion item.
-     */
-    resolveProvider?: boolean;
-
-    /**
-     * The characters that trigger completion automatically.
-     */
-    triggerCharacters?: string[];
-}
--}
-
-data CompletionOptions =
-  CompletionOptions
-    { _resolveProvider   :: Maybe Bool
-    , _triggerCharacters :: Maybe [String]
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions {omitNothingFields = True } ''CompletionOptions
-makeFieldsNoPrefix ''CompletionOptions
-
--- ---------------------------------------------------------------------
-{-
-/**
- * Signature help options.
- */
-interface SignatureHelpOptions {
-    /**
-     * The characters that trigger signature help automatically.
-     */
-    triggerCharacters?: string[];
--}
-
-data SignatureHelpOptions =
-  SignatureHelpOptions
-    { _triggerCharacters :: Maybe [String]
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''SignatureHelpOptions
-makeFieldsNoPrefix ''SignatureHelpOptions
-
--- ---------------------------------------------------------------------
-{-
-/**
- * Code Lens options.
- */
-interface CodeLensOptions {
-    /**
-     * Code lens has a resolve provider as well.
-     */
-    resolveProvider?: boolean;
-}
--}
-
-data CodeLensOptions =
-  CodeLensOptions
-    { _resolveProvider :: Maybe Bool
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''CodeLensOptions
-makeFieldsNoPrefix ''CodeLensOptions
-
--- ---------------------------------------------------------------------
-{-
-/**
- * Format document on type options
- */
-interface DocumentOnTypeFormattingOptions {
-    /**
-     * A character on which formatting should be triggered, like `}`.
-     */
-    firstTriggerCharacter: string;
-    /**
-     * More trigger characters.
-     */
-    moreTriggerCharacter?: string[]
-}
--}
-data DocumentOnTypeFormattingOptions =
-  DocumentOnTypeFormattingOptions
-    { _firstTriggerCharacter :: Text
-    , _moreTriggerCharacter  :: Maybe [String]
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DocumentOnTypeFormattingOptions
-makeFieldsNoPrefix ''DocumentOnTypeFormattingOptions
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-/**
- * Document link options
- */
-export interface DocumentLinkOptions {
-        /**
-         * Document links have a resolve provider as well.
-         */
-        resolveProvider?: boolean;
-}
--}
-
-data DocumentLinkOptions =
-  DocumentLinkOptions
-    { -- |Document links have a resolve provider as well.
-      _resolveProvider :: Maybe Bool
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''DocumentLinkOptions
-makeFieldsNoPrefix ''DocumentLinkOptions
-
--- ---------------------------------------------------------------------
-
-{-
-New in 3.0
------------
-
-/**
- * Execute command options.
- */
-export interface ExecuteCommandOptions {
-        /**
-         * The commands to be executed on the server
-         */
-        commands: string[]
-}
--}
-
-data ExecuteCommandOptions =
-  ExecuteCommandOptions
-    { -- | The commands to be executed on the server
-      _commands :: List Text
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''ExecuteCommandOptions
-makeFieldsNoPrefix ''ExecuteCommandOptions
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-/**
- * Save options.
- */
-export interface SaveOptions {
-        /**
-         * The client is supposed to include the content on save.
-         */
-        includeText?: boolean;
-}
--}
-data SaveOptions =
-  SaveOptions
-    { -- |The client is supposed to include the content on save.
-      _includeText :: Maybe Bool
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''SaveOptions
-makeFieldsNoPrefix ''SaveOptions
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-export interface TextDocumentSyncOptions {
-        /**
-         * Open and close notifications are sent to the server.
-         */
-        openClose?: boolean;
-        /**
-         * Change notificatins are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
-         * and TextDocumentSyncKindIncremental.
-         */
-        change?: number;
-        /**
-         * Will save notifications are sent to the server.
-         */
-        willSave?: boolean;
-        /**
-         * Will save wait until requests are sent to the server.
-         */
-        willSaveWaitUntil?: boolean;
-        /**
-         * Save notifications are sent to the server.
-         */
-        save?: SaveOptions;
-}
--}
-
-data TextDocumentSyncOptions =
-  TextDocumentSyncOptions
-    { -- | Open and close notifications are sent to the server.
-      _openClose         :: Maybe Bool
-
-      -- | Change notificatins are sent to the server. See
-      -- TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
-      -- TextDocumentSyncKindIncremental.
-    , _change            :: Maybe TextDocumentSyncKind
-
-      -- | Will save notifications are sent to the server.
-    , _willSave          :: Maybe Bool
-
-      -- | Will save wait until requests are sent to the server.
-    , _willSaveWaitUntil :: Maybe Bool
-
-      -- |Save notifications are sent to the server.
-    , _save              :: Maybe SaveOptions
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentSyncOptions
-makeFieldsNoPrefix ''TextDocumentSyncOptions
-
--- ---------------------------------------------------------------------
-{-
-
-Extended in 3.0
----------------
-
-interface ServerCapabilities {
-        /**
-         * Defines how text documents are synced. Is either a detailed structure defining each notification or
-         * for backwards compatibility the TextDocumentSyncKind number.
-         */
-        textDocumentSync?: TextDocumentSyncOptions | number;
-        /**
-         * The server provides hover support.
-         */
-        hoverProvider?: boolean;
-        /**
-         * The server provides completion support.
-         */
-        completionProvider?: CompletionOptions;
-        /**
-         * The server provides signature help support.
-         */
-        signatureHelpProvider?: SignatureHelpOptions;
-        /**
-         * The server provides goto definition support.
-         */
-        definitionProvider?: boolean;
-        /**
-         * The server provides find references support.
-         */
-        referencesProvider?: boolean;
-        /**
-         * The server provides document highlight support.
-         */
-        documentHighlightProvider?: boolean;
-        /**
-         * The server provides document symbol support.
-         */
-        documentSymbolProvider?: boolean;
-        /**
-         * The server provides workspace symbol support.
-         */
-        workspaceSymbolProvider?: boolean;
-        /**
-         * The server provides code actions.
-         */
-        codeActionProvider?: boolean;
-        /**
-         * The server provides code lens.
-         */
-        codeLensProvider?: CodeLensOptions;
-        /**
-         * The server provides document formatting.
-         */
-        documentFormattingProvider?: boolean;
-        /**
-         * The server provides document range formatting.
-         */
-        documentRangeFormattingProvider?: boolean;
-        /**
-         * The server provides document formatting on typing.
-         */
-        documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions;
-        /**
-         * The server provides rename support.
-         */
-        renameProvider?: boolean;
-        /**
-         * The server provides document link support.
-         */
-        documentLinkProvider?: DocumentLinkOptions;
-        /**
-         * The server provides execute command support.
-         */
-        executeCommandProvider?: ExecuteCommandOptions;
-        /**
-         * Experimental server capabilities.
-         */
-        experimental?: any;
-}
--}
-
-data InitializeResponseCapabilitiesInner =
-  InitializeResponseCapabilitiesInner
-    { _textDocumentSync                 :: Maybe TextDocumentSyncOptions
-    , _hoverProvider                    :: Maybe Bool
-    , _completionProvider               :: Maybe CompletionOptions
-    , _signatureHelpProvider            :: Maybe SignatureHelpOptions
-    , _definitionProvider               :: Maybe Bool
-    , _referencesProvider               :: Maybe Bool
-    , _documentHighlightProvider        :: Maybe Bool
-    , _documentSymbolProvider           :: Maybe Bool
-    , _workspaceSymbolProvider          :: Maybe Bool
-    , _codeActionProvider               :: Maybe Bool
-    , _codeLensProvider                 :: Maybe CodeLensOptions
-    , _documentFormattingProvider       :: Maybe Bool
-    , _documentRangeFormattingProvider  :: Maybe Bool
-    , _documentOnTypeFormattingProvider :: Maybe DocumentOnTypeFormattingOptions
-    , _renameProvider                   :: Maybe Bool
-    -- Following are new in 3.0
-    , _documentLinkProvider             :: Maybe DocumentLinkOptions
-    , _executeCommandProvider           :: Maybe ExecuteCommandOptions
-    , _experimental                     :: Maybe A.Value
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''InitializeResponseCapabilitiesInner
-makeFieldsNoPrefix ''InitializeResponseCapabilitiesInner
-
-
--- ---------------------------------------------------------------------
--- |
---   Information about the capabilities of a language server
---
-data InitializeResponseCapabilities =
-  InitializeResponseCapabilities {
-    _capabilities :: InitializeResponseCapabilitiesInner
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''InitializeResponseCapabilities
-makeFieldsNoPrefix ''InitializeResponseCapabilities
-
--- ---------------------------------------------------------------------
-
-type InitializeResponse = ResponseMessage InitializeResponseCapabilities
-
-type InitializeRequest = RequestMessage ClientMethod InitializeParams InitializeResponseCapabilities
-
-{-
-    error.code:
-
-/**
- * Known error codes for an `InitializeError`;
- */
-export namespace InitializeError {
-        /**
-         * If the protocol version provided by the client can't be handled by the server.
-         * @deprecated This initialize error got replaced by client capabilities. There is
-         * no version handshake in version 3.0x
-         */
-        export const unknownProtocolVersion: number = 1;
-}
-
-    error.data:
-
-interface InitializeError {
-        /**
-         * Indicates whether the client execute the following retry logic:
-         * (1) show the message provided by the ResponseError to the user
-         * (2) user selects retry or cancel
-         * (3) if user selected retry the initialize method is sent again.
-         */
-        retry: boolean;
-}
--}
-
--- ---------------------------------------------------------------------
-
-{-
-New in 3.0
-----------
-Initialized Notification
-
-The initialized notification is sent from the client to the server after the
-client is fully initialized and is able to listen to arbritary requests and
-notifications sent from the server.
-
-Notification:
-
-    method: 'initialized'
-    params: void
-
--}
-
-data InitializedParams =
-  InitializedParams
-    {
-    } deriving (Show, Read, Eq)
-
-instance A.FromJSON InitializedParams where
-  parseJSON (A.Object _) = pure InitializedParams
-  parseJSON _            = mempty
-
-instance A.ToJSON InitializedParams where
-  toJSON InitializedParams = A.Object mempty
-
-type InitializedNotification = NotificationMessage ClientMethod (Maybe InitializedParams)
-
--- ---------------------------------------------------------------------
-{-
-Shutdown Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#shutdown-request
-
-The shutdown request is sent from the client to the server. It asks the server
-to shut down, but to not exit (otherwise the response might not be delivered
-correctly to the client). There is a separate exit notification that asks the
-server to exit.
-
-Request
-
-    method: 'shutdown'
-    params: undefined
-
-Response
-
-    result: undefined
-    error: code and message set in case an exception happens during shutdown request.
-
-
--}
-
-type ShutdownRequest  = RequestMessage ClientMethod (Maybe A.Value) Text
-type ShutdownResponse = ResponseMessage Text
-
--- ---------------------------------------------------------------------
-{-
-Exit Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#exit-notification
-
-A notification to ask the server to exit its process.
-
-Notification
-
-    method: 'exit'
-
--}
-
--- |
---   Notification from the server to actually exit now, after shutdown acked
---
-data ExitParams =
-  ExitParams
-    {
-    } deriving (Show, Read, Eq)
-
-deriveJSON defaultOptions ''ExitParams
-
-type ExitNotification = NotificationMessage ClientMethod (Maybe ExitParams)
-
--- ---------------------------------------------------------------------
-{-
-ShowMessage Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#showmessage-notification
-
-The show message notification is sent from a server to a client to ask the
-client to display a particular message in the user interface.
-
-Notification:
-
-    method: 'window/showMessage'
-    params: ShowMessageParams defined as follows:
-
-interface ShowMessageParams {
-    /**
-     * The message type. See {@link MessageType}.
-     */
-    type: number;
-
-    /**
-     * The actual message.
-     */
-    message: string;
-}
-
-Where the type is defined as follows:
-
-enum MessageType {
-    /**
-     * An error message.
-     */
-    Error = 1,
-    /**
-     * A warning message.
-     */
-    Warning = 2,
-    /**
-     * An information message.
-     */
-    Info = 3,
-    /**
-     * A log message.
-     */
-    Log = 4
-}
--}
-data MessageType = MtError   -- ^ Error = 1,
-                 | MtWarning -- ^ Warning = 2,
-                 | MtInfo    -- ^ Info = 3,
-                 | MtLog     -- ^ Log = 4
-        deriving (Eq,Ord,Show,Read,Enum)
-
-instance A.ToJSON MessageType where
-  toJSON MtError   = A.Number 1
-  toJSON MtWarning = A.Number 2
-  toJSON MtInfo    = A.Number 3
-  toJSON MtLog     = A.Number 4
-
-instance A.FromJSON MessageType where
-  parseJSON (A.Number 1) = pure MtError
-  parseJSON (A.Number 2) = pure MtWarning
-  parseJSON (A.Number 3) = pure MtInfo
-  parseJSON (A.Number 4) = pure MtLog
-  parseJSON _            = mempty
-
--- ---------------------------------------
-
-
-data ShowMessageParams =
-  ShowMessageParams {
-    _xtype   :: MessageType
-  , _message :: Text
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ShowMessageParams
-makeFieldsNoPrefix ''ShowMessageParams
-
-type ShowMessageNotification = NotificationMessage ServerMethod ShowMessageParams
-
--- ---------------------------------------------------------------------
-{-
-ShowMessage Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#showmessage-request
-
-    New: The show message request is sent from a server to a client to ask the
-    client to display a particular message in the user interface. In addition to
-    the show message notification the request allows to pass actions and to wait
-    for an answer from the client.
-
-Request:
-
-    method: 'window/showMessageRequest'
-    params: ShowMessageRequestParams defined as follows:
-
-Response:
-
-    result: the selected MessageActionItem
-    error: code and message set in case an exception happens during showing a message.
-
-interface ShowMessageRequestParams {
-    /**
-     * The message type. See {@link MessageType}
-     */
-    type: number;
-
-    /**
-     * The actual message
-     */
-    message: string;
-
-    /**
-     * The message action items to present.
-     */
-    actions?: MessageActionItem[];
-}
-
-Where the MessageActionItem is defined as follows:
-
-interface MessageActionItem {
-    /**
-     * A short title like 'Retry', 'Open Log' etc.
-     */
-    title: string;
-}
--}
-
-data MessageActionItem =
-  MessageActionItem
-    { _title :: Text
-    } deriving (Show,Read,Eq)
-
-deriveJSON lspOptions ''MessageActionItem
-makeFieldsNoPrefix ''MessageActionItem
-
-
-data ShowMessageRequestParams =
-  ShowMessageRequestParams
-    { _xtype   :: MessageType
-    , _message :: Text
-    , _actions :: Maybe [MessageActionItem]
-    } deriving (Show,Read,Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ShowMessageRequestParams
-makeFieldsNoPrefix ''ShowMessageRequestParams
-
-type ShowMessageRequest = RequestMessage ServerMethod ShowMessageRequestParams Text
-type ShowMessageResponse = ResponseMessage Text
-
--- ---------------------------------------------------------------------
-{-
-LogMessage Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#logmessage-notification
-
-The log message notification is sent from the server to the client to ask the
-client to log a particular message.
-
-Notification:
-
-    method: 'window/logMessage'
-    params: LogMessageParams defined as follows:
-
-interface LogMessageParams {
-    /**
-     * The message type. See {@link MessageType}
-     */
-    type: number;
-
-    /**
-     * The actual message
-     */
-    message: string;
-}
-
-Where type is defined as above.
--}
-
-data LogMessageParams =
-  LogMessageParams {
-    _xtype   :: MessageType
-  , _message :: Text
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''LogMessageParams
-makeFieldsNoPrefix ''LogMessageParams
-
-
-type LogMessageNotification = NotificationMessage ServerMethod LogMessageParams
-
--- ---------------------------------------------------------------------
-{-
-Telemetry Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#telemetry-notification
-
-    New: The telemetry notification is sent from the server to the client to ask
-    the client to log a telemetry event.
-
-Notification:
-
-    method: 'telemetry/event'
-    params: 'any'
--}
-
-
-type TelemetryNotification = NotificationMessage ServerMethod A.Value
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-Register Capability
-
-The client/registerCapability request is sent from the server to the client to
-register for a new capability on the client side. Not all clients need to
-support dynamic capability registration. A client opts in via the
-ClientCapabilities.dynamicRegistration property.
-
-Request:
-
-    method: 'client/registerCapability'
-    params: RegistrationParams
-
-Where RegistrationParams are defined as follows:
-
-/**
- * General paramters to to regsiter for a capability.
- */
-export interface Registration {
-        /**
-         * The id used to register the request. The id can be used to deregister
-         * the request again.
-         */
-        id: string;
-
-        /**
-         * The method / capability to register for.
-         */
-        method: string;
-
-        /**
-         * Options necessary for the registration.
-         */
-        registerOptions?: any;
-}
-
-export interface RegistrationParams {
-        registrations: Registration[];
-}
--}
-
-data Registration =
-  Registration
-    { -- |The id used to register the request. The id can be used to deregister
-      -- the request again.
-      _id              :: Text
-
-       -- | The method / capability to register for.
-    , _method          :: ClientMethod
-
-      -- | Options necessary for the registration.
-    , _registerOptions :: Maybe A.Value
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''Registration
-makeFieldsNoPrefix ''Registration
-
-data RegistrationParams =
-  RegistrationParams
-    { _registrations :: List Registration
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''RegistrationParams
-makeFieldsNoPrefix ''RegistrationParams
-
--- |Note: originates at the server
-type RegisterCapabilityRequest = RequestMessage ServerMethod RegistrationParams ()
-
--- -------------------------------------
-
-{-
-Since most of the registration options require to specify a document selector
-there is a base interface that can be used.
-
-export interface TextDocumentRegistrationOptions {
-        /**
-         * A document selector to identify the scope of the registration. If set to null
-         * the document selector provided on the client side will be used.
-         */
-        documentSelector: DocumentSelector | null;
-}
--}
-
-data TextDocumentRegistrationOptions =
-  TextDocumentRegistrationOptions
-    { _documentSelector :: Maybe DocumentSelector
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentRegistrationOptions
-makeFieldsNoPrefix ''TextDocumentRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-Unregister Capability
-
-The client/unregisterCapability request is sent from the server to the client to
-unregister a previously register capability.
-
-Request:
-
-    method: 'client/unregisterCapability'
-    params: UnregistrationParams
-
-Where UnregistrationParams are defined as follows:
-
-/**
- * General parameters to unregister a capability.
- */
-export interface Unregistration {
-        /**
-         * The id used to unregister the request or notification. Usually an id
-         * provided during the register request.
-         */
-        id: string;
-
-        /**
-         * The method / capability to unregister for.
-         */
-        method: string;
-}
-
-export interface UnregistrationParams {
-        unregisterations: Unregistration[];
-}
--}
-
-data Unregistration =
-  Unregistration
-    { -- | The id used to unregister the request or notification. Usually an id
-      -- provided during the register request.
-      _id     :: Text
-
-       -- |The method / capability to unregister for.
-    , _method :: Text
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''Unregistration
-makeFieldsNoPrefix ''Unregistration
-
-data UnregistrationParams =
-  UnregistrationParams
-    { _unregistrations :: List Unregistration
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''UnregistrationParams
-makeFieldsNoPrefix ''UnregistrationParams
-
-type UnregisterCapabilityRequest = RequestMessage ServerMethod UnregistrationParams ()
-
--- ---------------------------------------------------------------------
-{-
-DidChangeConfiguration Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didchangeconfiguration-notification
-
-A notification sent from the client to the server to signal the change of
-configuration settings.
-
-Notification:
-
-    method: 'workspace/didChangeConfiguration',
-    params: DidChangeConfigurationParams defined as follows:
-
-interface DidChangeConfigurationParams {
-    /**
-     * The actual changed settings
-     */
-    settings: any;
-}
--}
-
-data DidChangeConfigurationParams =
-  DidChangeConfigurationParams {
-    _settings :: A.Value
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''DidChangeConfigurationParams
-makeFieldsNoPrefix ''DidChangeConfigurationParams
-
-
-type DidChangeConfigurationNotification = NotificationMessage ClientMethod DidChangeConfigurationParams
-
--- ---------------------------------------------------------------------
-{-
-DidOpenTextDocument Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didopentextdocument-notification
-
-The document open notification is sent from the client to the server to signal
-newly opened text documents. The document's truth is now managed by the client
-and the server must not try to read the document's truth using the document's
-uri.
-
-Notification:
-
-    method: 'textDocument/didOpen'
-    params: DidOpenTextDocumentParams defined as follows:
-
-interface DidOpenTextDocumentParams {
-    /**
-     * The document that was opened.
-     */
-    textDocument: TextDocumentItem;
-}
-
-Registration Options: TextDocumentRegistrationOptions
--}
-
-data DidOpenTextDocumentParams =
-  DidOpenTextDocumentParams {
-    _textDocument :: TextDocumentItem
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''DidOpenTextDocumentParams
-makeFieldsNoPrefix ''DidOpenTextDocumentParams
-
-type DidOpenTextDocumentNotification = NotificationMessage ClientMethod DidOpenTextDocumentParams
-
--- ---------------------------------------------------------------------
-{-
-DidChangeTextDocument Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didchangetextdocument-notification
-
-    Changed: The document change notification is sent from the client to the
-    server to signal changes to a text document. In 2.0 the shape of the params
-    has changed to include proper version numbers and language ids.
-
-Notification:
-
-    method: 'textDocument/didChange'
-    params: DidChangeTextDocumentParams defined as follows:
-
-interface DidChangeTextDocumentParams {
-    /**
-     * The document that did change. The version number points
-     * to the version after all provided content changes have
-     * been applied.
-     */
-    textDocument: VersionedTextDocumentIdentifier;
-
-    /**
-     * The actual content changes.
-     */
-    contentChanges: TextDocumentContentChangeEvent[];
-}
-
-/**
- * An event describing a change to a text document. If range and rangeLength are omitted
- * the new text is considered to be the full content of the document.
- */
-interface TextDocumentContentChangeEvent {
-    /**
-     * The range of the document that changed.
-     */
-    range?: Range;
-
-    /**
-     * The length of the range that got replaced.
-     */
-    rangeLength?: number;
-
-    /**
-     * The new text of the document.
-     */
-    text: string;
-}
--}
-data TextDocumentContentChangeEvent =
-  TextDocumentContentChangeEvent
-    { _range       :: Maybe Range
-    , _rangeLength :: Maybe Int
-    , _text        :: Text
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions { omitNothingFields = True } ''TextDocumentContentChangeEvent
-makeFieldsNoPrefix ''TextDocumentContentChangeEvent
-
--- -------------------------------------
-
-data DidChangeTextDocumentParams =
-  DidChangeTextDocumentParams
-    { _textDocument   :: VersionedTextDocumentIdentifier
-    , _contentChanges :: List TextDocumentContentChangeEvent
-    } deriving (Show,Read,Eq)
-
-deriveJSON lspOptions ''DidChangeTextDocumentParams
-makeFieldsNoPrefix ''DidChangeTextDocumentParams
-
-type DidChangeTextDocumentNotification = NotificationMessage ClientMethod DidChangeTextDocumentParams
-{-
-New in 3.0
-----------
-
-Registration Options: TextDocumentChangeRegistrationOptions defined as follows:
-
-/**
- * Descibe options to be used when registered for text document change events.
- */
-export interface TextDocumentChangeRegistrationOptions extends TextDocumentRegistrationOptions {
-        /**
-         * How documents are synced to the server. See TextDocumentSyncKind.Full
-         * and TextDocumentSyncKindIncremental.
-         */
-        syncKind: number;
-}
--}
-
-data TextDocumentChangeRegistrationOptions =
-  TextDocumentChangeRegistrationOptions
-    { _documentSelector :: Maybe DocumentSelector
-    , _syncKind         :: TextDocumentSyncKind
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TextDocumentChangeRegistrationOptions
-makeFieldsNoPrefix ''TextDocumentChangeRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-
-New in 3.0
-----------
-
-WillSaveTextDocument Notification
-
-The document will save notification is sent from the client to the server before
-the document is actually saved.
-
-Notification:
-
-    method: 'textDocument/willSave'
-    params: WillSaveTextDocumentParams defined as follows:
-
-/**
- * The parameters send in a will save text document notification.
- */
-export interface WillSaveTextDocumentParams {
-        /**
-         * The document that will be saved.
-         */
-        textDocument: TextDocumentIdentifier;
-
-        /**
-         * The 'TextDocumentSaveReason'.
-         */
-        reason: number;
-}
-
-/**
- * Represents reasons why a text document is saved.
- */
-export namespace TextDocumentSaveReason {
-
-        /**
-         * Manually triggered, e.g. by the user pressing save, by starting debugging,
-         * or by an API call.
-         */
-        export const Manual = 1;
-
-        /**
-         * Automatic after a delay.
-         */
-        export const AfterDelay = 2;
-
-        /**
-         * When the editor lost focus.
-         */
-        export const FocusOut = 3;
-}
-Registration Options: TextDocumentRegistrationOptions
--}
-
-data TextDocumentSaveReason
-  = SaveManual
-         -- ^ Manually triggered, e.g. by the user pressing save, by starting
-         -- debugging, or by an API call.
-  | SaveAfterDelay -- ^ Automatic after a delay
-  | SaveFocusOut   -- ^ When the editor lost focus
-  deriving (Show, Read, Eq)
-
-instance A.ToJSON TextDocumentSaveReason where
-  toJSON SaveManual     = A.Number 1
-  toJSON SaveAfterDelay = A.Number 2
-  toJSON SaveFocusOut   = A.Number 3
-
-instance A.FromJSON TextDocumentSaveReason where
-  parseJSON (A.Number 1) = pure SaveManual
-  parseJSON (A.Number 2) = pure SaveAfterDelay
-  parseJSON (A.Number 3) = pure SaveFocusOut
-  parseJSON _            = mempty
-
-data WillSaveTextDocumentParams =
-  WillSaveTextDocumentParams
-    { _textDocument :: TextDocumentIdentifier
-    , _reason       :: TextDocumentSaveReason
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''WillSaveTextDocumentParams
-makeFieldsNoPrefix ''WillSaveTextDocumentParams
-
-type WillSaveTextDocumentNotification = NotificationMessage ClientMethod WillSaveTextDocumentParams
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-WillSaveWaitUntilTextDocument Request
-
-The document will save request is sent from the client to the server before the
-document is actually saved. The request can return an array of TextEdits which
-will be applied to the text document before it is saved. Please note that
-clients might drop results if computing the text edits took too long or if a
-server constantly fails on this request. This is done to keep the save fast and
-reliable.
-
-Request:
-
-    method: 'textDocument/willSaveWaitUntil'
-    params: WillSaveTextDocumentParams
-
-Response:
-
-    result: TextEdit[]
-    error: code and message set in case an exception happens during the willSaveWaitUntil request.
-
-Registration Options: TextDocumentRegistrationOptions
--}
-
-type WillSaveWaitUntilTextDocumentRequest = RequestMessage ClientMethod WillSaveTextDocumentParams (List TextEdit)
-type WillSaveWaitUntilTextDocumentResponse = ResponseMessage (List TextEdit)
-
--- ---------------------------------------------------------------------
-{-
-DidSaveTextDocument Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didsavetextdocument-notification
-
-    New: The document save notification is sent from the client to the server
-    when the document was saved in the client.
-
-    method: 'textDocument/didSave'
-    params: DidSaveTextDocumentParams defined as follows:
-
-interface DidSaveTextDocumentParams {
-    /**
-     * The document that was saved.
-     */
-    textDocument: TextDocumentIdentifier;
-}
--}
-data DidSaveTextDocumentParams =
-  DidSaveTextDocumentParams
-    { _textDocument :: TextDocumentIdentifier
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DidSaveTextDocumentParams
-makeFieldsNoPrefix ''DidSaveTextDocumentParams
-
-type DidSaveTextDocumentNotification = NotificationMessage ClientMethod DidSaveTextDocumentParams
-
-
-
--- ---------------------------------------------------------------------
-{-
-DidCloseTextDocument Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didclosetextdocument-notification
-
-The document close notification is sent from the client to the server when the
-document got closed in the client. The document's truth now exists where the
-document's uri points to (e.g. if the document's uri is a file uri the truth now
-exists on disk).
-
-    Changed: In 2.0 the params are of type DidCloseTextDocumentParams which
-    contains a reference to a text document.
-
-Notification:
-
-    method: 'textDocument/didClose'
-    params: DidCloseTextDocumentParams defined as follows:
-
-interface DidCloseTextDocumentParams {
-    /**
-     * The document that was closed.
-     */
-    textDocument: TextDocumentIdentifier;
-}
--}
-data DidCloseTextDocumentParams =
-  DidCloseTextDocumentParams
-    { _textDocument :: TextDocumentIdentifier
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DidCloseTextDocumentParams
-makeFieldsNoPrefix ''DidCloseTextDocumentParams
-
-
-type DidCloseTextDocumentNotification = NotificationMessage ClientMethod DidCloseTextDocumentParams
-
--- ---------------------------------------------------------------------
-{-
-DidChangeWatchedFiles Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didchangewatchedfiles-notification
-
-The watched files notification is sent from the client to the server when the
-client detects changes to files watched by the language client.
-
-Notification:
-
-    method: 'workspace/didChangeWatchedFiles'
-    params: DidChangeWatchedFilesParams defined as follows:
-
-interface DidChangeWatchedFilesParams {
-    /**
-     * The actual file events.
-     */
-    changes: FileEvent[];
-}
-
-Where FileEvents are described as follows:
-
-/**
- * The file event type.
- */
-enum FileChangeType {
-    /**
-     * The file got created.
-     */
-    Created = 1,
-    /**
-     * The file got changed.
-     */
-    Changed = 2,
-    /**
-     * The file got deleted.
-     */
-    Deleted = 3
-}
-
-/**
- * An event describing a file change.
- */
-interface FileEvent {
-    /**
-     * The file's URI.
-     */
-    uri: string;
-    /**
-     * The change type.
-     */
-    type: number;
--}
-data FileChangeType = FcCreated
-                    | FcChanged
-                    | FcDeleted
-       deriving (Read,Show,Eq)
-
-instance A.ToJSON FileChangeType where
-  toJSON FcCreated = A.Number 1
-  toJSON FcChanged = A.Number 2
-  toJSON FcDeleted = A.Number 3
-
-instance A.FromJSON FileChangeType where
-  parseJSON (A.Number 1) = pure FcCreated
-  parseJSON (A.Number 2) = pure FcChanged
-  parseJSON (A.Number 3) = pure FcDeleted
-  parseJSON _            = mempty
-
-
--- -------------------------------------
-
-data FileEvent =
-  FileEvent
-    { _uri   :: Uri
-    , _xtype :: FileChangeType
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''FileEvent
-makeFieldsNoPrefix ''FileEvent
-
-data DidChangeWatchedFilesParams =
-  DidChangeWatchedFilesParams
-    { _changes :: List FileEvent
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DidChangeWatchedFilesParams
-makeFieldsNoPrefix ''DidChangeWatchedFilesParams
-
-
-type DidChangeWatchedFilesNotification = NotificationMessage ClientMethod DidChangeWatchedFilesParams
-
--- ---------------------------------------------------------------------
-{-
-PublishDiagnostics Notification
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#publishdiagnostics-notification
-
-Diagnostics notification are sent from the server to the client to signal
-results of validation runs.
-
-Notification
-
-    method: 'textDocument/publishDiagnostics'
-    params: PublishDiagnosticsParams defined as follows:
-
-interface PublishDiagnosticsParams {
-    /**
-     * The URI for which diagnostic information is reported.
-     */
-    uri: string;
-
-    /**
-     * An array of diagnostic information items.
-     */
-    diagnostics: Diagnostic[];
-}
--}
-
-data PublishDiagnosticsParams =
-  PublishDiagnosticsParams
-    { _uri         :: Uri
-    , _diagnostics :: List Diagnostic
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''PublishDiagnosticsParams
-makeFieldsNoPrefix ''PublishDiagnosticsParams
-
-
-type PublishDiagnosticsNotification = NotificationMessage ServerMethod PublishDiagnosticsParams
-
--- ---------------------------------------------------------------------
-{-
-Completion Request
-
-The Completion request is sent from the client to the server to compute
-completion items at a given cursor position. Completion items are presented in
-the IntelliSense user interface. If computing full completion items is
-expensive, servers can additionally provide a handler for the completion item
-resolve request ('completionItem/resolve'). This request is sent when a
-completion item is selected in the user interface. A typically use case is for
-example: the 'textDocument/completion' request doesn't fill in the documentation
-property for returned completion items since it is expensive to compute. When
-the item is selected in the user interface then a 'completionItem/resolve'
-request is sent with the selected completion item as a param. The returned
-completion item should have the documentation property filled in.
-
-    Changed: In 2.0 the request uses TextDocumentPositionParams with a proper
-    textDocument and position property. In 1.0 the uri of the referenced text
-    document was inlined into the params object.
-
-Request
-
-    method: 'textDocument/completion'
-    params: TextDocumentPositionParams
--}
-
--- -------------------------------------
-
-{-
-
-Response
-
-    result: CompletionItem[] | CompletionList
-
-/**
- * Represents a collection of [completion items](#CompletionItem) to be presented
- * in the editor.
- */
-interface CompletionList {
-    /**
-     * This list it not complete. Further typing should result in recomputing
-     * this list.
-     */
-    isIncomplete: boolean;
-    /**
-     * The completion items.
-     */
-    items: CompletionItem[];
-}
-
-
-New in 3.0 : InsertTextFormat
-
-/**
- * Defines whether the insert text in a completion item should be interpreted as
- * plain text or a snippet.
- */
-namespace InsertTextFormat {
-        /**
-         * The primary text to be inserted is treated as a plain string.
-         */
-        export const PlainText = 1;
-
-        /**
-         * The primary text to be inserted is treated as a snippet.
-         *
-         * A snippet can define tab stops and placeholders with `$1`, `$2`
-         * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
-         * the end of the snippet. Placeholders with equal identifiers are linked,
-         * that is typing in one will update others too.
-         *
-         * See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
-         */
-        export const Snippet = 2;
-}
-
-
-
-interface CompletionItem {
-    /**
-     * The label of this completion item. By default
-     * also the text that is inserted when selecting
-     * this completion.
-     */
-    label: string;
-    /**
-     * The kind of this completion item. Based of the kind
-     * an icon is chosen by the editor.
-     */
-    kind?: number;
-    /**
-     * A human-readable string with additional information
-     * about this item, like type or symbol information.
-     */
-    detail?: string;
-    /**
-     * A human-readable string that represents a doc-comment.
-     */
-    documentation?: string;
-    /**
-     * A string that shoud be used when comparing this item
-     * with other items. When `falsy` the label is used.
-     */
-    sortText?: string;
-    /**
-     * A string that should be used when filtering a set of
-     * completion items. When `falsy` the label is used.
-     */
-    filterText?: string;
-    /**
-     * A string that should be inserted a document when selecting
-     * this completion. When `falsy` the label is used.
-     */
-    insertText?: string;
-    -- Following field is new in 3.0
-        /**
-         * The format of the insert text. The format applies to both the `insertText` property
-         * and the `newText` property of a provided `textEdit`.
-         */
-    insertTextFormat?: InsertTextFormat;
-        /**
-         * An edit which is applied to a document when selecting this completion. When an edit is provided the value of
-         * `insertText` is ignored.
-         *
-         * *Note:* The range of the edit must be a single line range and it must contain the position at which completion
-         * has been requested.
-         */
-
-    textEdit?: TextEdit;
-
-    -- Following field is new in 3.0
-        /**
-         * An optional array of additional text edits that are applied when
-         * selecting this completion. Edits must not overlap with the main edit
-         * nor with themselves.
-         */
-    additionalTextEdits?: TextEdit[];
-    -- Following field is new in 3.0
-        /**
-         * An optional command that is executed *after* inserting this completion. *Note* that
-         * additional modifications to the current document should be described with the
-         * additionalTextEdits-property.
-         */
-
-    command?: Command;
-        /**
-         * An data entry field that is preserved on a completion item between
-         * a completion and a completion resolve request.
-         */
-
-    data?: any
-}
-
-Where CompletionItemKind is defined as follows:
-
-/**
- * The kind of a completion entry.
- */
-enum CompletionItemKind {
-    Text = 1,
-    Method = 2,
-    Function = 3,
-    Constructor = 4,
-    Field = 5,
-    Variable = 6,
-    Class = 7,
-    Interface = 8,
-    Module = 9,
-    Property = 10,
-    Unit = 11,
-    Value = 12,
-    Enum = 13,
-    Keyword = 14,
-    Snippet = 15,
-    Color = 16,
-    File = 17,
-    Reference = 18
-}
-
-    error: code and message set in case an exception happens during the completion request.
--}
-
--- -------------------------------------
-
-data InsertTextFormat
-  = PlainText -- ^The primary text to be inserted is treated as a plain string.
-  | Snippet
-      -- ^ The primary text to be inserted is treated as a snippet.
-      --
-      -- A snippet can define tab stops and placeholders with `$1`, `$2`
-      -- and `${3:foo}`. `$0` defines the final tab stop, it defaults to
-      -- the end of the snippet. Placeholders with equal identifiers are linked,
-      -- that is typing in one will update others too.
-      --
-      -- See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
-    deriving (Show, Read, Eq)
-
-instance A.ToJSON InsertTextFormat where
-  toJSON PlainText = A.Number 1
-  toJSON Snippet   = A.Number 2
-
-instance A.FromJSON InsertTextFormat where
-  parseJSON (A.Number  1) = pure PlainText
-  parseJSON (A.Number  2) = pure Snippet
-  parseJSON _             = mempty
-
--- -------------------------------------
-
-data CompletionItemKind = CiText
-                        | CiMethod
-                        | CiFunction
-                        | CiConstructor
-                        | CiField
-                        | CiVariable
-                        | CiClass
-                        | CiInterface
-                        | CiModule
-                        | CiProperty
-                        | CiUnit
-                        | CiValue
-                        | CiEnum
-                        | CiKeyword
-                        | CiSnippet
-                        | CiColor
-                        | CiFile
-                        | CiReference
-         deriving (Read,Show,Eq,Ord)
-
-instance A.ToJSON CompletionItemKind where
-  toJSON CiText        = A.Number 1
-  toJSON CiMethod      = A.Number 2
-  toJSON CiFunction    = A.Number 3
-  toJSON CiConstructor = A.Number 4
-  toJSON CiField       = A.Number 5
-  toJSON CiVariable    = A.Number 6
-  toJSON CiClass       = A.Number 7
-  toJSON CiInterface   = A.Number 8
-  toJSON CiModule      = A.Number 9
-  toJSON CiProperty    = A.Number 10
-  toJSON CiUnit        = A.Number 11
-  toJSON CiValue       = A.Number 12
-  toJSON CiEnum        = A.Number 13
-  toJSON CiKeyword     = A.Number 14
-  toJSON CiSnippet     = A.Number 15
-  toJSON CiColor       = A.Number 16
-  toJSON CiFile        = A.Number 17
-  toJSON CiReference   = A.Number 18
-
-instance A.FromJSON CompletionItemKind where
-  parseJSON (A.Number  1) = pure CiText
-  parseJSON (A.Number  2) = pure CiMethod
-  parseJSON (A.Number  3) = pure CiFunction
-  parseJSON (A.Number  4) = pure CiConstructor
-  parseJSON (A.Number  5) = pure CiField
-  parseJSON (A.Number  6) = pure CiVariable
-  parseJSON (A.Number  7) = pure CiClass
-  parseJSON (A.Number  8) = pure CiInterface
-  parseJSON (A.Number  9) = pure CiModule
-  parseJSON (A.Number 10) = pure CiProperty
-  parseJSON (A.Number 11) = pure CiUnit
-  parseJSON (A.Number 12) = pure CiValue
-  parseJSON (A.Number 13) = pure CiEnum
-  parseJSON (A.Number 14) = pure CiKeyword
-  parseJSON (A.Number 15) = pure CiSnippet
-  parseJSON (A.Number 16) = pure CiColor
-  parseJSON (A.Number 17) = pure CiFile
-  parseJSON (A.Number 18) = pure CiReference
-  parseJSON _             = mempty
-
-
--- -------------------------------------
-
-data CompletionItem =
-  CompletionItem
-    { _label               :: Text -- ^ The label of this completion item. By default also
-                       -- the text that is inserted when selecting this
-                       -- completion.
-    , _kind                :: Maybe CompletionItemKind
-    , _detail              :: Maybe Text -- ^ A human-readable string with additional
-                              -- information about this item, like type or
-                              -- symbol information.
-    , _documentation       :: Maybe Text -- ^ A human-readable string that represents
-                                    -- a doc-comment.
-    , _sortText            :: Maybe Text -- ^ A string that should be used when filtering
-                                -- a set of completion items. When `falsy` the
-                                -- label is used.
-    , _filterText          :: Maybe Text -- ^ A string that should be used when
-                                  -- filtering a set of completion items. When
-                                  -- `falsy` the label is used.
-    , _insertText          :: Maybe Text -- ^ A string that should be inserted a
-                                  -- document when selecting this completion.
-                                  -- When `falsy` the label is used.
-    , _insertTextFormat    :: Maybe InsertTextFormat
-         -- ^ The format of the insert text. The format applies to both the
-         -- `insertText` property and the `newText` property of a provided
-         -- `textEdit`.
-    , _textEdit            :: Maybe TextEdit
-         -- ^ An edit which is applied to a document when selecting this
-         -- completion. When an edit is provided the value of `insertText` is
-         -- ignored.
-         --
-         -- *Note:* The range of the edit must be a single line range and it
-         -- must contain the position at which completion has been requested.
-    , _additionalTextEdits :: Maybe (List TextEdit)
-         -- ^ An optional array of additional text edits that are applied when
-         -- selecting this completion. Edits must not overlap with the main edit
-         -- nor with themselves.
-    , _command             :: Maybe Command
-        -- ^ An optional command that is executed *after* inserting this
-        -- completion. *Note* that additional modifications to the current
-        -- document should be described with the additionalTextEdits-property.
-    , _xdata               :: Maybe A.Value -- ^ An data entry field that is preserved on a
-                              -- completion item between a completion and a
-                              -- completion resolve request.
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''CompletionItem
-makeFieldsNoPrefix ''CompletionItem
-
-data CompletionListType =
-  CompletionListType
-    { _isIncomplete :: Bool
-    , _items        :: List CompletionItem
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''CompletionListType
-makeFieldsNoPrefix ''CompletionListType
-
-
-data CompletionResponseResult
-  = CompletionList CompletionListType
-  | Completions (List CompletionItem)
-  deriving (Read,Show,Eq)
-
-deriveJSON defaultOptions { fieldLabelModifier = rdrop (length ("CompletionResponseResult"::String)), sumEncoding = UntaggedValue } ''CompletionResponseResult
-
-type CompletionResponse = ResponseMessage CompletionResponseResult
-type CompletionRequest = RequestMessage ClientMethod TextDocumentPositionParams CompletionResponseResult
-
--- -------------------------------------
-{-
-New in 3.0
------------
-Registration Options: CompletionRegistrationOptions options defined as follows:
-
-export interface CompletionRegistrationOptions extends TextDocumentRegistrationOptions {
-        /**
-         * The characters that trigger completion automatically.
-         */
-        triggerCharacters?: string[];
-
-        /**
-         * The server provides support to resolve additional
-         * information for a completion item.
-         */
-        resolveProvider?: boolean;
-}
--}
-
-data CompletionRegistrationOptions =
-  CompletionRegistrationOptions
-    { _documentSelector  :: Maybe DocumentSelector
-    , _triggerCharacters :: Maybe (List String)
-    , _resolveProvider   :: Maybe Bool
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''CompletionRegistrationOptions
-makeFieldsNoPrefix ''CompletionRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-Completion Item Resolve Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#completion-item-resolve-request
-
-The request is sent from the client to the server to resolve additional
-information for a given completion item.
-
-Request
-
-    method: 'completionItem/resolve'
-    params: CompletionItem
-
-Response
-
-    result: CompletionItem
-    error: code and message set in case an exception happens during the completion resolve request.
--}
-
-type CompletionItemResolveRequest  = RequestMessage ClientMethod CompletionItem CompletionItem
-type CompletionItemResolveResponse = ResponseMessage CompletionItem
-
--- ---------------------------------------------------------------------
-{-
-Hover Request
-
-The hover request is sent from the client to the server to request hover
-information at a given text document position.
-
-    Changed: In 2.0 the request uses TextDocumentPositionParams with a proper
-    textDocument and position property. In 1.0 the uri of the referenced text
-    document was inlined into the params object.
-
-Request
-
-    method: 'textDocument/hover'
-    params: TextDocumentPositionParams
-
-Response
-
-    result: Hover defined as follows:
-
-/**
- * The result of a hove request.
- */
-interface Hover {
-    /**
-     * The hover's content
-     */
-    contents: MarkedString | MarkedString[];
-
-    /**
-     * An optional range
-     */
-    range?: Range;
-}
-
-Where MarkedString is defined as follows:
-/**
- * MarkedString can be used to render human readable text. It is either a markdown string
- * or a code-block that provides a language and a code snippet. The language identifier
- * is sematically equal to the optional language identifier in fenced code blocks in GitHub
- * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
- *
- * The pair of a language and a value is an equivalent to markdown:
- * ```${language}
- * ${value}
- * ```
- *
- * Note that markdown strings will be sanitized - that means html will be escaped.
- */
-type MarkedString = string | { language: string; value: string };
-
-    error: code and message set in case an exception happens during the hover
-    request.
-
-Registration Options: TextDocumentRegistrationOptions
-
--}
-
-data LanguageString =
-  LanguageString
-    { _language :: Text
-    , _value    :: Text
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''LanguageString
-makeFieldsNoPrefix ''LanguageString
-
-data MarkedString =
-    PlainString T.Text
-  | CodeString LanguageString
-    deriving (Eq,Read,Show)
-
-instance ToJSON MarkedString where
-  toJSON (PlainString x) = toJSON x
-  toJSON (CodeString  x) = toJSON x
-instance FromJSON MarkedString where
-  parseJSON (A.String t) = pure $ PlainString t
-  parseJSON o            = CodeString <$> parseJSON o
-
-data Hover =
-  Hover
-    { _contents :: List MarkedString
-    , _range    :: Maybe Range
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''Hover
-makeFieldsNoPrefix ''Hover
-
-
-type HoverRequest = RequestMessage ClientMethod TextDocumentPositionParams Hover
-type HoverResponse = ResponseMessage Hover
-
--- ---------------------------------------------------------------------
-{-
-Signature Help Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#signature-help-request
-
-The signature help request is sent from the client to the server to request
-signature information at a given cursor position.
-
-    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
-    textDocument and position properties. In 1.0 the uri of the referenced text
-    document was inlined into the params object.
-
-Request
-
-    method: 'textDocument/signatureHelp'
-    params: TextDocumentPositionParams
-
-Response
-
-    result: SignatureHelp defined as follows:
-
-/**
- * Signature help represents the signature of something
- * callable. There can be multiple signature but only one
- * active and only one active parameter.
- */
-interface SignatureHelp {
-    /**
-     * One or more signatures.
-     */
-    signatures: SignatureInformation[];
-
-    /**
-     * The active signature.
-     */
-    activeSignature?: number;
-
-    /**
-     * The active parameter of the active signature.
-     */
-    activeParameter?: number;
-}
-
-/**
- * Represents the signature of something callable. A signature
- * can have a label, like a function-name, a doc-comment, and
- * a set of parameters.
- */
-interface SignatureInformation {
-    /**
-     * The label of this signature. Will be shown in
-     * the UI.
-     */
-    label: string;
-
-    /**
-     * The human-readable doc-comment of this signature. Will be shown
-     * in the UI but can be omitted.
-     */
-    documentation?: string;
-
-    /**
-     * The parameters of this signature.
-     */
-    parameters?: ParameterInformation[];
-}
-
-/**
- * Represents a parameter of a callable-signature. A parameter can
- * have a label and a doc-comment.
- */
-interface ParameterInformation {
-    /**
-     * The label of this signature. Will be shown in
-     * the UI.
-     */
-    label: string;
-
-    /**
-     * The human-readable doc-comment of this signature. Will be shown
-     * in the UI but can be omitted.
-     */
-    documentation?: string;
-}
-
-    error: code and message set in case an exception happens during the
-    signature help request.
--}
-
-
-data ParameterInformation =
-  ParameterInformation
-    { _label         :: Text
-    , _documentation :: Maybe Text
-    } deriving (Read,Show,Eq)
-deriveJSON lspOptions ''ParameterInformation
-makeFieldsNoPrefix ''ParameterInformation
-
-
--- -------------------------------------
-
-data SignatureInformation =
-  SignatureInformation
-    { _label         :: Text
-    , _documentation :: Maybe Text
-    , _parameters    :: Maybe [ParameterInformation]
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''SignatureInformation
-makeFieldsNoPrefix ''SignatureInformation
-
-data SignatureHelp =
-  SignatureHelp
-    { _signatures      :: List SignatureInformation
-    , _activeSignature :: Maybe Int -- ^ The active signature
-    , _activeParameter :: Maybe Int -- ^ The active parameter of the active signature
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''SignatureHelp
-makeFieldsNoPrefix ''SignatureHelp
-
-type SignatureHelpRequest = RequestMessage ClientMethod TextDocumentPositionParams SignatureHelp
-type SignatureHelpResponse = ResponseMessage SignatureHelp
-
--- -------------------------------------
-{-
-New in 3.0
-----------
-Registration Options: SignatureHelpRegistrationOptions defined as follows:
-
-export interface SignatureHelpRegistrationOptions extends TextDocumentRegistrationOptions {
-        /**
-         * The characters that trigger signature help
-         * automatically.
-         */
-        triggerCharacters?: string[];
-}
--}
-
-data SignatureHelpRegistrationOptions =
-  SignatureHelpRegistrationOptions
-    { _documentSelector  :: Maybe DocumentSelector
-    , _triggerCharacters :: Maybe (List String)
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''SignatureHelpRegistrationOptions
-makeFieldsNoPrefix ''SignatureHelpRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-Goto Definition Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#goto-definition-request
-
-The goto definition request is sent from the client to the server to resolve the
-definition location of a symbol at a given text document position.
-
-    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
-    textDocument and position properties. In 1.0 the uri of the referenced text
-    document was inlined into the params object.
-
-Request
-
-    method: 'textDocument/definition'
-    params: TextDocumentPositionParams
-
-Response:
-
-    result: Location | Location[]
-    error: code and message set in case an exception happens during the definition request.
-
-
--}
-
--- {"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///tmp/Foo.hs"},"position":{"line":1,"character":8}}}
-
-data DefinitionResponseParams = SingleLoc Location | MultiLoc [Location]
-  deriving (Eq,Read,Show)
-
-instance A.ToJSON DefinitionResponseParams where
-  toJSON (SingleLoc x) = toJSON x
-  toJSON (MultiLoc xs) = toJSON xs
-
-instance A.FromJSON DefinitionResponseParams where
-  parseJSON xs@(A.Array _) = MultiLoc <$> parseJSON xs
-  parseJSON x              = SingleLoc <$> parseJSON x
-
-type DefinitionRequest  = RequestMessage ClientMethod TextDocumentPositionParams DefinitionResponseParams
-type DefinitionResponse = ResponseMessage DefinitionResponseParams
-
--- ---------------------------------------------------------------------
-
-{-
-Find References Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#find-references-request
-
-The references request is sent from the client to the server to resolve
-project-wide references for the symbol denoted by the given text document
-position.
-
-    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
-    textDocument and position properties. In 1.0 the uri of the referenced text
-    document was inlined into the params object.
-
-Request
-
-    method: 'textDocument/references'
-    params: ReferenceParams defined as follows:
-
-interface ReferenceParams extends TextDocumentPositionParams {
-    context: ReferenceContext
-}
-
-interface ReferenceContext {
-    /**
-     * Include the declaration of the current symbol.
-     */
-    includeDeclaration: boolean;
-}
-
-Response:
-
-    result: Location[]
-    error: code and message set in case an exception happens during the
-           reference request.
--}
-
-data ReferenceContext =
-  ReferenceContext
-    { _includeDeclaration :: Bool
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''ReferenceContext
-makeFieldsNoPrefix ''ReferenceContext
-
-
-data ReferenceParams =
-  ReferenceParams
-    { _textDocument :: TextDocumentIdentifier
-    , _position     :: Position
-    , _context      :: ReferenceContext
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''ReferenceParams
-makeFieldsNoPrefix ''ReferenceParams
-
-
-type ReferencesRequest  = RequestMessage ClientMethod ReferenceParams (List Location)
-type ReferencesResponse = ResponseMessage (List Location)
-
--- ---------------------------------------------------------------------
-{-
-Document Highlights Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-highlights-request
-
-The document highlight request is sent from the client to the server to resolve
-a document highlights for a given text document position. For programming
-languages this usually highlights all references to the symbol scoped to this
-file. However we kept 'textDocument/documentHighlight' and
-'textDocument/references' separate requests since the first one is allowed to be
-more fuzzy. Symbol matches usually have a DocumentHighlightKind of Read or Write
-whereas fuzzy or textual matches use Textas the kind.
-
-    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
-    textDocument and position properties. In 1.0 the uri of the referenced text
-    document was inlined into the params object.
-
-Request
-
-    method: 'textDocument/documentHighlight'
-    params: TextDocumentPositionParams
-
-Response
-
-    result: DocumentHighlight[] defined as follows:
-
-/**
- * A document highlight is a range inside a text document which deserves
- * special attention. Usually a document highlight is visualized by changing
- * the background color of its range.
- *
- */
-interface DocumentHighlight {
-    /**
-     * The range this highlight applies to.
-     */
-    range: Range;
-
-    /**
-     * The highlight kind, default is DocumentHighlightKind.Text.
-     */
-    kind?: number;
-}
-
-/**
- * A document highlight kind.
- */
-enum DocumentHighlightKind {
-    /**
-     * A textual occurrance.
-     */
-    Text = 1,
-
-    /**
-     * Read-access of a symbol, like reading a variable.
-     */
-    Read = 2,
-
-    /**
-     * Write-access of a symbol, like writing to a variable.
-     */
-    Write = 3
-}
-
-    error: code and message set in case an exception happens during the document
-           highlight request.
-
-Registration Options: TextDocumentRegistrationOptions
-
--}
-
-data DocumentHighlightKind = HkText | HkRead | HkWrite
-  deriving (Read,Show,Eq)
-
-instance A.ToJSON DocumentHighlightKind where
-  toJSON HkText  = A.Number 1
-  toJSON HkRead  = A.Number 2
-  toJSON HkWrite = A.Number 3
-
-instance A.FromJSON DocumentHighlightKind where
-  parseJSON (A.Number 1) = pure HkText
-  parseJSON (A.Number 2) = pure HkRead
-  parseJSON (A.Number 3) = pure HkWrite
-  parseJSON _            = mempty
-
--- -------------------------------------
-
-data DocumentHighlight =
-  DocumentHighlight
-    { _range :: Range
-    , _kind  :: Maybe DocumentHighlightKind
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DocumentHighlight
-makeFieldsNoPrefix ''DocumentHighlight
-
-type DocumentHighlightRequest = RequestMessage ClientMethod TextDocumentPositionParams (List DocumentHighlight)
-type DocumentHighlightsResponse = ResponseMessage (List DocumentHighlight)
-
--- ---------------------------------------------------------------------
-{-
-Document Symbols Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-symbols-request
-
-The document symbol request is sent from the client to the server to list all
-symbols found in a given text document.
-
-    Changed: In 2.0 the request uses DocumentSymbolParams instead of a single
-             uri.
-
-Request
-
-    method: 'textDocument/documentSymbol'
-    params: DocumentSymbolParams defined as follows:
-
-interface DocumentSymbolParams {
-    /**
-     * The text document.
-     */
-    textDocument: TextDocumentIdentifier;
-}
-
-Response
-
-    result: SymbolInformation[] defined as follows:
-
-/**
- * Represents information about programming constructs like variables, classes,
- * interfaces etc.
- */
-interface SymbolInformation {
-    /**
-     * The name of this symbol.
-     */
-    name: string;
-
-    /**
-     * The kind of this symbol.
-     */
-    kind: number;
-
-    /**
-     * The location of this symbol.
-     */
-    location: Location;
-
-    /**
-     * The name of the symbol containing this symbol.
-     */
-    containerName?: string;
-}
-
-Where the kind is defined like this:
-
-/**
- * A symbol kind.
- */
-export enum SymbolKind {
-    File = 1,
-    Module = 2,
-    Namespace = 3,
-    Package = 4,
-    Class = 5,
-    Method = 6,
-    Property = 7,
-    Field = 8,
-    Constructor = 9,
-    Enum = 10,
-    Interface = 11,
-    Function = 12,
-    Variable = 13,
-    Constant = 14,
-    Text = 15,
-    Number = 16,
-    Boolean = 17,
-    Array = 18,
-}
-
-    error: code and message set in case an exception happens during the document
-           symbol request.
-
-Registration Options: TextDocumentRegistrationOptions
--}
-
-data DocumentSymbolParams =
-  DocumentSymbolParams
-    { _textDocument :: TextDocumentIdentifier
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DocumentSymbolParams
-makeFieldsNoPrefix ''DocumentSymbolParams
-
--- -------------------------------------
-
-data SymbolKind
-    = SkFile
-    | SkModule
-    | SkNamespace
-    | SkPackage
-    | SkClass
-    | SkMethod
-    | SkProperty
-    | SkField
-    | SkConstructor
-    | SkEnum
-    | SkInterface
-    | SkFunction
-    | SkVariable
-    | SkConstant
-    | SkString
-    | SkNumber
-    | SkBoolean
-    | SkArray
-    deriving (Read,Show,Eq)
-
-instance A.ToJSON SymbolKind where
-  toJSON SkFile        = A.Number 1
-  toJSON SkModule      = A.Number 2
-  toJSON SkNamespace   = A.Number 3
-  toJSON SkPackage     = A.Number 4
-  toJSON SkClass       = A.Number 5
-  toJSON SkMethod      = A.Number 6
-  toJSON SkProperty    = A.Number 7
-  toJSON SkField       = A.Number 8
-  toJSON SkConstructor = A.Number 9
-  toJSON SkEnum        = A.Number 10
-  toJSON SkInterface   = A.Number 11
-  toJSON SkFunction    = A.Number 12
-  toJSON SkVariable    = A.Number 13
-  toJSON SkConstant    = A.Number 14
-  toJSON SkString      = A.Number 15
-  toJSON SkNumber      = A.Number 16
-  toJSON SkBoolean     = A.Number 17
-  toJSON SkArray       = A.Number 18
-
-instance A.FromJSON SymbolKind where
-  parseJSON (A.Number  1) = pure SkFile
-  parseJSON (A.Number  2) = pure SkModule
-  parseJSON (A.Number  3) = pure SkNamespace
-  parseJSON (A.Number  4) = pure SkPackage
-  parseJSON (A.Number  5) = pure SkClass
-  parseJSON (A.Number  6) = pure SkMethod
-  parseJSON (A.Number  7) = pure SkProperty
-  parseJSON (A.Number  8) = pure SkField
-  parseJSON (A.Number  9) = pure SkConstructor
-  parseJSON (A.Number 10) = pure SkEnum
-  parseJSON (A.Number 11) = pure SkInterface
-  parseJSON (A.Number 12) = pure SkFunction
-  parseJSON (A.Number 13) = pure SkVariable
-  parseJSON (A.Number 14) = pure SkConstant
-  parseJSON (A.Number 15) = pure SkString
-  parseJSON (A.Number 16) = pure SkNumber
-  parseJSON (A.Number 17) = pure SkBoolean
-  parseJSON (A.Number 18) = pure SkArray
-  parseJSON _             = mempty
-
-
--- ---------------------------------------------------------------------
-
-data SymbolInformation =
-  SymbolInformation
-    { _name          :: Text
-    , _kind          :: SymbolKind
-    , _location      :: Location
-    , _containerName :: Maybe Text -- ^The name of the symbol containing this
-                                     -- symbol.
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''SymbolInformation
-makeFieldsNoPrefix ''SymbolInformation
-
-
--- -------------------------------------
-
-type DocumentSymbolRequest = RequestMessage ClientMethod DocumentSymbolParams (List SymbolInformation)
-type DocumentSymbolsResponse = ResponseMessage (List SymbolInformation)
-
--- ---------------------------------------------------------------------
-{-
-Workspace Symbols Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#workspace-symbols-request
-
-The workspace symbol request is sent from the client to the server to list
-project-wide symbols matching the query string.
-
-Request
-
-    method: 'workspace/symbol'
-    params: WorkspaceSymbolParams defined as follows:
-
-/**
- * The parameters of a Workspace Symbol Request.
- */
-interface WorkspaceSymbolParams {
-    /**
-     * A non-empty query string
-     */
-    query: string;
-}
-
-Response
-
-    result: SymbolInformation[] as defined above.
-    error: code and message set in case an exception happens during the
-           workspace symbol request.
--}
-
-data WorkspaceSymbolParams =
-  WorkspaceSymbolParams
-    { _query :: Text
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''WorkspaceSymbolParams
-makeFieldsNoPrefix ''WorkspaceSymbolParams
-
-type WorkspaceSymbolRequest  = RequestMessage ClientMethod WorkspaceSymbolParams (List SymbolInformation)
-type WorkspaceSymbolsResponse = ResponseMessage (List SymbolInformation)
-
--- ---------------------------------------------------------------------
-{-
-Code Action Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#code-action-request
-
-The code action request is sent from the client to the server to compute
-commands for a given text document and range. The request is triggered when the
-user moves the cursor into a problem marker in the editor or presses the
-lightbulb associated with a marker.
-
-Request
-
-    method: 'textDocument/codeAction'
-    params: CodeActionParams defined as follows:
-
-/**
- * Params for the CodeActionRequest
- */
-interface CodeActionParams {
-    /**
-     * The document in which the command was invoked.
-     */
-    textDocument: TextDocumentIdentifier;
-
-    /**
-     * The range for which the command was invoked.
-     */
-    range: Range;
-
-    /**
-     * Context carrying additional information.
-     */
-    context: CodeActionContext;
-}
-
-/**
- * Contains additional diagnostic information about the context in which
- * a code action is run.
- */
-interface CodeActionContext {
-    /**
-     * An array of diagnostics.
-     */
-    diagnostics: Diagnostic[];
-}
-
-Response
-
-    result: Command[] defined as follows:
-    error: code and message set in case an exception happens during the code
-           action request.
-
--}
-
-data CodeActionContext =
-  CodeActionContext
-    { _diagnostics :: List Diagnostic
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''CodeActionContext
-makeFieldsNoPrefix ''CodeActionContext
-
-
-data CodeActionParams =
-  CodeActionParams
-    { _textDocument :: TextDocumentIdentifier
-    , _range        :: Range
-    , _context      :: CodeActionContext
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''CodeActionParams
-makeFieldsNoPrefix ''CodeActionParams
-
-
-type CodeActionRequest  = RequestMessage ClientMethod CodeActionParams (List Command)
-type CodeActionResponse = ResponseMessage (List Command)
-
--- ---------------------------------------------------------------------
-{-
-Code Lens Request
-
-The code lens request is sent from the client to the server to compute code
-lenses for a given text document.
-
-    Changed: In 2.0 the request uses CodeLensParams instead of a single uri.
-
-Request
-
-    method: 'textDocument/codeLens'
-    params: CodeLensParams defined as follows:
-
-interface CodeLensParams {
-    /**
-     * The document to request code lens for.
-     */
-    textDocument: TextDocumentIdentifier;
-}
-
-Response
-
-    result: CodeLens[] defined as follows:
-
-/**
- * A code lens represents a command that should be shown along with
- * source text, like the number of references, a way to run tests, etc.
- *
- * A code lens is _unresolved_ when no command is associated to it. For performance
- * reasons the creation of a code lens and resolving should be done in two stages.
- */
-interface CodeLens {
-    /**
-     * The range in which this code lens is valid. Should only span a single line.
-     */
-    range: Range;
-
-    /**
-     * The command this code lens represents.
-     */
-    command?: Command;
-
-    /**
-     * A data entry field that is preserved on a code lens item between
-     * a code lens and a code lens resolve request.
-     */
-    data?: any
-}
-
-    error: code and message set in case an exception happens during the code
-           lens request.
--}
-
-data CodeLensParams =
-  CodeLensParams
-    { _textDocument :: TextDocumentIdentifier
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''CodeLensParams
-makeFieldsNoPrefix ''CodeLensParams
-
-
--- -------------------------------------
-
-data CodeLens =
-  CodeLens
-    { _range   :: Range
-    , _command :: Maybe Command
-    , _xdata   :: Maybe A.Value
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''CodeLens
-makeFieldsNoPrefix ''CodeLens
-
-
-type CodeLensRequest = RequestMessage ClientMethod CodeLensParams (List CodeLens)
-type CodeLensResponse = ResponseMessage (List CodeLens)
-
--- -------------------------------------
-{-
-Registration Options: CodeLensRegistrationOptions defined as follows:
-
-export interface CodeLensRegistrationOptions extends TextDocumentRegistrationOptions {
-        /**
-         * Code lens has a resolve provider as well.
-         */
-        resolveProvider?: boolean;
-}
--}
-
-data CodeLensRegistrationOptions =
-  CodeLensRegistrationOptions
-    { _documentSelector :: Maybe DocumentSelector
-    , _resolveProvider  :: Maybe Bool
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''CodeLensRegistrationOptions
-makeFieldsNoPrefix ''CodeLensRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-Code Lens Resolve Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#code-lens-resolve-request
-
-The code lens resolve request is sent from the client to the server to resolve
-the command for a given code lens item.
-
-Request
-
-    method: 'codeLens/resolve'
-    params: CodeLens
-
-Response
-
-    result: CodeLens
-    error: code and message set in case an exception happens during the code
-           lens resolve request.
-
-
--}
-
-type CodeLensResolveRequest  = RequestMessage ClientMethod CodeLens (List CodeLens)
-type CodeLensResolveResponse = ResponseMessage (List CodeLens)
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-Document Link Request
-
-The document links request is sent from the client to the server to request the
-location of links in a document.
-
-Request:
-
-    method: 'textDocument/documentLink'
-    params: DocumentLinkParams, defined as follows
-
-interface DocumentLinkParams {
-        /**
-         * The document to provide document links for.
-         */
-        textDocument: TextDocumentIdentifier;
-}
-
-Response:
-
-    result: An array of DocumentLink, or null.
-
-/**
- * A document link is a range in a text document that links to an internal or external resource, like another
- * text document or a web site.
- */
-interface DocumentLink {
-        /**
-         * The range this link applies to.
-         */
-        range: Range;
-        /**
-         * The uri this link points to. If missing a resolve request is sent later.
-         */
-        target?: DocumentUri;
-}
-
-    error: code and message set in case an exception happens during the document link request.
-
-Registration Options: DocumentLinkRegistrationOptions defined as follows:
-
-export interface DocumentLinkRegistrationOptions extends TextDocumentRegistrationOptions {
-        /**
-         * Document links have a resolve provider as well.
-         */
-        resolveProvider?: boolean;
-}
--}
-
-data DocumentLinkParams =
-  DocumentLinkParams
-    { _textDocument :: TextDocumentIdentifier
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DocumentLinkParams
-makeFieldsNoPrefix ''DocumentLinkParams
-
-data DocumentLink =
-  DocumentLink
-    { _range  :: Range
-    , _target :: Maybe Text
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''DocumentLink
-makeFieldsNoPrefix ''DocumentLink
-
-type DocumentLinkRequest = RequestMessage ClientMethod DocumentLinkParams (List DocumentLink)
-type DocumentLinkResponse = ResponseMessage (List DocumentLink)
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-Document Link Resolve Request
-
-The document link resolve request is sent from the client to the server to resolve the target of a given document link.
-
-Request:
-
-    method: 'documentLink/resolve'
-    params: DocumentLink
-
-Response:
-
-    result: DocumentLink
-    error: code and message set in case an exception happens during the document link resolve request.
-
--}
-
-type DocumentLinkResolveRequest  = RequestMessage ClientMethod DocumentLink DocumentLink
-type DocumentLinkResolveResponse = ResponseMessage DocumentLink
-
--- ---------------------------------------------------------------------
-{-
-Document Formatting Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-formatting-request
-
-The document formatting request is sent from the server to the client to format
-a whole document.
-
-Request
-
-    method: 'textDocument/formatting'
-    params: DocumentFormattingParams defined as follows
-
-interface DocumentFormattingParams {
-    /**
-     * The document to format.
-     */
-    textDocument: TextDocumentIdentifier;
-
-    /**
-     * The format options.
-     */
-    options: FormattingOptions;
-}
-
-/**
- * Value-object describing what options formatting should use.
- */
-interface FormattingOptions {
-    /**
-     * Size of a tab in spaces.
-     */
-    tabSize: number;
-
-    /**
-     * Prefer spaces over tabs.
-     */
-    insertSpaces: boolean;
-
-    /**
-     * Signature for further properties.
-     */
-    [key: string]: boolean | number | string;
-}
-
-Response
-
-    result: TextEdit[] describing the modification to the document to be
-            formatted.
-    error: code and message set in case an exception happens during the
-           formatting request.
-
-Registration Options: TextDocumentRegistrationOptions
--}
-
-data FormattingOptions =
-  FormattingOptions
-    { _tabSize      :: Int
-    , _insertSpaces :: Bool -- ^ Prefer spaces over tabs
-    -- Note: May be more properties
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''FormattingOptions
-makeFieldsNoPrefix ''FormattingOptions
-
-data DocumentFormattingParams =
-  DocumentFormattingParams
-    { _textDocument :: TextDocumentIdentifier
-    , _options      :: FormattingOptions
-    } deriving (Show,Read,Eq)
-
-deriveJSON lspOptions ''DocumentFormattingParams
-makeFieldsNoPrefix ''DocumentFormattingParams
-
-type DocumentFormattingRequest  = RequestMessage ClientMethod DocumentFormattingParams (List TextEdit)
-type DocumentFormattingResponse = ResponseMessage (List TextEdit)
-
--- ---------------------------------------------------------------------
-{-
-Document Range Formatting Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-range-formatting-request
-
-The document range formatting request is sent from the client to the server to
-format a given range in a document.
-
-Request
-
-    method: 'textDocument/rangeFormatting',
-    params: DocumentRangeFormattingParams defined as follows
-
-interface DocumentRangeFormattingParams {
-    /**
-     * The document to format.
-     */
-    textDocument: TextDocumentIdentifier;
-
-    /**
-     * The range to format
-     */
-    range: Range;
-
-    /**
-     * The format options
-     */
-    options: FormattingOptions;
-}
-
-Response
-
-    result: TextEdit[] describing the modification to the document to be
-            formatted.
-    error: code and message set in case an exception happens during the range
-           formatting request.
--}
-
-data DocumentRangeFormattingParams =
-  DocumentRangeFormattingParams
-    { _textDocument :: TextDocumentIdentifier
-    , _range        :: Range
-    , _options      :: FormattingOptions
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DocumentRangeFormattingParams
-makeFieldsNoPrefix ''DocumentRangeFormattingParams
-
-type DocumentRangeFormattingRequest  = RequestMessage ClientMethod DocumentRangeFormattingParams (List TextEdit)
-type DocumentRangeFormattingResponse = ResponseMessage (List TextEdit)
-
--- ---------------------------------------------------------------------
-{-
-Document on Type Formatting Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-on-type-formatting-request
-
-The document on type formatting request is sent from the client to the server to
-format parts of the document during typing.
-
-Request
-
-    method: 'textDocument/onTypeFormatting'
-    params: DocumentOnTypeFormattingParams defined as follows
-
-interface DocumentOnTypeFormattingParams {
-    /**
-     * The document to format.
-     */
-    textDocument: TextDocumentIdentifier;
-
-    /**
-     * The position at which this request was sent.
-     */
-    position: Position;
-
-    /**
-     * The character that has been typed.
-     */
-    ch: string;
-
-    /**
-     * The format options.
-     */
-    options: FormattingOptions;
-}
-
-Response
-
-    result: TextEdit[] describing the modification to the document.
-    error: code and message set in case an exception happens during the range
-           formatting request.
-
-Registration Options: DocumentOnTypeFormattingRegistrationOptions defined as follows:
-
-export interface DocumentOnTypeFormattingRegistrationOptions extends TextDocumentRegistrationOptions {
-        /**
-         * A character on which formatting should be triggered, like `}`.
-         */
-        firstTriggerCharacter: string;
-        /**
-         * More trigger characters.
-         */
-        moreTriggerCharacter?: string[]
-}
--}
-
-data DocumentOnTypeFormattingParams =
-  DocumentOnTypeFormattingParams
-    { _textDocument :: TextDocumentIdentifier
-    , _position     :: Position
-    , _ch           :: Text
-    , _options      :: FormattingOptions
-    } deriving (Read,Show,Eq)
-
-deriveJSON lspOptions ''DocumentOnTypeFormattingParams
-makeFieldsNoPrefix ''DocumentOnTypeFormattingParams
-
-type DocumentOnTypeFormattingRequest  = RequestMessage ClientMethod DocumentOnTypeFormattingParams (List TextEdit)
-type DocumentOnTypeFormattingResponse = ResponseMessage (List TextEdit)
-
-data DocumentOnTypeFormattingRegistrationOptions =
-  DocumentOnTypeFormattingRegistrationOptions
-    { _firstTriggerCharacter :: Text
-    , _moreTriggerCharacter  :: Maybe (List String)
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''DocumentOnTypeFormattingRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-Rename Request
-
-https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#rename-request
-
-The rename request is sent from the client to the server to perform a
-workspace-wide rename of a symbol.
-
-Request
-
-    method: 'textDocument/rename'
-    params: RenameParams defined as follows
-
-interface RenameParams {
-    /**
-     * The document to format.
-     */
-    textDocument: TextDocumentIdentifier;
-
-    /**
-     * The position at which this request was sent.
-     */
-    position: Position;
-
-    /**
-     * The new name of the symbol. If the given name is not valid the
-     * request must return a [ResponseError](#ResponseError) with an
-     * appropriate message set.
-     */
-    newName: string;
-}
-
-Response
-
-    result: WorkspaceEdit describing the modification to the workspace.
-    error: code and message set in case an exception happens during the rename
-           request.
-
-Registration Options: TextDocumentRegistrationOptions
-
--}
-data RenameParams =
-  RenameParams
-    { _textDocument :: TextDocumentIdentifier
-    , _position     :: Position
-    , _newName      :: Text
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''RenameParams
-makeFieldsNoPrefix ''RenameParams
-
-
--- {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"textDocument/rename\",\"params\":{\"textDocument\":{\"uri\":\"file:///home/alanz/mysrc/github/alanz/haskell-lsp/src/HieVscode.hs\"},\"position\":{\"line\":37,\"character\":17},\"newName\":\"getArgs'\"}}
-
-type RenameRequest  = RequestMessage ClientMethod RenameParams WorkspaceEdit
-type RenameResponse = ResponseMessage WorkspaceEdit
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-Execute a command
-
-The workspace/executeCommand request is sent from the client to the server to
-trigger command execution on the server. In most cases the server creates a
-WorkspaceEdit structure and applies the changes to the workspace using the
-request workspace/applyEdit which is sent from the server to the client.
-
-Request:
-
-    method: 'workspace/executeCommand'
-    params: ExecuteCommandParams defined as follows:
-
-export interface ExecuteCommandParams {
-
-        /**
-         * The identifier of the actual command handler.
-         */
-        command: string;
-        /**
-         * Arguments that the command should be invoked with.
-         */
-        arguments?: any[];
-}
-
-The arguments are typically specified when a command is returned from the server
-to the client. Example requests that return a command are
-textDocument/codeAction or textDocument/codeLens.
-
-Response:
-
-    result: any
-    error: code and message set in case an exception happens during the request.
-
-Registration Options: ExecuteCommandRegistrationOptions defined as follows:
-
-/**
- * Execute command registration options.
- */
-export interface ExecuteCommandRegistrationOptions {
-        /**
-         * The commands to be executed on the server
-         */
-        commands: string[]
-}
--}
-
-data ExecuteCommandParams =
-  ExecuteCommandParams
-    { _command   :: Text
-    , _arguments :: Maybe (List A.Value)
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''ExecuteCommandParams
-makeFieldsNoPrefix ''ExecuteCommandParams
-
-type ExecuteCommandRequest = RequestMessage ClientMethod ExecuteCommandParams A.Value
-type ExecuteCommandResponse = ResponseMessage A.Value
-
-data ExecuteCommandRegistrationOptions =
-  ExecuteCommandRegistrationOptions
-    { _commands :: List Text
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''ExecuteCommandRegistrationOptions
-makeFieldsNoPrefix ''ExecuteCommandRegistrationOptions
-
--- ---------------------------------------------------------------------
-{-
-New in 3.0
-----------
-
-Applies a WorkspaceEdit
-
-The workspace/applyEdit request is sent from the server to the client to modify
-resource on the client side.
-
-Request:
-
-    method: 'workspace/applyEdit'
-    params: ApplyWorkspaceEditParams defined as follows:
-
-export interface ApplyWorkspaceEditParams {
-        /**
-         * The edits to apply.
-         */
-        edit: WorkspaceEdit;
-}
-
-Response:
-
-    result: ApplyWorkspaceEditResponse defined as follows:
-
-export interface ApplyWorkspaceEditResponse {
-        /**
-         * Indicates whether the edit was applied or not.
-         */
-        applied: boolean;
-}
-
-    error: code and message set in case an exception happens during the request.
-
--}
-data ApplyWorkspaceEditParams =
-  ApplyWorkspaceEditParams
-    { _edit :: WorkspaceEdit
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''ApplyWorkspaceEditParams
-makeFieldsNoPrefix ''ApplyWorkspaceEditParams
-
-data ApplyWorkspaceEditResponseBody =
-  ApplyWorkspaceEditResponseBody
-    { _applied :: Bool
-    } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''ApplyWorkspaceEditResponseBody
-makeFieldsNoPrefix ''ApplyWorkspaceEditResponseBody
-
--- | Sent from the server to the client
-type ApplyWorkspaceEditRequest  = RequestMessage ServerMethod ApplyWorkspaceEditParams ApplyWorkspaceEditResponseBody
-type ApplyWorkspaceEditResponse = ResponseMessage ApplyWorkspaceEditResponseBody
-
--- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
--- ---------------------------------------------------------------------
-
-data TraceParams =
-  TraceParams {
-    _value :: Text
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TraceParams
-makeFieldsNoPrefix ''TraceParams
-
-
-data TraceNotification =
-  TraceNotification {
-    _params :: TraceParams
-  } deriving (Show, Read, Eq)
-
-deriveJSON lspOptions ''TraceNotification
-makeFieldsNoPrefix ''TraceNotification
-
-
-
--- ---------------------------------------------------------------------
+module Language.Haskell.LSP.TH.DataTypesJSON
+    ( module Language.Haskell.LSP.TH.DataTypesJSON
+    , module Language.Haskell.LSP.TH.CodeAction
+    , module Language.Haskell.LSP.TH.Command
+    , module Language.Haskell.LSP.TH.Diagnostic
+    , module Language.Haskell.LSP.TH.List
+    , module Language.Haskell.LSP.TH.Location
+    , module Language.Haskell.LSP.TH.Message
+    , module Language.Haskell.LSP.TH.Symbol
+    , module Language.Haskell.LSP.TH.TextDocumentIdentifier
+    , module Language.Haskell.LSP.TH.Uri
+    , module Language.Haskell.LSP.TH.WorkspaceEdit
+    ) where
+
+import           Control.Applicative
+import           Control.Lens.TH                            (makeFieldsNoPrefix)
+import qualified Data.Aeson                                 as A
+import           Data.Aeson.TH
+import           Data.Aeson.Types
+import           Data.Text                                  (Text)
+import qualified Data.Text                                  as T
+
+import           Language.Haskell.LSP.TH.ClientCapabilities
+import           Language.Haskell.LSP.TH.CodeAction
+import           Language.Haskell.LSP.TH.Command
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.Diagnostic
+import           Language.Haskell.LSP.TH.List
+import           Language.Haskell.LSP.TH.Location
+import           Language.Haskell.LSP.TH.Message
+import           Language.Haskell.LSP.TH.Symbol
+import           Language.Haskell.LSP.TH.TextDocumentIdentifier
+import           Language.Haskell.LSP.TH.Utils
+import           Language.Haskell.LSP.TH.Uri
+import           Language.Haskell.LSP.TH.WorkspaceEdit
+
+-- ---------------------------------------------------------------------
+
+
+{-
+TextDocumentItem
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textdocumentitem
+
+    New: An item to transfer a text document from the client to the server.
+
+interface TextDocumentItem {
+    /**
+     * The text document's URI.
+     */
+    uri: string;
+
+    /**
+     * The text document's language identifier.
+     */
+    languageId: string;
+
+    /**
+     * The version number of this document (it will strictly increase after each
+     * change, including undo/redo).
+     */
+    version: number;
+
+    /**
+     * The content of the opened text document.
+     */
+    text: string;
+}
+-}
+
+data TextDocumentItem =
+  TextDocumentItem {
+    _uri        :: Uri
+  , _languageId :: Text
+  , _version    :: Int
+  , _text       :: Text
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentItem
+makeFieldsNoPrefix ''TextDocumentItem
+
+-- ---------------------------------------------------------------------
+{-
+TextDocumentPositionParams
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textdocumentpositionparams
+
+    Changed: Was TextDocumentPosition in 1.0 with inlined parameters
+
+
+interface TextDocumentPositionParams {
+    /**
+     * The text document.
+     */
+    textDocument: TextDocumentIdentifier;
+
+    /**
+     * The position inside the text document.
+     */
+    position: Position;
+}
+
+-}
+data TextDocumentPositionParams =
+  TextDocumentPositionParams
+    { _textDocument :: TextDocumentIdentifier
+    , _position     :: Position
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentPositionParams
+makeFieldsNoPrefix ''TextDocumentPositionParams
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+DocumentFilter
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#new-documentfilter
+
+A document filter denotes a document through properties like language, schema or
+pattern. Examples are a filter that applies to TypeScript files on disk or a
+filter the applies to JSON files with name package.json:
+
+    { language: 'typescript', scheme: 'file' }
+    { language: 'json', pattern: '**/package.json' }
+
+export interface DocumentFilter {
+        /**
+         * A language id, like `typescript`.
+         */
+        language?: string;
+
+        /**
+         * A Uri [scheme](#Uri.scheme), like `file` or `untitled`.
+         */
+        scheme?: string;
+
+        /**
+         * A glob pattern, like `*.{ts,js}`.
+         */
+        pattern?: string;
+}
+-}
+data DocumentFilter =
+  DocumentFilter
+    { _language :: Text
+    , _scheme   :: Text
+    , _pattern  :: Maybe Text
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''DocumentFilter
+makeFieldsNoPrefix ''DocumentFilter
+
+{-
+A document selector is the combination of one or many document filters.
+
+export type DocumentSelector = DocumentFilter[];
+-}
+type DocumentSelector = List DocumentFilter
+
+-- =====================================================================
+-- ACTUAL PROTOCOL -----------------------------------------------------
+-- =====================================================================
+
+-- ---------------------------------------------------------------------
+-- Initialize Request
+-- ---------------------------------------------------------------------
+{-
+Initialize Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#initialize-request
+
+The initialize request is sent as the first request from the client to the server.
+
+Request
+
+    method: 'initialize'
+    params: InitializeParams defined as follows:
+
+interface InitializeParams {
+        /**
+         * The process Id of the parent process that started
+         * the server. Is null if the process has not been started by another process.
+         * If the parent process is not alive then the server should exit (see exit notification) its process.
+         */
+        processId: number | null;
+
+        /**
+         * The rootPath of the workspace. Is null
+         * if no folder is open.
+         *
+         * @deprecated in favour of rootUri.
+         */
+        rootPath?: string | null;
+
+        /**
+         * The rootUri of the workspace. Is null if no
+         * folder is open. If both `rootPath` and `rootUri` are set
+         * `rootUri` wins.
+         */
+        rootUri: DocumentUri | null;
+
+        /**
+         * User provided initialization options.
+         */
+        initializationOptions?: any;
+
+        /**
+         * The capabilities provided by the client (editor or tool)
+         */
+        capabilities: ClientCapabilities;
+
+        /**
+         * The initial trace setting. If omitted trace is disabled ('off').
+         */
+        trace?: 'off' | 'messages' | 'verbose';
+}
+-}
+
+data Trace = TraceOff | TraceMessages | TraceVerbose
+           deriving (Show, Read, Eq)
+
+instance A.ToJSON Trace where
+  toJSON TraceOff      = A.String (T.pack "off")
+  toJSON TraceMessages = A.String (T.pack "messages")
+  toJSON TraceVerbose  = A.String (T.pack "verbose")
+
+instance A.FromJSON Trace where
+  parseJSON (A.String s) = case T.unpack s of
+    "off"      -> return TraceOff
+    "messages" -> return TraceMessages
+    "verbose"  -> return TraceVerbose
+    _          -> mempty
+  parseJSON _                               = mempty
+
+data InitializeParams =
+  InitializeParams {
+    _processId             :: Maybe Int
+  , _rootPath              :: Maybe Text -- ^ Deprecated in favour of _rootUri
+  , _rootUri               :: Maybe Uri
+  , _initializationOptions :: Maybe A.Value
+  , _capabilities          :: ClientCapabilities
+  , _trace                 :: Maybe Trace
+  } deriving (Show, Read, Eq)
+
+
+deriveJSON lspOptions ''InitializeParams
+makeFieldsNoPrefix ''InitializeParams
+
+-- ---------------------------------------------------------------------
+-- Initialize Response
+-- ---------------------------------------------------------------------
+{-
+
+    error.data:
+
+interface InitializeError {
+    /**
+     * Indicates whether the client should retry to send the
+     * initilize request after showing the message provided
+     * in the ResponseError.
+     */
+    retry: boolean;
+-
+-}
+data InitializeError =
+  InitializeError
+    { _retry :: Bool
+    } deriving (Read, Show, Eq)
+
+deriveJSON lspOptions ''InitializeError
+makeFieldsNoPrefix ''InitializeError
+
+-- ---------------------------------------------------------------------
+{-
+The server can signal the following capabilities:
+
+/**
+ * Defines how the host (editor) should sync document changes to the language server.
+ */
+enum TextDocumentSyncKind {
+    /**
+     * Documents should not be synced at all.
+     */
+    None = 0,
+    /**
+     * Documents are synced by always sending the full content of the document.
+     */
+    Full = 1,
+    /**
+     * Documents are synced by sending the full content on open. After that only incremental
+     * updates to the document are sent.
+     */
+    Incremental = 2
+}
+-}
+
+-- ^ Note: Omitting this parameter from the capabilities is effectively a fourth
+-- state, where DidSave events are generated without sending document contents.
+data TextDocumentSyncKind = TdSyncNone
+                          | TdSyncFull
+                          | TdSyncIncremental
+       deriving (Read,Eq,Show)
+
+instance A.ToJSON TextDocumentSyncKind where
+  toJSON TdSyncNone        = A.Number 0
+  toJSON TdSyncFull        = A.Number 1
+  toJSON TdSyncIncremental = A.Number 2
+
+instance A.FromJSON TextDocumentSyncKind where
+  parseJSON (A.Number 0) = pure TdSyncNone
+  parseJSON (A.Number 1) = pure TdSyncFull
+  parseJSON (A.Number 2) = pure TdSyncIncremental
+  parseJSON _            = mempty
+
+-- ---------------------------------------------------------------------
+{-
+/**
+ * Completion options.
+ */
+interface CompletionOptions {
+    /**
+     * The server provides support to resolve additional information for a completion item.
+     */
+    resolveProvider?: boolean;
+
+    /**
+     * The characters that trigger completion automatically.
+     */
+    triggerCharacters?: string[];
+}
+-}
+
+data CompletionOptions =
+  CompletionOptions
+    { _resolveProvider   :: Maybe Bool
+    , _triggerCharacters :: Maybe [String]
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions {omitNothingFields = True } ''CompletionOptions
+makeFieldsNoPrefix ''CompletionOptions
+
+-- ---------------------------------------------------------------------
+{-
+/**
+ * Signature help options.
+ */
+interface SignatureHelpOptions {
+    /**
+     * The characters that trigger signature help automatically.
+     */
+    triggerCharacters?: string[];
+-}
+
+data SignatureHelpOptions =
+  SignatureHelpOptions
+    { _triggerCharacters :: Maybe [String]
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''SignatureHelpOptions
+makeFieldsNoPrefix ''SignatureHelpOptions
+
+-- ---------------------------------------------------------------------
+{-
+/**
+ * Code Lens options.
+ */
+interface CodeLensOptions {
+    /**
+     * Code lens has a resolve provider as well.
+     */
+    resolveProvider?: boolean;
+}
+-}
+
+data CodeLensOptions =
+  CodeLensOptions
+    { _resolveProvider :: Maybe Bool
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CodeLensOptions
+makeFieldsNoPrefix ''CodeLensOptions
+
+-- ---------------------------------------------------------------------
+{-
+/**
+ * Format document on type options
+ */
+interface DocumentOnTypeFormattingOptions {
+    /**
+     * A character on which formatting should be triggered, like `}`.
+     */
+    firstTriggerCharacter: string;
+    /**
+     * More trigger characters.
+     */
+    moreTriggerCharacter?: string[]
+}
+-}
+data DocumentOnTypeFormattingOptions =
+  DocumentOnTypeFormattingOptions
+    { _firstTriggerCharacter :: Text
+    , _moreTriggerCharacter  :: Maybe [String]
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DocumentOnTypeFormattingOptions
+makeFieldsNoPrefix ''DocumentOnTypeFormattingOptions
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+/**
+ * Document link options
+ */
+export interface DocumentLinkOptions {
+        /**
+         * Document links have a resolve provider as well.
+         */
+        resolveProvider?: boolean;
+}
+-}
+
+data DocumentLinkOptions =
+  DocumentLinkOptions
+    { -- |Document links have a resolve provider as well.
+      _resolveProvider :: Maybe Bool
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''DocumentLinkOptions
+makeFieldsNoPrefix ''DocumentLinkOptions
+
+-- ---------------------------------------------------------------------
+
+{-
+New in 3.0
+-----------
+
+/**
+ * Execute command options.
+ */
+export interface ExecuteCommandOptions {
+        /**
+         * The commands to be executed on the server
+         */
+        commands: string[]
+}
+-}
+
+data ExecuteCommandOptions =
+  ExecuteCommandOptions
+    { -- | The commands to be executed on the server
+      _commands :: List Text
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''ExecuteCommandOptions
+makeFieldsNoPrefix ''ExecuteCommandOptions
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+/**
+ * Save options.
+ */
+export interface SaveOptions {
+        /**
+         * The client is supposed to include the content on save.
+         */
+        includeText?: boolean;
+}
+-}
+data SaveOptions =
+  SaveOptions
+    { -- |The client is supposed to include the content on save.
+      _includeText :: Maybe Bool
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''SaveOptions
+makeFieldsNoPrefix ''SaveOptions
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+export interface TextDocumentSyncOptions {
+        /**
+         * Open and close notifications are sent to the server.
+         */
+        openClose?: boolean;
+        /**
+         * Change notificatins are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
+         * and TextDocumentSyncKindIncremental.
+         */
+        change?: number;
+        /**
+         * Will save notifications are sent to the server.
+         */
+        willSave?: boolean;
+        /**
+         * Will save wait until requests are sent to the server.
+         */
+        willSaveWaitUntil?: boolean;
+        /**
+         * Save notifications are sent to the server.
+         */
+        save?: SaveOptions;
+}
+-}
+
+data TextDocumentSyncOptions =
+  TextDocumentSyncOptions
+    { -- | Open and close notifications are sent to the server.
+      _openClose         :: Maybe Bool
+
+      -- | Change notificatins are sent to the server. See
+      -- TextDocumentSyncKind.None, TextDocumentSyncKind.Full and
+      -- TextDocumentSyncKindIncremental.
+    , _change            :: Maybe TextDocumentSyncKind
+
+      -- | Will save notifications are sent to the server.
+    , _willSave          :: Maybe Bool
+
+      -- | Will save wait until requests are sent to the server.
+    , _willSaveWaitUntil :: Maybe Bool
+
+      -- |Save notifications are sent to the server.
+    , _save              :: Maybe SaveOptions
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentSyncOptions
+makeFieldsNoPrefix ''TextDocumentSyncOptions
+
+-- ---------------------------------------------------------------------
+{-
+
+Extended in 3.0
+---------------
+
+interface ServerCapabilities {
+        /**
+         * Defines how text documents are synced. Is either a detailed structure defining each notification or
+         * for backwards compatibility the TextDocumentSyncKind number.
+         */
+        textDocumentSync?: TextDocumentSyncOptions | number;
+        /**
+         * The server provides hover support.
+         */
+        hoverProvider?: boolean;
+        /**
+         * The server provides completion support.
+         */
+        completionProvider?: CompletionOptions;
+        /**
+         * The server provides signature help support.
+         */
+        signatureHelpProvider?: SignatureHelpOptions;
+        /**
+         * The server provides goto definition support.
+         */
+        definitionProvider?: boolean;
+        /**
+         * The server provides find references support.
+         */
+        referencesProvider?: boolean;
+        /**
+         * The server provides document highlight support.
+         */
+        documentHighlightProvider?: boolean;
+        /**
+         * The server provides document symbol support.
+         */
+        documentSymbolProvider?: boolean;
+        /**
+         * The server provides workspace symbol support.
+         */
+        workspaceSymbolProvider?: boolean;
+        /**
+         * The server provides code actions.
+         */
+        codeActionProvider?: boolean;
+        /**
+         * The server provides code lens.
+         */
+        codeLensProvider?: CodeLensOptions;
+        /**
+         * The server provides document formatting.
+         */
+        documentFormattingProvider?: boolean;
+        /**
+         * The server provides document range formatting.
+         */
+        documentRangeFormattingProvider?: boolean;
+        /**
+         * The server provides document formatting on typing.
+         */
+        documentOnTypeFormattingProvider?: DocumentOnTypeFormattingOptions;
+        /**
+         * The server provides rename support.
+         */
+        renameProvider?: boolean;
+        /**
+         * The server provides document link support.
+         */
+        documentLinkProvider?: DocumentLinkOptions;
+        /**
+         * The server provides execute command support.
+         */
+        executeCommandProvider?: ExecuteCommandOptions;
+        /**
+         * Experimental server capabilities.
+         */
+        experimental?: any;
+}
+-}
+
+-- | Wrapper for TextDocumentSyncKind fallback.
+data TDS = TDSOptions TextDocumentSyncOptions
+         | TDSKind TextDocumentSyncKind
+    deriving (Show, Read, Eq)
+
+instance FromJSON TDS where
+    parseJSON x = TDSOptions <$> parseJSON x <|> TDSKind <$> parseJSON x
+    
+instance ToJSON TDS where
+    toJSON (TDSOptions x) = toJSON x
+    toJSON (TDSKind x) = toJSON x
+      
+data InitializeResponseCapabilitiesInner =
+  InitializeResponseCapabilitiesInner
+    { _textDocumentSync                 :: Maybe TDS
+    , _hoverProvider                    :: Maybe Bool
+    , _completionProvider               :: Maybe CompletionOptions
+    , _signatureHelpProvider            :: Maybe SignatureHelpOptions
+    , _definitionProvider               :: Maybe Bool
+    , _referencesProvider               :: Maybe Bool
+    , _documentHighlightProvider        :: Maybe Bool
+    , _documentSymbolProvider           :: Maybe Bool
+    , _workspaceSymbolProvider          :: Maybe Bool
+    , _codeActionProvider               :: Maybe Bool
+    , _codeLensProvider                 :: Maybe CodeLensOptions
+    , _documentFormattingProvider       :: Maybe Bool
+    , _documentRangeFormattingProvider  :: Maybe Bool
+    , _documentOnTypeFormattingProvider :: Maybe DocumentOnTypeFormattingOptions
+    , _renameProvider                   :: Maybe Bool
+    -- Following are new in 3.0
+    , _documentLinkProvider             :: Maybe DocumentLinkOptions
+    , _executeCommandProvider           :: Maybe ExecuteCommandOptions
+    , _experimental                     :: Maybe A.Value
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''InitializeResponseCapabilitiesInner
+makeFieldsNoPrefix ''InitializeResponseCapabilitiesInner
+
+-- ---------------------------------------------------------------------
+-- |
+--   Information about the capabilities of a language server
+--
+data InitializeResponseCapabilities =
+  InitializeResponseCapabilities {
+    _capabilities :: InitializeResponseCapabilitiesInner
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''InitializeResponseCapabilities
+makeFieldsNoPrefix ''InitializeResponseCapabilities
+
+-- ---------------------------------------------------------------------
+
+type InitializeResponse = ResponseMessage InitializeResponseCapabilities
+
+type InitializeRequest = RequestMessage ClientMethod InitializeParams InitializeResponseCapabilities
+
+{-
+    error.code:
+
+/**
+ * Known error codes for an `InitializeError`;
+ */
+export namespace InitializeError {
+        /**
+         * If the protocol version provided by the client can't be handled by the server.
+         * @deprecated This initialize error got replaced by client capabilities. There is
+         * no version handshake in version 3.0x
+         */
+        export const unknownProtocolVersion: number = 1;
+}
+
+    error.data:
+
+interface InitializeError {
+        /**
+         * Indicates whether the client execute the following retry logic:
+         * (1) show the message provided by the ResponseError to the user
+         * (2) user selects retry or cancel
+         * (3) if user selected retry the initialize method is sent again.
+         */
+        retry: boolean;
+}
+-}
+
+-- ---------------------------------------------------------------------
+
+{-
+New in 3.0
+----------
+Initialized Notification
+
+The initialized notification is sent from the client to the server after the
+client is fully initialized and is able to listen to arbritary requests and
+notifications sent from the server.
+
+Notification:
+
+    method: 'initialized'
+    params: void
+
+-}
+
+data InitializedParams =
+  InitializedParams
+    {
+    } deriving (Show, Read, Eq)
+
+instance A.FromJSON InitializedParams where
+  parseJSON (A.Object _) = pure InitializedParams
+  parseJSON _            = mempty
+
+instance A.ToJSON InitializedParams where
+  toJSON InitializedParams = A.Object mempty
+
+type InitializedNotification = NotificationMessage ClientMethod (Maybe InitializedParams)
+
+-- ---------------------------------------------------------------------
+{-
+Shutdown Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#shutdown-request
+
+The shutdown request is sent from the client to the server. It asks the server
+to shut down, but to not exit (otherwise the response might not be delivered
+correctly to the client). There is a separate exit notification that asks the
+server to exit.
+
+Request
+
+    method: 'shutdown'
+    params: undefined
+
+Response
+
+    result: undefined
+    error: code and message set in case an exception happens during shutdown request.
+
+
+-}
+
+type ShutdownRequest  = RequestMessage ClientMethod (Maybe A.Value) Text
+type ShutdownResponse = ResponseMessage Text
+
+-- ---------------------------------------------------------------------
+{-
+Exit Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#exit-notification
+
+A notification to ask the server to exit its process.
+
+Notification
+
+    method: 'exit'
+
+-}
+
+-- |
+--   Notification from the server to actually exit now, after shutdown acked
+--
+data ExitParams =
+  ExitParams
+    {
+    } deriving (Show, Read, Eq)
+
+deriveJSON defaultOptions ''ExitParams
+
+type ExitNotification = NotificationMessage ClientMethod (Maybe ExitParams)
+
+-- ---------------------------------------------------------------------
+{-
+ShowMessage Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#showmessage-notification
+
+The show message notification is sent from a server to a client to ask the
+client to display a particular message in the user interface.
+
+Notification:
+
+    method: 'window/showMessage'
+    params: ShowMessageParams defined as follows:
+
+interface ShowMessageParams {
+    /**
+     * The message type. See {@link MessageType}.
+     */
+    type: number;
+
+    /**
+     * The actual message.
+     */
+    message: string;
+}
+
+Where the type is defined as follows:
+
+enum MessageType {
+    /**
+     * An error message.
+     */
+    Error = 1,
+    /**
+     * A warning message.
+     */
+    Warning = 2,
+    /**
+     * An information message.
+     */
+    Info = 3,
+    /**
+     * A log message.
+     */
+    Log = 4
+}
+-}
+data MessageType = MtError   -- ^ Error = 1,
+                 | MtWarning -- ^ Warning = 2,
+                 | MtInfo    -- ^ Info = 3,
+                 | MtLog     -- ^ Log = 4
+        deriving (Eq,Ord,Show,Read,Enum)
+
+instance A.ToJSON MessageType where
+  toJSON MtError   = A.Number 1
+  toJSON MtWarning = A.Number 2
+  toJSON MtInfo    = A.Number 3
+  toJSON MtLog     = A.Number 4
+
+instance A.FromJSON MessageType where
+  parseJSON (A.Number 1) = pure MtError
+  parseJSON (A.Number 2) = pure MtWarning
+  parseJSON (A.Number 3) = pure MtInfo
+  parseJSON (A.Number 4) = pure MtLog
+  parseJSON _            = mempty
+
+-- ---------------------------------------
+
+
+data ShowMessageParams =
+  ShowMessageParams {
+    _xtype   :: MessageType
+  , _message :: Text
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ShowMessageParams
+makeFieldsNoPrefix ''ShowMessageParams
+
+type ShowMessageNotification = NotificationMessage ServerMethod ShowMessageParams
+
+-- ---------------------------------------------------------------------
+{-
+ShowMessage Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#showmessage-request
+
+    New: The show message request is sent from a server to a client to ask the
+    client to display a particular message in the user interface. In addition to
+    the show message notification the request allows to pass actions and to wait
+    for an answer from the client.
+
+Request:
+
+    method: 'window/showMessageRequest'
+    params: ShowMessageRequestParams defined as follows:
+
+Response:
+
+    result: the selected MessageActionItem
+    error: code and message set in case an exception happens during showing a message.
+
+interface ShowMessageRequestParams {
+    /**
+     * The message type. See {@link MessageType}
+     */
+    type: number;
+
+    /**
+     * The actual message
+     */
+    message: string;
+
+    /**
+     * The message action items to present.
+     */
+    actions?: MessageActionItem[];
+}
+
+Where the MessageActionItem is defined as follows:
+
+interface MessageActionItem {
+    /**
+     * A short title like 'Retry', 'Open Log' etc.
+     */
+    title: string;
+}
+-}
+
+data MessageActionItem =
+  MessageActionItem
+    { _title :: Text
+    } deriving (Show,Read,Eq)
+
+deriveJSON lspOptions ''MessageActionItem
+makeFieldsNoPrefix ''MessageActionItem
+
+
+data ShowMessageRequestParams =
+  ShowMessageRequestParams
+    { _xtype   :: MessageType
+    , _message :: Text
+    , _actions :: Maybe [MessageActionItem]
+    } deriving (Show,Read,Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ShowMessageRequestParams
+makeFieldsNoPrefix ''ShowMessageRequestParams
+
+type ShowMessageRequest = RequestMessage ServerMethod ShowMessageRequestParams Text
+type ShowMessageResponse = ResponseMessage Text
+
+-- ---------------------------------------------------------------------
+{-
+LogMessage Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#logmessage-notification
+
+The log message notification is sent from the server to the client to ask the
+client to log a particular message.
+
+Notification:
+
+    method: 'window/logMessage'
+    params: LogMessageParams defined as follows:
+
+interface LogMessageParams {
+    /**
+     * The message type. See {@link MessageType}
+     */
+    type: number;
+
+    /**
+     * The actual message
+     */
+    message: string;
+}
+
+Where type is defined as above.
+-}
+
+data LogMessageParams =
+  LogMessageParams {
+    _xtype   :: MessageType
+  , _message :: Text
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''LogMessageParams
+makeFieldsNoPrefix ''LogMessageParams
+
+
+type LogMessageNotification = NotificationMessage ServerMethod LogMessageParams
+
+-- ---------------------------------------------------------------------
+{-
+Telemetry Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#telemetry-notification
+
+    New: The telemetry notification is sent from the server to the client to ask
+    the client to log a telemetry event.
+
+Notification:
+
+    method: 'telemetry/event'
+    params: 'any'
+-}
+
+
+type TelemetryNotification = NotificationMessage ServerMethod A.Value
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+Register Capability
+
+The client/registerCapability request is sent from the server to the client to
+register for a new capability on the client side. Not all clients need to
+support dynamic capability registration. A client opts in via the
+ClientCapabilities.dynamicRegistration property.
+
+Request:
+
+    method: 'client/registerCapability'
+    params: RegistrationParams
+
+Where RegistrationParams are defined as follows:
+
+/**
+ * General paramters to to regsiter for a capability.
+ */
+export interface Registration {
+        /**
+         * The id used to register the request. The id can be used to deregister
+         * the request again.
+         */
+        id: string;
+
+        /**
+         * The method / capability to register for.
+         */
+        method: string;
+
+        /**
+         * Options necessary for the registration.
+         */
+        registerOptions?: any;
+}
+
+export interface RegistrationParams {
+        registrations: Registration[];
+}
+-}
+
+data Registration =
+  Registration
+    { -- |The id used to register the request. The id can be used to deregister
+      -- the request again.
+      _id              :: Text
+
+       -- | The method / capability to register for.
+    , _method          :: ClientMethod
+
+      -- | Options necessary for the registration.
+    , _registerOptions :: Maybe A.Value
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''Registration
+makeFieldsNoPrefix ''Registration
+
+data RegistrationParams =
+  RegistrationParams
+    { _registrations :: List Registration
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''RegistrationParams
+makeFieldsNoPrefix ''RegistrationParams
+
+-- |Note: originates at the server
+type RegisterCapabilityRequest = RequestMessage ServerMethod RegistrationParams ()
+
+type RegisterCapabilityResponse = ResponseMessage ()
+
+-- -------------------------------------
+
+{-
+Since most of the registration options require to specify a document selector
+there is a base interface that can be used.
+
+export interface TextDocumentRegistrationOptions {
+        /**
+         * A document selector to identify the scope of the registration. If set to null
+         * the document selector provided on the client side will be used.
+         */
+        documentSelector: DocumentSelector | null;
+}
+-}
+
+data TextDocumentRegistrationOptions =
+  TextDocumentRegistrationOptions
+    { _documentSelector :: Maybe DocumentSelector
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentRegistrationOptions
+makeFieldsNoPrefix ''TextDocumentRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+Unregister Capability
+
+The client/unregisterCapability request is sent from the server to the client to
+unregister a previously register capability.
+
+Request:
+
+    method: 'client/unregisterCapability'
+    params: UnregistrationParams
+
+Where UnregistrationParams are defined as follows:
+
+/**
+ * General parameters to unregister a capability.
+ */
+export interface Unregistration {
+        /**
+         * The id used to unregister the request or notification. Usually an id
+         * provided during the register request.
+         */
+        id: string;
+
+        /**
+         * The method / capability to unregister for.
+         */
+        method: string;
+}
+
+export interface UnregistrationParams {
+        unregisterations: Unregistration[];
+}
+-}
+
+data Unregistration =
+  Unregistration
+    { -- | The id used to unregister the request or notification. Usually an id
+      -- provided during the register request.
+      _id     :: Text
+
+       -- |The method / capability to unregister for.
+    , _method :: Text
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''Unregistration
+makeFieldsNoPrefix ''Unregistration
+
+data UnregistrationParams =
+  UnregistrationParams
+    { _unregistrations :: List Unregistration
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''UnregistrationParams
+makeFieldsNoPrefix ''UnregistrationParams
+
+type UnregisterCapabilityRequest = RequestMessage ServerMethod UnregistrationParams ()
+
+type UnregisterCapabilityResponse = ResponseMessage ()
+
+-- ---------------------------------------------------------------------
+{-
+DidChangeConfiguration Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didchangeconfiguration-notification
+
+A notification sent from the client to the server to signal the change of
+configuration settings.
+
+Notification:
+
+    method: 'workspace/didChangeConfiguration',
+    params: DidChangeConfigurationParams defined as follows:
+
+interface DidChangeConfigurationParams {
+    /**
+     * The actual changed settings
+     */
+    settings: any;
+}
+-}
+
+data DidChangeConfigurationParams =
+  DidChangeConfigurationParams {
+    _settings :: A.Value
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''DidChangeConfigurationParams
+makeFieldsNoPrefix ''DidChangeConfigurationParams
+
+
+type DidChangeConfigurationNotification = NotificationMessage ClientMethod DidChangeConfigurationParams
+
+-- ---------------------------------------------------------------------
+{-
+DidOpenTextDocument Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didopentextdocument-notification
+
+The document open notification is sent from the client to the server to signal
+newly opened text documents. The document's truth is now managed by the client
+and the server must not try to read the document's truth using the document's
+uri.
+
+Notification:
+
+    method: 'textDocument/didOpen'
+    params: DidOpenTextDocumentParams defined as follows:
+
+interface DidOpenTextDocumentParams {
+    /**
+     * The document that was opened.
+     */
+    textDocument: TextDocumentItem;
+}
+
+Registration Options: TextDocumentRegistrationOptions
+-}
+
+data DidOpenTextDocumentParams =
+  DidOpenTextDocumentParams {
+    _textDocument :: TextDocumentItem
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''DidOpenTextDocumentParams
+makeFieldsNoPrefix ''DidOpenTextDocumentParams
+
+type DidOpenTextDocumentNotification = NotificationMessage ClientMethod DidOpenTextDocumentParams
+
+-- ---------------------------------------------------------------------
+{-
+DidChangeTextDocument Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didchangetextdocument-notification
+
+    Changed: The document change notification is sent from the client to the
+    server to signal changes to a text document. In 2.0 the shape of the params
+    has changed to include proper version numbers and language ids.
+
+Notification:
+
+    method: 'textDocument/didChange'
+    params: DidChangeTextDocumentParams defined as follows:
+
+interface DidChangeTextDocumentParams {
+    /**
+     * The document that did change. The version number points
+     * to the version after all provided content changes have
+     * been applied.
+     */
+    textDocument: VersionedTextDocumentIdentifier;
+
+    /**
+     * The actual content changes.
+     */
+    contentChanges: TextDocumentContentChangeEvent[];
+}
+
+/**
+ * An event describing a change to a text document. If range and rangeLength are omitted
+ * the new text is considered to be the full content of the document.
+ */
+interface TextDocumentContentChangeEvent {
+    /**
+     * The range of the document that changed.
+     */
+    range?: Range;
+
+    /**
+     * The length of the range that got replaced.
+     */
+    rangeLength?: number;
+
+    /**
+     * The new text of the document.
+     */
+    text: string;
+}
+-}
+data TextDocumentContentChangeEvent =
+  TextDocumentContentChangeEvent
+    { _range       :: Maybe Range
+    , _rangeLength :: Maybe Int
+    , _text        :: Text
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions { omitNothingFields = True } ''TextDocumentContentChangeEvent
+makeFieldsNoPrefix ''TextDocumentContentChangeEvent
+
+-- -------------------------------------
+
+data DidChangeTextDocumentParams =
+  DidChangeTextDocumentParams
+    { _textDocument   :: VersionedTextDocumentIdentifier
+    , _contentChanges :: List TextDocumentContentChangeEvent
+    } deriving (Show,Read,Eq)
+
+deriveJSON lspOptions ''DidChangeTextDocumentParams
+makeFieldsNoPrefix ''DidChangeTextDocumentParams
+
+type DidChangeTextDocumentNotification = NotificationMessage ClientMethod DidChangeTextDocumentParams
+{-
+New in 3.0
+----------
+
+Registration Options: TextDocumentChangeRegistrationOptions defined as follows:
+
+/**
+ * Descibe options to be used when registered for text document change events.
+ */
+export interface TextDocumentChangeRegistrationOptions extends TextDocumentRegistrationOptions {
+        /**
+         * How documents are synced to the server. See TextDocumentSyncKind.Full
+         * and TextDocumentSyncKindIncremental.
+         */
+        syncKind: number;
+}
+-}
+
+data TextDocumentChangeRegistrationOptions =
+  TextDocumentChangeRegistrationOptions
+    { _documentSelector :: Maybe DocumentSelector
+    , _syncKind         :: TextDocumentSyncKind
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentChangeRegistrationOptions
+makeFieldsNoPrefix ''TextDocumentChangeRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+
+New in 3.0
+----------
+
+WillSaveTextDocument Notification
+
+The document will save notification is sent from the client to the server before
+the document is actually saved.
+
+Notification:
+
+    method: 'textDocument/willSave'
+    params: WillSaveTextDocumentParams defined as follows:
+
+/**
+ * The parameters send in a will save text document notification.
+ */
+export interface WillSaveTextDocumentParams {
+        /**
+         * The document that will be saved.
+         */
+        textDocument: TextDocumentIdentifier;
+
+        /**
+         * The 'TextDocumentSaveReason'.
+         */
+        reason: number;
+}
+
+/**
+ * Represents reasons why a text document is saved.
+ */
+export namespace TextDocumentSaveReason {
+
+        /**
+         * Manually triggered, e.g. by the user pressing save, by starting debugging,
+         * or by an API call.
+         */
+        export const Manual = 1;
+
+        /**
+         * Automatic after a delay.
+         */
+        export const AfterDelay = 2;
+
+        /**
+         * When the editor lost focus.
+         */
+        export const FocusOut = 3;
+}
+Registration Options: TextDocumentRegistrationOptions
+-}
+
+data TextDocumentSaveReason
+  = SaveManual
+         -- ^ Manually triggered, e.g. by the user pressing save, by starting
+         -- debugging, or by an API call.
+  | SaveAfterDelay -- ^ Automatic after a delay
+  | SaveFocusOut   -- ^ When the editor lost focus
+  deriving (Show, Read, Eq)
+
+instance A.ToJSON TextDocumentSaveReason where
+  toJSON SaveManual     = A.Number 1
+  toJSON SaveAfterDelay = A.Number 2
+  toJSON SaveFocusOut   = A.Number 3
+
+instance A.FromJSON TextDocumentSaveReason where
+  parseJSON (A.Number 1) = pure SaveManual
+  parseJSON (A.Number 2) = pure SaveAfterDelay
+  parseJSON (A.Number 3) = pure SaveFocusOut
+  parseJSON _            = mempty
+
+data WillSaveTextDocumentParams =
+  WillSaveTextDocumentParams
+    { _textDocument :: TextDocumentIdentifier
+    , _reason       :: TextDocumentSaveReason
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''WillSaveTextDocumentParams
+makeFieldsNoPrefix ''WillSaveTextDocumentParams
+
+type WillSaveTextDocumentNotification = NotificationMessage ClientMethod WillSaveTextDocumentParams
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+WillSaveWaitUntilTextDocument Request
+
+The document will save request is sent from the client to the server before the
+document is actually saved. The request can return an array of TextEdits which
+will be applied to the text document before it is saved. Please note that
+clients might drop results if computing the text edits took too long or if a
+server constantly fails on this request. This is done to keep the save fast and
+reliable.
+
+Request:
+
+    method: 'textDocument/willSaveWaitUntil'
+    params: WillSaveTextDocumentParams
+
+Response:
+
+    result: TextEdit[]
+    error: code and message set in case an exception happens during the willSaveWaitUntil request.
+
+Registration Options: TextDocumentRegistrationOptions
+-}
+
+type WillSaveWaitUntilTextDocumentRequest = RequestMessage ClientMethod WillSaveTextDocumentParams (List TextEdit)
+type WillSaveWaitUntilTextDocumentResponse = ResponseMessage (List TextEdit)
+
+-- ---------------------------------------------------------------------
+{-
+DidSaveTextDocument Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didsavetextdocument-notification
+
+    New: The document save notification is sent from the client to the server
+    when the document was saved in the client.
+
+    method: 'textDocument/didSave'
+    params: DidSaveTextDocumentParams defined as follows:
+
+interface DidSaveTextDocumentParams {
+    /**
+     * The document that was saved.
+     */
+    textDocument: TextDocumentIdentifier;
+}
+-}
+data DidSaveTextDocumentParams =
+  DidSaveTextDocumentParams
+    { _textDocument :: TextDocumentIdentifier
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DidSaveTextDocumentParams
+makeFieldsNoPrefix ''DidSaveTextDocumentParams
+
+type DidSaveTextDocumentNotification = NotificationMessage ClientMethod DidSaveTextDocumentParams
+
+
+
+-- ---------------------------------------------------------------------
+{-
+DidCloseTextDocument Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didclosetextdocument-notification
+
+The document close notification is sent from the client to the server when the
+document got closed in the client. The document's truth now exists where the
+document's uri points to (e.g. if the document's uri is a file uri the truth now
+exists on disk).
+
+    Changed: In 2.0 the params are of type DidCloseTextDocumentParams which
+    contains a reference to a text document.
+
+Notification:
+
+    method: 'textDocument/didClose'
+    params: DidCloseTextDocumentParams defined as follows:
+
+interface DidCloseTextDocumentParams {
+    /**
+     * The document that was closed.
+     */
+    textDocument: TextDocumentIdentifier;
+}
+-}
+data DidCloseTextDocumentParams =
+  DidCloseTextDocumentParams
+    { _textDocument :: TextDocumentIdentifier
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DidCloseTextDocumentParams
+makeFieldsNoPrefix ''DidCloseTextDocumentParams
+
+
+type DidCloseTextDocumentNotification = NotificationMessage ClientMethod DidCloseTextDocumentParams
+
+-- ---------------------------------------------------------------------
+{-
+DidChangeWatchedFiles Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#didchangewatchedfiles-notification
+
+The watched files notification is sent from the client to the server when the
+client detects changes to files watched by the language client.
+
+Notification:
+
+    method: 'workspace/didChangeWatchedFiles'
+    params: DidChangeWatchedFilesParams defined as follows:
+
+interface DidChangeWatchedFilesParams {
+    /**
+     * The actual file events.
+     */
+    changes: FileEvent[];
+}
+
+Where FileEvents are described as follows:
+
+/**
+ * The file event type.
+ */
+enum FileChangeType {
+    /**
+     * The file got created.
+     */
+    Created = 1,
+    /**
+     * The file got changed.
+     */
+    Changed = 2,
+    /**
+     * The file got deleted.
+     */
+    Deleted = 3
+}
+
+/**
+ * An event describing a file change.
+ */
+interface FileEvent {
+    /**
+     * The file's URI.
+     */
+    uri: string;
+    /**
+     * The change type.
+     */
+    type: number;
+-}
+data FileChangeType = FcCreated
+                    | FcChanged
+                    | FcDeleted
+       deriving (Read,Show,Eq)
+
+instance A.ToJSON FileChangeType where
+  toJSON FcCreated = A.Number 1
+  toJSON FcChanged = A.Number 2
+  toJSON FcDeleted = A.Number 3
+
+instance A.FromJSON FileChangeType where
+  parseJSON (A.Number 1) = pure FcCreated
+  parseJSON (A.Number 2) = pure FcChanged
+  parseJSON (A.Number 3) = pure FcDeleted
+  parseJSON _            = mempty
+
+
+-- -------------------------------------
+
+data FileEvent =
+  FileEvent
+    { _uri   :: Uri
+    , _xtype :: FileChangeType
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''FileEvent
+makeFieldsNoPrefix ''FileEvent
+
+data DidChangeWatchedFilesParams =
+  DidChangeWatchedFilesParams
+    { _changes :: List FileEvent
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DidChangeWatchedFilesParams
+makeFieldsNoPrefix ''DidChangeWatchedFilesParams
+
+
+type DidChangeWatchedFilesNotification = NotificationMessage ClientMethod DidChangeWatchedFilesParams
+
+-- ---------------------------------------------------------------------
+{-
+PublishDiagnostics Notification
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#publishdiagnostics-notification
+
+Diagnostics notification are sent from the server to the client to signal
+results of validation runs.
+
+Notification
+
+    method: 'textDocument/publishDiagnostics'
+    params: PublishDiagnosticsParams defined as follows:
+
+interface PublishDiagnosticsParams {
+    /**
+     * The URI for which diagnostic information is reported.
+     */
+    uri: string;
+
+    /**
+     * An array of diagnostic information items.
+     */
+    diagnostics: Diagnostic[];
+}
+-}
+
+data PublishDiagnosticsParams =
+  PublishDiagnosticsParams
+    { _uri         :: Uri
+    , _diagnostics :: List Diagnostic
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''PublishDiagnosticsParams
+makeFieldsNoPrefix ''PublishDiagnosticsParams
+
+
+type PublishDiagnosticsNotification = NotificationMessage ServerMethod PublishDiagnosticsParams
+
+-- ---------------------------------------------------------------------
+{-
+Completion Request
+
+The Completion request is sent from the client to the server to compute
+completion items at a given cursor position. Completion items are presented in
+the IntelliSense user interface. If computing full completion items is
+expensive, servers can additionally provide a handler for the completion item
+resolve request ('completionItem/resolve'). This request is sent when a
+completion item is selected in the user interface. A typically use case is for
+example: the 'textDocument/completion' request doesn't fill in the documentation
+property for returned completion items since it is expensive to compute. When
+the item is selected in the user interface then a 'completionItem/resolve'
+request is sent with the selected completion item as a param. The returned
+completion item should have the documentation property filled in.
+
+    Changed: In 2.0 the request uses TextDocumentPositionParams with a proper
+    textDocument and position property. In 1.0 the uri of the referenced text
+    document was inlined into the params object.
+
+Request
+
+    method: 'textDocument/completion'
+    params: TextDocumentPositionParams
+-}
+
+-- -------------------------------------
+
+{-
+
+Response
+
+    result: CompletionItem[] | CompletionList
+
+/**
+ * Represents a collection of [completion items](#CompletionItem) to be presented
+ * in the editor.
+ */
+interface CompletionList {
+    /**
+     * This list it not complete. Further typing should result in recomputing
+     * this list.
+     */
+    isIncomplete: boolean;
+    /**
+     * The completion items.
+     */
+    items: CompletionItem[];
+}
+
+
+New in 3.0 : InsertTextFormat
+
+/**
+ * Defines whether the insert text in a completion item should be interpreted as
+ * plain text or a snippet.
+ */
+namespace InsertTextFormat {
+        /**
+         * The primary text to be inserted is treated as a plain string.
+         */
+        export const PlainText = 1;
+
+        /**
+         * The primary text to be inserted is treated as a snippet.
+         *
+         * A snippet can define tab stops and placeholders with `$1`, `$2`
+         * and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+         * the end of the snippet. Placeholders with equal identifiers are linked,
+         * that is typing in one will update others too.
+         *
+         * See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
+         */
+        export const Snippet = 2;
+}
+
+
+
+interface CompletionItem {
+    /**
+     * The label of this completion item. By default
+     * also the text that is inserted when selecting
+     * this completion.
+     */
+    label: string;
+    /**
+     * The kind of this completion item. Based of the kind
+     * an icon is chosen by the editor.
+     */
+    kind?: number;
+    /**
+     * A human-readable string with additional information
+     * about this item, like type or symbol information.
+     */
+    detail?: string;
+    /**
+     * A human-readable string that represents a doc-comment.
+     */
+    documentation?: string;
+    /**
+     * A string that shoud be used when comparing this item
+     * with other items. When `falsy` the label is used.
+     */
+    sortText?: string;
+    /**
+     * A string that should be used when filtering a set of
+     * completion items. When `falsy` the label is used.
+     */
+    filterText?: string;
+    /**
+     * A string that should be inserted a document when selecting
+     * this completion. When `falsy` the label is used.
+     */
+    insertText?: string;
+    -- Following field is new in 3.0
+        /**
+         * The format of the insert text. The format applies to both the `insertText` property
+         * and the `newText` property of a provided `textEdit`.
+         */
+    insertTextFormat?: InsertTextFormat;
+        /**
+         * An edit which is applied to a document when selecting this completion. When an edit is provided the value of
+         * `insertText` is ignored.
+         *
+         * *Note:* The range of the edit must be a single line range and it must contain the position at which completion
+         * has been requested.
+         */
+
+    textEdit?: TextEdit;
+
+    -- Following field is new in 3.0
+        /**
+         * An optional array of additional text edits that are applied when
+         * selecting this completion. Edits must not overlap with the main edit
+         * nor with themselves.
+         */
+    additionalTextEdits?: TextEdit[];
+    -- Following field is new in 3.0
+        /**
+         * An optional command that is executed *after* inserting this completion. *Note* that
+         * additional modifications to the current document should be described with the
+         * additionalTextEdits-property.
+         */
+
+    command?: Command;
+        /**
+         * An data entry field that is preserved on a completion item between
+         * a completion and a completion resolve request.
+         */
+
+    data?: any
+}
+
+Where CompletionItemKind is defined as follows:
+
+/**
+ * The kind of a completion entry.
+ */
+enum CompletionItemKind {
+    Text = 1,
+    Method = 2,
+    Function = 3,
+    Constructor = 4,
+    Field = 5,
+    Variable = 6,
+    Class = 7,
+    Interface = 8,
+    Module = 9,
+    Property = 10,
+    Unit = 11,
+    Value = 12,
+    Enum = 13,
+    Keyword = 14,
+    Snippet = 15,
+    Color = 16,
+    File = 17,
+    Reference = 18
+}
+
+    error: code and message set in case an exception happens during the completion request.
+-}
+
+-- -------------------------------------
+
+data InsertTextFormat
+  = PlainText -- ^The primary text to be inserted is treated as a plain string.
+  | Snippet
+      -- ^ The primary text to be inserted is treated as a snippet.
+      --
+      -- A snippet can define tab stops and placeholders with `$1`, `$2`
+      -- and `${3:foo}`. `$0` defines the final tab stop, it defaults to
+      -- the end of the snippet. Placeholders with equal identifiers are linked,
+      -- that is typing in one will update others too.
+      --
+      -- See also: https://github.com/Microsoft/vscode/blob/master/src/vs/editor/contrib/snippet/common/snippet.md
+    deriving (Show, Read, Eq)
+
+instance A.ToJSON InsertTextFormat where
+  toJSON PlainText = A.Number 1
+  toJSON Snippet   = A.Number 2
+
+instance A.FromJSON InsertTextFormat where
+  parseJSON (A.Number  1) = pure PlainText
+  parseJSON (A.Number  2) = pure Snippet
+  parseJSON _             = mempty
+
+-- -------------------------------------
+
+data CompletionItemKind = CiText
+                        | CiMethod
+                        | CiFunction
+                        | CiConstructor
+                        | CiField
+                        | CiVariable
+                        | CiClass
+                        | CiInterface
+                        | CiModule
+                        | CiProperty
+                        | CiUnit
+                        | CiValue
+                        | CiEnum
+                        | CiKeyword
+                        | CiSnippet
+                        | CiColor
+                        | CiFile
+                        | CiReference
+         deriving (Read,Show,Eq,Ord)
+
+instance A.ToJSON CompletionItemKind where
+  toJSON CiText        = A.Number 1
+  toJSON CiMethod      = A.Number 2
+  toJSON CiFunction    = A.Number 3
+  toJSON CiConstructor = A.Number 4
+  toJSON CiField       = A.Number 5
+  toJSON CiVariable    = A.Number 6
+  toJSON CiClass       = A.Number 7
+  toJSON CiInterface   = A.Number 8
+  toJSON CiModule      = A.Number 9
+  toJSON CiProperty    = A.Number 10
+  toJSON CiUnit        = A.Number 11
+  toJSON CiValue       = A.Number 12
+  toJSON CiEnum        = A.Number 13
+  toJSON CiKeyword     = A.Number 14
+  toJSON CiSnippet     = A.Number 15
+  toJSON CiColor       = A.Number 16
+  toJSON CiFile        = A.Number 17
+  toJSON CiReference   = A.Number 18
+
+instance A.FromJSON CompletionItemKind where
+  parseJSON (A.Number  1) = pure CiText
+  parseJSON (A.Number  2) = pure CiMethod
+  parseJSON (A.Number  3) = pure CiFunction
+  parseJSON (A.Number  4) = pure CiConstructor
+  parseJSON (A.Number  5) = pure CiField
+  parseJSON (A.Number  6) = pure CiVariable
+  parseJSON (A.Number  7) = pure CiClass
+  parseJSON (A.Number  8) = pure CiInterface
+  parseJSON (A.Number  9) = pure CiModule
+  parseJSON (A.Number 10) = pure CiProperty
+  parseJSON (A.Number 11) = pure CiUnit
+  parseJSON (A.Number 12) = pure CiValue
+  parseJSON (A.Number 13) = pure CiEnum
+  parseJSON (A.Number 14) = pure CiKeyword
+  parseJSON (A.Number 15) = pure CiSnippet
+  parseJSON (A.Number 16) = pure CiColor
+  parseJSON (A.Number 17) = pure CiFile
+  parseJSON (A.Number 18) = pure CiReference
+  parseJSON _             = mempty
+
+
+-- -------------------------------------
+
+data CompletionItem =
+  CompletionItem
+    { _label               :: Text -- ^ The label of this completion item. By default also
+                       -- the text that is inserted when selecting this
+                       -- completion.
+    , _kind                :: Maybe CompletionItemKind
+    , _detail              :: Maybe Text -- ^ A human-readable string with additional
+                              -- information about this item, like type or
+                              -- symbol information.
+    , _documentation       :: Maybe Text -- ^ A human-readable string that represents
+                                    -- a doc-comment.
+    , _sortText            :: Maybe Text -- ^ A string that should be used when filtering
+                                -- a set of completion items. When `falsy` the
+                                -- label is used.
+    , _filterText          :: Maybe Text -- ^ A string that should be used when
+                                  -- filtering a set of completion items. When
+                                  -- `falsy` the label is used.
+    , _insertText          :: Maybe Text -- ^ A string that should be inserted a
+                                  -- document when selecting this completion.
+                                  -- When `falsy` the label is used.
+    , _insertTextFormat    :: Maybe InsertTextFormat
+         -- ^ The format of the insert text. The format applies to both the
+         -- `insertText` property and the `newText` property of a provided
+         -- `textEdit`.
+    , _textEdit            :: Maybe TextEdit
+         -- ^ An edit which is applied to a document when selecting this
+         -- completion. When an edit is provided the value of `insertText` is
+         -- ignored.
+         --
+         -- *Note:* The range of the edit must be a single line range and it
+         -- must contain the position at which completion has been requested.
+    , _additionalTextEdits :: Maybe (List TextEdit)
+         -- ^ An optional array of additional text edits that are applied when
+         -- selecting this completion. Edits must not overlap with the main edit
+         -- nor with themselves.
+    , _command             :: Maybe Command
+        -- ^ An optional command that is executed *after* inserting this
+        -- completion. *Note* that additional modifications to the current
+        -- document should be described with the additionalTextEdits-property.
+    , _xdata               :: Maybe A.Value -- ^ An data entry field that is preserved on a
+                              -- completion item between a completion and a
+                              -- completion resolve request.
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''CompletionItem
+makeFieldsNoPrefix ''CompletionItem
+
+data CompletionListType =
+  CompletionListType
+    { _isIncomplete :: Bool
+    , _items        :: List CompletionItem
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CompletionListType
+makeFieldsNoPrefix ''CompletionListType
+
+
+data CompletionResponseResult
+  = CompletionList CompletionListType
+  | Completions (List CompletionItem)
+  deriving (Read,Show,Eq)
+
+deriveJSON defaultOptions { fieldLabelModifier = rdrop (length ("CompletionResponseResult"::String)), sumEncoding = UntaggedValue } ''CompletionResponseResult
+
+type CompletionResponse = ResponseMessage CompletionResponseResult
+type CompletionRequest = RequestMessage ClientMethod TextDocumentPositionParams CompletionResponseResult
+
+-- -------------------------------------
+{-
+New in 3.0
+-----------
+Registration Options: CompletionRegistrationOptions options defined as follows:
+
+export interface CompletionRegistrationOptions extends TextDocumentRegistrationOptions {
+        /**
+         * The characters that trigger completion automatically.
+         */
+        triggerCharacters?: string[];
+
+        /**
+         * The server provides support to resolve additional
+         * information for a completion item.
+         */
+        resolveProvider?: boolean;
+}
+-}
+
+data CompletionRegistrationOptions =
+  CompletionRegistrationOptions
+    { _documentSelector  :: Maybe DocumentSelector
+    , _triggerCharacters :: Maybe (List String)
+    , _resolveProvider   :: Maybe Bool
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''CompletionRegistrationOptions
+makeFieldsNoPrefix ''CompletionRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+Completion Item Resolve Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#completion-item-resolve-request
+
+The request is sent from the client to the server to resolve additional
+information for a given completion item.
+
+Request
+
+    method: 'completionItem/resolve'
+    params: CompletionItem
+
+Response
+
+    result: CompletionItem
+    error: code and message set in case an exception happens during the completion resolve request.
+-}
+
+type CompletionItemResolveRequest  = RequestMessage ClientMethod CompletionItem CompletionItem
+type CompletionItemResolveResponse = ResponseMessage CompletionItem
+
+-- ---------------------------------------------------------------------
+{-
+Hover Request
+
+The hover request is sent from the client to the server to request hover
+information at a given text document position.
+
+    Changed: In 2.0 the request uses TextDocumentPositionParams with a proper
+    textDocument and position property. In 1.0 the uri of the referenced text
+    document was inlined into the params object.
+
+Request
+
+    method: 'textDocument/hover'
+    params: TextDocumentPositionParams
+
+Response
+
+    result: Hover defined as follows:
+
+/**
+ * The result of a hove request.
+ */
+interface Hover {
+    /**
+     * The hover's content
+     */
+    contents: MarkedString | MarkedString[];
+
+    /**
+     * An optional range
+     */
+    range?: Range;
+}
+
+Where MarkedString is defined as follows:
+/**
+ * MarkedString can be used to render human readable text. It is either a markdown string
+ * or a code-block that provides a language and a code snippet. The language identifier
+ * is sematically equal to the optional language identifier in fenced code blocks in GitHub
+ * issues. See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
+ *
+ * The pair of a language and a value is an equivalent to markdown:
+ * ```${language}
+ * ${value}
+ * ```
+ *
+ * Note that markdown strings will be sanitized - that means html will be escaped.
+ */
+type MarkedString = string | { language: string; value: string };
+
+    error: code and message set in case an exception happens during the hover
+    request.
+
+Registration Options: TextDocumentRegistrationOptions
+
+-}
+
+data LanguageString =
+  LanguageString
+    { _language :: Text
+    , _value    :: Text
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''LanguageString
+makeFieldsNoPrefix ''LanguageString
+
+data MarkedString =
+    PlainString T.Text
+  | CodeString LanguageString
+    deriving (Eq,Read,Show)
+
+instance ToJSON MarkedString where
+  toJSON (PlainString x) = toJSON x
+  toJSON (CodeString  x) = toJSON x
+instance FromJSON MarkedString where
+  parseJSON (A.String t) = pure $ PlainString t
+  parseJSON o            = CodeString <$> parseJSON o
+
+data Hover =
+  Hover
+    { _contents :: List MarkedString
+    , _range    :: Maybe Range
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''Hover
+makeFieldsNoPrefix ''Hover
+
+
+type HoverRequest = RequestMessage ClientMethod TextDocumentPositionParams Hover
+type HoverResponse = ResponseMessage Hover
+
+-- ---------------------------------------------------------------------
+{-
+Signature Help Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#signature-help-request
+
+The signature help request is sent from the client to the server to request
+signature information at a given cursor position.
+
+    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
+    textDocument and position properties. In 1.0 the uri of the referenced text
+    document was inlined into the params object.
+
+Request
+
+    method: 'textDocument/signatureHelp'
+    params: TextDocumentPositionParams
+
+Response
+
+    result: SignatureHelp defined as follows:
+
+/**
+ * Signature help represents the signature of something
+ * callable. There can be multiple signature but only one
+ * active and only one active parameter.
+ */
+interface SignatureHelp {
+    /**
+     * One or more signatures.
+     */
+    signatures: SignatureInformation[];
+
+    /**
+     * The active signature.
+     */
+    activeSignature?: number;
+
+    /**
+     * The active parameter of the active signature.
+     */
+    activeParameter?: number;
+}
+
+/**
+ * Represents the signature of something callable. A signature
+ * can have a label, like a function-name, a doc-comment, and
+ * a set of parameters.
+ */
+interface SignatureInformation {
+    /**
+     * The label of this signature. Will be shown in
+     * the UI.
+     */
+    label: string;
+
+    /**
+     * The human-readable doc-comment of this signature. Will be shown
+     * in the UI but can be omitted.
+     */
+    documentation?: string;
+
+    /**
+     * The parameters of this signature.
+     */
+    parameters?: ParameterInformation[];
+}
+
+/**
+ * Represents a parameter of a callable-signature. A parameter can
+ * have a label and a doc-comment.
+ */
+interface ParameterInformation {
+    /**
+     * The label of this signature. Will be shown in
+     * the UI.
+     */
+    label: string;
+
+    /**
+     * The human-readable doc-comment of this signature. Will be shown
+     * in the UI but can be omitted.
+     */
+    documentation?: string;
+}
+
+    error: code and message set in case an exception happens during the
+    signature help request.
+-}
+
+
+data ParameterInformation =
+  ParameterInformation
+    { _label         :: Text
+    , _documentation :: Maybe Text
+    } deriving (Read,Show,Eq)
+deriveJSON lspOptions ''ParameterInformation
+makeFieldsNoPrefix ''ParameterInformation
+
+
+-- -------------------------------------
+
+data SignatureInformation =
+  SignatureInformation
+    { _label         :: Text
+    , _documentation :: Maybe Text
+    , _parameters    :: Maybe [ParameterInformation]
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''SignatureInformation
+makeFieldsNoPrefix ''SignatureInformation
+
+data SignatureHelp =
+  SignatureHelp
+    { _signatures      :: List SignatureInformation
+    , _activeSignature :: Maybe Int -- ^ The active signature
+    , _activeParameter :: Maybe Int -- ^ The active parameter of the active signature
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''SignatureHelp
+makeFieldsNoPrefix ''SignatureHelp
+
+type SignatureHelpRequest = RequestMessage ClientMethod TextDocumentPositionParams SignatureHelp
+type SignatureHelpResponse = ResponseMessage SignatureHelp
+
+-- -------------------------------------
+{-
+New in 3.0
+----------
+Registration Options: SignatureHelpRegistrationOptions defined as follows:
+
+export interface SignatureHelpRegistrationOptions extends TextDocumentRegistrationOptions {
+        /**
+         * The characters that trigger signature help
+         * automatically.
+         */
+        triggerCharacters?: string[];
+}
+-}
+
+data SignatureHelpRegistrationOptions =
+  SignatureHelpRegistrationOptions
+    { _documentSelector  :: Maybe DocumentSelector
+    , _triggerCharacters :: Maybe (List String)
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''SignatureHelpRegistrationOptions
+makeFieldsNoPrefix ''SignatureHelpRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+Goto Definition Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#goto-definition-request
+
+The goto definition request is sent from the client to the server to resolve the
+definition location of a symbol at a given text document position.
+
+    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
+    textDocument and position properties. In 1.0 the uri of the referenced text
+    document was inlined into the params object.
+
+Request
+
+    method: 'textDocument/definition'
+    params: TextDocumentPositionParams
+
+Response:
+
+    result: Location | Location[]
+    error: code and message set in case an exception happens during the definition request.
+
+
+-}
+
+-- {"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"file:///tmp/Foo.hs"},"position":{"line":1,"character":8}}}
+
+data DefinitionResponseParams = SingleLoc Location | MultiLoc [Location]
+  deriving (Eq,Read,Show)
+
+instance A.ToJSON DefinitionResponseParams where
+  toJSON (SingleLoc x) = toJSON x
+  toJSON (MultiLoc xs) = toJSON xs
+
+instance A.FromJSON DefinitionResponseParams where
+  parseJSON xs@(A.Array _) = MultiLoc <$> parseJSON xs
+  parseJSON x              = SingleLoc <$> parseJSON x
+
+type DefinitionRequest  = RequestMessage ClientMethod TextDocumentPositionParams DefinitionResponseParams
+type DefinitionResponse = ResponseMessage DefinitionResponseParams
+
+-- ---------------------------------------------------------------------
+
+{-
+Find References Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#find-references-request
+
+The references request is sent from the client to the server to resolve
+project-wide references for the symbol denoted by the given text document
+position.
+
+    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
+    textDocument and position properties. In 1.0 the uri of the referenced text
+    document was inlined into the params object.
+
+Request
+
+    method: 'textDocument/references'
+    params: ReferenceParams defined as follows:
+
+interface ReferenceParams extends TextDocumentPositionParams {
+    context: ReferenceContext
+}
+
+interface ReferenceContext {
+    /**
+     * Include the declaration of the current symbol.
+     */
+    includeDeclaration: boolean;
+}
+
+Response:
+
+    result: Location[]
+    error: code and message set in case an exception happens during the
+           reference request.
+-}
+
+data ReferenceContext =
+  ReferenceContext
+    { _includeDeclaration :: Bool
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''ReferenceContext
+makeFieldsNoPrefix ''ReferenceContext
+
+
+data ReferenceParams =
+  ReferenceParams
+    { _textDocument :: TextDocumentIdentifier
+    , _position     :: Position
+    , _context      :: ReferenceContext
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''ReferenceParams
+makeFieldsNoPrefix ''ReferenceParams
+
+
+type ReferencesRequest  = RequestMessage ClientMethod ReferenceParams (List Location)
+type ReferencesResponse = ResponseMessage (List Location)
+
+-- ---------------------------------------------------------------------
+{-
+Document Highlights Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-highlights-request
+
+The document highlight request is sent from the client to the server to resolve
+a document highlights for a given text document position. For programming
+languages this usually highlights all references to the symbol scoped to this
+file. However we kept 'textDocument/documentHighlight' and
+'textDocument/references' separate requests since the first one is allowed to be
+more fuzzy. Symbol matches usually have a DocumentHighlightKind of Read or Write
+whereas fuzzy or textual matches use Textas the kind.
+
+    Changed: In 2.0 the request uses TextDocumentPositionParams with proper
+    textDocument and position properties. In 1.0 the uri of the referenced text
+    document was inlined into the params object.
+
+Request
+
+    method: 'textDocument/documentHighlight'
+    params: TextDocumentPositionParams
+
+Response
+
+    result: DocumentHighlight[] defined as follows:
+
+/**
+ * A document highlight is a range inside a text document which deserves
+ * special attention. Usually a document highlight is visualized by changing
+ * the background color of its range.
+ *
+ */
+interface DocumentHighlight {
+    /**
+     * The range this highlight applies to.
+     */
+    range: Range;
+
+    /**
+     * The highlight kind, default is DocumentHighlightKind.Text.
+     */
+    kind?: number;
+}
+
+/**
+ * A document highlight kind.
+ */
+enum DocumentHighlightKind {
+    /**
+     * A textual occurrance.
+     */
+    Text = 1,
+
+    /**
+     * Read-access of a symbol, like reading a variable.
+     */
+    Read = 2,
+
+    /**
+     * Write-access of a symbol, like writing to a variable.
+     */
+    Write = 3
+}
+
+    error: code and message set in case an exception happens during the document
+           highlight request.
+
+Registration Options: TextDocumentRegistrationOptions
+
+-}
+
+data DocumentHighlightKind = HkText | HkRead | HkWrite
+  deriving (Read,Show,Eq)
+
+instance A.ToJSON DocumentHighlightKind where
+  toJSON HkText  = A.Number 1
+  toJSON HkRead  = A.Number 2
+  toJSON HkWrite = A.Number 3
+
+instance A.FromJSON DocumentHighlightKind where
+  parseJSON (A.Number 1) = pure HkText
+  parseJSON (A.Number 2) = pure HkRead
+  parseJSON (A.Number 3) = pure HkWrite
+  parseJSON _            = mempty
+
+-- -------------------------------------
+
+data DocumentHighlight =
+  DocumentHighlight
+    { _range :: Range
+    , _kind  :: Maybe DocumentHighlightKind
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DocumentHighlight
+makeFieldsNoPrefix ''DocumentHighlight
+
+type DocumentHighlightRequest = RequestMessage ClientMethod TextDocumentPositionParams (List DocumentHighlight)
+type DocumentHighlightsResponse = ResponseMessage (List DocumentHighlight)
+
+-- ---------------------------------------------------------------------
+{-
+Workspace Symbols Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#workspace-symbols-request
+
+The workspace symbol request is sent from the client to the server to list
+project-wide symbols matching the query string.
+
+Request
+
+    method: 'workspace/symbol'
+    params: WorkspaceSymbolParams defined as follows:
+
+/**
+ * The parameters of a Workspace Symbol Request.
+ */
+interface WorkspaceSymbolParams {
+    /**
+     * A non-empty query string
+     */
+    query: string;
+}
+
+Response
+
+    result: SymbolInformation[] as defined above.
+    error: code and message set in case an exception happens during the
+           workspace symbol request.
+-}
+
+data WorkspaceSymbolParams =
+  WorkspaceSymbolParams
+    { _query :: Text
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''WorkspaceSymbolParams
+makeFieldsNoPrefix ''WorkspaceSymbolParams
+
+type WorkspaceSymbolRequest  = RequestMessage ClientMethod WorkspaceSymbolParams (List SymbolInformation)
+type WorkspaceSymbolsResponse = ResponseMessage (List SymbolInformation)
+
+-- ---------------------------------------------------------------------
+{-
+Code Lens Request
+
+The code lens request is sent from the client to the server to compute code
+lenses for a given text document.
+
+    Changed: In 2.0 the request uses CodeLensParams instead of a single uri.
+
+Request
+
+    method: 'textDocument/codeLens'
+    params: CodeLensParams defined as follows:
+
+interface CodeLensParams {
+    /**
+     * The document to request code lens for.
+     */
+    textDocument: TextDocumentIdentifier;
+}
+
+Response
+
+    result: CodeLens[] defined as follows:
+
+/**
+ * A code lens represents a command that should be shown along with
+ * source text, like the number of references, a way to run tests, etc.
+ *
+ * A code lens is _unresolved_ when no command is associated to it. For performance
+ * reasons the creation of a code lens and resolving should be done in two stages.
+ */
+interface CodeLens {
+    /**
+     * The range in which this code lens is valid. Should only span a single line.
+     */
+    range: Range;
+
+    /**
+     * The command this code lens represents.
+     */
+    command?: Command;
+
+    /**
+     * A data entry field that is preserved on a code lens item between
+     * a code lens and a code lens resolve request.
+     */
+    data?: any
+}
+
+    error: code and message set in case an exception happens during the code
+           lens request.
+-}
+
+data CodeLensParams =
+  CodeLensParams
+    { _textDocument :: TextDocumentIdentifier
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CodeLensParams
+makeFieldsNoPrefix ''CodeLensParams
+
+
+-- -------------------------------------
+
+data CodeLens =
+  CodeLens
+    { _range   :: Range
+    , _command :: Maybe Command
+    , _xdata   :: Maybe A.Value
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''CodeLens
+makeFieldsNoPrefix ''CodeLens
+
+
+type CodeLensRequest = RequestMessage ClientMethod CodeLensParams (List CodeLens)
+type CodeLensResponse = ResponseMessage (List CodeLens)
+
+-- -------------------------------------
+{-
+Registration Options: CodeLensRegistrationOptions defined as follows:
+
+export interface CodeLensRegistrationOptions extends TextDocumentRegistrationOptions {
+        /**
+         * Code lens has a resolve provider as well.
+         */
+        resolveProvider?: boolean;
+}
+-}
+
+data CodeLensRegistrationOptions =
+  CodeLensRegistrationOptions
+    { _documentSelector :: Maybe DocumentSelector
+    , _resolveProvider  :: Maybe Bool
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''CodeLensRegistrationOptions
+makeFieldsNoPrefix ''CodeLensRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+Code Lens Resolve Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#code-lens-resolve-request
+
+The code lens resolve request is sent from the client to the server to resolve
+the command for a given code lens item.
+
+Request
+
+    method: 'codeLens/resolve'
+    params: CodeLens
+
+Response
+
+    result: CodeLens
+    error: code and message set in case an exception happens during the code
+           lens resolve request.
+
+
+-}
+
+type CodeLensResolveRequest  = RequestMessage ClientMethod CodeLens (List CodeLens)
+type CodeLensResolveResponse = ResponseMessage (List CodeLens)
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+Document Link Request
+
+The document links request is sent from the client to the server to request the
+location of links in a document.
+
+Request:
+
+    method: 'textDocument/documentLink'
+    params: DocumentLinkParams, defined as follows
+
+interface DocumentLinkParams {
+        /**
+         * The document to provide document links for.
+         */
+        textDocument: TextDocumentIdentifier;
+}
+
+Response:
+
+    result: An array of DocumentLink, or null.
+
+/**
+ * A document link is a range in a text document that links to an internal or external resource, like another
+ * text document or a web site.
+ */
+interface DocumentLink {
+        /**
+         * The range this link applies to.
+         */
+        range: Range;
+        /**
+         * The uri this link points to. If missing a resolve request is sent later.
+         */
+        target?: DocumentUri;
+}
+
+    error: code and message set in case an exception happens during the document link request.
+
+Registration Options: DocumentLinkRegistrationOptions defined as follows:
+
+export interface DocumentLinkRegistrationOptions extends TextDocumentRegistrationOptions {
+        /**
+         * Document links have a resolve provider as well.
+         */
+        resolveProvider?: boolean;
+}
+-}
+
+data DocumentLinkParams =
+  DocumentLinkParams
+    { _textDocument :: TextDocumentIdentifier
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DocumentLinkParams
+makeFieldsNoPrefix ''DocumentLinkParams
+
+data DocumentLink =
+  DocumentLink
+    { _range  :: Range
+    , _target :: Maybe Text
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''DocumentLink
+makeFieldsNoPrefix ''DocumentLink
+
+type DocumentLinkRequest = RequestMessage ClientMethod DocumentLinkParams (List DocumentLink)
+type DocumentLinkResponse = ResponseMessage (List DocumentLink)
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+Document Link Resolve Request
+
+The document link resolve request is sent from the client to the server to resolve the target of a given document link.
+
+Request:
+
+    method: 'documentLink/resolve'
+    params: DocumentLink
+
+Response:
+
+    result: DocumentLink
+    error: code and message set in case an exception happens during the document link resolve request.
+
+-}
+
+type DocumentLinkResolveRequest  = RequestMessage ClientMethod DocumentLink DocumentLink
+type DocumentLinkResolveResponse = ResponseMessage DocumentLink
+
+-- ---------------------------------------------------------------------
+{-
+Document Formatting Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-formatting-request
+
+The document formatting request is sent from the server to the client to format
+a whole document.
+
+Request
+
+    method: 'textDocument/formatting'
+    params: DocumentFormattingParams defined as follows
+
+interface DocumentFormattingParams {
+    /**
+     * The document to format.
+     */
+    textDocument: TextDocumentIdentifier;
+
+    /**
+     * The format options.
+     */
+    options: FormattingOptions;
+}
+
+/**
+ * Value-object describing what options formatting should use.
+ */
+interface FormattingOptions {
+    /**
+     * Size of a tab in spaces.
+     */
+    tabSize: number;
+
+    /**
+     * Prefer spaces over tabs.
+     */
+    insertSpaces: boolean;
+
+    /**
+     * Signature for further properties.
+     */
+    [key: string]: boolean | number | string;
+}
+
+Response
+
+    result: TextEdit[] describing the modification to the document to be
+            formatted.
+    error: code and message set in case an exception happens during the
+           formatting request.
+
+Registration Options: TextDocumentRegistrationOptions
+-}
+
+data FormattingOptions =
+  FormattingOptions
+    { _tabSize      :: Int
+    , _insertSpaces :: Bool -- ^ Prefer spaces over tabs
+    -- Note: May be more properties
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''FormattingOptions
+makeFieldsNoPrefix ''FormattingOptions
+
+data DocumentFormattingParams =
+  DocumentFormattingParams
+    { _textDocument :: TextDocumentIdentifier
+    , _options      :: FormattingOptions
+    } deriving (Show,Read,Eq)
+
+deriveJSON lspOptions ''DocumentFormattingParams
+makeFieldsNoPrefix ''DocumentFormattingParams
+
+type DocumentFormattingRequest  = RequestMessage ClientMethod DocumentFormattingParams (List TextEdit)
+type DocumentFormattingResponse = ResponseMessage (List TextEdit)
+
+-- ---------------------------------------------------------------------
+{-
+Document Range Formatting Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-range-formatting-request
+
+The document range formatting request is sent from the client to the server to
+format a given range in a document.
+
+Request
+
+    method: 'textDocument/rangeFormatting',
+    params: DocumentRangeFormattingParams defined as follows
+
+interface DocumentRangeFormattingParams {
+    /**
+     * The document to format.
+     */
+    textDocument: TextDocumentIdentifier;
+
+    /**
+     * The range to format
+     */
+    range: Range;
+
+    /**
+     * The format options
+     */
+    options: FormattingOptions;
+}
+
+Response
+
+    result: TextEdit[] describing the modification to the document to be
+            formatted.
+    error: code and message set in case an exception happens during the range
+           formatting request.
+-}
+
+data DocumentRangeFormattingParams =
+  DocumentRangeFormattingParams
+    { _textDocument :: TextDocumentIdentifier
+    , _range        :: Range
+    , _options      :: FormattingOptions
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DocumentRangeFormattingParams
+makeFieldsNoPrefix ''DocumentRangeFormattingParams
+
+type DocumentRangeFormattingRequest  = RequestMessage ClientMethod DocumentRangeFormattingParams (List TextEdit)
+type DocumentRangeFormattingResponse = ResponseMessage (List TextEdit)
+
+-- ---------------------------------------------------------------------
+{-
+Document on Type Formatting Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-on-type-formatting-request
+
+The document on type formatting request is sent from the client to the server to
+format parts of the document during typing.
+
+Request
+
+    method: 'textDocument/onTypeFormatting'
+    params: DocumentOnTypeFormattingParams defined as follows
+
+interface DocumentOnTypeFormattingParams {
+    /**
+     * The document to format.
+     */
+    textDocument: TextDocumentIdentifier;
+
+    /**
+     * The position at which this request was sent.
+     */
+    position: Position;
+
+    /**
+     * The character that has been typed.
+     */
+    ch: string;
+
+    /**
+     * The format options.
+     */
+    options: FormattingOptions;
+}
+
+Response
+
+    result: TextEdit[] describing the modification to the document.
+    error: code and message set in case an exception happens during the range
+           formatting request.
+
+Registration Options: DocumentOnTypeFormattingRegistrationOptions defined as follows:
+
+export interface DocumentOnTypeFormattingRegistrationOptions extends TextDocumentRegistrationOptions {
+        /**
+         * A character on which formatting should be triggered, like `}`.
+         */
+        firstTriggerCharacter: string;
+        /**
+         * More trigger characters.
+         */
+        moreTriggerCharacter?: string[]
+}
+-}
+
+data DocumentOnTypeFormattingParams =
+  DocumentOnTypeFormattingParams
+    { _textDocument :: TextDocumentIdentifier
+    , _position     :: Position
+    , _ch           :: Text
+    , _options      :: FormattingOptions
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DocumentOnTypeFormattingParams
+makeFieldsNoPrefix ''DocumentOnTypeFormattingParams
+
+type DocumentOnTypeFormattingRequest  = RequestMessage ClientMethod DocumentOnTypeFormattingParams (List TextEdit)
+type DocumentOnTypeFormattingResponse = ResponseMessage (List TextEdit)
+
+data DocumentOnTypeFormattingRegistrationOptions =
+  DocumentOnTypeFormattingRegistrationOptions
+    { _firstTriggerCharacter :: Text
+    , _moreTriggerCharacter  :: Maybe (List String)
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''DocumentOnTypeFormattingRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+Rename Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#rename-request
+
+The rename request is sent from the client to the server to perform a
+workspace-wide rename of a symbol.
+
+Request
+
+    method: 'textDocument/rename'
+    params: RenameParams defined as follows
+
+interface RenameParams {
+    /**
+     * The document to format.
+     */
+    textDocument: TextDocumentIdentifier;
+
+    /**
+     * The position at which this request was sent.
+     */
+    position: Position;
+
+    /**
+     * The new name of the symbol. If the given name is not valid the
+     * request must return a [ResponseError](#ResponseError) with an
+     * appropriate message set.
+     */
+    newName: string;
+}
+
+Response
+
+    result: WorkspaceEdit describing the modification to the workspace.
+    error: code and message set in case an exception happens during the rename
+           request.
+
+Registration Options: TextDocumentRegistrationOptions
+
+-}
+data RenameParams =
+  RenameParams
+    { _textDocument :: TextDocumentIdentifier
+    , _position     :: Position
+    , _newName      :: Text
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''RenameParams
+makeFieldsNoPrefix ''RenameParams
+
+
+-- {\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"textDocument/rename\",\"params\":{\"textDocument\":{\"uri\":\"file:///home/alanz/mysrc/github/alanz/haskell-lsp/src/HieVscode.hs\"},\"position\":{\"line\":37,\"character\":17},\"newName\":\"getArgs'\"}}
+
+type RenameRequest  = RequestMessage ClientMethod RenameParams WorkspaceEdit
+type RenameResponse = ResponseMessage WorkspaceEdit
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+Execute a command
+
+The workspace/executeCommand request is sent from the client to the server to
+trigger command execution on the server. In most cases the server creates a
+WorkspaceEdit structure and applies the changes to the workspace using the
+request workspace/applyEdit which is sent from the server to the client.
+
+Request:
+
+    method: 'workspace/executeCommand'
+    params: ExecuteCommandParams defined as follows:
+
+export interface ExecuteCommandParams {
+
+        /**
+         * The identifier of the actual command handler.
+         */
+        command: string;
+        /**
+         * Arguments that the command should be invoked with.
+         */
+        arguments?: any[];
+}
+
+The arguments are typically specified when a command is returned from the server
+to the client. Example requests that return a command are
+textDocument/codeAction or textDocument/codeLens.
+
+Response:
+
+    result: any
+    error: code and message set in case an exception happens during the request.
+
+Registration Options: ExecuteCommandRegistrationOptions defined as follows:
+
+/**
+ * Execute command registration options.
+ */
+export interface ExecuteCommandRegistrationOptions {
+        /**
+         * The commands to be executed on the server
+         */
+        commands: string[]
+}
+-}
+
+data ExecuteCommandParams =
+  ExecuteCommandParams
+    { _command   :: Text
+    , _arguments :: Maybe (List A.Value)
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''ExecuteCommandParams
+makeFieldsNoPrefix ''ExecuteCommandParams
+
+type ExecuteCommandRequest = RequestMessage ClientMethod ExecuteCommandParams A.Value
+type ExecuteCommandResponse = ResponseMessage A.Value
+
+data ExecuteCommandRegistrationOptions =
+  ExecuteCommandRegistrationOptions
+    { _commands :: List Text
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''ExecuteCommandRegistrationOptions
+makeFieldsNoPrefix ''ExecuteCommandRegistrationOptions
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+Applies a WorkspaceEdit
+
+The workspace/applyEdit request is sent from the server to the client to modify
+resource on the client side.
+
+Request:
+
+    method: 'workspace/applyEdit'
+    params: ApplyWorkspaceEditParams defined as follows:
+
+export interface ApplyWorkspaceEditParams {
+        /**
+         * The edits to apply.
+         */
+        edit: WorkspaceEdit;
+}
+
+Response:
+
+    result: ApplyWorkspaceEditResponse defined as follows:
+
+export interface ApplyWorkspaceEditResponse {
+        /**
+         * Indicates whether the edit was applied or not.
+         */
+        applied: boolean;
+}
+
+    error: code and message set in case an exception happens during the request.
+
+-}
+data ApplyWorkspaceEditParams =
+  ApplyWorkspaceEditParams
+    { _edit :: WorkspaceEdit
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''ApplyWorkspaceEditParams
+makeFieldsNoPrefix ''ApplyWorkspaceEditParams
+
+data ApplyWorkspaceEditResponseBody =
+  ApplyWorkspaceEditResponseBody
+    { _applied :: Bool
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''ApplyWorkspaceEditResponseBody
+makeFieldsNoPrefix ''ApplyWorkspaceEditResponseBody
+
+-- | Sent from the server to the client
+type ApplyWorkspaceEditRequest  = RequestMessage ServerMethod ApplyWorkspaceEditParams ApplyWorkspaceEditResponseBody
+type ApplyWorkspaceEditResponse = ResponseMessage ApplyWorkspaceEditResponseBody
+
+-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-- ---------------------------------------------------------------------
+
+data TraceParams =
+  TraceParams {
+    _value :: Text
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TraceParams
+makeFieldsNoPrefix ''TraceParams
+
+
+data TraceNotification =
+  TraceNotification {
+    _params :: TraceParams
+  } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TraceNotification
+makeFieldsNoPrefix ''TraceNotification
+
+
+
+-- ---------------------------------------------------------------------
+
+-- Generating lenses
+-- Need to do this all in one file or else we get duplicate functions
+
+-- Location
+makeFieldsNoPrefix ''Position
+makeFieldsNoPrefix ''Range
+makeFieldsNoPrefix ''Location
+
+-- CodeActions
+makeFieldsNoPrefix ''CodeActionContext
+makeFieldsNoPrefix ''CodeActionParams
+makeFieldsNoPrefix ''CodeAction
+
+-- WorkspaceEdit
+makeFieldsNoPrefix ''TextEdit
+makeFieldsNoPrefix ''VersionedTextDocumentIdentifier
+makeFieldsNoPrefix ''TextDocumentEdit
+makeFieldsNoPrefix ''WorkspaceEdit
+
+-- Message
+makeFieldsNoPrefix ''RequestMessage
+makeFieldsNoPrefix ''ResponseError
+makeFieldsNoPrefix ''ResponseMessage
+makeFieldsNoPrefix ''NotificationMessage
+makeFieldsNoPrefix ''CancelParams
+
+-- TextDocumentIdentifier
+makeFieldsNoPrefix ''TextDocumentIdentifier
+
+-- Command
+makeFieldsNoPrefix ''Command
+
+-- Diagnostic
+makeFieldsNoPrefix ''Diagnostic
+makeFieldsNoPrefix ''DiagnosticRelatedInformation
+
+-- Symbol
+makeFieldsNoPrefix ''DocumentSymbolParams
+makeFieldsNoPrefix ''SymbolInformation
diff --git a/src/Language/Haskell/LSP/TH/Diagnostic.hs b/src/Language/Haskell/LSP/TH/Diagnostic.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/Diagnostic.hs
@@ -0,0 +1,139 @@
+{-# LANGUAGE DuplicateRecordFields      #-}
+{-# LANGUAGE TemplateHaskell            #-}
+
+module Language.Haskell.LSP.TH.Diagnostic where
+
+import qualified Data.Aeson                                 as A
+import           Data.Aeson.TH
+import           Data.Text
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.List
+import           Language.Haskell.LSP.TH.Location
+
+-- ---------------------------------------------------------------------
+{-
+The protocol currently supports the following diagnostic severities:
+
+enum DiagnosticSeverity {
+    /**
+     * Reports an error.
+     */
+    Error = 1,
+    /**
+     * Reports a warning.
+     */
+    Warning = 2,
+    /**
+     * Reports an information.
+     */
+    Information = 3,
+    /**
+     * Reports a hint.
+     */
+    Hint = 4
+}
+-}
+data DiagnosticSeverity
+  = DsError   -- ^ Error = 1,
+  | DsWarning -- ^ Warning = 2,
+  | DsInfo    -- ^ Info = 3,
+  | DsHint    -- ^ Hint = 4
+  deriving (Eq,Ord,Show,Read)
+
+instance A.ToJSON DiagnosticSeverity where
+  toJSON DsError   = A.Number 1
+  toJSON DsWarning = A.Number 2
+  toJSON DsInfo    = A.Number 3
+  toJSON DsHint    = A.Number 4
+
+instance A.FromJSON DiagnosticSeverity where
+  parseJSON (A.Number 1) = pure DsError
+  parseJSON (A.Number 2) = pure DsWarning
+  parseJSON (A.Number 3) = pure DsInfo
+  parseJSON (A.Number 4) = pure DsHint
+  parseJSON _            = mempty
+
+-- ---------------------------------------------------------------------
+{-
+Represents a related message and source code location for a diagnostic. This should be
+used to point to code locations that cause or related to a diagnostics, e.g when duplicating
+a symbol in a scope.
+
+export interface DiagnosticRelatedInformation {
+  /**
+   * The location of this related diagnostic information.
+   */
+  location: Location;
+
+  /**
+   * The message of this related diagnostic information.
+   */
+  message: string;
+}
+-}
+
+data DiagnosticRelatedInformation =
+  DiagnosticRelatedInformation
+    { _location :: Location
+    , _message  :: Text
+    } deriving (Show, Read, Eq, Ord)
+
+deriveJSON lspOptions ''DiagnosticRelatedInformation
+
+-- ---------------------------------------------------------------------
+{-
+Diagnostic
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#diagnostic
+
+Represents a diagnostic, such as a compiler error or warning. Diagnostic objects
+are only valid in the scope of a resource.
+
+interface Diagnostic {
+    /**
+     * The range at which the message applies.
+     */
+    range: Range;
+
+    /**
+     * The diagnostic's severity. Can be omitted. If omitted it is up to the
+     * client to interpret diagnostics as error, warning, info or hint.
+     */
+    severity?: number;
+
+    /**
+     * The diagnostic's code. Can be omitted.
+     */
+    code?: number | string;
+
+    /**
+     * A human-readable string describing the source of this
+     * diagnostic, e.g. 'typescript' or 'super lint'.
+     */
+    source?: string;
+
+    /**
+     * The diagnostic's message.
+     */
+    message: string;
+
+    /**
+     * An array of related diagnostic information, e.g. when symbol-names within
+     * a scope collide all definitions can be marked via this property.
+     */
+    relatedInformation?: DiagnosticRelatedInformation[];
+}
+-}
+
+type DiagnosticSource = Text
+data Diagnostic =
+  Diagnostic
+    { _range              :: Range
+    , _severity           :: Maybe DiagnosticSeverity
+    , _code               :: Maybe Text -- Note: Protocol allows Int too.
+    , _source             :: Maybe DiagnosticSource
+    , _message            :: Text
+    , _relatedInformation :: Maybe (List DiagnosticRelatedInformation)
+    } deriving (Show, Read, Eq, Ord)
+
+deriveJSON lspOptions ''Diagnostic
diff --git a/src/Language/Haskell/LSP/TH/List.hs b/src/Language/Haskell/LSP/TH/List.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/List.hs
@@ -0,0 +1,26 @@
+-- Need to split these types out into a separate module since
+-- ClientCapabilities also depends on them
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE DeriveTraversable          #-}
+module Language.Haskell.LSP.TH.List where
+
+import qualified Data.Aeson                                 as A
+import           Data.Aeson.Types
+
+-- | This data type is used to host a FromJSON instance for the encoding used by
+-- elisp, where an empty list shows up as "null"
+newtype List a = List [a]
+                deriving (Show,Read,Eq,Ord,Monoid,Functor,Foldable,Traversable)
+
+instance (A.ToJSON a) => A.ToJSON (List a) where
+  toJSON (List ls) = toJSON ls
+
+instance (A.FromJSON a) => A.FromJSON (List a) where
+  parseJSON A.Null = return (List [])
+  parseJSON v      = List <$> parseJSON v
+
+#if __GLASGOW_HASKELL__ >= 804
+instance Semigroup (List a) where
+  (<>) = mappend
+#endif
diff --git a/src/Language/Haskell/LSP/TH/Location.hs b/src/Language/Haskell/LSP/TH/Location.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/Location.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE TemplateHaskell            #-}
+module Language.Haskell.LSP.TH.Location where
+
+import           Data.Aeson.TH
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.Uri
+
+-- ---------------------------------------------------------------------
+
+{-
+The current protocol is talored for textual documents which content can be
+represented as a string. There is currently no support for binary documents.
+Positions inside a document (see Position definition below) are expressed as a
+zero-based line and character offset. To ensure that both client and server
+split the string into the same line representation the protocol specs the
+following end of line sequences: '\n', '\r\n' and '\r'.
+
+export const EOL: string[] = ['\n', '\r\n', '\r'];
+-}
+{-
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#position
+
+Position in a text document expressed as zero-based line and character offset. A
+position is between two characters like an 'insert' cursor in a editor.
+
+interface Position {
+    /**
+     * Line position in a document (zero-based).
+     */
+    line: number;
+
+    /**
+     * Character offset on a line in a document (zero-based).
+     */
+    character: number;
+}
+-}
+data Position =
+  Position
+    { _line      :: Int
+    , _character :: Int
+    } deriving (Show, Read, Eq, Ord)
+
+deriveJSON lspOptions ''Position
+
+-- ---------------------------------------------------------------------
+{-
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#range
+
+A range in a text document expressed as (zero-based) start and end positions. A
+range is comparable to a selection in an editor. Therefore the end position is
+exclusive.
+
+interface Range {
+    /**
+     * The range's start position.
+     */
+    start: Position;
+
+    /**
+     * The range's end position.
+     */
+    end: Position;
+}
+-}
+
+data Range =
+  Range
+    { _start :: Position
+    , _end   :: Position
+    } deriving (Show, Read, Eq, Ord)
+
+deriveJSON lspOptions ''Range
+
+-- ---------------------------------------------------------------------
+{-
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#location
+
+Represents a location inside a resource, such as a line inside a text file.
+
+interface Location {
+    uri: string;
+    range: Range;
+}
+-}
+
+data Location =
+  Location
+    { _uri   :: Uri
+    , _range :: Range
+    } deriving (Show, Read, Eq, Ord)
+
+deriveJSON lspOptions ''Location
diff --git a/src/Language/Haskell/LSP/TH/Message.hs b/src/Language/Haskell/LSP/TH/Message.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/Message.hs
@@ -0,0 +1,417 @@
+{-# LANGUAGE DuplicateRecordFields      #-}
+{-# LANGUAGE OverloadedStrings          #-}
+{-# LANGUAGE TemplateHaskell            #-}
+module Language.Haskell.LSP.TH.Message where
+
+import qualified Data.Aeson                                 as A
+import           Data.Aeson.TH
+import           Data.Aeson.Types
+import           Data.Hashable
+-- For <= 8.2.2
+import           Data.Monoid                                ((<>))
+import           Data.Text                                  (Text)
+import qualified Data.Text                                  as T
+import           Language.Haskell.LSP.TH.Constants
+
+
+-- | Id used for a request, Can be either a String or an Int
+data LspId = IdInt Int | IdString Text
+            deriving (Show,Read,Eq,Ord)
+
+instance A.ToJSON LspId where
+  toJSON (IdInt i)    = toJSON i
+  toJSON (IdString s) = toJSON s
+
+instance A.FromJSON LspId where
+  parseJSON v@(A.Number _) = IdInt <$> parseJSON v
+  parseJSON  (A.String  s) = return (IdString s)
+  parseJSON _              = mempty
+
+instance Hashable LspId where
+  hashWithSalt salt (IdInt i) = hashWithSalt salt i
+  hashWithSalt salt (IdString s) = hashWithSalt salt s
+
+-- ---------------------------------------------------------------------
+
+-- | Id used for a response, Can be either a String or an Int, or Null. If a
+-- request doesn't provide a result value the receiver of a request still needs
+-- to return a response message to conform to the JSON RPC specification. The
+-- result property of the ResponseMessage should be set to null in this case to
+-- signal a successful request.
+data LspIdRsp = IdRspInt Int | IdRspString Text | IdRspNull
+            deriving (Show,Read,Eq)
+
+instance A.ToJSON LspIdRsp where
+  toJSON (IdRspInt i)    = toJSON i
+  toJSON (IdRspString s) = toJSON s
+  toJSON IdRspNull       = A.Null
+
+instance A.FromJSON LspIdRsp where
+  parseJSON v@(A.Number _) = IdRspInt <$> parseJSON v
+  parseJSON  (A.String  s) = return $ IdRspString s
+  parseJSON  A.Null        = return IdRspNull
+  parseJSON _              = mempty
+
+instance Hashable LspIdRsp where
+  hashWithSalt salt (IdRspInt i) = hashWithSalt salt i
+  hashWithSalt salt (IdRspString s) = hashWithSalt salt s
+  hashWithSalt _ IdRspNull = 0
+
+-- | Converts an LspId to its LspIdRsp counterpart.
+responseId :: LspId -> LspIdRsp
+responseId (IdInt    i) = IdRspInt i
+responseId (IdString s) = IdRspString s
+
+-- | Converts an LspIdRsp to its LspId counterpart. 
+requestId :: LspIdRsp -> LspId
+requestId (IdRspInt    i) = IdInt i
+requestId (IdRspString s) = IdString s
+requestId IdRspNull       = error "Null response id"
+
+-- ---------------------------------------------------------------------
+
+-- Client Methods
+data ClientMethod =
+ -- General
+   Initialize
+ | Initialized
+ | Shutdown
+ | Exit
+ | CancelRequest
+ -- Workspace
+ | WorkspaceDidChangeConfiguration
+ | WorkspaceDidChangeWatchedFiles
+ | WorkspaceSymbol
+ | WorkspaceExecuteCommand
+ -- Document
+ | TextDocumentDidOpen
+ | TextDocumentDidChange
+ | TextDocumentWillSave
+ | TextDocumentWillSaveWaitUntil
+ | TextDocumentDidSave
+ | TextDocumentDidClose
+ | TextDocumentCompletion
+ | CompletionItemResolve
+ | TextDocumentHover
+ | TextDocumentSignatureHelp
+ | TextDocumentReferences
+ | TextDocumentDocumentHighlight
+ | TextDocumentDocumentSymbol
+ | TextDocumentFormatting
+ | TextDocumentRangeFormatting
+ | TextDocumentOnTypeFormatting
+ | TextDocumentDefinition
+ | TextDocumentCodeAction
+ | TextDocumentCodeLens
+ | CodeLensResolve
+ | TextDocumentDocumentLink
+ | DocumentLinkResolve
+ | TextDocumentRename
+ -- Messages of the form $/message
+ -- Implementation Dependent, can be ignored
+ | Misc Text
+   deriving (Eq,Ord,Read,Show)
+
+instance A.FromJSON ClientMethod where
+  -- General
+  parseJSON (A.String "initialize")                       = return Initialize
+  parseJSON (A.String "initialized")                      = return Initialized
+  parseJSON (A.String "shutdown")                         = return Shutdown
+  parseJSON (A.String "exit")                             = return Exit
+  parseJSON (A.String "$/cancelRequest")                  = return CancelRequest
+ -- Workspace
+  parseJSON (A.String "workspace/didChangeConfiguration") = return WorkspaceDidChangeConfiguration
+  parseJSON (A.String "workspace/didChangeWatchedFiles")  = return WorkspaceDidChangeWatchedFiles
+  parseJSON (A.String "workspace/symbol")                 = return WorkspaceSymbol
+  parseJSON (A.String "workspace/executeCommand")         = return WorkspaceExecuteCommand
+ -- Document
+  parseJSON (A.String "textDocument/didOpen")             = return TextDocumentDidOpen
+  parseJSON (A.String "textDocument/didChange")           = return TextDocumentDidChange
+  parseJSON (A.String "textDocument/willSave")            = return TextDocumentWillSave
+  parseJSON (A.String "textDocument/willSaveWaitUntil")   = return TextDocumentWillSaveWaitUntil
+  parseJSON (A.String "textDocument/didSave")             = return TextDocumentDidSave
+  parseJSON (A.String "textDocument/didClose")            = return TextDocumentDidClose
+  parseJSON (A.String "textDocument/completion")          = return TextDocumentCompletion
+  parseJSON (A.String "completionItem/resolve")           = return CompletionItemResolve
+  parseJSON (A.String "textDocument/hover")               = return TextDocumentHover
+  parseJSON (A.String "textDocument/signatureHelp")       = return TextDocumentSignatureHelp
+  parseJSON (A.String "textDocument/references")          = return TextDocumentReferences
+  parseJSON (A.String "textDocument/documentHighlight")   = return TextDocumentDocumentHighlight
+  parseJSON (A.String "textDocument/documentSymbol")      = return TextDocumentDocumentSymbol
+  parseJSON (A.String "textDocument/formatting")          = return TextDocumentFormatting
+  parseJSON (A.String "textDocument/rangeFormatting")     = return TextDocumentRangeFormatting
+  parseJSON (A.String "textDocument/onTypeFormatting")    = return TextDocumentOnTypeFormatting
+  parseJSON (A.String "textDocument/definition")          = return TextDocumentDefinition
+  parseJSON (A.String "textDocument/codeAction")          = return TextDocumentCodeAction
+  parseJSON (A.String "textDocument/codeLens")            = return TextDocumentCodeLens
+  parseJSON (A.String "codeLens/resolve")                 = return CodeLensResolve
+  parseJSON (A.String "textDocument/documentLink")        = return TextDocumentDocumentLink
+  parseJSON (A.String "documentLink/resolve")             = return DocumentLinkResolve
+  parseJSON (A.String "textDocument/rename")              = return TextDocumentRename
+  parseJSON (A.String x)                                  = if T.isPrefixOf "$/" x
+                                                               then return $ Misc (T.drop 2 x)
+                                                            else mempty
+  parseJSON _                                             = mempty
+
+instance A.ToJSON ClientMethod where
+  -- General
+  toJSON Initialize                      = A.String "initialize"
+  toJSON Initialized                     = A.String "initialized"
+  toJSON Shutdown                        = A.String "shutdown"
+  toJSON Exit                            = A.String "exit"
+  toJSON CancelRequest                   = A.String "$/cancelRequest"
+  -- Workspace
+  toJSON WorkspaceDidChangeConfiguration = A.String "workspace/didChangeConfiguration"
+  toJSON WorkspaceDidChangeWatchedFiles  = A.String "workspace/didChangeWatchedFiles"
+  toJSON WorkspaceSymbol                 = A.String "workspace/symbol"
+  toJSON WorkspaceExecuteCommand         = A.String "workspace/executeCommand"
+  -- Document
+  toJSON TextDocumentDidOpen             = A.String "textDocument/didOpen"
+  toJSON TextDocumentDidChange           = A.String "textDocument/didChange"
+  toJSON TextDocumentWillSave            = A.String "textDocument/willSave"
+  toJSON TextDocumentWillSaveWaitUntil   = A.String "textDocument/willSaveWaitUntil"
+  toJSON TextDocumentDidSave             = A.String "textDocument/didSave"
+  toJSON TextDocumentDidClose            = A.String "textDocument/didClose"
+  toJSON TextDocumentCompletion          = A.String "textDocument/completion"
+  toJSON CompletionItemResolve           = A.String "completionItem/resolve"
+  toJSON TextDocumentHover               = A.String "textDocument/hover"
+  toJSON TextDocumentSignatureHelp       = A.String "textDocument/signatureHelp"
+  toJSON TextDocumentReferences          = A.String "textDocument/references"
+  toJSON TextDocumentDocumentHighlight   = A.String "textDocument/documentHighlight"
+  toJSON TextDocumentDocumentSymbol      = A.String "textDocument/documentSymbol"
+  toJSON TextDocumentFormatting          = A.String "textDocument/formatting"
+  toJSON TextDocumentRangeFormatting     = A.String "textDocument/rangeFormatting"
+  toJSON TextDocumentOnTypeFormatting    = A.String "textDocument/onTypeFormatting"
+  toJSON TextDocumentDefinition          = A.String "textDocument/definition"
+  toJSON TextDocumentCodeAction          = A.String "textDocument/codeAction"
+  toJSON TextDocumentCodeLens            = A.String "textDocument/codeLens"
+  toJSON CodeLensResolve                 = A.String "codeLens/resolve"
+  toJSON TextDocumentRename              = A.String "textDocument/rename"
+  toJSON TextDocumentDocumentLink        = A.String "textDocument/documentLink"
+  toJSON DocumentLinkResolve             = A.String "documentLink/resolve"
+  toJSON (Misc xs)                       = A.String $ "$/" <> xs
+
+data ServerMethod =
+  -- Window
+    WindowShowMessage
+  | WindowShowMessageRequest
+  | WindowLogMessage
+  | TelemetryEvent
+  -- Client
+  | ClientRegisterCapability
+  | ClientUnregisterCapability
+  -- Workspace
+  | WorkspaceApplyEdit
+  -- Document
+  | TextDocumentPublishDiagnostics
+  -- Cancelling
+  | CancelRequestServer  
+   deriving (Eq,Ord,Read,Show)
+
+instance A.FromJSON ServerMethod where
+  -- Window
+  parseJSON (A.String "window/showMessage")              = return WindowShowMessage
+  parseJSON (A.String "window/showMessageRequest")       = return WindowShowMessageRequest
+  parseJSON (A.String "window/logMessage")               = return WindowLogMessage
+  parseJSON (A.String "telemetry/event")                 = return TelemetryEvent
+  -- Client
+  parseJSON (A.String "client/registerCapability")       = return ClientRegisterCapability
+  parseJSON (A.String "client/unregisterCapability")     = return ClientUnregisterCapability
+  -- Workspace
+  parseJSON (A.String "workspace/applyEdit")             = return WorkspaceApplyEdit
+  -- Document
+  parseJSON (A.String "textDocument/publishDiagnostics") = return TextDocumentPublishDiagnostics
+  -- Cancelling
+  parseJSON (A.String "$/cancelRequest")                 = return CancelRequestServer
+  parseJSON _                                            = mempty
+
+instance A.ToJSON ServerMethod where
+  -- Window
+  toJSON WindowShowMessage = A.String "window/showMessage"
+  toJSON WindowShowMessageRequest = A.String "window/showMessageRequest"
+  toJSON WindowLogMessage = A.String "window/logMessage"
+  toJSON TelemetryEvent = A.String "telemetry/event"
+  -- Client
+  toJSON ClientRegisterCapability = A.String "client/registerCapability"
+  toJSON ClientUnregisterCapability = A.String "client/unregisterCapability"
+  -- Workspace
+  toJSON WorkspaceApplyEdit = A.String "workspace/applyEdit"
+  -- Document
+  toJSON TextDocumentPublishDiagnostics = A.String "textDocument/publishDiagnostics"
+  -- Cancelling
+  toJSON CancelRequestServer = A.String "$/cancelRequest"
+
+data RequestMessage m req resp =
+  RequestMessage
+    { _jsonrpc :: Text
+    , _id      :: LspId
+    , _method  :: m
+    , _params  :: req
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''RequestMessage
+
+-- ---------------------------------------------------------------------
+{-
+interface ResponseError<D> {
+    /**
+     * A number indicating the error type that occurred.
+     */
+    code: number;
+
+    /**
+     * A string providing a short description of the error.
+     */
+    message: string;
+
+    /**
+     * A Primitive or Structured value that contains additional
+     * information about the error. Can be omitted.
+     */
+    data?: D;
+}
+
+export namespace ErrorCodes {
+        // Defined by JSON RPC
+        export const ParseError: number = -32700;
+        export const InvalidRequest: number = -32600;
+        export const MethodNotFound: number = -32601;
+        export const InvalidParams: number = -32602;
+        export const InternalError: number = -32603;
+        export const serverErrorStart: number = -32099;
+        export const serverErrorEnd: number = -32000;
+        export const ServerNotInitialized: number = -32002;
+        export const UnknownErrorCode: number = -32001;
+
+        // Defined by the protocol.
+        export const RequestCancelled: number = -32800;
+}
+-}
+
+data ErrorCode = ParseError
+               | InvalidRequest
+               | MethodNotFound
+               | InvalidParams
+               | InternalError
+               | ServerErrorStart
+               | ServerErrorEnd
+               | ServerNotInitialized
+               | UnknownErrorCode
+               | RequestCancelled
+               -- ^ Note: server error codes are reserved from -32099 to -32000
+               deriving (Read,Show,Eq)
+
+instance A.ToJSON ErrorCode where
+  toJSON ParseError           = A.Number (-32700)
+  toJSON InvalidRequest       = A.Number (-32600)
+  toJSON MethodNotFound       = A.Number (-32601)
+  toJSON InvalidParams        = A.Number (-32602)
+  toJSON InternalError        = A.Number (-32603)
+  toJSON ServerErrorStart     = A.Number (-32099)
+  toJSON ServerErrorEnd       = A.Number (-32000)
+  toJSON ServerNotInitialized = A.Number (-32002)
+  toJSON UnknownErrorCode     = A.Number (-32001)
+  toJSON RequestCancelled     = A.Number (-32800)
+
+instance A.FromJSON ErrorCode where
+  parseJSON (A.Number (-32700)) = pure ParseError
+  parseJSON (A.Number (-32600)) = pure InvalidRequest
+  parseJSON (A.Number (-32601)) = pure MethodNotFound
+  parseJSON (A.Number (-32602)) = pure InvalidParams
+  parseJSON (A.Number (-32603)) = pure InternalError
+  parseJSON (A.Number (-32099)) = pure ServerErrorStart
+  parseJSON (A.Number (-32000)) = pure ServerErrorEnd
+  parseJSON (A.Number (-32002)) = pure ServerNotInitialized
+  parseJSON (A.Number (-32001)) = pure UnknownErrorCode
+  parseJSON (A.Number (-32800)) = pure RequestCancelled
+  parseJSON _                   = mempty
+
+-- -------------------------------------
+
+data ResponseError =
+  ResponseError
+    { _code    :: ErrorCode
+    , _message :: Text
+    , _xdata   :: Maybe A.Value
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions{ fieldLabelModifier = customModifier } ''ResponseError
+
+-- ---------------------------------------------------------------------
+
+data ResponseMessage a =
+  ResponseMessage
+    { _jsonrpc :: Text
+    , _id      :: LspIdRsp
+    , _result  :: Maybe a
+    , _error   :: Maybe ResponseError
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''ResponseMessage
+
+type ErrorResponse = ResponseMessage ()
+
+-- ---------------------------------------------------------------------
+
+type BareResponseMessage = ResponseMessage A.Value
+
+-- ---------------------------------------------------------------------
+{-
+$ Notifications and Requests
+
+Notification and requests ids starting with '$/' are messages which are protocol
+implementation dependent and might not be implementable in all clients or
+servers. For example if the server implementation uses a single threaded
+synchronous programming language then there is little a server can do to react
+to a '$/cancelRequest'. If a server or client receives notifications or requests
+starting with '$/' it is free to ignore them if they are unknown.
+-}
+
+data NotificationMessage m a =
+  NotificationMessage
+    { _jsonrpc :: Text
+    , _method  :: m
+    , _params  :: a
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''NotificationMessage
+
+-- ---------------------------------------------------------------------
+{-
+Cancellation Support
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#cancellation-support
+
+    New: The base protocol now offers support for request cancellation. To
+    cancel a request, a notification message with the following properties is
+    sent:
+
+Notification:
+
+    method: '$/cancelRequest'
+    params: CancelParams defined as follows:
+
+interface CancelParams {
+    /**
+     * The request id to cancel.
+     */
+    id: number | string;
+}
+
+A request that got canceled still needs to return from the server and send a
+response back. It can not be left open / hanging. This is in line with the JSON
+RPC protocol that requires that every request sends a response back. In addition
+it allows for returning partial results on cancel.
+-}
+
+data CancelParams =
+  CancelParams
+    { _id :: LspId
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''CancelParams
+
+type CancelNotification = NotificationMessage ClientMethod CancelParams
+type CancelNotificationServer = NotificationMessage ServerMethod CancelParams
+
+-- ---------------------------------------------------------------------
diff --git a/src/Language/Haskell/LSP/TH/MessageFuncs.hs b/src/Language/Haskell/LSP/TH/MessageFuncs.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/MessageFuncs.hs
@@ -0,0 +1,310 @@
+{-# LANGUAGE GADTs               #-}
+{-# LANGUAGE MultiWayIf          #-}
+{-# LANGUAGE BinaryLiterals      #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE RankNTypes          #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Language.Haskell.LSP.TH.MessageFuncs (
+  -- * General
+    fmClientInitializeRequest
+  , fmClientInitializedNotification
+  , fmClientShutdownRequest
+  , fmClientExitNotification
+  , fmClientCancelNotification
+
+  -- * Window
+  , fmServerShowMessageNotification
+  , fmServerShowMessageRequest
+  , fmServerLogMessageNotification
+  , fmServerTelemetryNotification
+
+  -- * Client
+  , fmServerRegisterCapabilityRequest
+  , fmServerUnregisterCapabilityRequest
+
+  -- * Workspace
+  , fmClientDidChangeConfigurationNotification
+  , fmClientDidChangeWatchedFilesNotification
+  , fmClientWorkspaceSymbolRequest
+  , fmClientExecuteCommandRequest
+  , fmServerApplyWorkspaceEditRequest
+
+  -- * Document
+  , fmServerPublishDiagnosticsNotification
+  , fmClientDidOpenTextDocumentNotification
+  , fmClientDidChangeTextDocumentNotification
+  , fmClientWillSaveTextDocumentNotification
+  , fmClientWillSaveWaitUntilRequest
+  , fmClientDidSaveTextDocumentNotification
+  , fmClientDidCloseTextDocumentNotification
+  , fmClientCompletionRequest
+  , fmClientCompletionItemResolveRequest
+  , fmClientHoverRequest
+  , fmClientSignatureHelpRequest
+  , fmClientReferencesRequest
+  , fmClientDocumentHighlightRequest
+  , fmClientDocumentSymbolRequest
+  , fmClientDocumentFormattingRequest
+  , fmClientDocumentRangeFormattingRequest
+  , fmClientDocumentOnTypeFormattingRequest
+  , fmClientDefinitionRequest
+  , fmClientCodeActionRequest
+  , fmClientCodeLensRequest
+  , fmClientCodeLensResolveRequest
+  , fmClientDocumentLinkRequest
+  , fmClientDocumentLinkResolveRequest
+  , fmClientRenameRequest
+  ) where
+
+import qualified Data.Aeson as J
+import           Data.Text ( Text )
+import qualified Language.Haskell.LSP.TH.DataTypesJSON      as J
+
+-- ---------------------------------------------------------------------
+{-# ANN module ("HLint: ignore Eta reduce"         :: String) #-}
+{-# ANN module ("HLint: ignore Redundant do"       :: String) #-}
+{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+-- ---------------------------------------------------------------------
+
+-- ----------------------------------------------------------------------
+-- General
+-- ----------------------------------------------------------------------
+
+-- * :leftwards_arrow_with_hook: [initialize](#initialize)
+
+fmClientInitializeRequest :: J.LspId -> J.InitializeParams -> J.InitializeRequest
+fmClientInitializeRequest rid params
+  = J.RequestMessage  "2.0" rid J.Initialize params
+
+-- ----------------------------------------------------------------------
+-- * **New** :arrow_right: [initialized](#initialized)
+
+-- | From 3.0
+fmClientInitializedNotification :: J.InitializedNotification
+fmClientInitializedNotification = J.NotificationMessage "2.0" J.Initialized Nothing
+
+-- ----------------------------------------------------------------------
+-- * :leftwards_arrow_with_hook: [shutdown](#shutdown)
+
+fmClientShutdownRequest :: J.LspId -> Maybe J.Value -> J.ShutdownRequest
+fmClientShutdownRequest rid params
+  = J.RequestMessage  "2.0" rid J.Shutdown params
+
+-- ----------------------------------------------------------------------
+-- * :arrow_right: [exit](#exit)
+
+fmClientExitNotification :: J.ExitNotification
+fmClientExitNotification = J.NotificationMessage "2.0" J.Exit Nothing
+
+-- ----------------------------------------------------------------------
+-- * :arrow_right: [$/cancelRequest](#cancelRequest)
+
+fmClientCancelNotification :: J.LspId -> J.CancelNotification
+fmClientCancelNotification idToCancel
+  = J.NotificationMessage "2.0" J.CancelRequest  (J.CancelParams idToCancel)
+
+-- ----------------------------------------------------------------------
+-- Window
+-- ----------------------------------------------------------------------
+
+-- * :arrow_left: [window/showMessage](#window_showMessage)
+
+fmServerShowMessageNotification :: J.MessageType -> Text -> J.ShowMessageNotification
+fmServerShowMessageNotification mt msg
+  = J.NotificationMessage "2.0" J.WindowShowMessage (J.ShowMessageParams mt msg)
+
+-- ----------------------------------------------------------------------
+-- * :arrow_right_hook: [window/showMessageRequest](#window_showMessageRequest)
+
+fmServerShowMessageRequest :: J.LspId -> J.ShowMessageRequestParams -> J.ShowMessageRequest
+fmServerShowMessageRequest rid params
+  = J.RequestMessage  "2.0" rid J.WindowShowMessageRequest params
+
+-- ----------------------------------------------------------------------
+-- * :arrow_left: [window/logMessage](#window_logMessage)
+
+fmServerLogMessageNotification :: J.MessageType -> Text -> J.LogMessageNotification
+fmServerLogMessageNotification mt msg
+  = J.NotificationMessage "2.0" J.WindowLogMessage (J.LogMessageParams mt msg)
+
+-- ----------------------------------------------------------------------
+-- * :arrow_left: [telemetry/event](#telemetry_event)
+
+fmServerTelemetryNotification :: J.Value  -> J.TelemetryNotification
+fmServerTelemetryNotification params
+  = J.NotificationMessage "2.0" J.TelemetryEvent params
+
+-- ----------------------------------------------------------------------
+--  Client
+-- ----------------------------------------------------------------------
+
+-- * :arrow_right_hook: [client/registerCapability](#client_registerCapability)
+-- | from 3.0
+fmServerRegisterCapabilityRequest :: J.LspId -> J.RegistrationParams -> J.RegisterCapabilityRequest
+fmServerRegisterCapabilityRequest rid params
+  = J.RequestMessage  "2.0" rid J.ClientRegisterCapability params
+
+-- * :arrow_right_hook: [client/unregisterCapability](#client_unregisterCapability)
+-- | from 3.0
+fmServerUnregisterCapabilityRequest :: J.LspId -> J.UnregistrationParams -> J.UnregisterCapabilityRequest
+fmServerUnregisterCapabilityRequest rid params
+  = J.RequestMessage  "2.0" rid J.ClientUnregisterCapability params
+
+-- ----------------------------------------------------------------------
+-- Workspace
+-- ----------------------------------------------------------------------
+
+-- * :arrow_right: [workspace/didChangeConfiguration](#workspace_didChangeConfiguration)
+fmClientDidChangeConfigurationNotification :: J.DidChangeConfigurationParams -> J.DidChangeConfigurationNotification
+fmClientDidChangeConfigurationNotification params
+  = J.NotificationMessage "2.0" J.WorkspaceDidChangeConfiguration params
+
+-- * :arrow_right: [workspace/didChangeWatchedFiles](#workspace_didChangeWatchedFiles)
+fmClientDidChangeWatchedFilesNotification :: J.DidChangeWatchedFilesParams -> J.DidChangeWatchedFilesNotification
+fmClientDidChangeWatchedFilesNotification params
+  = J.NotificationMessage "2.0" J.WorkspaceDidChangeWatchedFiles params
+
+-- * :leftwards_arrow_with_hook: [workspace/symbol](#workspace_symbol)
+fmClientWorkspaceSymbolRequest :: J.LspId -> J.WorkspaceSymbolParams -> J.WorkspaceSymbolRequest
+fmClientWorkspaceSymbolRequest rid params
+  = J.RequestMessage  "2.0" rid J.WorkspaceSymbol params
+
+-- * **New** :leftwards_arrow_with_hook: [workspace/executeCommand](#workspace_executeCommand)
+-- | From 3.0
+fmClientExecuteCommandRequest :: J.LspId -> J.ExecuteCommandParams -> J.ExecuteCommandRequest
+fmClientExecuteCommandRequest rid params
+  = J.RequestMessage  "2.0" rid J.WorkspaceExecuteCommand params
+
+-- * **New** :arrow_right_hook: [workspace/applyEdit](#workspace_applyEdit)
+-- | From 3.0
+fmServerApplyWorkspaceEditRequest :: J.LspId -> J.ApplyWorkspaceEditParams -> J.ApplyWorkspaceEditRequest
+fmServerApplyWorkspaceEditRequest rid params
+  = J.RequestMessage  "2.0" rid J.WorkspaceApplyEdit params
+
+-- ----------------------------------------------------------------------
+ -- Document
+-- ----------------------------------------------------------------------
+
+-- * :arrow_left: [textDocument/publishDiagnostics](#textDocument_publishDiagnostics)
+fmServerPublishDiagnosticsNotification :: J.PublishDiagnosticsParams -> J.PublishDiagnosticsNotification
+fmServerPublishDiagnosticsNotification params
+  = J.NotificationMessage "2.0" J.TextDocumentPublishDiagnostics params
+
+-- * :arrow_right: [textDocument/didOpen](#textDocument_didOpen)
+fmClientDidOpenTextDocumentNotification :: J.DidOpenTextDocumentParams -> J.DidOpenTextDocumentNotification
+fmClientDidOpenTextDocumentNotification params
+  = J.NotificationMessage "2.0" J.TextDocumentDidOpen params
+
+-- * :arrow_right: [textDocument/didChange](#textDocument_didChange)
+fmClientDidChangeTextDocumentNotification :: J.DidChangeTextDocumentParams -> J.DidChangeTextDocumentNotification
+fmClientDidChangeTextDocumentNotification params
+  = J.NotificationMessage "2.0" J.TextDocumentDidChange params
+
+-- * :arrow_right: [textDocument/willSave](#textDocument_willSave)
+fmClientWillSaveTextDocumentNotification :: J.WillSaveTextDocumentParams -> J.WillSaveTextDocumentNotification
+fmClientWillSaveTextDocumentNotification params
+  = J.NotificationMessage "2.0" J.TextDocumentWillSave params
+
+-- * **New** :leftwards_arrow_with_hook: [textDocument/willSaveWaitUntil](#textDocument_willSaveWaitUntil)
+-- | From 3.0
+fmClientWillSaveWaitUntilRequest :: J.LspId -> J.WillSaveTextDocumentParams -> J.WillSaveWaitUntilTextDocumentRequest
+fmClientWillSaveWaitUntilRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentWillSaveWaitUntil params
+
+-- * **New** :arrow_right: [textDocument/didSave](#textDocument_didSave)
+-- | 3.0
+fmClientDidSaveTextDocumentNotification :: J.DidSaveTextDocumentParams -> J.DidSaveTextDocumentNotification
+fmClientDidSaveTextDocumentNotification params
+  = J.NotificationMessage "2.0" J.TextDocumentDidSave params
+
+-- * :arrow_right: [textDocument/didClose](#textDocument_didClose)
+fmClientDidCloseTextDocumentNotification :: J.DidCloseTextDocumentParams -> J.DidCloseTextDocumentNotification
+fmClientDidCloseTextDocumentNotification params
+  = J.NotificationMessage "2.0" J.TextDocumentDidClose params
+
+-- * :leftwards_arrow_with_hook: [textDocument/completion](#textDocument_completion)
+fmClientCompletionRequest :: J.LspId -> J.TextDocumentPositionParams -> J.CompletionRequest
+fmClientCompletionRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentCompletion params
+
+-- * :leftwards_arrow_with_hook: [completionItem/resolve](#completionItem_resolve)
+fmClientCompletionItemResolveRequest :: J.LspId -> J.CompletionItem -> J.CompletionItemResolveRequest
+fmClientCompletionItemResolveRequest rid params
+  = J.RequestMessage "2.0" rid J.CompletionItemResolve params
+
+-- * :leftwards_arrow_with_hook: [textDocument/hover](#textDocument_hover)
+fmClientHoverRequest :: J.LspId -> J.TextDocumentPositionParams -> J.HoverRequest
+fmClientHoverRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentHover params
+
+-- * :leftwards_arrow_with_hook: [textDocument/signatureHelp](#textDocument_signatureHelp)
+fmClientSignatureHelpRequest :: J.LspId -> J.TextDocumentPositionParams -> J.SignatureHelpRequest
+fmClientSignatureHelpRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentSignatureHelp params
+
+-- * :leftwards_arrow_with_hook: [textDocument/references](#textDocument_references)
+fmClientReferencesRequest :: J.LspId -> J.ReferenceParams -> J.ReferencesRequest
+fmClientReferencesRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentReferences params
+
+-- * :leftwards_arrow_with_hook: [textDocument/documentHighlight](#textDocument_documentHighlight)
+fmClientDocumentHighlightRequest :: J.LspId -> J.TextDocumentPositionParams -> J.DocumentHighlightRequest
+fmClientDocumentHighlightRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentDocumentHighlight params
+
+-- * :leftwards_arrow_with_hook: [textDocument/documentSymbol](#textDocument_documentSymbol)
+fmClientDocumentSymbolRequest :: J.LspId -> J.DocumentSymbolParams -> J.DocumentSymbolRequest
+fmClientDocumentSymbolRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentDocumentSymbol params
+
+-- * :leftwards_arrow_with_hook: [textDocument/formatting](#textDocument_formatting)
+fmClientDocumentFormattingRequest :: J.LspId -> J.DocumentFormattingParams -> J.DocumentFormattingRequest
+fmClientDocumentFormattingRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentFormatting params
+
+-- * :leftwards_arrow_with_hook: [textDocument/rangeFormatting](#textDocument_rangeFormatting)
+fmClientDocumentRangeFormattingRequest :: J.LspId -> J.DocumentRangeFormattingParams -> J.DocumentRangeFormattingRequest
+fmClientDocumentRangeFormattingRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentRangeFormatting params
+
+-- * :leftwards_arrow_with_hook: [textDocument/onTypeFormatting](#textDocument_onTypeFormatting)
+fmClientDocumentOnTypeFormattingRequest :: J.LspId -> J.DocumentOnTypeFormattingParams -> J.DocumentOnTypeFormattingRequest
+fmClientDocumentOnTypeFormattingRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentOnTypeFormatting params
+
+-- * :leftwards_arrow_with_hook: [textDocument/definition](#textDocument_definition)
+fmClientDefinitionRequest :: J.LspId -> J.TextDocumentPositionParams -> J.DefinitionRequest
+fmClientDefinitionRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentDefinition params
+
+-- * :leftwards_arrow_with_hook: [textDocument/codeAction](#textDocument_codeAction)
+fmClientCodeActionRequest :: J.LspId -> J.CodeActionParams -> J.CodeActionRequest
+fmClientCodeActionRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentCodeAction params
+
+-- * :leftwards_arrow_with_hook: [textDocument/codeLens](#textDocument_codeLens)
+fmClientCodeLensRequest :: J.LspId -> J.CodeLensParams -> J.CodeLensRequest
+fmClientCodeLensRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentCodeLens params
+
+-- * :leftwards_arrow_with_hook: [codeLens/resolve](#codeLens_resolve)
+fmClientCodeLensResolveRequest :: J.LspId -> J.CodeLens -> J.CodeLensResolveRequest
+fmClientCodeLensResolveRequest rid params
+  = J.RequestMessage "2.0" rid J.CodeLensResolve params
+
+-- * :leftwards_arrow_with_hook: [textDocument/documentLink](#textDocument_documentLink)
+fmClientDocumentLinkRequest :: J.LspId -> J.DocumentLinkParams -> J.DocumentLinkRequest
+fmClientDocumentLinkRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentDocumentLink params
+
+-- * :leftwards_arrow_with_hook: [documentLink/resolve](#documentLink_resolve)
+fmClientDocumentLinkResolveRequest :: J.LspId -> J.DocumentLink -> J.DocumentLinkResolveRequest
+fmClientDocumentLinkResolveRequest rid params
+  = J.RequestMessage "2.0" rid J.DocumentLinkResolve params
+
+-- * :leftwards_arrow_with_hook: [textDocument/rename](#textDocument_rename)
+fmClientRenameRequest :: J.LspId -> J.RenameParams -> J.RenameRequest
+fmClientRenameRequest rid params
+  = J.RequestMessage "2.0" rid J.TextDocumentRename params
+
diff --git a/src/Language/Haskell/LSP/TH/Messages.hs b/src/Language/Haskell/LSP/TH/Messages.hs
deleted file mode 100644
--- a/src/Language/Haskell/LSP/TH/Messages.hs
+++ /dev/null
@@ -1,311 +0,0 @@
-{-# LANGUAGE GADTs               #-}
-{-# LANGUAGE LambdaCase          #-}
-{-# LANGUAGE MultiWayIf          #-}
-{-# LANGUAGE BinaryLiterals      #-}
-{-# LANGUAGE OverloadedStrings   #-}
-{-# LANGUAGE RankNTypes          #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Language.Haskell.LSP.TH.Messages (
-  -- * General
-    fmClientInitializeRequest
-  , fmClientInitializedNotification
-  , fmClientShutdownRequest
-  , fmClientExitNotification
-  , fmClientCancelNotification
-
-  -- * Window
-  , fmServerShowMessageNotification
-  , fmServerShowMessageRequest
-  , fmServerLogMessageNotification
-  , fmServerTelemetryNotification
-
-  -- * Client
-  , fmServerRegisterCapabilityRequest
-  , fmServerUnregisterCapabilityRequest
-
-  -- * Workspace
-  , fmClientDidChangeConfigurationNotification
-  , fmClientDidChangeWatchedFilesNotification
-  , fmClientWorkspaceSymbolRequest
-  , fmClientExecuteCommandRequest
-  , fmServerApplyWorkspaceEditRequest
-
-  -- * Document
-  , fmServerPublishDiagnosticsNotification
-  , fmClientDidOpenTextDocumentNotification
-  , fmClientDidChangeTextDocumentNotification
-  , fmClientWillSaveTextDocumentNotification
-  , fmClientWillSaveWaitUntilRequest
-  , fmClientDidSaveTextDocumentNotification
-  , fmClientDidCloseTextDocumentNotification
-  , fmClientCompletionRequest
-  , fmClientCompletionItemResolveRequest
-  , fmClientHoverRequest
-  , fmClientSignatureHelpRequest
-  , fmClientReferencesRequest
-  , fmClientDocumentHighlightRequest
-  , fmClientDocumentSymbolRequest
-  , fmClientDocumentFormattingRequest
-  , fmClientDocumentRangeFormattingRequest
-  , fmClientDocumentOnTypeFormattingRequest
-  , fmClientDefinitionRequest
-  , fmClientCodeActionRequest
-  , fmClientCodeLensRequest
-  , fmClientCodeLensResolveRequest
-  , fmClientDocumentLinkRequest
-  , fmClientDocumentLinkResolveRequest
-  , fmClientRenameRequest
-  ) where
-
-import qualified Data.Aeson as J
-import           Data.Text ( Text )
-import qualified Language.Haskell.LSP.TH.DataTypesJSON      as J
-
--- ---------------------------------------------------------------------
-{-# ANN module ("HLint: ignore Eta reduce"         :: String) #-}
-{-# ANN module ("HLint: ignore Redundant do"       :: String) #-}
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
--- ---------------------------------------------------------------------
-
--- ----------------------------------------------------------------------
--- General
--- ----------------------------------------------------------------------
-
--- * :leftwards_arrow_with_hook: [initialize](#initialize)
-
-fmClientInitializeRequest :: J.LspId -> J.InitializeParams -> J.InitializeRequest
-fmClientInitializeRequest rid params
-  = J.RequestMessage  "2.0" rid J.Initialize params
-
--- ----------------------------------------------------------------------
--- * **New** :arrow_right: [initialized](#initialized)
-
--- | From 3.0
-fmClientInitializedNotification :: J.InitializedNotification
-fmClientInitializedNotification = J.NotificationMessage "2.0" J.Initialized Nothing
-
--- ----------------------------------------------------------------------
--- * :leftwards_arrow_with_hook: [shutdown](#shutdown)
-
-fmClientShutdownRequest :: J.LspId -> Maybe J.Value -> J.ShutdownRequest
-fmClientShutdownRequest rid params
-  = J.RequestMessage  "2.0" rid J.Shutdown params
-
--- ----------------------------------------------------------------------
--- * :arrow_right: [exit](#exit)
-
-fmClientExitNotification :: J.ExitNotification
-fmClientExitNotification = J.NotificationMessage "2.0" J.Exit Nothing
-
--- ----------------------------------------------------------------------
--- * :arrow_right: [$/cancelRequest](#cancelRequest)
-
-fmClientCancelNotification :: J.LspId -> J.CancelNotification
-fmClientCancelNotification idToCancel
-  = J.NotificationMessage "2.0" J.CancelRequest  (J.CancelParams idToCancel)
-
--- ----------------------------------------------------------------------
--- Window
--- ----------------------------------------------------------------------
-
--- * :arrow_left: [window/showMessage](#window_showMessage)
-
-fmServerShowMessageNotification :: J.MessageType -> Text -> J.ShowMessageNotification
-fmServerShowMessageNotification mt msg
-  = J.NotificationMessage "2.0" J.WindowShowMessage (J.ShowMessageParams mt msg)
-
--- ----------------------------------------------------------------------
--- * :arrow_right_hook: [window/showMessageRequest](#window_showMessageRequest)
-
-fmServerShowMessageRequest :: J.LspId -> J.ShowMessageRequestParams -> J.ShowMessageRequest
-fmServerShowMessageRequest rid params
-  = J.RequestMessage  "2.0" rid J.WindowShowMessageRequest params
-
--- ----------------------------------------------------------------------
--- * :arrow_left: [window/logMessage](#window_logMessage)
-
-fmServerLogMessageNotification :: J.MessageType -> Text -> J.LogMessageNotification
-fmServerLogMessageNotification mt msg
-  = J.NotificationMessage "2.0" J.WindowLogMessage (J.LogMessageParams mt msg)
-
--- ----------------------------------------------------------------------
--- * :arrow_left: [telemetry/event](#telemetry_event)
-
-fmServerTelemetryNotification :: J.Value  -> J.TelemetryNotification
-fmServerTelemetryNotification params
-  = J.NotificationMessage "2.0" J.TelemetryEvent params
-
--- ----------------------------------------------------------------------
---  Client
--- ----------------------------------------------------------------------
-
--- * :arrow_right_hook: [client/registerCapability](#client_registerCapability)
--- | from 3.0
-fmServerRegisterCapabilityRequest :: J.LspId -> J.RegistrationParams -> J.RegisterCapabilityRequest
-fmServerRegisterCapabilityRequest rid params
-  = J.RequestMessage  "2.0" rid J.ClientRegisterCapability params
-
--- * :arrow_right_hook: [client/unregisterCapability](#client_unregisterCapability)
--- | from 3.0
-fmServerUnregisterCapabilityRequest :: J.LspId -> J.UnregistrationParams -> J.UnregisterCapabilityRequest
-fmServerUnregisterCapabilityRequest rid params
-  = J.RequestMessage  "2.0" rid J.ClientUnregisterCapability params
-
--- ----------------------------------------------------------------------
--- Workspace
--- ----------------------------------------------------------------------
-
--- * :arrow_right: [workspace/didChangeConfiguration](#workspace_didChangeConfiguration)
-fmClientDidChangeConfigurationNotification :: J.DidChangeConfigurationParams -> J.DidChangeConfigurationNotification
-fmClientDidChangeConfigurationNotification params
-  = J.NotificationMessage "2.0" J.WorkspaceDidChangeConfiguration params
-
--- * :arrow_right: [workspace/didChangeWatchedFiles](#workspace_didChangeWatchedFiles)
-fmClientDidChangeWatchedFilesNotification :: J.DidChangeWatchedFilesParams -> J.DidChangeWatchedFilesNotification
-fmClientDidChangeWatchedFilesNotification params
-  = J.NotificationMessage "2.0" J.WorkspaceDidChangeWatchedFiles params
-
--- * :leftwards_arrow_with_hook: [workspace/symbol](#workspace_symbol)
-fmClientWorkspaceSymbolRequest :: J.LspId -> J.WorkspaceSymbolParams -> J.WorkspaceSymbolRequest
-fmClientWorkspaceSymbolRequest rid params
-  = J.RequestMessage  "2.0" rid J.WorkspaceSymbol params
-
--- * **New** :leftwards_arrow_with_hook: [workspace/executeCommand](#workspace_executeCommand)
--- | From 3.0
-fmClientExecuteCommandRequest :: J.LspId -> J.ExecuteCommandParams -> J.ExecuteCommandRequest
-fmClientExecuteCommandRequest rid params
-  = J.RequestMessage  "2.0" rid J.WorkspaceExecuteCommand params
-
--- * **New** :arrow_right_hook: [workspace/applyEdit](#workspace_applyEdit)
--- | From 3.0
-fmServerApplyWorkspaceEditRequest :: J.LspId -> J.ApplyWorkspaceEditParams -> J.ApplyWorkspaceEditRequest
-fmServerApplyWorkspaceEditRequest rid params
-  = J.RequestMessage  "2.0" rid J.WorkspaceApplyEdit params
-
--- ----------------------------------------------------------------------
- -- Document
--- ----------------------------------------------------------------------
-
--- * :arrow_left: [textDocument/publishDiagnostics](#textDocument_publishDiagnostics)
-fmServerPublishDiagnosticsNotification :: J.PublishDiagnosticsParams -> J.PublishDiagnosticsNotification
-fmServerPublishDiagnosticsNotification params
-  = J.NotificationMessage "2.0" J.TextDocumentPublishDiagnostics params
-
--- * :arrow_right: [textDocument/didOpen](#textDocument_didOpen)
-fmClientDidOpenTextDocumentNotification :: J.DidOpenTextDocumentParams -> J.DidOpenTextDocumentNotification
-fmClientDidOpenTextDocumentNotification params
-  = J.NotificationMessage "2.0" J.TextDocumentDidOpen params
-
--- * :arrow_right: [textDocument/didChange](#textDocument_didChange)
-fmClientDidChangeTextDocumentNotification :: J.DidChangeTextDocumentParams -> J.DidChangeTextDocumentNotification
-fmClientDidChangeTextDocumentNotification params
-  = J.NotificationMessage "2.0" J.TextDocumentDidChange params
-
--- * :arrow_right: [textDocument/willSave](#textDocument_willSave)
-fmClientWillSaveTextDocumentNotification :: J.WillSaveTextDocumentParams -> J.WillSaveTextDocumentNotification
-fmClientWillSaveTextDocumentNotification params
-  = J.NotificationMessage "2.0" J.TextDocumentWillSave params
-
--- * **New** :leftwards_arrow_with_hook: [textDocument/willSaveWaitUntil](#textDocument_willSaveWaitUntil)
--- | From 3.0
-fmClientWillSaveWaitUntilRequest :: J.LspId -> J.WillSaveTextDocumentParams -> J.WillSaveWaitUntilTextDocumentRequest
-fmClientWillSaveWaitUntilRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentWillSaveWaitUntil params
-
--- * **New** :arrow_right: [textDocument/didSave](#textDocument_didSave)
--- | 3.0
-fmClientDidSaveTextDocumentNotification :: J.DidSaveTextDocumentParams -> J.DidSaveTextDocumentNotification
-fmClientDidSaveTextDocumentNotification params
-  = J.NotificationMessage "2.0" J.TextDocumentDidSave params
-
--- * :arrow_right: [textDocument/didClose](#textDocument_didClose)
-fmClientDidCloseTextDocumentNotification :: J.DidCloseTextDocumentParams -> J.DidCloseTextDocumentNotification
-fmClientDidCloseTextDocumentNotification params
-  = J.NotificationMessage "2.0" J.TextDocumentDidClose params
-
--- * :leftwards_arrow_with_hook: [textDocument/completion](#textDocument_completion)
-fmClientCompletionRequest :: J.LspId -> J.TextDocumentPositionParams -> J.CompletionRequest
-fmClientCompletionRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentCompletion params
-
--- * :leftwards_arrow_with_hook: [completionItem/resolve](#completionItem_resolve)
-fmClientCompletionItemResolveRequest :: J.LspId -> J.CompletionItem -> J.CompletionItemResolveRequest
-fmClientCompletionItemResolveRequest rid params
-  = J.RequestMessage "2.0" rid J.CompletionItemResolve params
-
--- * :leftwards_arrow_with_hook: [textDocument/hover](#textDocument_hover)
-fmClientHoverRequest :: J.LspId -> J.TextDocumentPositionParams -> J.HoverRequest
-fmClientHoverRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentHover params
-
--- * :leftwards_arrow_with_hook: [textDocument/signatureHelp](#textDocument_signatureHelp)
-fmClientSignatureHelpRequest :: J.LspId -> J.TextDocumentPositionParams -> J.SignatureHelpRequest
-fmClientSignatureHelpRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentSignatureHelp params
-
--- * :leftwards_arrow_with_hook: [textDocument/references](#textDocument_references)
-fmClientReferencesRequest :: J.LspId -> J.ReferenceParams -> J.ReferencesRequest
-fmClientReferencesRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentReferences params
-
--- * :leftwards_arrow_with_hook: [textDocument/documentHighlight](#textDocument_documentHighlight)
-fmClientDocumentHighlightRequest :: J.LspId -> J.TextDocumentPositionParams -> J.DocumentHighlightRequest
-fmClientDocumentHighlightRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentDocumentHighlight params
-
--- * :leftwards_arrow_with_hook: [textDocument/documentSymbol](#textDocument_documentSymbol)
-fmClientDocumentSymbolRequest :: J.LspId -> J.DocumentSymbolParams -> J.DocumentSymbolRequest
-fmClientDocumentSymbolRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentDocumentSymbol params
-
--- * :leftwards_arrow_with_hook: [textDocument/formatting](#textDocument_formatting)
-fmClientDocumentFormattingRequest :: J.LspId -> J.DocumentFormattingParams -> J.DocumentFormattingRequest
-fmClientDocumentFormattingRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentFormatting params
-
--- * :leftwards_arrow_with_hook: [textDocument/rangeFormatting](#textDocument_rangeFormatting)
-fmClientDocumentRangeFormattingRequest :: J.LspId -> J.DocumentRangeFormattingParams -> J.DocumentRangeFormattingRequest
-fmClientDocumentRangeFormattingRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentRangeFormatting params
-
--- * :leftwards_arrow_with_hook: [textDocument/onTypeFormatting](#textDocument_onTypeFormatting)
-fmClientDocumentOnTypeFormattingRequest :: J.LspId -> J.DocumentOnTypeFormattingParams -> J.DocumentOnTypeFormattingRequest
-fmClientDocumentOnTypeFormattingRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentOnTypeFormatting params
-
--- * :leftwards_arrow_with_hook: [textDocument/definition](#textDocument_definition)
-fmClientDefinitionRequest :: J.LspId -> J.TextDocumentPositionParams -> J.DefinitionRequest
-fmClientDefinitionRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentDefinition params
-
--- * :leftwards_arrow_with_hook: [textDocument/codeAction](#textDocument_codeAction)
-fmClientCodeActionRequest :: J.LspId -> J.CodeActionParams -> J.CodeActionRequest
-fmClientCodeActionRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentCodeAction params
-
--- * :leftwards_arrow_with_hook: [textDocument/codeLens](#textDocument_codeLens)
-fmClientCodeLensRequest :: J.LspId -> J.CodeLensParams -> J.CodeLensRequest
-fmClientCodeLensRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentCodeLens params
-
--- * :leftwards_arrow_with_hook: [codeLens/resolve](#codeLens_resolve)
-fmClientCodeLensResolveRequest :: J.LspId -> J.CodeLens -> J.CodeLensResolveRequest
-fmClientCodeLensResolveRequest rid params
-  = J.RequestMessage "2.0" rid J.CodeLensResolve params
-
--- * :leftwards_arrow_with_hook: [textDocument/documentLink](#textDocument_documentLink)
-fmClientDocumentLinkRequest :: J.LspId -> J.DocumentLinkParams -> J.DocumentLinkRequest
-fmClientDocumentLinkRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentDocumentLink params
-
--- * :leftwards_arrow_with_hook: [documentLink/resolve](#documentLink_resolve)
-fmClientDocumentLinkResolveRequest :: J.LspId -> J.DocumentLink -> J.DocumentLinkResolveRequest
-fmClientDocumentLinkResolveRequest rid params
-  = J.RequestMessage "2.0" rid J.DocumentLinkResolve params
-
--- * :leftwards_arrow_with_hook: [textDocument/rename](#textDocument_rename)
-fmClientRenameRequest :: J.LspId -> J.RenameParams -> J.RenameRequest
-fmClientRenameRequest rid params
-  = J.RequestMessage "2.0" rid J.TextDocumentRename params
-
diff --git a/src/Language/Haskell/LSP/TH/Symbol.hs b/src/Language/Haskell/LSP/TH/Symbol.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/Symbol.hs
@@ -0,0 +1,187 @@
+{-# LANGUAGE TemplateHaskell            #-}
+module Language.Haskell.LSP.TH.Symbol where
+
+import           Data.Aeson
+import           Data.Aeson.TH
+import           Data.Text                                      (Text)
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.TextDocumentIdentifier
+import           Language.Haskell.LSP.TH.List
+import           Language.Haskell.LSP.TH.Location
+import           Language.Haskell.LSP.TH.Message
+
+-- ---------------------------------------------------------------------
+{-
+Document Symbols Request
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#document-symbols-request
+
+The document symbol request is sent from the client to the server to list all
+symbols found in a given text document.
+
+    Changed: In 2.0 the request uses DocumentSymbolParams instead of a single
+             uri.
+
+Request
+
+    method: 'textDocument/documentSymbol'
+    params: DocumentSymbolParams defined as follows:
+
+interface DocumentSymbolParams {
+    /**
+     * The text document.
+     */
+    textDocument: TextDocumentIdentifier;
+}
+
+Response
+
+    result: SymbolInformation[] defined as follows:
+
+/**
+ * Represents information about programming constructs like variables, classes,
+ * interfaces etc.
+ */
+interface SymbolInformation {
+    /**
+     * The name of this symbol.
+     */
+    name: string;
+
+    /**
+     * The kind of this symbol.
+     */
+    kind: number;
+
+    /**
+     * The location of this symbol.
+     */
+    location: Location;
+
+    /**
+     * The name of the symbol containing this symbol.
+     */
+    containerName?: string;
+}
+
+Where the kind is defined like this:
+
+/**
+ * A symbol kind.
+ */
+export enum SymbolKind {
+    File = 1,
+    Module = 2,
+    Namespace = 3,
+    Package = 4,
+    Class = 5,
+    Method = 6,
+    Property = 7,
+    Field = 8,
+    Constructor = 9,
+    Enum = 10,
+    Interface = 11,
+    Function = 12,
+    Variable = 13,
+    Constant = 14,
+    Text = 15,
+    Number = 16,
+    Boolean = 17,
+    Array = 18,
+}
+
+    error: code and message set in case an exception happens during the document
+           symbol request.
+
+Registration Options: TextDocumentRegistrationOptions
+-}
+
+data DocumentSymbolParams =
+  DocumentSymbolParams
+    { _textDocument :: TextDocumentIdentifier
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''DocumentSymbolParams
+
+-- -------------------------------------
+
+data SymbolKind
+    = SkFile
+    | SkModule
+    | SkNamespace
+    | SkPackage
+    | SkClass
+    | SkMethod
+    | SkProperty
+    | SkField
+    | SkConstructor
+    | SkEnum
+    | SkInterface
+    | SkFunction
+    | SkVariable
+    | SkConstant
+    | SkString
+    | SkNumber
+    | SkBoolean
+    | SkArray
+    deriving (Read,Show,Eq)
+
+instance ToJSON SymbolKind where
+  toJSON SkFile        = Number 1
+  toJSON SkModule      = Number 2
+  toJSON SkNamespace   = Number 3
+  toJSON SkPackage     = Number 4
+  toJSON SkClass       = Number 5
+  toJSON SkMethod      = Number 6
+  toJSON SkProperty    = Number 7
+  toJSON SkField       = Number 8
+  toJSON SkConstructor = Number 9
+  toJSON SkEnum        = Number 10
+  toJSON SkInterface   = Number 11
+  toJSON SkFunction    = Number 12
+  toJSON SkVariable    = Number 13
+  toJSON SkConstant    = Number 14
+  toJSON SkString      = Number 15
+  toJSON SkNumber      = Number 16
+  toJSON SkBoolean     = Number 17
+  toJSON SkArray       = Number 18
+
+instance FromJSON SymbolKind where
+  parseJSON (Number  1) = pure SkFile
+  parseJSON (Number  2) = pure SkModule
+  parseJSON (Number  3) = pure SkNamespace
+  parseJSON (Number  4) = pure SkPackage
+  parseJSON (Number  5) = pure SkClass
+  parseJSON (Number  6) = pure SkMethod
+  parseJSON (Number  7) = pure SkProperty
+  parseJSON (Number  8) = pure SkField
+  parseJSON (Number  9) = pure SkConstructor
+  parseJSON (Number 10) = pure SkEnum
+  parseJSON (Number 11) = pure SkInterface
+  parseJSON (Number 12) = pure SkFunction
+  parseJSON (Number 13) = pure SkVariable
+  parseJSON (Number 14) = pure SkConstant
+  parseJSON (Number 15) = pure SkString
+  parseJSON (Number 16) = pure SkNumber
+  parseJSON (Number 17) = pure SkBoolean
+  parseJSON (Number 18) = pure SkArray
+  parseJSON _             = mempty
+
+
+-- ---------------------------------------------------------------------
+
+data SymbolInformation =
+  SymbolInformation
+    { _name          :: Text
+    , _kind          :: SymbolKind
+    , _location      :: Location
+    , _containerName :: Maybe Text -- ^The name of the symbol containing this
+                                     -- symbol.
+    } deriving (Read,Show,Eq)
+
+deriveJSON lspOptions ''SymbolInformation
+
+-- -------------------------------------
+
+type DocumentSymbolRequest = RequestMessage ClientMethod DocumentSymbolParams (List SymbolInformation)
+type DocumentSymbolsResponse = ResponseMessage (List SymbolInformation)
diff --git a/src/Language/Haskell/LSP/TH/TextDocumentIdentifier.hs b/src/Language/Haskell/LSP/TH/TextDocumentIdentifier.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/TextDocumentIdentifier.hs
@@ -0,0 +1,30 @@
+{-# LANGUAGE DuplicateRecordFields      #-}
+{-# LANGUAGE TemplateHaskell            #-}
+module Language.Haskell.LSP.TH.TextDocumentIdentifier where
+
+import           Data.Aeson.TH
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.Uri
+
+-- ---------------------------------------------------------------------
+{-
+TextDocumentIdentifier
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textdocumentidentifier
+
+Text documents are identified using a URI. On the protocol level, URIs are
+passed as strings. The corresponding JSON structure looks like this:
+
+interface TextDocumentIdentifier {
+    /**
+     * The text document's URI.
+     */
+    uri: string;
+}
+-}
+data TextDocumentIdentifier =
+  TextDocumentIdentifier
+    { _uri :: Uri
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentIdentifier
diff --git a/src/Language/Haskell/LSP/TH/Uri.hs b/src/Language/Haskell/LSP/TH/Uri.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/Uri.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+module Language.Haskell.LSP.TH.Uri where
+
+import qualified Data.Aeson                                 as A
+import           Data.Hashable
+import           Data.Text                                  (Text)
+import qualified Data.Text                                  as T
+import           Network.URI
+import qualified System.FilePath.Posix                      as FPP
+import qualified System.FilePath.Windows                    as FPW
+import qualified System.Info
+
+newtype Uri = Uri { getUri :: Text }
+  deriving (Eq,Ord,Read,Show,A.FromJSON,A.ToJSON,Hashable,A.ToJSONKey,A.FromJSONKey)
+
+fileScheme :: String
+fileScheme = "file:"
+
+windowsOS :: String
+windowsOS = "mingw32"
+
+type SystemOS = String
+
+uriToFilePath :: Uri -> Maybe FilePath
+uriToFilePath = platformAwareUriToFilePath System.Info.os
+
+platformAwareUriToFilePath :: String -> Uri -> Maybe FilePath
+platformAwareUriToFilePath systemOS (Uri uri) = do
+  parsedUri <- parseURI $ T.unpack uri
+  if uriScheme parsedUri == fileScheme
+    then return $ (platformAdjustFromUriPath systemOS . unEscapeString . uriPath) parsedUri
+    else Nothing
+
+platformAdjustFromUriPath :: SystemOS -> String -> FilePath
+platformAdjustFromUriPath systemOS srcPath =
+  if systemOS /= windowsOS then srcPath
+    else let
+      firstSegment:rest = (FPP.splitDirectories . tail) srcPath  -- Drop leading '/' for absolute Windows paths
+      drive = if FPW.isDrive firstSegment then FPW.addTrailingPathSeparator firstSegment else firstSegment
+      in FPW.joinDrive drive $ FPW.joinPath rest
+
+filePathToUri :: FilePath -> Uri
+filePathToUri = platformAwareFilePathToUri System.Info.os
+
+platformAwareFilePathToUri :: SystemOS -> FilePath -> Uri
+platformAwareFilePathToUri systemOS fp = Uri . T.pack . show $ URI
+  { uriScheme = fileScheme
+  , uriAuthority = Just $ URIAuth "" "" ""
+  , uriPath = platformAdjustToUriPath systemOS fp
+  , uriQuery = ""
+  , uriFragment = ""
+  }
+
+platformAdjustToUriPath :: SystemOS -> FilePath -> String
+platformAdjustToUriPath systemOS srcPath =
+  if systemOS /= windowsOS then srcPath
+    else let
+      drive:rest = FPW.splitDirectories srcPath
+      leaveCharUnescaped = (/= ':')
+      removePathSeparator = filter (not . FPW.isPathSeparator)
+      escapedDrive = removePathSeparator $ escapeURIString leaveCharUnescaped drive
+      in '/' : FPP.joinPath (escapedDrive : rest)
diff --git a/src/Language/Haskell/LSP/TH/WorkspaceEdit.hs b/src/Language/Haskell/LSP/TH/WorkspaceEdit.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Haskell/LSP/TH/WorkspaceEdit.hs
@@ -0,0 +1,160 @@
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DuplicateRecordFields      #-}
+{-# LANGUAGE TemplateHaskell            #-}
+module Language.Haskell.LSP.TH.WorkspaceEdit where
+
+import           Data.Aeson.TH
+import qualified Data.HashMap.Strict                        as H
+-- For <= 8.2.2
+import           Data.Monoid                                ((<>))
+import           Data.Text                                  (Text)
+import           Language.Haskell.LSP.TH.Constants
+import           Language.Haskell.LSP.TH.List
+import           Language.Haskell.LSP.TH.Location
+import           Language.Haskell.LSP.TH.Uri
+
+-- ---------------------------------------------------------------------
+{-
+TextEdit
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#textedit
+
+A textual edit applicable to a text document.
+
+interface TextEdit {
+    /**
+     * The range of the text document to be manipulated. To insert
+     * text into a document create a range where start === end.
+     */
+    range: Range;
+
+    /**
+     * The string to be inserted. For delete operations use an
+     * empty string.
+     */
+    newText: string;
+}
+
+
+-}
+
+data TextEdit =
+  TextEdit
+    { _range   :: Range
+    , _newText :: Text
+    } deriving (Show,Read,Eq)
+
+deriveJSON lspOptions ''TextEdit
+
+-- ---------------------------------------------------------------------
+{-
+VersionedTextDocumentIdentifier
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#versionedtextdocumentidentifier
+
+    New: An identifier to denote a specific version of a text document.
+
+interface VersionedTextDocumentIdentifier extends TextDocumentIdentifier {
+    /**
+	 * The version number of this document. If a versioned text document identifier
+	 * is sent from the server to the client and the file is not open in the editor
+	 * (the server has not received an open notification before) the server can send
+	 * `null` to indicate that the version is known and the content on disk is the
+	 * truth (as speced with document content ownership)
+	 */
+	version: number | null;
+-}
+
+type TextDocumentVersion = Maybe Int
+
+data VersionedTextDocumentIdentifier =
+  VersionedTextDocumentIdentifier
+    { _uri     :: Uri
+    , _version :: TextDocumentVersion
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''VersionedTextDocumentIdentifier
+
+-- ---------------------------------------------------------------------
+{-
+New in 3.0
+----------
+
+TextDocumentEdit
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#new-textdocumentedit
+
+If multiple TextEdits are applied to a text document, all text edits describe
+changes made to the initial document version. Execution wise text edits should
+applied from the bottom to the top of the text document. Overlapping text edits
+are not supported.
+
+export interface TextDocumentEdit {
+        /**
+         * The text document to change.
+         */
+        textDocument: VersionedTextDocumentIdentifier;
+
+        /**
+         * The edits to be applied.
+         */
+        edits: TextEdit[];
+}
+
+-}
+
+data TextDocumentEdit =
+  TextDocumentEdit
+    { _textDocument :: VersionedTextDocumentIdentifier
+    , _edits        :: List TextEdit
+    } deriving (Show, Read, Eq)
+
+deriveJSON lspOptions ''TextDocumentEdit
+
+-- ---------------------------------------------------------------------
+{-
+Changed in 3.0
+--------------
+
+WorkspaceEdit
+
+https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md#workspaceedit
+
+
+Changed A workspace edit represents changes to many resources managed in the
+workspace. The edit should either provide changes or documentChanges. If
+documentChanges are present they are preferred over changes if the client can
+handle versioned document edits.
+
+export interface WorkspaceEdit {
+        /**
+         * Holds changes to existing resources.
+         */
+        changes?: { [uri: string]: TextEdit[]; };
+
+        /**
+         * An array of `TextDocumentEdit`s to express changes to specific a specific
+         * version of a text document. Whether a client supports versioned document
+         * edits is expressed via `WorkspaceClientCapabilities.versionedWorkspaceEdit`.
+         */
+        documentChanges?: TextDocumentEdit[];
+}
+-}
+
+type WorkspaceEditMap = H.HashMap Uri (List TextEdit)
+
+data WorkspaceEdit =
+  WorkspaceEdit
+    { _changes         :: Maybe WorkspaceEditMap
+    , _documentChanges :: Maybe (List TextDocumentEdit)
+    } deriving (Show, Read, Eq)
+
+instance Monoid WorkspaceEdit where
+  mempty = WorkspaceEdit Nothing Nothing
+  mappend (WorkspaceEdit a b) (WorkspaceEdit c d) = WorkspaceEdit (a <> c) (b <> d)
+
+deriveJSON lspOptions ''WorkspaceEdit
+
+#if __GLASGOW_HASKELL__ >= 804
+instance Semigroup WorkspaceEdit where
+  (<>) = mappend
+#endif
