Skip to content

Commit 0fc8dbc

Browse files
TheAngryByrdbaronfel
authored andcommitted
Adds Progress/WorkDone types
1 parent a201c71 commit 0fc8dbc

File tree

6 files changed

+218
-40
lines changed

6 files changed

+218
-40
lines changed

src/Client.fs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ type ILspClient =
100100
/// on the client side.
101101
abstract member TextDocumentPublishDiagnostics: PublishDiagnosticsParams -> Async<unit>
102102

103+
/// The window/workDoneProgress/create request is sent from the server to the client to ask the client to create a work done progress.
104+
abstract member WorkDoneProgressCreate: ProgressToken -> AsyncLspResult<unit>
105+
106+
/// The base protocol offers also support to report progress in a generic fashion.
107+
/// This mechanism can be used to report any kind of progress including work done progress
108+
/// (usually used to report progress in the user interface using a progress bar) and
109+
/// partial result progress to support streaming of results.
110+
abstract member Progress: ProgressToken * 'Progress -> Async<unit>
111+
103112
[<AbstractClass>]
104113
type LspClient() =
105114

@@ -208,6 +217,14 @@ type LspClient() =
208217

209218
default __.TextDocumentPublishDiagnostics(_) = ignoreNotification
210219

220+
abstract member Progress: ProgressToken * 'Progress -> Async<unit>
221+
222+
default __.Progress(_, _) = ignoreNotification
223+
224+
/// The window/workDoneProgress/create request is sent from the server to the client to ask the client to create a work done progress.
225+
abstract member WorkDoneProgressCreate: ProgressToken -> AsyncLspResult<unit>
226+
default __.WorkDoneProgressCreate(_) = notImplemented
227+
211228
interface ILspClient with
212229
member this.WindowShowMessage(p: ShowMessageParams) = this.WindowShowMessage(p)
213230
member this.WindowShowMessageRequest(p: ShowMessageRequestParams) = this.WindowShowMessageRequest(p)
@@ -220,4 +237,6 @@ type LspClient() =
220237
member this.WorkspaceApplyEdit(p: ApplyWorkspaceEditParams) = this.WorkspaceApplyEdit(p)
221238
member this.WorkspaceSemanticTokensRefresh() = this.WorkspaceSemanticTokensRefresh()
222239
member this.WorkspaceInlayHintRefresh() = this.WorkspaceInlayHintRefresh()
223-
member this.TextDocumentPublishDiagnostics(p: PublishDiagnosticsParams) = this.TextDocumentPublishDiagnostics(p)
240+
member this.TextDocumentPublishDiagnostics(p: PublishDiagnosticsParams) = this.TextDocumentPublishDiagnostics(p)
241+
member this.WorkDoneProgressCreate(token: ProgressToken) = this.WorkDoneProgressCreate(token)
242+
member this.Progress(token, data) = this.Progress(token, data)

src/LanguageServerProtocol.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ module Server =
248248
"workspace/didDeleteFiles", requestHandling (fun s p -> s.WorkspaceDidDeleteFiles(p) |> notificationSuccess)
249249
"workspace/symbol", requestHandling (fun s p -> s.WorkspaceSymbol(p))
250250
"workspace/executeCommand", requestHandling (fun s p -> s.WorkspaceExecuteCommand(p))
251+
"window/workDoneProgress/cancel", requestHandling (fun s p -> s.WorkDoneProgessCancel(p) |> notificationSuccess)
251252
"shutdown", requestHandling (fun s () -> s.Shutdown() |> notificationSuccess)
252253
"exit", requestHandling (fun s () -> s.Exit() |> notificationSuccess) ]
253254
|> Map.ofList

src/Server.fs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,12 @@ type ILspServer =
300300
/// then an inlay hint with a label part without a location needs to be resolved using the `inlayHint/resolve` request before it can be used.
301301
abstract member InlayHintResolve: InlayHint -> AsyncLspResult<InlayHint>
302302

