From 6f74c8439149c4b0b2038eec29d6e50a9dea14d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Sun, 16 Jan 2022 21:24:00 +0200 Subject: [PATCH] Use Ionide.LanguageServerProtocol nuget (#875) Co-authored-by: Chet Husk --- .paket/Paket.Restore.targets | 79 +- FsAutoComplete.sln | 6 - paket.dependencies | 3 +- paket.lock | 28 +- .../FsAutoComplete.BackgroundServices.fsproj | 3 - .../Program.fs | 8 +- .../paket.references | 1 + src/FsAutoComplete.Core/BackgroundServices.fs | 2 +- src/FsAutoComplete.Core/Commands.fs | 2 +- .../FsAutoComplete.Core.fsproj | 1 - src/FsAutoComplete.Core/KeywordList.fs | 2 +- src/FsAutoComplete.Core/paket.references | 1 + src/FsAutoComplete/CodeFixes.fs | 11 +- .../CodeFixes/AddExplicitTypeToParameter.fs | 2 +- .../CodeFixes/AddMissingFunKeyword.fs | 2 +- .../CodeFixes/AddMissingInstanceMember.fs | 2 +- .../CodeFixes/AddMissingRecKeyword.fs | 2 +- .../CodeFixes/AddTypeToIndeterminateValue.fs | 2 +- .../CodeFixes/ChangeCSharpLambdaToFSharp.fs | 2 +- .../ChangeComparisonToMutableAssignment.fs | 2 +- .../CodeFixes/ChangeTypeOfNameToNameOf.fs | 1 - .../CodeFixes/ColonInFieldType.fs | 1 - .../ConvertBangEqualsToInequality.fs | 1 - .../ConvertInvalidRecordToAnonRecord.fs | 2 +- .../CodeFixes/DoubleEqualsToSingleEquals.fs | 1 - .../CodeFixes/ExternalSystemDiagnostics.fs | 2 +- .../CodeFixes/GenerateAbstractClassStub.fs | 2 +- .../CodeFixes/GenerateInterfaceStub.fs | 2 +- .../CodeFixes/GenerateRecordStub.fs | 2 +- .../CodeFixes/GenerateUnionCases.fs | 2 +- .../CodeFixes/MakeDeclarationMutable.fs | 2 +- .../CodeFixes/MakeOuterBindingRecursive.fs | 2 +- src/FsAutoComplete/CodeFixes/MissingEquals.fs | 2 +- .../CodeFixes/NegationToSubtraction.fs | 2 +- .../CodeFixes/NewWithDisposables.fs | 2 +- .../CodeFixes/ParenthesizeExpression.fs | 2 +- .../CodeFixes/RedundantQualifier.fs | 2 +- .../CodeFixes/RefCellAccessToNot.fs | 2 +- .../RemoveUnnecessaryReturnOrYield.fs | 2 +- .../CodeFixes/RemoveUnusedBinding.fs | 2 +- .../CodeFixes/ReplaceBangWithValueFunction.fs | 2 - .../CodeFixes/ResolveNamespace.fs | 2 +- .../CodeFixes/SuggestedIdentifier.fs | 1 - src/FsAutoComplete/CodeFixes/UnusedOpens.fs | 2 +- src/FsAutoComplete/CodeFixes/UnusedValue.fs | 1 - .../CodeFixes/UseSafeCastInsteadOfUnsafe.fs | 2 +- src/FsAutoComplete/CommandResponse.fs | 2 +- src/FsAutoComplete/FsAutoComplete.Lsp.fs | 19 +- src/FsAutoComplete/FsAutoComplete.fsproj | 1 - src/FsAutoComplete/LspHelpers.fs | 10 +- src/FsAutoComplete/paket.references | 1 + .../LanguageServerProtocol.fs | 3037 ----------------- .../LanguageServerProtocol.fsproj | 16 - src/LanguageServerProtocol/paket.references | 5 - test/FsAutoComplete.Tests.Lsp/CodeFixTests.fs | 14 +- .../CompletionTests.fs | 4 +- test/FsAutoComplete.Tests.Lsp/CoreTests.fs | 6 +- .../ExtensionsTests.fs | 2 +- .../FindReferencesTests.fs | 2 +- test/FsAutoComplete.Tests.Lsp/GoToTests.fs | 2 +- test/FsAutoComplete.Tests.Lsp/Helpers.fs | 25 +- .../HighlightingTests.fs | 2 +- test/FsAutoComplete.Tests.Lsp/RenameTests.fs | 2 +- test/FsAutoComplete.Tests.Lsp/ScriptTests.fs | 4 +- .../SignatureHelpTests.fs | 2 +- 65 files changed, 187 insertions(+), 3176 deletions(-) delete mode 100644 src/LanguageServerProtocol/LanguageServerProtocol.fs delete mode 100644 src/LanguageServerProtocol/LanguageServerProtocol.fsproj delete mode 100644 src/LanguageServerProtocol/paket.references diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets index 0ec281627..e230bb215 100644 --- a/.paket/Paket.Restore.targets +++ b/.paket/Paket.Restore.targets @@ -159,7 +159,7 @@ This value should match the version in the props generated by paket If they differ, this means we need to do a restore in order to ensure correct dependencies --> - + true @@ -236,13 +236,16 @@ $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) - $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[6]) + $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[7]) %(PaketReferencesFileLinesInfo.PackageVersion) All - runtime - runtime + runtime + $(ExcludeAssets);contentFiles + $(ExcludeAssets);build;buildMultitargeting;buildTransitive true true @@ -289,14 +292,16 @@ $(MSBuildProjectDirectory)/$(MSBuildProjectFile) true + false + true false - true + true false true false - true + true false - true + true $(PaketIntermediateOutputPath)\$(Configuration) $(PaketIntermediateOutputPath) @@ -314,6 +319,55 @@ + + + PackageLicenseExpressionVersion="$(PackageLicenseExpressionVersion)" + NoDefaultExcludes="$(NoDefaultExcludes)" /> = 4.3.2) System.Configuration.ConfigurationManager (>= 4.4) - CliWrap (3.3.3) - Microsoft.Bcl.AsyncInterfaces (>= 5.0) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) + CliWrap (3.4) + Microsoft.Bcl.AsyncInterfaces (>= 6.0) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) System.Buffers (>= 4.5.1) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netstandard2.1)) (== netstandard2.0) Dapper (2.0.123) @@ -29,9 +29,9 @@ NUGET StreamJsonRpc (>= 2.8.28) FParsec (1.1.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) FSharp.Core (>= 4.3.4) - FSharp.Analyzers.SDK (0.10.1) - FSharp.Compiler.Service (>= 40.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) - FSharp.Core (>= 5.0.2) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Analyzers.SDK (0.11) + FSharp.Compiler.Service (>= 41.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) + FSharp.Core (>= 6.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) McMaster.NETCore.Plugins (>= 1.4) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) FSharp.Compiler.Service (41.0.1) FSharp.Core (6.0.1) @@ -87,13 +87,17 @@ NUGET FSharpx.Async (1.14.1) FSharp.Control.AsyncSeq (>= 2.0.21) FSharp.Core (>= 4.6.2) - FsToolkit.ErrorHandling (2.11.1) + FsToolkit.ErrorHandling (2.13) FSharp.Core (>= 4.7.2) GitHubActionsTestLogger (1.2) Microsoft.TestPlatform.ObjectModel (>= 16.8.3) ICSharpCode.Decompiler (7.1.0.6543) System.Collections.Immutable (>= 5.0) System.Reflection.Metadata (>= 5.0) + Ionide.LanguageServerProtocol (0.3.1) + FSharp.Core (>= 6.0.1) + Microsoft.NETFramework.ReferenceAssemblies (>= 1.0.2) + Newtonsoft.Json (>= 13.0.1) Ionide.ProjInfo (0.55.4) FSharp.Core (>= 6.0.1) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) Ionide.ProjInfo.Sln (>= 0.55.4) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net5.0)) @@ -183,9 +187,9 @@ NUGET Microsoft.NET.Test.Sdk (17.0) Microsoft.CodeCoverage (>= 17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= net45)) (&& (== netstandard2.0) (>= netcoreapp1.0)) Microsoft.TestPlatform.TestHost (>= 17.0) - restriction: || (== net5.0) (&& (== netstandard2.0) (>= netcoreapp1.0)) - Microsoft.NETCore.Platforms (6.0) + Microsoft.NETCore.Platforms (6.0.1) Microsoft.NETCore.Targets (5.0) - Microsoft.NETFramework.ReferenceAssemblies (1.0) + Microsoft.NETFramework.ReferenceAssemblies (1.0.2) Microsoft.SourceLink.AzureRepos.Git (1.1.1) - copy_local: true Microsoft.Build.Tasks.Git (>= 1.1.1) Microsoft.SourceLink.Common (>= 1.1.1) @@ -418,7 +422,7 @@ NUGET System.Threading.Tasks (>= 4.3) System.IO.FileSystem.Primitives (4.3) System.Runtime (>= 4.3) - System.IO.Pipelines (6.0) + System.IO.Pipelines (6.0.1) System.Buffers (>= 4.5.1) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netcoreapp3.1)) (== netstandard2.0) System.Memory (>= 4.5.4) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netcoreapp3.1)) (== netstandard2.0) System.Threading.Tasks.Extensions (>= 4.5.4) - restriction: || (&& (== net5.0) (>= net461)) (&& (== net5.0) (< netcoreapp3.1)) (== netstandard2.0) @@ -731,7 +735,7 @@ NUGET System.Text.Encoding (>= 4.3) System.Text.Encodings.Web (6.0) - copy_local: false, restriction: || (== net5.0) (&& (== netstandard2.0) (>= net472)) (&& (== netstandard2.0) (>= net5.0)) System.Runtime.CompilerServices.Unsafe (>= 6.0) - System.Text.Json (6.0) - copy_local: false, restriction: || (== net5.0) (&& (== netstandard2.0) (>= net472)) (&& (== netstandard2.0) (>= net5.0)) + System.Text.Json (6.0.1) - copy_local: false, restriction: || (== net5.0) (&& (== netstandard2.0) (>= net472)) (&& (== netstandard2.0) (>= net5.0)) System.Runtime.CompilerServices.Unsafe (>= 6.0) System.Text.Encodings.Web (>= 6.0) System.Threading (4.3) @@ -923,7 +927,7 @@ NUGET Microsoft.NET.StringTools (1.0) System.Memory (>= 4.5.4) System.Runtime.CompilerServices.Unsafe (>= 5.0) - Microsoft.NETCore.Platforms (6.0) + Microsoft.NETCore.Platforms (6.0.1) Microsoft.NETCore.Targets (5.0) Microsoft.Win32.Registry (5.0) System.Buffers (>= 4.5.1) diff --git a/src/FsAutoComplete.BackgroundServices/FsAutoComplete.BackgroundServices.fsproj b/src/FsAutoComplete.BackgroundServices/FsAutoComplete.BackgroundServices.fsproj index b5d547d7c..d7b01c826 100644 --- a/src/FsAutoComplete.BackgroundServices/FsAutoComplete.BackgroundServices.fsproj +++ b/src/FsAutoComplete.BackgroundServices/FsAutoComplete.BackgroundServices.fsproj @@ -8,9 +8,6 @@ false - - LanguageServerProtocol.fsproj - diff --git a/src/FsAutoComplete.BackgroundServices/Program.fs b/src/FsAutoComplete.BackgroundServices/Program.fs index 23e1a77d1..316e985f1 100644 --- a/src/FsAutoComplete.BackgroundServices/Program.fs +++ b/src/FsAutoComplete.BackgroundServices/Program.fs @@ -3,9 +3,9 @@ open System open System.IO open System.Text -open LanguageServerProtocol.Server -open LanguageServerProtocol.Types -open LanguageServerProtocol +open Ionide.LanguageServerProtocol.Server +open Ionide.LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol open FSharp.Compiler open FSharp.Compiler.Diagnostics open FSharp.Compiler.Text @@ -497,7 +497,7 @@ module Program = |> Map.add "background/save" (requestHandling (fun s p -> s.FileSaved(p) )) |> Map.add "background/init" (requestHandling (fun s p -> s.InitWorkspace() )) - LanguageServerProtocol.Server.start requestsHandlings input output FsacClient (fun lspClient -> new BackgroundServiceServer(state, lspClient)) + Ionide.LanguageServerProtocol.Server.start requestsHandlings input output FsacClient (fun lspClient -> new BackgroundServiceServer(state, lspClient)) open FSharp.Compiler.IO diff --git a/src/FsAutoComplete.BackgroundServices/paket.references b/src/FsAutoComplete.BackgroundServices/paket.references index 7c3171b2e..91b2eab56 100644 --- a/src/FsAutoComplete.BackgroundServices/paket.references +++ b/src/FsAutoComplete.BackgroundServices/paket.references @@ -9,3 +9,4 @@ Ionide.ProjInfo.FCS Ionide.ProjInfo.ProjectSystem FSharp.UMX Microsoft.NETFramework.ReferenceAssemblies +Ionide.LanguageServerProtocol diff --git a/src/FsAutoComplete.Core/BackgroundServices.fs b/src/FsAutoComplete.Core/BackgroundServices.fs index 614720389..2949e96bc 100644 --- a/src/FsAutoComplete.Core/BackgroundServices.fs +++ b/src/FsAutoComplete.Core/BackgroundServices.fs @@ -1,7 +1,7 @@ module BackgroundServices open FsAutoComplete -open LanguageServerProtocol +open Ionide.LanguageServerProtocol open System.IO open FSharp.Compiler.CodeAnalysis open Ionide.ProjInfo.ProjectSystem diff --git a/src/FsAutoComplete.Core/Commands.fs b/src/FsAutoComplete.Core/Commands.fs index 38405e6da..7d17cc525 100644 --- a/src/FsAutoComplete.Core/Commands.fs +++ b/src/FsAutoComplete.Core/Commands.fs @@ -72,7 +72,7 @@ type NotificationEvent = | UnusedDeclarations of file: string * decls: (range * bool) [] | SimplifyNames of file: string * names: SimplifyNames.SimplifiableRange [] | Canceled of errorMessage: string - | Diagnostics of LanguageServerProtocol.Types.PublishDiagnosticsParams + | Diagnostics of Ionide.LanguageServerProtocol.Types.PublishDiagnosticsParams | FileParsed of string type Commands diff --git a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj index 469f825e6..6afca584c 100644 --- a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj +++ b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj @@ -4,7 +4,6 @@ false - diff --git a/src/FsAutoComplete.Core/KeywordList.fs b/src/FsAutoComplete.Core/KeywordList.fs index 817ecd3d8..1fd99fdc5 100644 --- a/src/FsAutoComplete.Core/KeywordList.fs +++ b/src/FsAutoComplete.Core/KeywordList.fs @@ -1,6 +1,6 @@ namespace FsAutoComplete -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FSharp.Compiler.Text open FSharp.Compiler.Tokenization open FSharp.Compiler.EditorServices diff --git a/src/FsAutoComplete.Core/paket.references b/src/FsAutoComplete.Core/paket.references index 09835dfa4..aea39be5f 100644 --- a/src/FsAutoComplete.Core/paket.references +++ b/src/FsAutoComplete.Core/paket.references @@ -16,3 +16,4 @@ Fantomas.Client System.Reflection.Metadata Microsoft.Build.Utilities.Core +Ionide.LanguageServerProtocol diff --git a/src/FsAutoComplete/CodeFixes.fs b/src/FsAutoComplete/CodeFixes.fs index 813ca8f18..90fa207de 100644 --- a/src/FsAutoComplete/CodeFixes.fs +++ b/src/FsAutoComplete/CodeFixes.fs @@ -4,7 +4,7 @@ namespace FsAutoComplete.CodeFix open FsAutoComplete open FsAutoComplete.LspHelpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.Logging open FSharp.UMX open FsToolkit.ErrorHandling @@ -14,7 +14,7 @@ module FcsRange = FSharp.Compiler.Text.Range type FcsRange = FSharp.Compiler.Text.Range type FcsPos = FSharp.Compiler.Text.Position -module LspTypes = LanguageServerProtocol.Types +module LspTypes = Ionide.LanguageServerProtocol.Types module Types = type IsEnabled = unit -> bool @@ -67,8 +67,11 @@ module Types = | FixKind.Refactor -> "refactor" | FixKind.Rewrite -> "refactor.rewrite") Diagnostics = diagnostic |> Option.map Array.singleton - Edit = workspaceEdit - Command = None } + IsPreferred = None + Disabled = None + Edit = Some workspaceEdit + Command = None + Data = None } /// helpers for iterating along text lines module Navigation = diff --git a/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs b/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs index 6a74e7757..c02755a0c 100644 --- a/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs +++ b/src/FsAutoComplete/CodeFixes/AddExplicitTypeToParameter.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.AddExplicitTypeToParameter open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.Compiler.CodeAnalysis diff --git a/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs b/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs index 5450969b8..af3d3296c 100644 --- a/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs +++ b/src/FsAutoComplete/CodeFixes/AddMissingFunKeyword.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.AddMissingFunKeyword open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/AddMissingInstanceMember.fs b/src/FsAutoComplete/CodeFixes/AddMissingInstanceMember.fs index 59aa1d517..460e5eaff 100644 --- a/src/FsAutoComplete/CodeFixes/AddMissingInstanceMember.fs +++ b/src/FsAutoComplete/CodeFixes/AddMissingInstanceMember.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.AddMissingInstanceMember open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types let fix = Run.ifDiagnosticByCode (Set.ofList [ "673" ]) (fun diagnostic codeActionParams -> asyncResult { diff --git a/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs b/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs index 78a6de66f..b41ff3f0d 100644 --- a/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs +++ b/src/FsAutoComplete/CodeFixes/AddMissingRecKeyword.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.AddMissingRecKeyword open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.UMX diff --git a/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs b/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs index 6c66abf70..c27e19875 100644 --- a/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs +++ b/src/FsAutoComplete/CodeFixes/AddTypeToIndeterminateValue.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.AddTypeToIndeterminateValue open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.Compiler.EditorServices diff --git a/src/FsAutoComplete/CodeFixes/ChangeCSharpLambdaToFSharp.fs b/src/FsAutoComplete/CodeFixes/ChangeCSharpLambdaToFSharp.fs index 2cecab018..e18247812 100644 --- a/src/FsAutoComplete/CodeFixes/ChangeCSharpLambdaToFSharp.fs +++ b/src/FsAutoComplete/CodeFixes/ChangeCSharpLambdaToFSharp.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.ChangeCSharpLambdaToFSharp open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs b/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs index 8b1c4a484..faa14deed 100644 --- a/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs +++ b/src/FsAutoComplete/CodeFixes/ChangeComparisonToMutableAssignment.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.ChangeComparisonToMutableAssignment open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs b/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs index 84451368b..0ab49495f 100644 --- a/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs +++ b/src/FsAutoComplete/CodeFixes/ChangeTypeOfNameToNameOf.fs @@ -3,7 +3,6 @@ module FsAutoComplete.CodeFix.ChangeTypeOfNameToNameOf open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.Compiler.CodeAnalysis diff --git a/src/FsAutoComplete/CodeFixes/ColonInFieldType.fs b/src/FsAutoComplete/CodeFixes/ColonInFieldType.fs index 67cfbf824..ab051801e 100644 --- a/src/FsAutoComplete/CodeFixes/ColonInFieldType.fs +++ b/src/FsAutoComplete/CodeFixes/ColonInFieldType.fs @@ -2,7 +2,6 @@ module FsAutoComplete.CodeFix.ColonInFieldType open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types open FsAutoComplete /// a codefix that fixes a malformed record type annotation to use colon instead of equals diff --git a/src/FsAutoComplete/CodeFixes/ConvertBangEqualsToInequality.fs b/src/FsAutoComplete/CodeFixes/ConvertBangEqualsToInequality.fs index 9dd244659..957591a56 100644 --- a/src/FsAutoComplete/CodeFixes/ConvertBangEqualsToInequality.fs +++ b/src/FsAutoComplete/CodeFixes/ConvertBangEqualsToInequality.fs @@ -3,7 +3,6 @@ module FsAutoComplete.CodeFix.ConvertBangEqualsToInequality open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/ConvertInvalidRecordToAnonRecord.fs b/src/FsAutoComplete/CodeFixes/ConvertInvalidRecordToAnonRecord.fs index 9e3136b72..f7e2f81f4 100644 --- a/src/FsAutoComplete/CodeFixes/ConvertInvalidRecordToAnonRecord.fs +++ b/src/FsAutoComplete/CodeFixes/ConvertInvalidRecordToAnonRecord.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.ConvertInvalidRecordToAnonRecord open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/DoubleEqualsToSingleEquals.fs b/src/FsAutoComplete/CodeFixes/DoubleEqualsToSingleEquals.fs index dec14ed21..82d3fcd2a 100644 --- a/src/FsAutoComplete/CodeFixes/DoubleEqualsToSingleEquals.fs +++ b/src/FsAutoComplete/CodeFixes/DoubleEqualsToSingleEquals.fs @@ -2,7 +2,6 @@ module FsAutoComplete.CodeFix.DoubleEqualsToSingleEquals open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/ExternalSystemDiagnostics.fs b/src/FsAutoComplete/CodeFixes/ExternalSystemDiagnostics.fs index 04af79444..f939d290d 100644 --- a/src/FsAutoComplete/CodeFixes/ExternalSystemDiagnostics.fs +++ b/src/FsAutoComplete/CodeFixes/ExternalSystemDiagnostics.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.ExternalSystemDiagnostics open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete let private mapExternalDiagnostic diagnosticType = diff --git a/src/FsAutoComplete/CodeFixes/GenerateAbstractClassStub.fs b/src/FsAutoComplete/CodeFixes/GenerateAbstractClassStub.fs index b28750737..d8ae983c0 100644 --- a/src/FsAutoComplete/CodeFixes/GenerateAbstractClassStub.fs +++ b/src/FsAutoComplete/CodeFixes/GenerateAbstractClassStub.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.GenerateAbstractClassStub open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.UMX diff --git a/src/FsAutoComplete/CodeFixes/GenerateInterfaceStub.fs b/src/FsAutoComplete/CodeFixes/GenerateInterfaceStub.fs index 59be4a26c..ec13c5b5a 100644 --- a/src/FsAutoComplete/CodeFixes/GenerateInterfaceStub.fs +++ b/src/FsAutoComplete/CodeFixes/GenerateInterfaceStub.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.GenerateInterfaceStub open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open System.IO diff --git a/src/FsAutoComplete/CodeFixes/GenerateRecordStub.fs b/src/FsAutoComplete/CodeFixes/GenerateRecordStub.fs index d2130f180..e79b7c4a2 100644 --- a/src/FsAutoComplete/CodeFixes/GenerateRecordStub.fs +++ b/src/FsAutoComplete/CodeFixes/GenerateRecordStub.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.GenerateRecordStub open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/GenerateUnionCases.fs b/src/FsAutoComplete/CodeFixes/GenerateUnionCases.fs index 32b36ff7f..a14570683 100644 --- a/src/FsAutoComplete/CodeFixes/GenerateUnionCases.fs +++ b/src/FsAutoComplete/CodeFixes/GenerateUnionCases.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.GenerateUnionCases open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/MakeDeclarationMutable.fs b/src/FsAutoComplete/CodeFixes/MakeDeclarationMutable.fs index 39d2b5276..3c1b5d482 100644 --- a/src/FsAutoComplete/CodeFixes/MakeDeclarationMutable.fs +++ b/src/FsAutoComplete/CodeFixes/MakeDeclarationMutable.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.MakeDeclarationMutable open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.UMX diff --git a/src/FsAutoComplete/CodeFixes/MakeOuterBindingRecursive.fs b/src/FsAutoComplete/CodeFixes/MakeOuterBindingRecursive.fs index faf87b36f..52f5fe745 100644 --- a/src/FsAutoComplete/CodeFixes/MakeOuterBindingRecursive.fs +++ b/src/FsAutoComplete/CodeFixes/MakeOuterBindingRecursive.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.MakeOuterBindingRecursive open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/MissingEquals.fs b/src/FsAutoComplete/CodeFixes/MissingEquals.fs index 2d95184ee..7517f6b50 100644 --- a/src/FsAutoComplete/CodeFixes/MissingEquals.fs +++ b/src/FsAutoComplete/CodeFixes/MissingEquals.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.MissingEquals open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/NegationToSubtraction.fs b/src/FsAutoComplete/CodeFixes/NegationToSubtraction.fs index 3c5818295..76d3be472 100644 --- a/src/FsAutoComplete/CodeFixes/NegationToSubtraction.fs +++ b/src/FsAutoComplete/CodeFixes/NegationToSubtraction.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.NegationToSubtraction open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/NewWithDisposables.fs b/src/FsAutoComplete/CodeFixes/NewWithDisposables.fs index cc5970f92..e9016a21c 100644 --- a/src/FsAutoComplete/CodeFixes/NewWithDisposables.fs +++ b/src/FsAutoComplete/CodeFixes/NewWithDisposables.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.NewWithDisposables open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/ParenthesizeExpression.fs b/src/FsAutoComplete/CodeFixes/ParenthesizeExpression.fs index 037d2cd05..ecc095a04 100644 --- a/src/FsAutoComplete/CodeFixes/ParenthesizeExpression.fs +++ b/src/FsAutoComplete/CodeFixes/ParenthesizeExpression.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.ParenthesizeExpression open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/RedundantQualifier.fs b/src/FsAutoComplete/CodeFixes/RedundantQualifier.fs index 9f2348a11..7d68a84dc 100644 --- a/src/FsAutoComplete/CodeFixes/RedundantQualifier.fs +++ b/src/FsAutoComplete/CodeFixes/RedundantQualifier.fs @@ -3,7 +3,7 @@ module FsAutoComplete.CodeFix.RedundantQualifier open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types /// a codefix that removes unnecessary qualifiers from an identifier let fix = diff --git a/src/FsAutoComplete/CodeFixes/RefCellAccessToNot.fs b/src/FsAutoComplete/CodeFixes/RefCellAccessToNot.fs index ca3f885c3..5fb38bb30 100644 --- a/src/FsAutoComplete/CodeFixes/RefCellAccessToNot.fs +++ b/src/FsAutoComplete/CodeFixes/RefCellAccessToNot.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.RefCellAccesToNot open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/RemoveUnnecessaryReturnOrYield.fs b/src/FsAutoComplete/CodeFixes/RemoveUnnecessaryReturnOrYield.fs index 236b8998f..3237cafde 100644 --- a/src/FsAutoComplete/CodeFixes/RemoveUnnecessaryReturnOrYield.fs +++ b/src/FsAutoComplete/CodeFixes/RemoveUnnecessaryReturnOrYield.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.RemoveUnnecessaryReturnOrYield open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs b/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs index 30ab3e277..a432935ca 100644 --- a/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs +++ b/src/FsAutoComplete/CodeFixes/RemoveUnusedBinding.fs @@ -4,7 +4,7 @@ module FsAutoComplete.CodeFix.RemoveUnusedBinding open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Navigation open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.Compiler.CodeAnalysis diff --git a/src/FsAutoComplete/CodeFixes/ReplaceBangWithValueFunction.fs b/src/FsAutoComplete/CodeFixes/ReplaceBangWithValueFunction.fs index 13f7f6929..a77d648e6 100644 --- a/src/FsAutoComplete/CodeFixes/ReplaceBangWithValueFunction.fs +++ b/src/FsAutoComplete/CodeFixes/ReplaceBangWithValueFunction.fs @@ -3,10 +3,8 @@ module FsAutoComplete.CodeFix.ReplaceBangWithValueFunction open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers -open FsAutoComplete.FCSPatches let fix (getParseResultsForFile: GetParseResultsForFile) (getLineText: GetLineText): CodeFix = fun codeActionParams -> diff --git a/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs b/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs index ed43807e9..3d2012add 100644 --- a/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs +++ b/src/FsAutoComplete/CodeFixes/ResolveNamespace.fs @@ -1,6 +1,6 @@ module FsAutoComplete.CodeFix.ResolveNamespace -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types open FsToolkit.ErrorHandling diff --git a/src/FsAutoComplete/CodeFixes/SuggestedIdentifier.fs b/src/FsAutoComplete/CodeFixes/SuggestedIdentifier.fs index f7c448d65..896e191a4 100644 --- a/src/FsAutoComplete/CodeFixes/SuggestedIdentifier.fs +++ b/src/FsAutoComplete/CodeFixes/SuggestedIdentifier.fs @@ -1,6 +1,5 @@ module FsAutoComplete.CodeFix.SuggestedIdentifier -open LanguageServerProtocol.Types open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types open FsToolkit.ErrorHandling diff --git a/src/FsAutoComplete/CodeFixes/UnusedOpens.fs b/src/FsAutoComplete/CodeFixes/UnusedOpens.fs index 09856084f..c0f42db19 100644 --- a/src/FsAutoComplete/CodeFixes/UnusedOpens.fs +++ b/src/FsAutoComplete/CodeFixes/UnusedOpens.fs @@ -1,6 +1,6 @@ module FsAutoComplete.CodeFix.UnusedOpens -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types open FsToolkit.ErrorHandling diff --git a/src/FsAutoComplete/CodeFixes/UnusedValue.fs b/src/FsAutoComplete/CodeFixes/UnusedValue.fs index aaa52f861..976465b91 100644 --- a/src/FsAutoComplete/CodeFixes/UnusedValue.fs +++ b/src/FsAutoComplete/CodeFixes/UnusedValue.fs @@ -3,7 +3,6 @@ module FsAutoComplete.CodeFix.UnusedValue open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CodeFixes/UseSafeCastInsteadOfUnsafe.fs b/src/FsAutoComplete/CodeFixes/UseSafeCastInsteadOfUnsafe.fs index e913b5328..db61a88ee 100644 --- a/src/FsAutoComplete/CodeFixes/UseSafeCastInsteadOfUnsafe.fs +++ b/src/FsAutoComplete/CodeFixes/UseSafeCastInsteadOfUnsafe.fs @@ -2,7 +2,7 @@ module FsAutoComplete.CodeFix.UseSafeCastInsteadOfUnsafe open FsToolkit.ErrorHandling open FsAutoComplete.CodeFix.Types -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers diff --git a/src/FsAutoComplete/CommandResponse.fs b/src/FsAutoComplete/CommandResponse.fs index 41b28002d..acd457403 100644 --- a/src/FsAutoComplete/CommandResponse.fs +++ b/src/FsAutoComplete/CommandResponse.fs @@ -333,7 +333,7 @@ module CommandResponse = ParameterStr : string } - type HighlightingRange = { Range: LanguageServerProtocol.Types.Range ; TokenType: string } + type HighlightingRange = { Range: Ionide.LanguageServerProtocol.Types.Range ; TokenType: string } type HighlightingResponse = { Highlights: HighlightingRange [] diff --git a/src/FsAutoComplete/FsAutoComplete.Lsp.fs b/src/FsAutoComplete/FsAutoComplete.Lsp.fs index 31fac34a5..6d3eaf300 100644 --- a/src/FsAutoComplete/FsAutoComplete.Lsp.fs +++ b/src/FsAutoComplete/FsAutoComplete.Lsp.fs @@ -9,10 +9,10 @@ open FsAutoComplete.Utils open FsAutoComplete.CodeFix open FsAutoComplete.CodeFix.Types open FsAutoComplete.Logging -open LanguageServerProtocol -open LanguageServerProtocol.LspResult -open LanguageServerProtocol.Server -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol +open Ionide.LanguageServerProtocol.LspResult +open Ionide.LanguageServerProtocol.Server +open Ionide.LanguageServerProtocol.Types open LspHelpers open Newtonsoft.Json.Linq open Ionide.ProjInfo.ProjectSystem @@ -747,10 +747,10 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS commands.TryGetFileCheckerOptionsWithLines >> Result.map snd - let getLineText (lines: ISourceText) (range: LanguageServerProtocol.Types.Range) = + let getLineText (lines: ISourceText) (range: Ionide.LanguageServerProtocol.Types.Range) = lines.GetText(protocolRangeToRange "unknown.fsx" range) - let getRangeText fileName (range: LanguageServerProtocol.Types.Range) = + let getRangeText fileName (range: Ionide.LanguageServerProtocol.Types.Range) = getFileLines fileName |> Result.bind (fun lines -> lines.GetText(protocolRangeToRange (UMX.untag fileName) range)) @@ -920,7 +920,10 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS AllCommitCharacters = None //TODO: what chars shoudl commit completions? } CodeLensProvider = Some { CodeLensOptions.ResolveProvider = Some true } - CodeActionProvider = Some true + CodeActionProvider = + Some + { CodeActionKinds = None + ResolveProvider = None } TextDocumentSync = Some { TextDocumentSyncOptions.Default with @@ -2705,7 +2708,7 @@ let startCore backgroundServiceEnabled toolsPath workspaceLoaderFactory = FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem <- FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) - LanguageServerProtocol.Server.start requestsHandlings input output FSharpLspClient (fun lspClient -> + Ionide.LanguageServerProtocol.Server.start requestsHandlings input output FSharpLspClient (fun lspClient -> new FSharpLspServer(backgroundServiceEnabled, state, lspClient)) let start backgroundServiceEnabled toolsPath workspaceLoaderFactory = diff --git a/src/FsAutoComplete/FsAutoComplete.fsproj b/src/FsAutoComplete/FsAutoComplete.fsproj index 277b4e143..39c239dc5 100644 --- a/src/FsAutoComplete/FsAutoComplete.fsproj +++ b/src/FsAutoComplete/FsAutoComplete.fsproj @@ -33,7 +33,6 @@ - diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs index 2bed7a3ae..9df8e5bdc 100644 --- a/src/FsAutoComplete/LspHelpers.fs +++ b/src/FsAutoComplete/LspHelpers.fs @@ -2,7 +2,7 @@ module FsAutoComplete.LspHelpers open System open System.IO -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.Utils open FSharp.Reflection open System.Collections.Generic @@ -17,7 +17,7 @@ type FcsPos = FSharp.Compiler.Text.Position [] module Conversions = - module Lsp = LanguageServerProtocol.Types + module Lsp = Ionide.LanguageServerProtocol.Types /// convert an LSP position to a compiler position let protocolPosToPos (pos: Lsp.Position): FcsPos = @@ -209,7 +209,7 @@ module internal GlyphConversions = fun glyph -> cache.[glyph] - type CompletionItemKind = LanguageServerProtocol.Types.CompletionItemKind + type CompletionItemKind = Ionide.LanguageServerProtocol.Types.CompletionItemKind /// Compute the best possible CompletionItemKind for each FSharpGlyph according /// to the client capabilities @@ -795,9 +795,9 @@ let createTokenLegend<'types, 'modifiers when 'types : enum and /// /// /// -let encodeSemanticHighlightRanges (rangesAndHighlights: (struct(LanguageServerProtocol.Types.Range * ClassificationUtils.SemanticTokenTypes * ClassificationUtils.SemanticTokenModifier list)) array) = +let encodeSemanticHighlightRanges (rangesAndHighlights: (struct(Ionide.LanguageServerProtocol.Types.Range * ClassificationUtils.SemanticTokenTypes * ClassificationUtils.SemanticTokenModifier list)) array) = let fileStart = { Start = { Line = 0; Character = 0}; End = { Line = 0; Character = 0 } } - let computeLine (prev: LanguageServerProtocol.Types.Range) ((range, ty, mods): struct(LanguageServerProtocol.Types.Range * ClassificationUtils.SemanticTokenTypes * ClassificationUtils.SemanticTokenModifier list)): uint32 [] = + let computeLine (prev: Ionide.LanguageServerProtocol.Types.Range) ((range, ty, mods): struct(Ionide.LanguageServerProtocol.Types.Range * ClassificationUtils.SemanticTokenTypes * ClassificationUtils.SemanticTokenModifier list)): uint32 [] = let lineDelta = if prev.Start.Line = range.Start.Line then 0u else uint32 (range.Start.Line - prev.Start.Line) diff --git a/src/FsAutoComplete/paket.references b/src/FsAutoComplete/paket.references index fc078834f..5404259c8 100644 --- a/src/FsAutoComplete/paket.references +++ b/src/FsAutoComplete/paket.references @@ -21,3 +21,4 @@ Serilog.Sinks.Async Serilog.Sinks.Console Serilog.Sinks.File System.Configuration.ConfigurationManager +Ionide.LanguageServerProtocol diff --git a/src/LanguageServerProtocol/LanguageServerProtocol.fs b/src/LanguageServerProtocol/LanguageServerProtocol.fs deleted file mode 100644 index 67ea04a93..000000000 --- a/src/LanguageServerProtocol/LanguageServerProtocol.fs +++ /dev/null @@ -1,3037 +0,0 @@ -module LanguageServerProtocol - -open System.Diagnostics - - -[] -module LspJsonConverters = - open Microsoft.FSharp.Reflection - open Newtonsoft.Json - open System - open System.Collections.Concurrent - - let inline memorise (f: 'a -> 'b) : ('a -> 'b) = - let d = ConcurrentDictionary<'a, 'b>() - fun key -> - d.GetOrAdd(key, f) - - type ErasedUnionAttribute() = - inherit Attribute() - - [] - type U2<'a, 'b> = First of 'a | Second of 'b - - type ErasedUnionConverter() = - inherit JsonConverter() - - let canConvert = - memorise (fun t -> - if not (FSharpType.IsUnion t) then - false - else - t.BaseType.GetCustomAttributes(typedefof, false).Length > 0) - - override __.CanConvert(t) = canConvert t - - override __.WriteJson(writer, value, serializer) = - let _, fields = FSharpValue.GetUnionFields(value, value.GetType()) - let unionField = fields.[0] - serializer.Serialize(writer, unionField) - - override __.ReadJson(_reader, _t, _existingValue, _serializer) = - failwith "Not implemented" - - /// converter that can convert enum-style DUs - type SingleCaseUnionConverter() = - inherit JsonConverter() - - - let canConvert = - let allCases (t: System.Type) = - FSharpType.GetUnionCases t - memorise (fun t -> - FSharpType.IsUnion t - && allCases t |> Array.forall (fun c -> c.GetFields().Length = 0) - ) - - override _.CanConvert t = canConvert t - - override _.WriteJson(writer: Newtonsoft.Json.JsonWriter, value: obj, serializer: Newtonsoft.Json.JsonSerializer) = - serializer.Serialize(writer, string value) - - override _.ReadJson(reader: Newtonsoft.Json.JsonReader, t, _existingValue, serializer) = - let caseName = string reader.Value - match FSharpType.GetUnionCases(t) |> Array.tryFind (fun c -> c.Name.Equals(caseName, StringComparison.OrdinalIgnoreCase)) with - | Some caseInfo -> - FSharpValue.MakeUnion(caseInfo, [||]) - | None -> - failwith $"Could not create an instance of the type '%s{t.Name}' with the name '%s{caseName}'" - - type U2BoolObjectConverter() = - inherit JsonConverter() - - let canConvert = - memorise (fun (t: System.Type) -> - t.IsGenericType - && t.GetGenericTypeDefinition() = typedefof> - && t.GetGenericArguments().Length = 2 - && t.GetGenericArguments().[0] = typeof - && not (t.GetGenericArguments().[1].IsValueType) - ) - - override _.CanConvert t = canConvert t - - override _.WriteJson(writer, value, serializer) = - let case, fields = FSharpValue.GetUnionFields(value, value.GetType()) - match case.Name with - | "First" -> - writer.WriteValue(value :?> bool) - | "Second" -> - serializer.Serialize(writer, fields.[0]) - | _ -> - failwith $"Unrecognized case '{case.Name}' for union type '{value.GetType().FullName}'." - - override _.ReadJson(reader, t, _existingValue, serializer) = - let cases = FSharpType.GetUnionCases(t) - match reader.TokenType with - | JsonToken.Boolean -> - // 'First' side - FSharpValue.MakeUnion(cases.[0], [| box(reader.Value :?> bool) |]) - | JsonToken.StartObject -> - // Second side - let value = serializer.Deserialize(reader, (t.GetGenericArguments().[1])) - FSharpValue.MakeUnion(cases.[1], [| value |]) - | _ -> - failwithf $"Unrecognized json TokenType '%s{string reader.TokenType}' when reading value of type '{t.FullName}'" - - type OptionConverter() = - inherit JsonConverter() - - override __.CanConvert(t) = - t.IsGenericType && t.GetGenericTypeDefinition() = typedefof> - - override __.WriteJson(writer, value, serializer) = - let value = - if isNull value then null - else - let _,fields = FSharpValue.GetUnionFields(value, value.GetType()) - fields.[0] - serializer.Serialize(writer, value) - - override __.ReadJson(reader, t, _existingValue, serializer) = - let innerType = t.GetGenericArguments().[0] - let innerType = - if innerType.IsValueType then (typedefof>).MakeGenericType([|innerType|]) - else innerType - let value = serializer.Deserialize(reader, innerType) - let cases = FSharpType.GetUnionCases(t) - if isNull value then FSharpValue.MakeUnion(cases.[0], [||]) - else FSharpValue.MakeUnion(cases.[1], [|value|]) - -module Types = - open Newtonsoft.Json - open Newtonsoft.Json.Linq - open System - - type TextDocumentSyncKind = - | None = 0 - | Full = 1 - | Incremental = 2 - - type DocumentFilter = { - /// A language id, like `typescript`. - Language: string option - - /// A Uri scheme, like `file` or `untitled`. - Scheme: string option - - /// A glob pattern, like `*.{ts,js}`. - Pattern: string option - } - - type DocumentSelector = DocumentFilter[] - - /// Position in a text document expressed as zero-based line and zero-based character offset. - /// A position is between two characters like an ‘insert’ cursor in a editor. - [] - type Position = - { - /// Line position in a document (zero-based). - Line: int - - /// Character offset on a line in a document (zero-based). Assuming that the line is - /// represented as a string, the `character` value represents the gap between the - /// `character` and `character + 1`. - /// - /// If the character value is greater than the line length it defaults back to the - /// line length. - Character: int - } - [] - member x.DebuggerDisplay = - $"({x.Line},{x.Character})" - - /// 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. - /// - /// If you want to specify a range that contains a line including the line ending character(s) - /// then use an end position denoting the start of the next line. For example: - /// - /// ```fsharp - /// { - /// Start = { Line = 5; character = 23 } - /// End = { Line = 6; character = 0 } - /// } - /// ``` - [] - type Range = - { - /// The range's start position. - Start: Position - - /// The range's end position. - End: Position - } - [] - member x.DebuggerDisplay = - $"{x.Start.DebuggerDisplay}-{x.End.DebuggerDisplay}" - - type DocumentUri = string - - /// Represents a location inside a resource, such as a line inside a text file. - type Location = { - Uri: DocumentUri - Range: Range - } - - type ITextDocumentIdentifier = - /// Warning: normalize this member by UrlDecoding it before use - abstract member Uri : DocumentUri with get - - type TextDocumentIdentifier = - { - /// The text document's URI. - Uri: DocumentUri - } - interface ITextDocumentIdentifier with - member this.Uri with get() = this.Uri - - type VersionedTextDocumentIdentifier = - { - /// The text document's URI. - Uri: DocumentUri - - /// 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) - /// Explicitly include the null value here. - [] - Version: int option - } - interface ITextDocumentIdentifier with - member this.Uri with get() = this.Uri - - type 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 - | String = 15 - | Number = 16 - | Boolean = 17 - | Array = 18 - | Object = 19 - | Key = 20 - | Null = 21 - | EnumMember = 22 - | Struct = 23 - | Event = 24 - | Operator = 25 - | TypeParameter = 26 - - /// Represents information about programming constructs like variables, classes, - /// interfaces etc. - type SymbolInformation = { - /// The name of this symbol. - Name: string - - /// The kind of this symbol. - Kind: SymbolKind - - /// The location of this symbol. The location's range is used by a tool - /// to reveal the location in the editor. If the symbol is selected in the - /// tool the range's start information is used to position the cursor. So - /// the range usually spans more then the actual symbol's name and does - /// normally include things like visibility modifiers. - /// - /// The range doesn't have to denote a node range in the sense of a abstract - /// syntax tree. It can therefore not be used to re-construct a hierarchy of - /// the symbols. - Location: Location - - /// The name of the symbol containing this symbol. This information is for - /// user interface purposes (e.g. to render a qualifier in the user interface - /// if necessary). It can't be used to re-infer a hierarchy for the document - /// symbols. - ContainerName: string option - } - - /// A textual edit applicable to a text document. - type 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 - } - - /// Describes textual changes on a single text document. The text document is referred to as a - /// `VersionedTextDocumentIdentifier` to allow clients to check the text document version before an edit is - /// applied. A `TextDocumentEdit` describes all changes on a version Si and after they are applied move the - /// document to version Si+1. So the creator of a `TextDocumentEdit `doesn't need to sort the array or do any - /// kind of ordering. However the edits must be non overlapping. - type TextDocumentEdit = { - /// The text document to change. - TextDocument: VersionedTextDocumentIdentifier - - /// The edits to be applied. - Edits: TextEdit[] - } - - type TraceSetting = - | Off = 0 - | Messages = 1 - | Verbose = 2 - - /// Capabilities for methods that support dynamic registration. - type DynamicCapabilities = { - /// Method supports dynamic registration. - DynamicRegistration: bool option - } - - type ResourceOperationKind = Create | Rename | Delete - - type FailureHandlingKind = Abort | Transactional | Undo | TextOnlyTransactional - - type ChangeAnnotationSupport = { - GroupsOnLabel: bool option - } - - /// Capabilities specific to `WorkspaceEdit`s - type WorkspaceEditCapabilities = { - /// The client supports versioned document changes in `WorkspaceEdit`s - DocumentChanges: bool option - /// The resource operations the client supports. Clients should at least - /// support 'create', 'rename' and 'delete' files and folders. - ResourceOperations: ResourceOperationKind [] option - /// The failure handling strategy of a client if applying the workspace edit fails. - FailureHandling: FailureHandlingKind option - /// Whether the client normalizes line endings to the client specific setting. - /// If set to `true` the client will normalize line ending characters - /// in a workspace edit to the client specific new line character(s). - NormalizesLineEndings: bool option - /// Whether the client in general supports change annotations on text edits, create file, rename file and delete file changes. - ChangeAnnotationSupport: ChangeAnnotationSupport option - } - - /// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. - type SymbolKindCapabilities = { - /// The symbol kind values the client supports. When this - /// property exists the client also guarantees that it will - /// handle values outside its set gracefully and falls back - /// to a default value when unknown. - /// - /// If this property is not present the client only supports - /// the symbol kinds from `File` to `Array` as defined in - /// the initial version of the protocol. - ValueSet: SymbolKind[] option - } - with - static member DefaultValueSet = - [| - SymbolKind.File - SymbolKind.Module - SymbolKind.Namespace - SymbolKind.Package - SymbolKind.Class - SymbolKind.Method - SymbolKind.Property - SymbolKind.Field - SymbolKind.Constructor - SymbolKind.Enum - SymbolKind.Interface - SymbolKind.Function - SymbolKind.Variable - SymbolKind.Constant - SymbolKind.String - SymbolKind.Number - SymbolKind.Boolean - SymbolKind.Array - |] - - /// Capabilities specific to the `workspace/symbol` request. - type SymbolCapabilities = { - /// Symbol request supports dynamic registration. - DynamicRegistration: bool option - - /// Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. - SymbolKind: SymbolKindCapabilities option - } - - type SemanticTokensWorkspaceClientCapabilities = { - /// Whether the client implementation supports a refresh request sent from - /// the server to the client. - /// - /// Note that this event is global and will force the client to refresh all - /// semantic tokens currently shown. It should be used with absolute care - /// and is useful for situation where a server for example detect a project - /// wide change that requires such a calculation. - RefreshSupport: bool option - } - - /// Workspace specific client capabilities. - type WorkspaceClientCapabilities = { - /// The client supports applying batch edits to the workspace by supporting - /// the request 'workspace/applyEdit' - ApplyEdit: bool option - - /// Capabilities specific to `WorkspaceEdit`s - WorkspaceEdit: WorkspaceEditCapabilities option - - /// Capabilities specific to the `workspace/didChangeConfiguration` notification. - DidChangeConfiguration: DynamicCapabilities option - - /// Capabilities specific to the `workspace/didChangeWatchedFiles` notification. - DidChangeWatchedFiles: DynamicCapabilities option - - /// Capabilities specific to the `workspace/symbol` request. - Symbol: SymbolCapabilities option - - SemanticTokens: SemanticTokensWorkspaceClientCapabilities option - } - - type SynchronizationCapabilities = { - /// Whether text document synchronization supports dynamic registration. - DynamicRegistration: bool option - - /// The client supports sending will save notifications. - WillSave: bool option - - /// The client supports sending a will save request and - /// waits for a response providing text edits which will - /// be applied to the document before it is saved. - WillSaveWaitUntil: bool option - - /// The client supports did save notifications. - DidSave: bool option - } - - module MarkupKind = - let PlainText = "plaintext" - let Markdown = "markdown" - - type HoverCapabilities = { - /// Whether hover synchronization supports dynamic registration. - DynamicRegistration: bool option - - /// Client supports the follow content formats for the content - /// property. The order describes the preferred format of the client. - /// See `MarkupKind` for common values - ContentFormat: string[] option - } - - type CompletionItemCapabilities = { - /// Client supports snippets as insert text. - /// - /// 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. - SnippetSupport: bool option - - /// Client supports commit characters on a completion item. - CommitCharactersSupport: bool option - - /// Client supports the follow content formats for the documentation - /// property. The order describes the preferred format of the client. - /// See `MarkupKind` for common values - DocumentationFormat: string[] option - } - - type 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 - | Folder = 19 - | EnumMember = 20 - | Constant = 21 - | Struct = 22 - | Event = 23 - | Operator = 24 - | TypeParameter = 25 - - type CompletionItemKindCapabilities = { - /// The completion item kind values the client supports. When this - /// property exists the client also guarantees that it will - /// handle values outside its set gracefully and falls back - /// to a default value when unknown. - /// - /// If this property is not present the client only supports - /// the completion items kinds from `Text` to `Reference` as defined in - /// the initial version of the protocol. - ValueSet: CompletionItemKind[] option - } - with - static member DefaultValueSet = - [| - CompletionItemKind.Text - CompletionItemKind.Method - CompletionItemKind.Function - CompletionItemKind.Constructor - CompletionItemKind.Field - CompletionItemKind.Variable - CompletionItemKind.Class - CompletionItemKind.Interface - CompletionItemKind.Module - CompletionItemKind.Property - CompletionItemKind.Unit - CompletionItemKind.Value - CompletionItemKind.Enum - CompletionItemKind.Keyword - CompletionItemKind.Snippet - CompletionItemKind.Color - CompletionItemKind.File - CompletionItemKind.Reference - |] - - /// Capabilities specific to the `textDocument/completion` - type CompletionCapabilities = { - /// Whether completion supports dynamic registration. - DynamicRegistration: bool option - - /// The client supports the following `CompletionItem` specific - /// capabilities. - CompletionItem: CompletionItemCapabilities option - - CompletionItemKind: CompletionItemKindCapabilities option - - /// The client supports to send additional context information for a - /// `textDocument/completion` request. - ContextSupport: bool option - } - - type SignatureInformationCapabilities = { - /// Client supports the follow content formats for the documentation - /// property. The order describes the preferred format of the client. - /// See `MarkupKind` for common values - DocumentationFormat: string[] option - } - - type SignatureHelpCapabilities = { - /// Whether signature help supports dynamic registration. - DynamicRegistration: bool option - - /// The client supports the following `SignatureInformation` - /// specific properties. - SignatureInformation: SignatureInformationCapabilities option - } - - /// capabilities specific to the `textDocument/documentSymbol` - type DocumentSymbolCapabilities = { - /// Whether document symbol supports dynamic registration. - DynamicRegistration: bool option - - /// Specific capabilities for the `SymbolKind`. - SymbolKind: SymbolKindCapabilities option - } - - [] - type DiagnosticTag = - /// Unused or unnecessary code. - /// - /// Clients are allowed to render diagnostics with this tag faded out instead of having - /// an error squiggle. - | Unnecessary = 1 - - type DiagnosticTagSupport = { - - /// Represents the tags supported by the client - ValueSet: DiagnosticTag[] - } - - /// Capabilities specific to `textDocument/publishDiagnostics`. - type PublishDiagnosticsCapabilites = { - - /// Whether the clients accepts diagnostics with related information. - RelatedInformation: bool option - - /// Client supports the tag property to provide meta data about a diagnostic. - TagSupport: DiagnosticTagSupport option - } - - type FoldingRangeCapabilities = { - /// Whether implementation supports dynamic registration for folding range providers. If this is set to `true` - /// the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)` - /// return value for the corresponding server capability as well. - DynamicRegistration: bool option - /// The maximum number of folding ranges that the client prefers to receive per document. The value serves as a - /// hint, servers are free to follow the limit. - RangeLimit: int option - /// If set, the client signals that it only supports folding complete lines. If set, client will - /// ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange. - LineFoldingOnly: bool option - } - - type SemanticTokenFullRequestType = { - /// The client will send the `textDocument/semanticTokens/full/delta` - /// request if the server provides a corresponding handler. - Delta: bool option - } - - type SemanticTokensRequests = { - /// The client will send the `textDocument/semanticTokens/range` request - /// if the server provides a corresponding handler. - Range: U2 option - - /// The client will send the `textDocument/semanticTokens/full` request - /// if the server provides a corresponding handler. - Full: U2 option - } - - type TokenFormat = - | Relative - - type SemanticTokensClientCapabilities = { - /// Whether implementation supports dynamic registration. If this is set to - /// `true` the client supports the new `(TextDocumentRegistrationOptions & - /// StaticRegistrationOptions)` return value for the corresponding server - /// capability as well. - DynamicRegistration: bool option - - /// Which requests the client supports and might send to the server - /// depending on the server's capability. Please note that clients might not - /// show semantic tokens or degrade some of the user experience if a range - /// or full request is advertised by the client but not provided by the - /// server. If for example the client capability `requests.full` and - /// `request.range` are both set to true but the server only provides a - /// range provider the client might not render a minimap correctly or might - /// even decide to not show any semantic tokens at all. - Requests: SemanticTokensRequests - - /// The token types that the client supports. - TokenTypes: string[] - - /// The token modifiers that the client supports. - TokenModifiers: string[] - - /// The formats the clients supports. - Formats: TokenFormat[] - - /// Whether the client supports tokens that can overlap each other. - OverlappingTokenSupport: bool option - - /// Whether the client supports tokens that can span multiple lines. - MultilineTokenSupport: bool option - } - - /// Text document specific client capabilities. - type TextDocumentClientCapabilities = { - Synchronization: SynchronizationCapabilities option - - /// Capabilities specific to `textDocument/publishDiagnostics`. - PublishDiagnostics:PublishDiagnosticsCapabilites - - /// Capabilities specific to the `textDocument/completion` - Completion: CompletionCapabilities option - - /// Capabilities specific to the `textDocument/hover` - Hover: HoverCapabilities option - - /// Capabilities specific to the `textDocument/signatureHelp` - SignatureHelp: SignatureHelpCapabilities option - - /// Capabilities specific to the `textDocument/references` - References: DynamicCapabilities option - - /// Whether document highlight supports dynamic registration. - DocumentHighlight: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/documentSymbol` - DocumentSymbol: DocumentSymbolCapabilities option - - /// Capabilities specific to the `textDocument/formatting` - Formatting: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/rangeFormatting` - RangeFormatting: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/onTypeFormatting` - OnTypeFormatting: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/definition` - Definition: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/codeAction` - CodeAction: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/codeLens` - CodeLens: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/documentLink` - DocumentLink: DynamicCapabilities option - - /// Capabilities specific to the `textDocument/rename` - Rename: DynamicCapabilities option - - /// Capabilities for the `textDocument/foldingRange` - FoldingRange: FoldingRangeCapabilities option - - /// Capabilities for the `textDocument/selectionRange` - SelectionRange: DynamicCapabilities option - - /// Capabilities specific to the various semantic token requests. - /// @since 3.16.0 - SemanticTokens: SemanticTokensClientCapabilities option - } - - type ClientCapabilities = { - /// Workspace specific client capabilities. - Workspace: WorkspaceClientCapabilities option - - /// Text document specific client capabilities. - TextDocument: TextDocumentClientCapabilities option - - /// Experimental client capabilities. - Experimental: JToken option - } - - type InitializeParams = { - ProcessId: int option - RootPath: string option - RootUri: string option - InitializationOptions: JToken option - Capabilities: ClientCapabilities option - trace: string option - } - - type InitializedParams() = - class end - - /// Completion options. - type CompletionOptions = { - /// The server provides support to resolve additional information for a completion item. - ResolveProvider: bool option - - /// The characters that trigger completion automatically. - TriggerCharacters: char[] option - - /// The list of all possible characters that commit a completion. - /// This field can be used if clients don't support individual commit - /// characters per completion item. - /// - /// See `ClientCapabilities.textDocument.completion.completionItem.commitCharactersSupport`. - /// - /// If a server provides both `allCommitCharacters` and commit characters - /// on an individual completion item, the ones on the completion item win. - AllCommitCharacters: char[] option - } - - /// Signature help options. - type SignatureHelpOptions = { - /// The characters that trigger signature help automatically. - TriggerCharacters: char[] option - /// List of characters that re-trigger signature help. - /// - /// These trigger characters are only active when signature help is already showing. - /// All trigger characters are also counted as re-trigger characters. - RetriggerCharacters: char[] option - } - - /// Code Lens options. - type CodeLensOptions = { - /// Code lens has a resolve provider as well. - ResolveProvider: bool option - } - - /// Format document on type options - type DocumentOnTypeFormattingOptions = { - /// A character on which formatting should be triggered, like `}`. - FirstTriggerCharacter: char - - /// More trigger characters. - MoreTriggerCharacter: char[] option - } - - /// Document link options - type DocumentLinkOptions = { - /// Document links have a resolve provider as well. - ResolveProvider: bool option - } - - /// Execute command options. - type ExecuteCommandOptions = { - /// The commands to be executed on the server - commands: string[] option - } - - /// Save options. - type SaveOptions = { - /// The client is supposed to include the content on save. - IncludeText: bool option - } - - type TextDocumentSyncOptions = { - /// Open and close notifications are sent to the server. - OpenClose: bool option - - /// Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full - /// and TextDocumentSyncKindIncremental. - Change: TextDocumentSyncKind option - - /// Will save notifications are sent to the server. - WillSave: bool option - - /// Will save wait until requests are sent to the server. - WillSaveWaitUntil: bool option - - /// Save notifications are sent to the server. - Save: SaveOptions option - } - with - static member Default = - { - OpenClose = None - Change = None - WillSave = None - WillSaveWaitUntil = None - Save = None - } - - type SemanticTokensLegend = { - /// The token types a server uses. - TokenTypes: string[] - /// The token modifiers a server uses. - TokenModifiers: string[] - } - - type SemanticTokenFullOptions = - { - /// The server supports deltas for full documents. - Delta: bool option - } - type SemanticTokensOptions = { - /// The legend used by the server - Legend: SemanticTokensLegend - - /// Server supports providing semantic tokens for a specific range of a document. - Range: U2 option - - /// Server supports providing semantic tokens for a full document. - Full: U2 option - } - - type ServerCapabilities = { - /// Defines how text documents are synced. Is either a detailed structure defining each notification or - /// for backwards compatibility the TextDocumentSyncKind number. - TextDocumentSync: TextDocumentSyncOptions option - - /// The server provides hover support. - HoverProvider: bool option - - /// The server provides completion support. - CompletionProvider: CompletionOptions option - - /// The server provides signature help support. - SignatureHelpProvider: SignatureHelpOptions option - - /// The server provides goto definition support. - DefinitionProvider: bool option - - ///The server provides Goto Implementation support - ImplementationProvider :bool option - - /// The server provides goto type definition support. - TypeDefinitionProvider: bool option - - /// The server provides find references support. - ReferencesProvider: bool option - - /// The server provides document highlight support. - DocumentHighlightProvider: bool option - - /// The server provides document symbol support. - DocumentSymbolProvider: bool option - - /// The server provides workspace symbol support. - WorkspaceSymbolProvider: bool option - - /// The server provides code actions. - CodeActionProvider: bool option - - /// The server provides code lens. - CodeLensProvider: CodeLensOptions option - - /// The server provides document formatting. - DocumentFormattingProvider: bool option - - /// The server provides document range formatting. - DocumentRangeFormattingProvider: bool option - - /// The server provides document formatting on typing. - DocumentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions option - - /// The server provides rename support. - RenameProvider: bool option - - /// The server provides document link support. - DocumentLinkProvider: DocumentLinkOptions option - - /// The server provides execute command support. - ExecuteCommandProvider: ExecuteCommandOptions option - - /// Experimental server capabilities. - Experimental: JToken option - - /// - FoldingRangeProvider: bool option - - SelectionRangeProvider: bool option - - SemanticTokensProvider: SemanticTokensOptions option - - } - with - static member Default = - { - HoverProvider = None - TextDocumentSync = None - CompletionProvider = None - SignatureHelpProvider = None - DefinitionProvider = None - TypeDefinitionProvider = None - ImplementationProvider = None - ReferencesProvider = None - DocumentHighlightProvider = None - DocumentSymbolProvider = None - WorkspaceSymbolProvider = None - CodeActionProvider = None - CodeLensProvider = None - DocumentFormattingProvider = None - DocumentRangeFormattingProvider = None - DocumentOnTypeFormattingProvider = None - RenameProvider = None - DocumentLinkProvider = None - ExecuteCommandProvider = None - Experimental = None - FoldingRangeProvider = None - SelectionRangeProvider = None - SemanticTokensProvider = None - } - - type InitializeResult = { - Capabilities: ServerCapabilities - } - with - static member Default = - { - Capabilities = ServerCapabilities.Default - } - - /// A workspace edit represents changes to many resources managed in the workspace. - /// The edit should either provide `changes` or `documentChanges`. If the client can handle versioned document - /// edits and if `documentChanges` are present, the latter are preferred over `changes`. - type WorkspaceEdit = { - /// Holds changes to existing resources. - Changes: Map option - - /// An array of `TextDocumentEdit`s to express changes to n different text documents - /// where each text document edit addresses a specific version of a text document. - /// Whether a client supports versioned document edits is expressed via - /// `WorkspaceClientCapabilities.workspaceEdit.documentChanges`. - DocumentChanges: TextDocumentEdit[] option - } - with - static member DocumentChangesToChanges(edits: TextDocumentEdit[]) = - edits - |> Array.map (fun edit -> edit.TextDocument.Uri.ToString(), edit.Edits) - |> Map.ofArray - - static member CanUseDocumentChanges(capabilities: ClientCapabilities) = - (capabilities.Workspace - |> Option.bind(fun x -> x.WorkspaceEdit) - |> Option.bind (fun x -> x.DocumentChanges)) - = Some true - - static member Create(edits: TextDocumentEdit[], capabilities: ClientCapabilities ) = - if WorkspaceEdit.CanUseDocumentChanges(capabilities) then - { - Changes = None - DocumentChanges = Some edits - } - else - { - Changes = Some (WorkspaceEdit.DocumentChangesToChanges edits) - DocumentChanges = None - } - - type MessageType = - | Error = 1 - | Warning = 2 - | Info = 3 - | Log = 4 - - type LogMessageParams = { - Type: MessageType - Message: string - } - - type ShowMessageParams = { - Type: MessageType - Message: string - } - - type MessageActionItem = { - /// A short title like 'Retry', 'Open Log' etc. - Title: string; - } - - type ShowMessageRequestParams = { - /// The message type. - Type: MessageType - - /// The actual message - Message: string - - /// The message action items to present. - Actions: MessageActionItem[] option - } - - /// General parameters to register for a capability. - type 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: JToken option - } - - type RegistrationParams = { - Registrations: Registration[] - } - - type ITextDocumentRegistrationOptions = - /// 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. - abstract member DocumentSelector : DocumentSelector option with get - - /// General parameters to unregister a capability. - type 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 - } - - type UnregistrationParams = { - Unregisterations: Unregistration[] - } - - type FileChangeType = - | Created = 1 - | Changed = 2 - | Deleted = 3 - - /// An event describing a file change. - type FileEvent ={ - /// The file's URI. - Uri: DocumentUri - - /// The change type. - Type: FileChangeType - } - - type DidChangeWatchedFilesParams = { - /// The actual file events. - Changes: FileEvent[] - } - - type WorkspaceFolder = { - /// The associated URI for this workspace folder. - Uri: string; - - /// The name of the workspace folder. Defaults to the - /// uri's basename. - Name: string; - } - - /// The workspace folder change event. - type WorkspaceFoldersChangeEvent = { - /// The array of added workspace folders - Added: WorkspaceFolder[]; - - /// The array of the removed workspace folders - Removed: WorkspaceFolder[]; - } - - type DidChangeWorkspaceFoldersParams = { - /// The actual workspace folder change event. - Event: WorkspaceFoldersChangeEvent - } - - type DidChangeConfigurationParams = { - /// The actual changed settings - Settings: JToken; - } - - type ConfigurationItem = { - /// The scope to get the configuration section for. - ScopeUri: string option - - /// The configuration section asked for. - Section: string option - } - - type ConfigurationParams = { - items: ConfigurationItem[] - } - - /// The parameters of a Workspace Symbol Request. - type WorkspaceSymbolParams = { - /// A non-empty query string - Query: string - } - - type ExecuteCommandParams = { - /// The identifier of the actual command handler. - Command: string - /// Arguments that the command should be invoked with. - Arguments: JToken[] option - } - - type ApplyWorkspaceEditParams = { - /// An optional label of the workspace edit. This label is - /// presented in the user interface for example on an undo - /// stack to undo the workspace edit. - Label: string option - - /// The edits to apply. - Edit: WorkspaceEdit - } - - type ApplyWorkspaceEditResponse = { - /// Indicates whether the edit was applied or not. - Applied: bool - } - - /// Represents reasons why a text document is saved. - type TextDocumentSaveReason = - /// Manually triggered, e.g. by the user pressing save, by starting debugging, - /// or by an API call. - | Manual = 1 - - /// Automatic after a delay. - | AfterDelay = 2 - - /// When the editor lost focus. - | FocusOut = 3 - - /// The parameters send in a will save text document notification. - type WillSaveTextDocumentParams = { - /// The document that will be saved. - TextDocument: TextDocumentIdentifier - - /// The 'TextDocumentSaveReason'. - Reason: TextDocumentSaveReason - } - - type DidSaveTextDocumentParams = { - /// The document that was saved. - TextDocument: TextDocumentIdentifier - - /// Optional the content when saved. Depends on the includeText value - /// when the save notification was requested. - Text: string option - } - - type DidCloseTextDocumentParams = { - /// The document that was closed. - TextDocument: TextDocumentIdentifier - } - - /// Value-object describing what options formatting should use. - type FormattingOptions() = - /// Size of a tab in spaces. - member val TabSize : int = 0 with get, set - - /// Prefer spaces over tabs. - member val InsertSpaces: bool = false with get, set - - /// Further properties. - [] - member val AdditionalData: System.Collections.Generic.IDictionary = new System.Collections.Generic.Dictionary<_,_>() :> _ with get, set - - type DocumentFormattingParams = { - /// The document to format. - TextDocument: TextDocumentIdentifier - - /// The format options. - Options: FormattingOptions - } - - type DocumentRangeFormattingParams = { - /// The document to format. - TextDocument: TextDocumentIdentifier - - /// The range to format - Range: Range - - /// The format options - Options: FormattingOptions - } - - type DocumentOnTypeFormattingParams = { - /// The document to format. - TextDocument: TextDocumentIdentifier - - /// The position at which this request was sent. - Position: Position - - /// The character that has been typed. - Ch: char - - /// The format options. - Options: FormattingOptions - } - - type DocumentSymbolParams = { - /// The text document. - TextDocument: TextDocumentIdentifier - } - - type ITextDocumentPositionParams = - /// The text document. - abstract member TextDocument : TextDocumentIdentifier with get - /// The position inside the text document. - abstract member Position : Position with get - - type TextDocumentPositionParams = - { - /// The text document. - TextDocument: TextDocumentIdentifier - /// The position inside the text document. - Position: Position - } - interface ITextDocumentPositionParams with - member this.TextDocument with get() = this.TextDocument - member this.Position with get() = this.Position - - type ReferenceContext = { - /// Include the declaration of the current symbol. - IncludeDeclaration: bool - } - - type ReferenceParams = - { - /// The text document. - TextDocument: TextDocumentIdentifier - /// The position inside the text document. - Position: Position - Context: ReferenceContext - } - interface ITextDocumentPositionParams with - member this.TextDocument with get() = this.TextDocument - member this.Position with get() = this.Position - - /// A `MarkupContent` literal represents a string value which content is interpreted base on its - /// kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds. - /// - /// If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues. - /// See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting - /// - /// Here is an example how such a string can be constructed using JavaScript / TypeScript: - /// ```ts - /// let markdown: MarkdownContent = { - /// kind: MarkupKind.Markdown, - /// value: [ - /// '# Header', - /// 'Some text', - /// '```typescript', - /// 'someCode();', - /// '```' - /// ].join('\n') - /// }; - /// ``` - /// - /// *Please Note* that clients might sanitize the return markdown. A client could decide to - /// remove HTML from the markdown to avoid script execution. - type MarkupContent = { - /// The type of the Markup - Kind: string - - // The content itself - Value: string - } - - type MarkedStringData = { - Language: string - Value: string - } - - [] - [] - type MarkedString = - | String of string - | WithLanguage of MarkedStringData - - let plaintext s = { Kind = MarkupKind.PlainText; Value = s } - let markdown s = { Kind = MarkupKind.Markdown; Value = s } - - [] - type HoverContent = - | MarkedString of MarkedString - | MarkedStrings of MarkedString [] - | MarkupContent of MarkupContent - - /// The result of a hover request. - type Hover = { - /// The hover's content - Contents: HoverContent - - /// An optional range is a range inside a text document - /// that is used to visualize a hover, e.g. by changing the background color. - Range: Range option - } - - /// An item to transfer a text document from the client to the server. - type TextDocumentItem = { - /// The text document's URI. - Uri: DocumentUri - - /// The text document's language identifier. - LanguageId: string - - /// The version number of this document (it will increase after each - /// change, including undo/redo). - Version: int - - /// The content of the opened text document. - Text: string - } - - type DidOpenTextDocumentParams = { - /// The document that was opened. - TextDocument: TextDocumentItem - } - - /// 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. - type TextDocumentContentChangeEvent = { - /// The range of the document that changed. - Range: Range option - - /// The length of the range that got replaced. - RangeLength: int option - - /// The new text of the range/document. - Text: string - } - - type 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. The content changes describe single state changes - /// to the document. So if there are two content changes c1 and c2 for a document - /// in state S10 then c1 move the document to S11 and c2 to S12. - ContentChanges: TextDocumentContentChangeEvent[] - } - - [] - type WatchKind = - | Create = 1 - | Change = 2 - | Delete = 4 - - type FileSystemWatcher = { - /// The glob pattern to watch - GlobPattern: string - - /// The kind of events of interest. If omitted it defaults - /// to WatchKind.Create | WatchKind.Change | WatchKind.Delete - /// which is 7. - Kind: WatchKind option - } - - /// Describe options to be used when registered for text document change events. - type DidChangeWatchedFilesRegistrationOptions = { - /// The watchers to register. - Watchers: FileSystemWatcher[] - } - - /// How a completion was triggered - type CompletionTriggerKind = - /// Completion was triggered by typing an identifier (24x7 code - /// complete), manual invocation (e.g Ctrl+Space) or via API. - | Invoked = 1 - /// Completion was triggered by a trigger character specified by - /// the `triggerCharacters` properties of the `CompletionRegistrationOptions`. - | TriggerCharacter = 2 - - type CompletionContext = { - /// How the completion was triggered. - triggerKind: CompletionTriggerKind - - /// The trigger character (a single character) that has trigger code complete. - /// Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` - triggerCharacter: char option - } - - type CompletionParams = - { - /// The text document. - TextDocument: TextDocumentIdentifier - - /// The position inside the text document. - Position: Position - - /// The completion context. This is only available it the client specifies - /// to send this using `ClientCapabilities.textDocument.completion.contextSupport === true` - Context: CompletionContext option - } - interface ITextDocumentPositionParams with - member this.TextDocument with get() = this.TextDocument - member this.Position with get() = this.Position - - /// Represents a reference to a command. Provides a title which will be used to represent a command in the UI. - /// Commands are identified by a string identifier. The protocol currently doesn't specify a set of well-known - /// commands. So executing a command requires some tool extension code. - type 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: JToken[] option - } - - /// Defines whether the insert text in a completion item should be interpreted as - /// plain text or a snippet. - type InsertTextFormat = - /// The primary text to be inserted is treated as a plain string. - | 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. - | Snippet = 2 - - [] - [] - type Documentation = - | String of string - | Markup of MarkupContent - - type 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: CompletionItemKind option - - /// A human-readable string with additional information - /// about this item, like type or symbol information. - Detail: string option - - /// A human-readable string that represents a doc-comment. - Documentation: Documentation option - - /// A string that should be used when comparing this item - /// with other items. When `falsy` the label is used. - SortText: string option - - /// A string that should be used when filtering a set of - /// completion items. When `falsy` the label is used. - FilterText: string option - - /// A string that should be inserted into a document when selecting - /// this completion. When `falsy` the label is used. - /// - /// The `insertText` is subject to interpretation by the client side. - /// Some tools might not take the string literally. For example - /// VS Code when code complete is requested in this example `con` - /// and a completion item with an `insertText` of `console` is provided it - /// will only insert `sole`. Therefore it is recommended to use `textEdit` instead - /// since it avoids additional client side interpretation. - /// - /// @deprecated Use textEdit instead. - InsertText: string option - - /// The format of the insert text. The format applies to both the `insertText` property - /// and the `newText` property of a provided `textEdit`. - InsertTextFormat: InsertTextFormat option - - /// 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 option - - /// 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[] option - - /// An optional set of characters that when pressed while this completion is active will accept it first and - /// then type that character. *Note* that all commit characters should have `length=1` and that superfluous - /// characters will be ignored. - CommitCharacters: char[] option - - /// 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 option - - /// An data entry field that is preserved on a completion item between - /// a completion and a completion resolve request. - Data: JToken option - } - with - static member Create(label:string) = - { - Label = label - Kind = None - Detail = None - Documentation = None - SortText = None - FilterText = None - InsertText = None - InsertTextFormat = None - TextEdit = None - AdditionalTextEdits = None - CommitCharacters = None - Command = None - Data = None - } - - type CompletionList = { - /// This list it not complete. Further typing should result in recomputing - /// this list. - IsIncomplete: bool - - /// The completion items. - Items: CompletionItem[] - } - - [] - [] - type DiagnosticCode = - | Number of int - | String of string - - [] - type DiagnosticSeverity = - /// Reports an error. - | Error = 1 - /// Reports a warning. - | Warning = 2 - /// Reports an information. - | Information = 3 - /// Reports a hint. - | Hint = 4 - - /// 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. - type DiagnosticRelatedInformation = { - Location: Location - Message: string - } - - // Structure to capture a description for an error code. - type CodeDescription = - { - // An URI to open with more information about the diagnostic error. - Href: Uri option - } - - /// Represents a diagnostic, such as a compiler error or warning. Diagnostic objects are only valid in the - /// scope of a resource. - [] - type 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: DiagnosticSeverity option - - /// The diagnostic's code. Can be omitted. - Code: string option - /// An optional property to describe the error code. - CodeDescription: CodeDescription option - - /// A human-readable string describing the source of this - /// diagnostic, e.g. 'typescript' or 'super lint'. - Source: string - - /// The diagnostic's message. - Message: string - RelatedInformation: DiagnosticRelatedInformation [] option - Tags: DiagnosticTag[] option - /// A data entry field that is preserved between a - /// `textDocument/publishDiagnostics` notification and - /// `textDocument/codeAction` request. - Data: obj option - - } - [] - member x.DebuggerDisplay = $"[{defaultArg x.Severity DiagnosticSeverity.Error}] ({x.Range.DebuggerDisplay}) {x.Message} ({defaultArg x.Code String.Empty})" - - type PublishDiagnosticsParams = { - /// The URI for which diagnostic information is reported. - Uri: DocumentUri - - /// An array of diagnostic information items. - Diagnostics: Diagnostic[] - } - - /// 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. - type CodeAction = { - - /// A short, human-readable, title for this code action. - Title: string - - /// The kind of the code action. - /// Used to filter code actions. - Kind: string option - - /// The diagnostics that this code action resolves. - Diagnostics: Diagnostic[] option - - /// 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 option - } - - [] - [] - type TextDocumentCodeActionResult = - | Commands of Command [] - | CodeActions of CodeAction [] - - type RenameParams = - { - /// The document to rename. - 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** with an - /// appropriate message set. - NewName: string - } - interface ITextDocumentPositionParams with - member this.TextDocument with get() = this.TextDocument - member this.Position with get() = this.Position - - [] - [] - type GotoResult = - | Single of Location - | Multiple of Location [] - - /// A document highlight kind. - [] - type DocumentHighlightKind = - /// A textual occurrence. - | 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 - - /// 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. - type DocumentHighlight = { - /// The range this highlight applies to. - Range: Range - - /// The highlight kind, default is DocumentHighlightKind.Text. - Kind: DocumentHighlightKind option - } - - type DocumentLinkParams = { - /// The document to provide document links for. - TextDocument: TextDocumentIdentifier - } - - /// 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. - type 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 option - } - - type DocumentColorParams = { - /// The text document. - TextDocument: TextDocumentIdentifier - } - - /// Represents a color in RGBA space. - type Color = { - /// The red component of this color in the range [0-1]. - Red: float - - /// The green component of this color in the range [0-1]. - Green: float - - /// The blue component of this color in the range [0-1]. - Blue: float - - /// The alpha component of this color in the range [0-1]. - Alpha: float - } - - type ColorInformation = { - /// The range in the document where this color appears. - Range: Range - - /// The actual color value for this color range. - Color: Color - } - - type ColorPresentationParams = { - /// The text document. - TextDocument: TextDocumentIdentifier - - /// The color information to request presentations for. - ColorInfo: Color - - /// The range where the color would be inserted. Serves as a context. - Range: Range - } - - type ColorPresentation = { - /// The label of this color presentation. It will be shown on the color - /// picker header. By default this is also the text that is inserted when selecting - /// this color presentation. - Label: string - - /// An edit which is applied to a document when selecting - /// this presentation for the color. When `falsy` the label - /// is used. - TextEdit: TextEdit option - - /// An optional array of additional text edits that are applied when - /// selecting this color presentation. Edits must not overlap with the main edit nor with themselves. - AdditionalTextEdits: TextEdit[] option - } - - /// Contains additional diagnostic information about the context in which - /// a code action is run. - type CodeActionContext = { - /// An array of diagnostics. - Diagnostics: Diagnostic[] - } - - /// Params for the CodeActionRequest - type 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 - } - - type CodeLensParams = { - /// The document to request code lens for. - TextDocument: TextDocumentIdentifier; - } - - /// 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. - type 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 option - - /// A data entry field that is preserved on a code lens item between - /// a code lens and a code lens resolve request. - Data: JToken option - } - - /// Represents a parameter of a callable-signature. A parameter can - /// have a label and a doc-comment. - type ParameterInformation = { - /// The label of this parameter. Will be shown in - /// the UI. - Label: string - - /// The human-readable doc-comment of this parameter. Will be shown - /// in the UI but can be omitted. - Documentation: Documentation option - } - - ///Represents the signature of something callable. A signature - /// can have a label, like a function-name, a doc-comment, and - /// a set of parameters. - type 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: Documentation option - - /// The parameters of this signature. - Parameters: ParameterInformation[] option - } - - /// Signature help represents the signature of something - /// callable. There can be multiple signature but only one - /// active and only one active parameter. - type SignatureHelp = { - /// One or more signatures. - Signatures: SignatureInformation[] - - /// The active signature. If omitted or the value lies outside the - /// range of `signatures` the value defaults to zero or is ignored if - /// `signatures.length === 0`. Whenever possible implementors should - /// make an active decision about the active signature and shouldn't - /// rely on a default value. - /// In future version of the protocol this property might become - /// mandatory to better express this. - ActiveSignature: int option - - /// The active parameter of the active signature. If omitted or the value - /// lies outside the range of `signatures[activeSignature].parameters` - /// defaults to 0 if the active signature has parameters. If - /// the active signature has no parameters it is ignored. - /// In future version of the protocol this property might become - /// mandatory to better express the active parameter if the - /// active signature does have any. - ActiveParameter: int option - } - - type SignatureHelpTriggerKind = - /// manually invoked via command - | Invoked = 1 - /// trigger by a configured trigger character - | TriggerCharacter = 2 - /// triggered by cursor movement or document content changing - | ContentChange = 3 - - type SignatureHelpContext = - { - /// action that caused signature help to be triggered - TriggerKind: SignatureHelpTriggerKind - /// character that caused signature help to be triggered. None when kind is not TriggerCharacter. - TriggerCharacter: char option - /// true if signature help was already showing when this was triggered - IsRetrigger: bool - /// the current active SignatureHelp - ActiveSignatureHelp: SignatureHelp option - - } - - type SignatureHelpParams = - { - /// the text document - TextDocument: TextDocumentIdentifier - /// the position inside the text document - Position: Position - /// Additional information about the context in which a signature help request was triggered. - Context: SignatureHelpContext option - } - interface ITextDocumentPositionParams with - member this.TextDocument with get () = this.TextDocument - member this.Position with get () = this.Position - - type FoldingRangeParams = { - /// the document to generate ranges for - TextDocument: TextDocumentIdentifier - } - - module FoldingRangeKind = - let Comment = "comment" - let Imports = "imports" - let Region = "region" - - type FoldingRange = { - /// The zero-based line number from where the folded range starts. - StartLine: int - - /// The zero-based character offset from where the folded range starts. If not defined, defaults to the length of the start line. - StartCharacter: int option - - /// The zero-based line number where the folded range ends. - EndLine: int - - /// The zero-based character offset before the folded range ends. If not defined, defaults to the length of the end line. - EndCharacter: int option - - /// Describes the kind of the folding range such as 'comment' or 'region'. The kind - /// is used to categorize folding ranges and used by commands like 'Fold all comments'. See - /// [FoldingRangeKind](#FoldingRangeKind) for an enumeration of standardized kinds. - Kind: string option - } - - type SelectionRangeParams = { - /// The document to generate ranges for - TextDocument: TextDocumentIdentifier - - /// The positions inside the text document. - Positions: Position[] - } - - type SelectionRange = { - /// The range of this selection range. - Range: Range - - /// The parent selection range containing this range. Therefore `parent.range` must contain `this.range`. - Parent: SelectionRange option - } - - type SemanticTokensParams = { - TextDocument: TextDocumentIdentifier - } - - type SemanticTokensDeltaParams = { - TextDocument: TextDocumentIdentifier - /// The result id of a previous response. The result Id can either point to - /// a full response or a delta response depending on what was received last. - PreviousResultId: string - } - - type SemanticTokensRangeParams = { - TextDocument: TextDocumentIdentifier - Range: Range - } - - type SemanticTokens = { - /// An optional result id. If provided and clients support delta updating - /// the client will include the result id in the next semantic token request. - /// A server can then instead of computing all semantic tokens again simply - /// send a delta. - ResultId: string option - Data: uint32[] - } - - type SemanticTokensEdit = { - /// The start offset of the edit. - Start: uint32 - - /// The count of elements to remove. - DeleteCount: uint32 - - /// The elements to insert. - Data: uint32[] option - } - - type SemanticTokensDelta = { - ResultId: string option - - /// The semantic token edits to transform a previous result into a new - /// result. - Edits: SemanticTokensEdit[]; - } - -module LowLevel = - open System - open System.IO - open System.Text - - let headerBufferSize = 300 - let minimumHeaderLength = 21 - let cr = byte '\r' - let lf = byte '\f' - let headerEncoding = Encoding.ASCII - - let private readLine (stream: Stream) = - let buffer = Array.zeroCreate headerBufferSize - let readCount = stream.Read(buffer, 0, 2) - let mutable count = readCount - if count < 2 then - None - else - // TODO: Check that we don't over-fill headerBufferSize - while count < headerBufferSize && (buffer.[count-2] <> cr && buffer.[count-1] <> lf) do - let additionalBytesRead = stream.Read(buffer, count, 1) - // TODO: exit when additionalBytesRead = 0, end of stream - count <- count + additionalBytesRead - - if count >= headerBufferSize then - None - else - Some (headerEncoding.GetString(buffer, 0, count - 2)) - - let rec private readHeaders (stream: Stream) = - let line = readLine stream - match line with - | Some "" -> [] - | Some line -> - let separatorPos = line.IndexOf(": ") - if separatorPos = -1 then - raise (Exception(sprintf "Separator not found in header '%s'" line)) - else - let name = line.Substring(0, separatorPos) - let value = line.Substring(separatorPos + 2) - let otherHeaders = readHeaders stream - (name,value) :: otherHeaders - | None -> - raise (EndOfStreamException()) - - let read (stream: Stream) = - let headers = readHeaders stream - - let contentLength = - headers - |> List.tryFind(fun (name, _) -> name = "Content-Length") - |> Option.map snd - |> Option.bind (fun s -> match Int32.TryParse(s) with | true, x -> Some x | _ -> None) - - if contentLength = None then - failwithf "Content-Length header not found" - else - let result = Array.zeroCreate contentLength.Value - let mutable readCount = 0 - while readCount < contentLength.Value do - let toRead = contentLength.Value - readCount - let readInCurrentBatch = stream.Read(result, readCount, toRead) - readCount <- readCount + readInCurrentBatch - let str = Encoding.UTF8.GetString(result, 0, readCount) - headers, str - - let write (stream: Stream) (data: string) = - let bytes = Encoding.UTF8.GetBytes(data) - let header = sprintf "Content-Type: application/vscode-jsonrpc; charset=utf-8\r\nContent-Length: %d\r\n\r\n" bytes.Length - let headerBytes = Encoding.ASCII.GetBytes header - use ms = new MemoryStream(headerBytes.Length + bytes.Length) - ms.Write(headerBytes, 0, headerBytes.Length) - ms.Write(bytes, 0, bytes.Length) - stream.Write(ms.ToArray(), 0, int ms.Position) - -module JsonRpc = - open Newtonsoft.Json - open Newtonsoft.Json.Linq - - type MessageTypeTest = { - [] Version: string - Id: int option - Method: string option - } - [] - type MessageType = - | Notification - | Request - | Response - | Error - - let getMessageType messageTest = - match messageTest with - | { Version = "2.0"; Id = Some _; Method = Some _; } -> MessageType.Request - | { Version = "2.0"; Id = Some _; Method = None; } -> MessageType.Response - | { Version = "2.0"; Id = None; Method = Some _; } -> MessageType.Notification - | _ -> MessageType.Error - - type Request = { - [] Version: string - Id: int - Method: string - Params: JToken option - } - with - static member Create(id: int, method': string, rpcParams: JToken option) = - { Version = "2.0"; Id = id; Method = method'; Params = rpcParams } - - type Notification = { - [] Version: string - Method: string - Params: JToken option - } - with - static member Create(method': string, rpcParams: JToken option) = - { Version = "2.0"; Method = method'; Params = rpcParams } - - module ErrorCodes = - let parseError = -32700 - let invalidRequest = -32600 - let methodNotFound = -32601 - let invalidParams = -32602 - let internalError = -32603 - let serverErrorStart = -32000 - let serverErrorEnd = -32099 - - type Error = { - Code: int - Message: string - Data: JToken option - } - with - static member Create(code: int, message: string) = - { Code = code; Message = message; Data = None } - static member ParseError = Error.Create(ErrorCodes.parseError, "Parse error") - static member InvalidRequest = Error.Create(ErrorCodes.invalidRequest, "Invalid Request") - static member MethodNotFound = Error.Create(ErrorCodes.methodNotFound, "Method not found") - static member InvalidParams = Error.Create(ErrorCodes.invalidParams, "Invalid params") - static member InternalError = Error.Create(ErrorCodes.internalError, "Internal error") - static member InternalErrorMessage message = Error.Create(ErrorCodes.internalError, message) - - type Response = { - [] Version: string - Id: int option - Error: Error option - [] - Result: JToken option - } - with - /// Json.NET conditional property serialization, controlled by naming convention - member x.ShouldSerializeResult() = x.Error.IsNone - static member Success(id: int, result: JToken option) = - { Version = "2.0"; Id = Some id; Result = result; Error = None } - static member Failure(id: int, error: Error) = - { Version = "2.0"; Id = Some id; Result = None; Error = Some error } - -type LspResult<'t> = Result<'t, JsonRpc.Error> -type AsyncLspResult<'t> = Async> - -module LspResult = - let success x : LspResult<_> = - Result.Ok x - - let invalidParams s : LspResult<_> = - Result.Error (JsonRpc.Error.Create(JsonRpc.ErrorCodes.invalidParams, s)) - - let internalError<'a> (s: string): LspResult<'a> = - Result.Error (JsonRpc.Error.Create(JsonRpc.ErrorCodes.internalError, s)) - - let notImplemented<'a> : LspResult<'a> = - Result.Error (JsonRpc.Error.MethodNotFound) - -module AsyncLspResult = - let success x : AsyncLspResult<_> = - async.Return (Result.Ok x) - - let invalidParams s : AsyncLspResult<_> = - async.Return (Result.Error (JsonRpc.Error.Create(JsonRpc.ErrorCodes.invalidParams, s))) - - let internalError s : AsyncLspResult<_> = - async.Return (Result.Error (JsonRpc.Error.Create(JsonRpc.ErrorCodes.internalError, s))) - - let notImplemented<'a> : AsyncLspResult<'a> = - async.Return (Result.Error (JsonRpc.Error.MethodNotFound)) - -/// Return the JSON-RPC "not implemented" error -let private notImplemented<'t> = async.Return LspResult.notImplemented<'t> - -/// Do nothing and ignore the notification -let private ignoreNotification = async.Return(()) - -open Types -open Newtonsoft.Json.Linq - -[] -type LspClient() = - /// 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. - abstract member WindowShowMessage: ShowMessageParams -> Async - default __.WindowShowMessage(_) = ignoreNotification - - /// 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. - abstract member WindowShowMessageRequest: ShowMessageRequestParams -> AsyncLspResult - default __.WindowShowMessageRequest(_) = notImplemented - - /// The log message notification is sent from the server to the client to ask the client to log - ///a particular message. - abstract member WindowLogMessage: LogMessageParams -> Async - default __.WindowLogMessage(_) = ignoreNotification - - /// The telemetry notification is sent from the server to the client to ask the client to log - /// a telemetry event. - abstract member TelemetryEvent: Newtonsoft.Json.Linq.JToken -> Async - default __.TelemetryEvent(_) = ignoreNotification - - /// 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 dynamicRegistration property on the specific client capabilities. A client - /// can even provide dynamic registration for capability A but not for capability B. - abstract member ClientRegisterCapability: RegistrationParams -> AsyncLspResult - default __.ClientRegisterCapability(_) = notImplemented - - /// The `client/unregisterCapability` request is sent from the server to the client to unregister a previously - /// registered capability. - abstract member ClientUnregisterCapability: UnregistrationParams -> AsyncLspResult - default __.ClientUnregisterCapability(_) = notImplemented - - /// Many tools support more than one root folder per workspace. Examples for this are VS Code’s multi-root - /// support, Atom’s project folder support or Sublime’s project support. If a client workspace consists of - /// multiple roots then a server typically needs to know about this. The protocol up to know assumes one root - /// folder which is announce to the server by the rootUri property of the InitializeParams. - /// If the client supports workspace folders and announces them via the corresponding workspaceFolders client - /// capability the InitializeParams contain an additional property workspaceFolders with the configured - /// workspace folders when the server starts. - /// - /// The workspace/workspaceFolders request is sent from the server to the client to fetch the current open - /// list of workspace folders. Returns null in the response if only a single file is open in the tool. - /// Returns an empty array if a workspace is open but no folders are configured. - abstract member WorkspaceWorkspaceFolders: unit -> AsyncLspResult - default __.WorkspaceWorkspaceFolders() = notImplemented - - /// The workspace/configuration request is sent from the server to the client to fetch configuration - /// settings from the client. - /// - /// The request can fetch n configuration settings in one roundtrip. The order of the returned configuration - /// settings correspond to the order of the passed ConfigurationItems (e.g. the first item in the response - /// is the result for the first configuration item in the params). - abstract member WorkspaceConfiguration : ConfigurationParams -> AsyncLspResult - default __.WorkspaceConfiguration(_) = notImplemented - - abstract member WorkspaceApplyEdit : ApplyWorkspaceEditParams -> AsyncLspResult - default __.WorkspaceApplyEdit(_) = notImplemented - - /// The workspace/semanticTokens/refresh request is sent from the server to the client. - /// Servers can use it to ask clients to refresh the editors for which this server provides semantic tokens. - /// As a result the client should ask the server to recompute the semantic tokens for these editors. - /// This is useful if a server detects a project wide configuration change which requires a re-calculation - /// of all semantic tokens. Note that the client still has the freedom to delay the re-calculation of - /// the semantic tokens if for example an editor is currently not visible. - abstract member WorkspaceSemanticTokensRefresh: unit -> Async - default __.WorkspaceSemanticTokensRefresh() = ignoreNotification - - /// Diagnostics notification are sent from the server to the client to signal results of validation runs. - /// - /// Diagnostics are “owned” by the server so it is the server’s responsibility to clear them if necessary. - /// The following rule is used for VS Code servers that generate diagnostics: - /// - /// * if a language is single file only (for example HTML) then diagnostics are cleared by the server when - /// the file is closed. - /// * if a language has a project system (for example C#) diagnostics are not cleared when a file closes. - /// When a project is opened all diagnostics for all files are recomputed (or read from a cache). - /// - /// When a file changes it is the server’s responsibility to re-compute diagnostics and push them to the - /// client. If the computed set is empty it has to push the empty array to clear former diagnostics. - /// Newly pushed diagnostics always replace previously pushed diagnostics. There is no merging that happens - /// on the client side. - abstract member TextDocumentPublishDiagnostics: PublishDiagnosticsParams -> Async - default __.TextDocumentPublishDiagnostics(_) = ignoreNotification - - - -[] -type LspServer() = - interface System.IDisposable with - member x.Dispose() = x.Dispose() - - abstract member Dispose : unit -> unit - - /// The initialize request is sent as the first request from the client to the server. - /// The initialize request may only be sent once. - abstract member Initialize: InitializeParams -> AsyncLspResult - default __.Initialize(_) = notImplemented - - /// The initialized notification is sent from the client to the server after the client received the result - /// of the initialize request but before the client is sending any other request or notification to the server. - /// The server can use the initialized notification for example to dynamically register capabilities. - /// The initialized notification may only be sent once. - abstract member Initialized: InitializedParams -> Async - default __.Initialized(_) = ignoreNotification - - /// 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. - abstract member Shutdown : unit -> Async - default __.Shutdown() = ignoreNotification - - /// A notification to ask the server to exit its process. - abstract member Exit : unit -> Async - default __.Exit() = ignoreNotification - - /// The hover request is sent from the client to the server to request hover information at a given text - /// document position. - abstract member TextDocumentHover: TextDocumentPositionParams -> AsyncLspResult - default __.TextDocumentHover(_) = notImplemented - - /// 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. Open in this sense means it is managed by the client. It doesn't - /// necessarily mean that its content is presented in an editor. An open notification must not be sent - /// more than once without a corresponding close notification send before. This means open and close - /// notification must be balanced and the max open count for a particular textDocument is one. - abstract member TextDocumentDidOpen: DidOpenTextDocumentParams -> Async - default __.TextDocumentDidOpen(_) = ignoreNotification - - /// The document change notification is sent from the client to the server to signal changes to a text document. - abstract member TextDocumentDidChange: DidChangeTextDocumentParams -> Async - default __.TextDocumentDidChange(_) = ignoreNotification - - /// 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 typical 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. The request can delay the computation of the detail and documentation - /// properties. However, properties that are needed for the initial sorting and filtering, like sortText, - /// filterText, insertText, and textEdit must be provided in the textDocument/completion request and must - /// not be changed during resolve. - abstract member TextDocumentCompletion: CompletionParams -> AsyncLspResult - default __.TextDocumentCompletion(_) = notImplemented - - /// The request is sent from the client to the server to resolve additional information for a given - /// completion item. - abstract member CompletionItemResolve: CompletionItem -> AsyncLspResult - default __.CompletionItemResolve(_) = notImplemented - - /// The rename request is sent from the client to the server to perform a workspace-wide rename of a symbol. - abstract member TextDocumentRename: RenameParams -> AsyncLspResult - default __.TextDocumentRename(_) = notImplemented - - /// 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. - abstract member TextDocumentDefinition: TextDocumentPositionParams -> AsyncLspResult - default __.TextDocumentDefinition(_) = notImplemented - - /// 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. - abstract member TextDocumentReferences: ReferenceParams -> AsyncLspResult - default __.TextDocumentReferences(_) = notImplemented - - /// 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 Text as the kind. - abstract member TextDocumentDocumentHighlight: TextDocumentPositionParams -> AsyncLspResult - default __.TextDocumentDocumentHighlight(_) = notImplemented - - /// The document links request is sent from the client to the server to request the location of links - /// in a document. - abstract member TextDocumentDocumentLink: DocumentLinkParams -> AsyncLspResult - default __.TextDocumentDocumentLink(_) = notImplemented - - /// The goto type definition request is sent from the client to the server to resolve the type definition - /// location of a symbol at a given text document position. - abstract member TextDocumentTypeDefinition: TextDocumentPositionParams -> AsyncLspResult - default __.TextDocumentTypeDefinition(_) = notImplemented - - /// The goto implementation request is sent from the client to the server to resolve the implementation - /// location of a symbol at a given text document position. - abstract member TextDocumentImplementation: TextDocumentPositionParams -> AsyncLspResult - default __.TextDocumentImplementation(_) = notImplemented - - /// The code action request is sent from the client to the server to compute 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. - abstract member TextDocumentCodeAction: CodeActionParams -> AsyncLspResult - default __.TextDocumentCodeAction(_) = notImplemented - - /// The code lens request is sent from the client to the server to compute code lenses for a given - /// text document. - abstract member TextDocumentCodeLens: CodeLensParams -> AsyncLspResult - default __.TextDocumentCodeLens(_) = notImplemented - - /// The code lens resolve request is sent from the client to the server to resolve the command for - /// a given code lens item. - abstract member CodeLensResolve: CodeLens -> AsyncLspResult - default __.CodeLensResolve(_) = notImplemented - - /// The signature help request is sent from the client to the server to request signature information at - /// a given cursor position. - abstract member TextDocumentSignatureHelp: SignatureHelpParams -> AsyncLspResult - default __.TextDocumentSignatureHelp(_) = notImplemented - - /// The document link resolve request is sent from the client to the server to resolve the target of - /// a given document link. - abstract member DocumentLinkResolve: DocumentLink -> AsyncLspResult - default __.DocumentLinkResolve(_) = notImplemented - - /// The document color request is sent from the client to the server to list all color references - /// found in a given text document. Along with the range, a color value in RGB is returned. - abstract member TextDocumentDocumentColor: DocumentColorParams -> AsyncLspResult - default __.TextDocumentDocumentColor(_) = notImplemented - - /// The color presentation request is sent from the client to the server to obtain a list of - /// presentations for a color value at a given location. Clients can use the result to - abstract member TextDocumentColorPresentation: ColorPresentationParams -> AsyncLspResult - default __.TextDocumentColorPresentation(_) = notImplemented - - /// The document formatting request is sent from the client to the server to format a whole document. - abstract member TextDocumentFormatting: DocumentFormattingParams -> AsyncLspResult - default __.TextDocumentFormatting(_) = notImplemented - - /// The document range formatting request is sent from the client to the server to format a given - /// range in a document. - abstract member TextDocumentRangeFormatting: DocumentRangeFormattingParams -> AsyncLspResult - default __.TextDocumentRangeFormatting(_) = notImplemented - - /// The document on type formatting request is sent from the client to the server to format parts - /// of the document during typing. - abstract member TextDocumentOnTypeFormatting: DocumentOnTypeFormattingParams -> AsyncLspResult - default __.TextDocumentOnTypeFormatting(_) = notImplemented - - /// The document symbol request is sent from the client to the server to return a flat list of all symbols - /// found in a given text document. Neither the symbol’s location range nor the symbol’s container name - /// should be used to infer a hierarchy. - abstract member TextDocumentDocumentSymbol: DocumentSymbolParams -> AsyncLspResult - default __.TextDocumentDocumentSymbol(_) = notImplemented - - /// The watched files notification is sent from the client to the server when the client detects changes - /// to files watched by the language client. It is recommended that servers register for these file - /// events using the registration mechanism. In former implementations clients pushed file events without - /// the server actively asking for it. - abstract member WorkspaceDidChangeWatchedFiles: DidChangeWatchedFilesParams -> Async - default __.WorkspaceDidChangeWatchedFiles(_) = ignoreNotification - - /// The `workspace/didChangeWorkspaceFolders` notification is sent from the client to the server to inform - /// the server about workspace folder configuration changes. The notification is sent by default if both - /// *ServerCapabilities/workspace/workspaceFolders* and *ClientCapabilities/workapce/workspaceFolders* are - /// true; or if the server has registered to receive this notification it first. - abstract member WorkspaceDidChangeWorkspaceFolders: DidChangeWorkspaceFoldersParams -> Async - default __.WorkspaceDidChangeWorkspaceFolders(_) = ignoreNotification - - /// A notification sent from the client to the server to signal the change of configuration settings. - abstract member WorkspaceDidChangeConfiguration: DidChangeConfigurationParams -> Async - default __.WorkspaceDidChangeConfiguration(_) = ignoreNotification - - /// The workspace symbol request is sent from the client to the server to list project-wide symbols matching - /// the query string. - abstract member WorkspaceSymbol: WorkspaceSymbolParams -> AsyncLspResult - default __.WorkspaceSymbol(_) = notImplemented - - /// 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. - abstract member WorkspaceExecuteCommand : ExecuteCommandParams -> AsyncLspResult - default __.WorkspaceExecuteCommand(_) = notImplemented - - /// The document will save notification is sent from the client to the server before the document is - /// actually saved. - abstract member TextDocumentWillSave: WillSaveTextDocumentParams -> Async - default __.TextDocumentWillSave(_) = ignoreNotification - - /// 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. - abstract member TextDocumentWillSaveWaitUntil: WillSaveTextDocumentParams -> AsyncLspResult - default __.TextDocumentWillSaveWaitUntil(_) = notImplemented - - /// The document save notification is sent from the client to the server when the document was saved - /// in the client. - abstract member TextDocumentDidSave: DidSaveTextDocumentParams -> Async - default __.TextDocumentDidSave(_) = ignoreNotification - - /// 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). As with the open notification the close notification is about - /// managing the document’s content. Receiving a close notification doesn't mean that the document was open in - /// an editor before. A close notification requires a previous open notification to be sent. - abstract member TextDocumentDidClose: DidCloseTextDocumentParams -> Async - default __.TextDocumentDidClose(_) = ignoreNotification - - /// The folding range request is sent from the client to the server to return all folding ranges found in a given text document. - abstract member TextDocumentFoldingRange: FoldingRangeParams -> AsyncLspResult - default __.TextDocumentFoldingRange(_) = notImplemented - - /// The selection range request is sent from the client to the server to return suggested selection ranges at an array of given positions. - /// A selection range is a range around the cursor position which the user might be interested in selecting. - abstract member TextDocumentSelectionRange: SelectionRangeParams -> AsyncLspResult - default __.TextDocumentSelectionRange(_) = notImplemented - - abstract member TextDocumentSemanticTokensFull: SemanticTokensParams -> AsyncLspResult - default __.TextDocumentSemanticTokensFull(_) = notImplemented - - abstract member TextDocumentSemanticTokensFullDelta: SemanticTokensDeltaParams -> AsyncLspResult option> - default __.TextDocumentSemanticTokensFullDelta(_) = notImplemented - - abstract member TextDocumentSemanticTokensRange: SemanticTokensRangeParams -> AsyncLspResult - default __.TextDocumentSemanticTokensRange(_) = notImplemented - -module Server = - open System.IO - open FsAutoComplete.Logging - open Newtonsoft.Json - open Newtonsoft.Json.Serialization - - open JsonRpc - - let logger = LogProvider.getLoggerByName "LSP Server" - - let jsonSettings = - let result = JsonSerializerSettings(NullValueHandling = NullValueHandling.Ignore) - result.Converters.Add(SingleCaseUnionConverter()) - result.Converters.Add(U2BoolObjectConverter()) - result.Converters.Add(OptionConverter()) - result.Converters.Add(ErasedUnionConverter()) - result.ContractResolver <- CamelCasePropertyNamesContractResolver() - result - - let jsonSerializer = JsonSerializer.Create(jsonSettings) - - type RequestHandling<'server when 'server :> LspServer> = { - Run: 'server -> JToken option -> AsyncLspResult - } - - let deserialize<'t> (token: JToken) = token.ToObject<'t>(jsonSerializer) - - let serialize<'t> (o: 't) = JToken.FromObject(o, jsonSerializer) - - let requestHandling<'param, 'result, 'server when 'server :> LspServer> (run: 'server -> 'param -> AsyncLspResult<'result>): RequestHandling<'server> = - let tokenRun (lspServer: 'server) (paramsToken: JToken option): AsyncLspResult = - try - let p = - match paramsToken with - | Some paramsToken -> - let typedParams = paramsToken.ToObject<'param>(jsonSerializer) - Some typedParams - | None -> - if typeof<'param> = typeof then - Some (unbox ()) - else - None - match p with - | Some p -> - async { - try - let! result = run lspServer p - match result with - | Result.Ok ok -> - if isNull (box ok) then - return Result.Ok None - else - let resultToken = JToken.FromObject(ok, jsonSerializer) - return Result.Ok (Some resultToken) - | Result.Error err -> - return Result.Error err - with - | ex -> - return Result.Error (Error.Create(ErrorCodes.internalError, ex.ToString())) - } - | None -> - async.Return (Result.Error (Error.Create(ErrorCodes.invalidRequest, "No params found"))) - with - | :? JsonException as ex -> - async.Return (Result.Error (Error.Create(ErrorCodes.parseError, ex.ToString()))) - - { Run = tokenRun } - - /// Notifications don't generate a response or error, but to unify things we consider them as always successful. - /// They will still not send any response because their ID is null. - let private notificationSuccess (response: Async) = async { - do! response - return Result.Ok () - } - - let defaultRequestHandlings<'server when 'server :> LspServer> () : Map> = - [ - "initialize", requestHandling (fun s p -> s.Initialize(p)) - "initialized", requestHandling (fun s p -> s.Initialized(p) |> notificationSuccess) - "textDocument/hover", requestHandling (fun s p -> s.TextDocumentHover(p)) - "textDocument/didOpen", requestHandling (fun s p -> s.TextDocumentDidOpen(p) |> notificationSuccess) - "textDocument/didChange", requestHandling (fun s p -> s.TextDocumentDidChange(p) |> notificationSuccess) - "textDocument/completion", requestHandling (fun s p -> s.TextDocumentCompletion(p)) - "completionItem/resolve", requestHandling (fun s p -> s.CompletionItemResolve(p)) - "textDocument/rename", requestHandling (fun s p -> s.TextDocumentRename(p)) - "textDocument/definition", requestHandling (fun s p -> s.TextDocumentDefinition(p)) - "textDocument/typeDefinition", requestHandling (fun s p -> s.TextDocumentTypeDefinition(p)) - "textDocument/implementation", requestHandling (fun s p -> s.TextDocumentImplementation(p)) - "textDocument/codeAction", requestHandling (fun s p -> s.TextDocumentCodeAction(p)) - "textDocument/codeLens", requestHandling (fun s p -> s.TextDocumentCodeLens(p)) - "codeLens/resolve", requestHandling (fun s p -> s.CodeLensResolve(p)) - "textDocument/references", requestHandling (fun s p -> s.TextDocumentReferences(p)) - "textDocument/documentHighlight", requestHandling (fun s p -> s.TextDocumentDocumentHighlight(p)) - "textDocument/documentLink", requestHandling (fun s p -> s.TextDocumentDocumentLink(p)) - "textDocument/signatureHelp", requestHandling (fun s p -> s.TextDocumentSignatureHelp(p)) - "documentLink/resolve", requestHandling (fun s p -> s.DocumentLinkResolve(p)) - "textDocument/documentColor", requestHandling (fun s p -> s.TextDocumentDocumentColor(p)) - "textDocument/colorPresentation", requestHandling (fun s p -> s.TextDocumentColorPresentation(p)) - "textDocument/formatting", requestHandling (fun s p -> s.TextDocumentFormatting(p)) - "textDocument/rangeFormatting", requestHandling (fun s p -> s.TextDocumentRangeFormatting(p)) - "textDocument/onTypeFormatting", requestHandling (fun s p -> s.TextDocumentOnTypeFormatting(p)) - "textDocument/willSave", requestHandling (fun s p -> s.TextDocumentWillSave(p) |> notificationSuccess) - "textDocument/willSaveWaitUntil", requestHandling (fun s p -> s.TextDocumentWillSaveWaitUntil(p)) - "textDocument/didSave", requestHandling (fun s p -> s.TextDocumentDidSave(p) |> notificationSuccess) - "textDocument/didClose", requestHandling (fun s p -> s.TextDocumentDidClose(p) |> notificationSuccess) - "textDocument/documentSymbol", requestHandling (fun s p -> s.TextDocumentDocumentSymbol(p)) - "textDocument/foldingRange", requestHandling (fun s p -> s.TextDocumentFoldingRange(p)) - "textDocument/selectionRange", requestHandling (fun s p -> s.TextDocumentSelectionRange(p)) - "textDocument/semanticTokens/full", requestHandling(fun s p -> s.TextDocumentSemanticTokensFull(p)) - "textDocument/semanticTokens/full/delta", requestHandling(fun s p -> s.TextDocumentSemanticTokensFullDelta(p)) - "textDocument/semanticTokens/range", requestHandling(fun s p -> s.TextDocumentSemanticTokensRange(p)) - "workspace/didChangeWatchedFiles", requestHandling (fun s p -> s.WorkspaceDidChangeWatchedFiles(p) |> notificationSuccess) - "workspace/didChangeWorkspaceFolders", requestHandling (fun s p -> s.WorkspaceDidChangeWorkspaceFolders (p) |> notificationSuccess) - "workspace/didChangeConfiguration", requestHandling (fun s p -> s.WorkspaceDidChangeConfiguration (p) |> notificationSuccess) - "workspace/symbol", requestHandling (fun s p -> s.WorkspaceSymbol (p)) - "workspace/executeCommand ", requestHandling (fun s p -> s.WorkspaceExecuteCommand (p)) - "shutdown", requestHandling (fun s () -> s.Shutdown() |> notificationSuccess) - "exit", requestHandling (fun s () -> s.Exit() |> notificationSuccess) - ] - |> Map.ofList - - let handleRequest<'server when 'server :> LspServer> (requestHandlings : Map>) (request: JsonRpc.Request) (lspServer: 'server): Async = - async { - let mutable methodCallResult = Result.Error (Error.MethodNotFound) - match requestHandlings |> Map.tryFind request.Method with - | Some handling -> - try - let! result = handling.Run lspServer request.Params - methodCallResult <- result - with - | ex -> - methodCallResult <- Result.Error (Error.Create(ErrorCodes.internalError, ex.ToString())) - | None -> () - match methodCallResult with - | Result.Ok ok -> - return Some (JsonRpc.Response.Success(request.Id, ok)) - | Result.Error err -> - return Some (JsonRpc.Response.Failure(request.Id, err)) - } - - let handleNotification<'server when 'server :> LspServer> (requestHandlings : Map>) (notification: JsonRpc.Notification) (lspServer: 'server): Async> = - async { - let mutable methodCallResult = Result.Error (Error.MethodNotFound) - match requestHandlings |> Map.tryFind notification.Method with - | Some handling -> - try - let! _ = handling.Run lspServer notification.Params - methodCallResult <- Result.Ok () - with - | ex -> - methodCallResult <- Result.Error (Error.Create(ErrorCodes.internalError, ex.ToString())) - | None -> () - return methodCallResult - } - - type ClientNotificationSender = string -> obj -> AsyncLspResult - - type ClientRequestSender = - abstract member Send<'a> : string -> obj -> AsyncLspResult<'a> - - type private MessageHandlingResult = - | Normal - | WasExit - | WasShutdown - - type LspCloseReason = - | RequestedByClient = 0 - | ErrorExitWithoutShutdown = 1 - | ErrorStreamClosed = 2 - - type ResponseMailboxMsg = - | Request of int * AsyncReplyChannel - | Response of int option * Response - - let getNextRequestId = - let mutable counter = 0 - fun () -> - counter <- counter + 1 - counter - - let start<'a, 'b when 'a :> LspClient and 'b :> LspServer> (requestHandlings : Map>) (input: Stream) (output: Stream) (clientCreator: (ClientNotificationSender * ClientRequestSender) -> 'a) (serverCreator: 'a -> 'b) = - let sender = MailboxProcessor.Start(fun inbox -> - let rec loop () = async { - let! str = inbox.Receive() - LowLevel.write output str - // do! Async.Sleep 1000 - return! loop () - } - loop ()) - - let responseAgent = MailboxProcessor.Start(fun agent -> - let rec loop state = - async{ - let! msg = agent.Receive() - match msg with - | Request (rid, reply) -> - return! loop (state |> Map.add rid reply) - | Response (Some rid, value) -> - let result = state |> Map.tryFind rid - match result with - |Some(reply) -> - reply.Reply(value.Result) - |None -> - logger.warn (Log.setMessage "ResponseAgent - Unexpected response (id {rid}) {response}" >> Log.addContextDestructured "response" value >> Log.addContext "rid" rid) - return! loop (state |> Map.remove rid) - | Response (None, response) -> - logger.error (Log.setMessage "ResponseAgent - Client reports we sent a corrupt request id, error: {error}" >> Log.addContextDestructured "error" (response.Error)) - return! loop state - } - loop Map.empty) - - - /// When the server wants to send a notification to the client - let sendServerNotification (rpcMethod: string) (notificationObj: obj): AsyncLspResult = - let serializedNotification = JToken.FromObject(notificationObj, jsonSerializer) - let notification = JsonRpc.Notification.Create(rpcMethod, Some serializedNotification) - let notString = JsonConvert.SerializeObject(notification, jsonSettings) - sender.Post(notString) - async.Return (LspResult.Ok ()) - - /// When the server wants to send a request to the client - let sendServerRequest (rpcMethod: string) (requestObj: obj): AsyncLspResult<'response> = - async { - let serializedRequest = - if isNull requestObj then - None - else - Some (JToken.FromObject(requestObj, jsonSerializer)) - let req = JsonRpc.Request.Create(getNextRequestId(), rpcMethod, serializedRequest) - let reqString = JsonConvert.SerializeObject(req, jsonSettings) - sender.Post(reqString) - let! response = responseAgent.PostAndAsyncReply((fun replyChannel -> Request(req.Id, replyChannel))) - try - match response with - | Some responseToken -> - let typedResponse = responseToken.ToObject<'response>(jsonSerializer) - return (LspResult.Ok typedResponse) - | None -> - if typeof<'response> = typeof then - return (LspResult.Ok (unbox ())) - else - logger.error (Log.setMessage "ResponseHandling - Invalid response type for response {response}, expected {expectedType}, got unit" >> Log.addContextDestructured "response" response >> Log.addContext "expectedType" (typeof<'response>).Name) - return (LspResult.invalidParams (sprintf "Response params expected for %i but missing" req.Id)) - with - | :? JsonException as ex -> - logger.error (Log.setMessage "ResponseHandling - Parsing failed for response {response}" >> Log.addContextDestructured "response" response >> Log.addExn ex) - return (LspResult.invalidParams (sprintf "Response params invalid for %i" req.Id)) - } - - let lspClient = clientCreator (sendServerNotification, { new ClientRequestSender with member __.Send x t = sendServerRequest x t}) - use lspServer = serverCreator lspClient - - let handleClientMessage (messageString: string): MessageHandlingResult = - let messageTypeTest = JsonConvert.DeserializeObject(messageString, jsonSettings) - match getMessageType messageTypeTest with - | MessageType.Response -> - let response = JsonConvert.DeserializeObject(messageString, jsonSettings) - responseAgent.Post(Response(response.Id, response)) - MessageHandlingResult.Normal - | MessageType.Notification -> - let notification = JsonConvert.DeserializeObject(messageString, jsonSettings) - async { - let! result = handleNotification requestHandlings notification lspServer - match result with - | Result.Ok _ -> () - | Result.Error ( { Code = code }) when code = JsonRpc.Error.MethodNotFound.Code -> - logger.trace (Log.setMessage "don't know how to handle method {messageType}" >> Log.addContext "messageType" notification.Method) - | Result.Error (error) -> - logger.error (Log.setMessage "HandleClientMessage - Error {error} when handling notification {notification}" >> Log.addContext "error" error >> Log.addContextDestructured "notification" notification) - //TODO: Handle error on receiving notification, send message to user? - () - } - |> Async.StartAsTask - |> ignore - - match notification.Method with - | "exit" -> MessageHandlingResult.WasExit - | _ -> MessageHandlingResult.Normal - | MessageType.Request -> - let request = JsonConvert.DeserializeObject(messageString, jsonSettings) - async { - let! result = handleRequest requestHandlings request lspServer - match result with - | Some response -> - let responseString = JsonConvert.SerializeObject(response, jsonSettings) - sender.Post(responseString) - | None -> () - } - |> Async.StartAsTask - |> ignore - - match request.Method with - | "shutdown" -> MessageHandlingResult.WasShutdown - | _ -> MessageHandlingResult.Normal - | MessageType.Error -> - logger.error (Log.setMessage "HandleClientMessage - Message had invalid jsonrpc version: {messageTypeTest}" >> Log.addContextDestructured "messageTypeTest" messageTypeTest) - MessageHandlingResult.Normal - - let mutable shutdownReceived = false - let mutable quitReceived = false - let mutable quit = false - while not quit do - try - let _, requestString = LowLevel.read input - - match handleClientMessage requestString with - | MessageHandlingResult.WasShutdown -> shutdownReceived <- true - | MessageHandlingResult.WasExit -> - quitReceived <- true - quit <- true - | MessageHandlingResult.Normal -> () - with - | :? EndOfStreamException -> - quit <- true - | ex -> - () - - match shutdownReceived, quitReceived with - | true, true -> LspCloseReason.RequestedByClient - | false, true -> LspCloseReason.ErrorExitWithoutShutdown - | _ -> LspCloseReason.ErrorStreamClosed - -module Client = - open System - open System.IO - open FsAutoComplete.Logging - open Newtonsoft.Json - open Newtonsoft.Json.Serialization - - open JsonRpc - - let logger = LogProvider.getLoggerByName "LSP Client" - - let internal jsonSettings = - let result = JsonSerializerSettings(NullValueHandling = NullValueHandling.Ignore) - result.Converters.Add(OptionConverter()) - result.Converters.Add(ErasedUnionConverter()) - result.ContractResolver <- CamelCasePropertyNamesContractResolver() - result - - let internal jsonSerializer = JsonSerializer.Create(jsonSettings) - - let internal deserialize (token: JToken) = token.ToObject<'t>(jsonSerializer) - - let internal serialize (o: 't) = JToken.FromObject(o, jsonSerializer) - - type NotificationHandler = { - Run: JToken -> Async - } - - let notificationHandling<'p, 'r> (handler: 'p -> Async<'r option>) : NotificationHandler = - let run (token: JToken) = - async { - try - let p = token.ToObject<'p>(jsonSerializer) - let! res = handler p - return res |> Option.map (fun n -> JToken.FromObject(n, jsonSerializer)) - with - | _ -> return None - } - {Run = run} - - type Client(exec: string, args: string, notificationHandlings: Map) = - - let mutable outuptStream : StreamReader option = None - let mutable inputStream : StreamWriter option = None - - let sender = MailboxProcessor.Start(fun inbox -> - let rec loop () = async { - let! str = inbox.Receive() - inputStream |> Option.iter (fun input -> - // fprintfn stderr "[CLIENT] Writing: %s" str - LowLevel.write input.BaseStream str - input.BaseStream.Flush() - ) - // do! Async.Sleep 1000 - return! loop () - } - loop ()) - - let handleRequest (request: JsonRpc.Request) = - async { - let mutable methodCallResult = None - match notificationHandlings |> Map.tryFind request.Method with - | Some handling -> - try - match request.Params with - | None -> () - | Some prms -> - let! result = handling.Run prms - methodCallResult <- result - with - | ex -> - methodCallResult <- None - | None -> () - - match methodCallResult with - | Some ok -> - return Some (JsonRpc.Response.Success(request.Id, Some ok)) - | None -> - return None - } - - let handleNotification (notification: JsonRpc.Notification) = - async { - match notificationHandlings |> Map.tryFind notification.Method with - | Some handling -> - try - match notification.Params with - | None -> return Result.Error (Error.InvalidParams) - | Some prms -> - let! result = handling.Run prms - return Result.Ok () - with - | ex -> - return Result.Error (Error.Create(ErrorCodes.internalError, ex.ToString())) - | None -> - return Result.Error (Error.MethodNotFound) - } - - let messageHanlder str = - let messageTypeTest = JsonConvert.DeserializeObject(str, jsonSettings) - match getMessageType messageTypeTest with - | MessageType.Notification -> - let notification = JsonConvert.DeserializeObject(str, jsonSettings) - async { - let! result = handleNotification notification - match result with - | Result.Ok _ -> () - | Result.Error error -> - logger.error (Log.setMessage "HandleServerMessage - Error {error} when handling notification {notification}" >> Log.addContextDestructured "error" error >> Log.addContextDestructured "notification" notification) - //TODO: Handle error on receiving notification, send message to user? - () - } - |> Async.StartAsTask - |> ignore - | MessageType.Request -> - let request = JsonConvert.DeserializeObject(str, jsonSettings) - async { - let! result = handleRequest request - match result with - | Some response -> - let responseString = JsonConvert.SerializeObject(response, jsonSettings) - sender.Post(responseString) - | None -> () - } - |> Async.StartAsTask - |> ignore - | MessageType.Response - | MessageType.Error -> - logger.error (Log.setMessage "HandleServerMessage - Message had invalid jsonrpc version: {messageTypeTest}" >> Log.addContextDestructured "messageTypeTest" messageTypeTest) - () - - let request = JsonConvert.DeserializeObject(str, jsonSettings) - async { - let! result = handleRequest request - match result with - | Some response -> - let responseString = JsonConvert.SerializeObject(response, jsonSettings) - sender.Post(responseString) - | None -> () - } - |> Async.StartAsTask - |> ignore - - member __.SendNotification (rpcMethod: string) (requestObj: obj) = - let serializedResponse = JToken.FromObject(requestObj, jsonSerializer) - let notification = JsonRpc.Notification.Create(rpcMethod, Some serializedResponse) - let notString = JsonConvert.SerializeObject(notification, jsonSettings) - sender.Post(notString) - - member __.Start() = - async { - let si = ProcessStartInfo() - si.RedirectStandardOutput <- true - si.RedirectStandardInput <- true - si.RedirectStandardError <- true - si.UseShellExecute <- false - si.WorkingDirectory <- Environment.CurrentDirectory - si.FileName <- exec - si.Arguments <- args - let proc = - try - Process.Start(si) - with ex -> - let newEx = System.Exception(sprintf "%s on %s" ex.Message exec, ex) - raise newEx - - inputStream <- Some (proc.StandardInput) - outuptStream <- Some (proc.StandardOutput) - - let mutable quit = false - let outStream = proc.StandardOutput.BaseStream - while not quit do - try - let _, notificationString = LowLevel.read outStream - // fprintfn stderr "[CLIENT] READING: %s" notificationString - messageHanlder notificationString - with - | :? EndOfStreamException -> - quit <- true - | ex -> - () - - return () - } |> Async.Start diff --git a/src/LanguageServerProtocol/LanguageServerProtocol.fsproj b/src/LanguageServerProtocol/LanguageServerProtocol.fsproj deleted file mode 100644 index 1b8206270..000000000 --- a/src/LanguageServerProtocol/LanguageServerProtocol.fsproj +++ /dev/null @@ -1,16 +0,0 @@ - - - - netstandard2.0 - false - - - - - - - - - - - diff --git a/src/LanguageServerProtocol/paket.references b/src/LanguageServerProtocol/paket.references deleted file mode 100644 index 00d3ab538..000000000 --- a/src/LanguageServerProtocol/paket.references +++ /dev/null @@ -1,5 +0,0 @@ -Newtonsoft.Json -FSharp.Core -Microsoft.SourceLink.GitHub - -Microsoft.NETFramework.ReferenceAssemblies diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests.fs index f9cb7dd72..6d4fcd195 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests.fs @@ -3,7 +3,7 @@ module FsAutoComplete.Tests.CodeFixTests open Expecto open System.IO open Helpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.Utils let pos (line, character) = { Line = line; Character = character } @@ -13,7 +13,7 @@ let (|Refactor|_|) title newText action = match action with | { Title = title' Kind = Some "refactor" - Edit = { DocumentChanges = Some [| + Edit = Some { DocumentChanges = Some [| { Edits = [| { NewText = newText' } |] } |] } } @@ -22,7 +22,7 @@ let (|Refactor|_|) title newText action = let (|AtRange|_|) range (action: CodeAction) = match action with - | { Edit = { DocumentChanges = Some [| + | { Edit = Some { DocumentChanges = Some [| { Edits = [| { Range = range' } |] } |] } } when range = range' -> Some () | _ -> None @@ -124,7 +124,7 @@ let missingFunKeywordTests state = match response with | Ok (Some (TextDocumentCodeActionResult.CodeActions [| { Title = "Add missing 'fun' keyword" Kind = Some "quickfix" - Edit = { DocumentChanges = Some [| { Edits = [| { NewText = "fun " } |] } |] } } |] )) -> () + Edit = Some { DocumentChanges = Some [| { Edits = [| { NewText = "fun " } |] } |] } } |] )) -> () | Ok other -> failtestf $"Should have generated missing fun keyword, but instead generated %A{other}" | Error reason -> failtestf $"Should have succeeded, but failed with %A{reason}" }) @@ -155,7 +155,7 @@ let outerBindingRecursiveTests state = match response with | Ok (Some (TextDocumentCodeActionResult.CodeActions [| { Title = "Make outer binding recursive" Kind = Some "quickfix" - Edit = { DocumentChanges = Some [| { Edits = [| { NewText = "rec " } |] } |] } } |] )) -> () + Edit = Some { DocumentChanges = Some [| { Edits = [| { NewText = "rec " } |] } |] } } |] )) -> () | Ok other -> failtestf $"Should have generated a rec keyword, but instead generated %A{other}" | Error reason -> failtestf $"Should have succeeded, but failed with %A{reason}" }) @@ -184,7 +184,7 @@ let nameofInsteadOfTypeofNameTests state = match response with | Ok (Some (TextDocumentCodeActionResult.CodeActions [| { Title = "Use 'nameof'" Kind = Some "refactor" - Edit = { DocumentChanges = Some [| { Edits = [| { NewText = "nameof(Async)" } |] } |] } } |] )) -> () + Edit = Some { DocumentChanges = Some [| { Edits = [| { NewText = "nameof(Async)" } |] } |] } } |] )) -> () | Ok other -> failtestf $"Should have generated nameof, but instead generated %A{other}" | Error reason -> failtestf $"Should have succeeded, but failed with %A{reason}" }) @@ -217,7 +217,7 @@ let missingInstanceMemberTests state = Some ( TextDocumentCodeActionResult.CodeActions [| { Title = "Add missing instance member parameter" Kind = Some "quickfix" - Edit = { + Edit = Some { DocumentChanges = Some [| { Edits = [| { NewText = "x." } |] } |] } } |] )) -> () diff --git a/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs b/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs index 89cfd963e..b6a7be8c0 100644 --- a/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CompletionTests.fs @@ -3,7 +3,7 @@ module FsAutoComplete.Tests.Completion open Expecto open System.IO open Helpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.Utils open FsAutoComplete.Lsp @@ -238,7 +238,7 @@ let autoOpenTests state = | Ok None -> return failtest "Quick fix Request none" | Ok (Some (TextDocumentCodeActionResult.CodeActions (ContainsOpenAction quickfix))) -> let ns = quickfix.Title.Substring ("open ".Length) - let edit = quickfix.Edit.DocumentChanges.Value.[0].Edits.[0] + let edit = quickfix.Edit.Value.DocumentChanges.Value.[0].Edits.[0] let openPos = calcOpenPos edit return (edit, ns, openPos) | Ok _ -> return failtest $"Quick fix on `{word}` doesn't contain open action" diff --git a/test/FsAutoComplete.Tests.Lsp/CoreTests.fs b/test/FsAutoComplete.Tests.Lsp/CoreTests.fs index bc41d65bd..628c53ffa 100644 --- a/test/FsAutoComplete.Tests.Lsp/CoreTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CoreTests.fs @@ -3,8 +3,8 @@ module FsAutoComplete.Tests.CoreTest open System open Expecto open System.IO -open LanguageServerProtocol -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open Helpers @@ -26,7 +26,7 @@ let initTests state = let! result = server.Initialize p match result with | Result.Ok res -> - Expect.equal res.Capabilities.CodeActionProvider (Some true) "Code Action Provider" + Expect.equal res.Capabilities.CodeActionProvider (Some {CodeActionOptions.ResolveProvider = None; CodeActionOptions.CodeActionKinds = None}) "Code Action Provider" Expect.equal res.Capabilities.CodeLensProvider (Some {CodeLensOptions.ResolveProvider = Some true}) "Code Lens Provider" Expect.equal res.Capabilities.DefinitionProvider (Some true) "Definition Provider" Expect.equal res.Capabilities.DocumentFormattingProvider (Some true) "Document Formatting Provider" diff --git a/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs b/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs index 78e177b37..b4db3c204 100644 --- a/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/ExtensionsTests.fs @@ -3,7 +3,7 @@ module FsAutoComplete.Tests.ExtensionsTests open System open Expecto open System.IO -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open Helpers diff --git a/test/FsAutoComplete.Tests.Lsp/FindReferencesTests.fs b/test/FsAutoComplete.Tests.Lsp/FindReferencesTests.fs index cfa18fc18..4acfa70e7 100644 --- a/test/FsAutoComplete.Tests.Lsp/FindReferencesTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/FindReferencesTests.fs @@ -4,7 +4,7 @@ open Expecto open System.IO open FsAutoComplete open Helpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types let tests state = testList diff --git a/test/FsAutoComplete.Tests.Lsp/GoToTests.fs b/test/FsAutoComplete.Tests.Lsp/GoToTests.fs index eff5d1a54..c64734c56 100644 --- a/test/FsAutoComplete.Tests.Lsp/GoToTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/GoToTests.fs @@ -4,7 +4,7 @@ module FsAutoComplete.Tests.GoTo open Expecto open System.IO open Helpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsToolkit.ErrorHandling open FsAutoComplete diff --git a/test/FsAutoComplete.Tests.Lsp/Helpers.fs b/test/FsAutoComplete.Tests.Lsp/Helpers.fs index 453223f81..d2e9dfc4b 100644 --- a/test/FsAutoComplete.Tests.Lsp/Helpers.fs +++ b/test/FsAutoComplete.Tests.Lsp/Helpers.fs @@ -4,8 +4,8 @@ open System open Expecto open System.IO open FsAutoComplete.Lsp -open LanguageServerProtocol -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open FSharp.Control.Reactive @@ -116,7 +116,7 @@ type ClientEvents = IObservable let createServer (state: State) = let event = new System.Reactive.Subjects.ReplaySubject<_>() - let client = FSharpLspClient ((fun name o -> event.OnNext (name ,o); AsyncLspResult.success ()), { new LanguageServerProtocol.Server.ClientRequestSender with member __.Send _ _ = AsyncLspResult.notImplemented}) + let client = FSharpLspClient ((fun name o -> event.OnNext (name ,o); AsyncLspResult.success ()), { new Ionide.LanguageServerProtocol.Server.ClientRequestSender with member __.Send _ _ = AsyncLspResult.notImplemented}) let originalFs = FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem let fs = FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem <- fs @@ -234,6 +234,17 @@ let clientCaps : ClientCapabilities = MultilineTokenSupport = None } + let codeActionCaps = + { + DynamicRegistration = Some true + CodeActionLiteralSupport = None + IsPreferredSupport = None + DisabledSupport = None + DataSupport = None + ResolveSupport = None + HonorsChangeAnnotations = None + } + { Synchronization = Some syncCaps PublishDiagnostics = diagCaps Completion = Some compCaps @@ -246,7 +257,7 @@ let clientCaps : ClientCapabilities = RangeFormatting = Some dynCaps OnTypeFormatting = Some dynCaps Definition = Some dynCaps - CodeAction = Some dynCaps + CodeAction = Some codeActionCaps CodeLens = Some dynCaps DocumentLink = Some dynCaps Rename = Some dynCaps @@ -387,11 +398,11 @@ let private payloadAs<'t> = Observable.map (fun (_typ, o) -> unbox<'t> o) let private getDiagnosticsEvents: IObservable -> IObservable<_> = - typedEvents "textDocument/publishDiagnostics" + typedEvents "textDocument/publishDiagnostics" /// note that the files here are intended to be the filename only., not the full URI. let private matchFiles (files: string Set) = - Observable.choose (fun (p: LanguageServerProtocol.Types.PublishDiagnosticsParams) -> + Observable.choose (fun (p: Ionide.LanguageServerProtocol.Types.PublishDiagnosticsParams) -> let filename = p.Uri.Split([| '/'; '\\' |], StringSplitOptions.RemoveEmptyEntries) |> Array.last if Set.contains filename files then Some (filename, p) @@ -448,7 +459,7 @@ let waitForCompilerDiagnosticsForFile file = let waitForParsedScript (event: ClientEvents) = event - |> typedEvents "textDocument/publishDiagnostics" + |> typedEvents "textDocument/publishDiagnostics" |> Observable.choose (fun n -> let filename = n.Uri.Replace('\\', '/').Split('/') |> Array.last if filename = "Script.fs" then Some n else None diff --git a/test/FsAutoComplete.Tests.Lsp/HighlightingTests.fs b/test/FsAutoComplete.Tests.Lsp/HighlightingTests.fs index d944f0512..169a9ed5b 100644 --- a/test/FsAutoComplete.Tests.Lsp/HighlightingTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/HighlightingTests.fs @@ -4,7 +4,7 @@ open System.IO open Expecto open Helpers open FsAutoComplete.LspHelpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsAutoComplete.Utils let tests state = diff --git a/test/FsAutoComplete.Tests.Lsp/RenameTests.fs b/test/FsAutoComplete.Tests.Lsp/RenameTests.fs index f97769d0a..69cc59bd1 100644 --- a/test/FsAutoComplete.Tests.Lsp/RenameTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/RenameTests.fs @@ -2,7 +2,7 @@ module FsAutoComplete.Tests.Rename open System.IO open Helpers open Expecto.Tests -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsToolkit.ErrorHandling open Expecto open FsAutoComplete.Utils diff --git a/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs b/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs index 6ddc11f01..eab48521a 100644 --- a/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs @@ -2,8 +2,8 @@ module FsAutoComplete.Tests.ScriptTest open Expecto open System.IO -open LanguageServerProtocol -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol +open Ionide.LanguageServerProtocol.Types open FsAutoComplete open FsAutoComplete.LspHelpers open Helpers diff --git a/test/FsAutoComplete.Tests.Lsp/SignatureHelpTests.fs b/test/FsAutoComplete.Tests.Lsp/SignatureHelpTests.fs index 646dbb1f8..daabd64d9 100644 --- a/test/FsAutoComplete.Tests.Lsp/SignatureHelpTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/SignatureHelpTests.fs @@ -3,7 +3,7 @@ module FsAutoComplete.Tests.SignatureHelp open Expecto open System.IO open Helpers -open LanguageServerProtocol.Types +open Ionide.LanguageServerProtocol.Types open FsToolkit.ErrorHandling open FsAutoComplete