303+
/// The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a
304+
/// progress initiated on the server side using the `window/workDoneProgress/create`. The progress need
305+
/// not be marked as cancellable to be cancelled and a client may cancel a progress for any number of
306+
/// reasons: in case of error, reloading a workspace etc.
307+
abstract member WorkDoneProgessCancel: ProgressToken -> Async<unit>
308+
303309
[<AbstractClass>]
304310
type LspServer() =
305311
abstract member Dispose: unit -> unit
@@ -646,6 +652,14 @@ type LspServer() =
646652

647653
default __.InlayHintResolve(_) = notImplemented
648654

655+
/// The `window/workDoneProgress/cancel` notification is sent from the client to the server to cancel a
656+
/// progress initiated on the server side using the `window/workDoneProgress/create`. The progress need
657+
/// not be marked as cancellable to be cancelled and a client may cancel a progress for any number of
658+
/// reasons: in case of error, reloading a workspace etc.
659+
abstract member WorkDoneProgessCancel: ProgressToken -> Async<unit>
660+
661+
default __.WorkDoneProgessCancel(_) = ignoreNotification
662+
649663
interface ILspServer with
650664
member this.Dispose() = this.Dispose()
651665
member this.Initialize(p: InitializeParams) = this.Initialize(p)
@@ -706,4 +720,5 @@ type LspServer() =
706720

707721
member this.TextDocumentSemanticTokensRange(p: SemanticTokensRangeParams) = this.TextDocumentSemanticTokensRange(p)
708722
member this.TextDocumentInlayHint(p: InlayHintParams) = this.TextDocumentInlayHint(p)
709-
member this.InlayHintResolve(p: InlayHint) = this.InlayHintResolve(p)
723+
member this.InlayHintResolve(p: InlayHint) = this.InlayHintResolve(p)
724+
member this.WorkDoneProgessCancel(token) = this.WorkDoneProgessCancel(token)

src/Types.fs

Lines changed: 159 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -333,16 +333,15 @@ type InlayHintWorkspaceClientCapabilities =
333333
/// change that requires such a calculation.
334334
RefreshSupport: bool option }
335335

336-
type CodeLensWorkspaceClientCapabilities = {
337-
/// Whether the client implementation supports a refresh request sent from the
338-
/// server to the client.
339-
///
340-
/// Note that this event is global and will force the client to refresh all
341-
/// code lenses currently shown. It should be used with absolute care and is
342-
/// useful for situation where a server for example detect a project wide
343-
/// change that requires such a calculation.
344-
RefreshSupport: bool option
345-
}
336+
type CodeLensWorkspaceClientCapabilities =
337+
{ /// Whether the client implementation supports a refresh request sent from the
338+
/// server to the client.
339+
///
340+
/// Note that this event is global and will force the client to refresh all
341+
/// code lenses currently shown. It should be used with absolute care and is
342+
/// useful for situation where a server for example detect a project wide
343+
/// change that requires such a calculation.
344+
RefreshSupport: bool option }
346345

347346
/// Workspace specific client capabilities.
348347
type WorkspaceClientCapabilities =
@@ -804,6 +803,48 @@ type TextDocumentClientCapabilities =
804803
/// @since 3.17.0
805804
InlayHint: InlayHintClientCapabilities option }
806805

806+
/// Client capabilities for the showDocument request.
807+
///
808+
/// @since 3.16.0
809+
type ShowDocumentClientCapabilities =
810+
{ /// The client has support for the showDocument request
811+
support: bool }
812+
813+
/// Capabilities specific to the `MessageActionItem` type
814+
type MessageActionItemCapabilties =
815+
{ /// Whether the client supports additional attributes which
816+
/// are preserved and send back to the server in the
817+
/// request's response.
818+
additionalPropertiesSupport: bool option }
819+
820+
/// Show message request client capabilities
821+
type ShowMessageRequestClientCapabilities =
822+
{ /// Capabilities specific to the `MessageActionItem` type
823+
messageActionItem: MessageActionItemCapabilties option }
824+
825+
type WindowClientCapabilities =
826+
{ ///
827+
/// It indicates whether the client supports server initiated
828+
/// progress using the `window/workDoneProgress/create` request.
829+
///
830+
/// The capability also controls Whether client supports handling
831+
/// of progress notifications. If set servers are allowed to report a
832+
/// `workDoneProgress` property in the request specific server
833+
/// capabilities.
834+
///
835+
/// @since 3.15.0
836+
workDoneProgress: bool option
837+
838+
/// Capabilities specific to the showMessage request.
839+
///
840+
/// @since 3.16.0
841+
showMessage: ShowMessageRequestClientCapabilities option
842+
843+
/// Capabilities specific to the showDocument request.
844+
///
845+
/// @since 3.16.0
846+
showDocument: ShowDocumentClientCapabilities option }
847+
807848
type ClientCapabilities =
808849
{ /// Workspace specific client capabilities.
809850
Workspace: WorkspaceClientCapabilities option
@@ -812,7 +853,10 @@ type ClientCapabilities =
812853
TextDocument: TextDocumentClientCapabilities option
813854

814855
/// Experimental client capabilities.
815-
Experimental: JToken option }
856+
Experimental: JToken option
857+
858+
/// Window specific client capabilities.
859+
Window: WindowClientCapabilities option }
816860

817861
type WorkspaceFolder =
818862
{ /// The associated URI for this workspace folder.
@@ -1942,11 +1986,11 @@ type ColorPresentation =
19421986
type CodeActionKind = string
19431987

19441988
type CodeActionTriggerKind =
1945-
/// Code actions were explicitly requested by the user or by an extension.
1946-
| Invoked = 1
1947-
/// Code actions were requested automatically.
1948-
/// This typically happens when current selection in a file changes, but can also be triggered when file content changes.
1949-
| Automatic = 2
1989+
/// Code actions were explicitly requested by the user or by an extension.
1990+
| Invoked = 1
1991+
/// Code actions were requested automatically.
1992+
/// This typically happens when current selection in a file changes, but can also be triggered when file content changes.
1993+
| Automatic = 2
19501994

19511995
/// Contains additional diagnostic information about the context in which
19521996
/// a code action is run.
@@ -2284,4 +2328,102 @@ type InlayHint =
22842328

22852329
/// A data entry field that is preserved on a inlay hint between
22862330
/// a `textDocument/inlayHint` and a `inlayHint/resolve` request.
2287-
Data: LSPAny option }
2331+
Data: LSPAny option }
2332+
2333+
type ProgressToken = U2<int, string>
2334+
2335+
type WorkDoneProgressCreateParams =
2336+
{ ///The token to be used to report progress.
2337+
token: ProgressToken }
2338+
2339+
/// The base protocol offers also support to report progress in a generic fashion.
2340+
/// This mechanism can be used to report any kind of progress including work done progress
2341+
/// (usually used to report progress in the user interface using a progress bar) and partial
2342+
/// result progress to support streaming of results.
2343+
type ProgressParams<'T> =
2344+
{ /// The progress token provided by the client or server.
2345+
token: ProgressToken
2346+
/// The progress data.
2347+
value: 'T }
2348+
2349+
type WorkDoneProgressKind =
2350+
| Begin
2351+
| Report
2352+
| End
2353+
override x.ToString() =
2354+
match x with
2355+
| Begin -> "begin"
2356+
| Report -> "report"
2357+
| End -> "end"
2358+
2359+
type WorkDoneProgressEnd =
2360+
{ /// WorkDoneProgressKind.End
2361+
kind: string
2362+
/// Optional, a final message indicating to for example indicate the outcome of the operation.
2363+
message: string option }
2364+
static member Create(?message) = { kind = WorkDoneProgressKind.End.ToString(); message = message }
2365+
2366+
type WorkDoneProgressBegin =
2367+
{ /// WorkDoneProgressKind.Begin
2368+
kind: string
2369+
2370+
/// Mandatory title of the progress operation. Used to briefly inform about
2371+
/// the kind of operation being performed.
2372+
///
2373+
/// Examples: "Indexing" or "Linking dependencies".
2374+
title: string option
2375+
/// Controls if a cancel button should show to allow the user to cancel the
2376+
/// long running operation. Clients that don't support cancellation are allowed
2377+
/// to ignore the setting.
2378+
cancellable: bool option
2379+
/// Optional, more detailed associated progress message. Contains
2380+
/// complementary information to the `title`.
2381+
///
2382+
/// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
2383+
/// If unset, the previous progress message (if any) is still valid.
2384+
message: string option
2385+
/// Optional progress percentage to display (value 100 is considered 100%).
2386+
/// If not provided infinite progress is assumed and clients are allowed
2387+
/// to ignore the `percentage` value in subsequent in report notifications.
2388+
///
2389+
/// The value should be steadily rising. Clients are free to ignore values
2390+
/// that are not following this rule. The value range is [0, 100].
2391+
percentage: uint option }
2392+
2393+
static member Create(title, ?cancellable, ?message, ?percentage) =
2394+
{ kind = WorkDoneProgressKind.Begin.ToString()
2395+
title = Some title
2396+
cancellable = cancellable
2397+
message = message
2398+
percentage = percentage }
2399+
2400+
type WorkDoneProgressReport =
2401+
{ /// WorkDoneProgressKind.Report
2402+
kind: string
2403+
/// Controls enablement state of a cancel button.
2404+
///
2405+
/// Clients that don't support cancellation or don't support controlling the button's
2406+
/// enablement state are allowed to ignore the property.
2407+
cancellable: bool option
2408+
/// Optional, more detailed associated progress message. Contains
2409+
/// complementary information to the `title`.
2410+
///
2411+
/// Examples: "3/25 files", "project/src/module2", "node_modules/some_dep".
2412+
/// If unset, the previous progress message (if any) is still valid.
2413+
message: string option
2414+
/// Optional progress percentage to display (value 100 is considered 100%).
2415+
/// If not provided infinite progress is assumed and clients are allowed
2416+
/// to ignore the `percentage` value in subsequent in report notifications.
2417+
///
2418+
/// The value should be steadily rising. Clients are free to ignore values
2419+
/// that are not following this rule. The value range is [0, 100].
2420+
percentage: uint option }
2421+
2422+
static member Create(?cancellable, ?message, ?percentage) =
2423+
{ kind = WorkDoneProgressKind.Report.ToString()
2424+
cancellable = cancellable
2425+
message = message
2426+
percentage = percentage }
2427+
2428+
/// The token to be used to report progress.
2429+
type WorkDoneProgressCancelParams = { token: ProgressToken }

tests/Benchmarks.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,8 @@ type MultipleTypesBenchmarks() =
466466
Some
467467
{ DynamicRegistration = Some true
468468
ResolveSupport = Some { Properties = [| "Tooltip"; "Position"; "TextEdits" |] } } }
469-
Experimental = None }
469+
Experimental = None
470+
Window = None }
470471
trace = None
471472
WorkspaceFolders =
472473
Some [| { Uri = "..."; Name = "foo" }

tests/Program.fs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
module Ionide.LanguageServerProtocol.Tests.Root
2-
3-
open Expecto.Tests
4-
5-
[<EntryPoint>]
6-
let main args =
7-
let (|ShouldRunBenchmarks|_|) (args: string []) =
8-
let nArgs = args.Length
9-
let markers = [| "--benchmark"; "--benchmarks"; "-b" |]
10-
11-
let args =
12-
args
13-
|> Array.filter (fun arg -> markers |> Array.contains arg |> not)
14-
15-
if args.Length = nArgs then None else Some args
16-
17-
match args with
18-
| ShouldRunBenchmarks args ->
19-
// `--filter *` to run all
20-
Benchmarks.run args
1+
module Ionide.LanguageServerProtocol.Tests.Root
2+
3+
open Expecto.Tests
4+
5+
[<EntryPoint>]
6+
let main args =
7+
let (|ShouldRunBenchmarks|_|) (args: string []) =
8+
let nArgs = args.Length
9+
let markers = [| "--benchmark"; "--benchmarks"; "-b" |]
10+
11+
let args =
12+
args
13+
|> Array.filter (fun arg -> markers |> Array.contains arg |> not)
14+
15+
if args.Length = nArgs then None else Some args
16+
17+
match args with
18+
| ShouldRunBenchmarks args ->
19+
// `--filter *` to run all
20+
Benchmarks.run args
2121
| _ -> Expecto.Tests.runTestsWithCLIArgs [ Sequenced ] args Tests.tests

0 commit comments

Comments
 (0)