Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,13 @@ type AdaptiveFSharpLspServer
state.ClientCapabilities <- Some p.Capabilities
lspClient.ClientCapabilities <- Some p.Capabilities

// Enable Ionide-specific fsharp/ notifications only when the client sends
// Ionide configuration in InitializationOptions (a reliable Ionide client signal).
// Other LSP clients (Emacs, Helix, etc.) should not receive these notifications
// as they may crash or behave unexpectedly in response.
lspClient.SupportsCustomFSharpNotifications <-
p.InitializationOptions |> Option.exists (fun options -> options.HasValues)

state.DiagnosticCollections.ClientSupportsDiagnostics <-
match p.Capabilities with
| { TextDocument = Some { PublishDiagnostics = Some _ } } -> true
Expand Down
53 changes: 38 additions & 15 deletions src/FsAutoComplete/LspServers/FSharpLspClient.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ type FSharpLspClient(sendServerNotification: ClientNotificationSender, sendServe

member val ClientCapabilities: ClientCapabilities option = None with get, set

/// When true, the client supports Ionide-specific fsharp/ custom notifications.
/// Set to true during Initialize if the client sends Ionide configuration in InitializationOptions.
member val SupportsCustomFSharpNotifications: bool = false with get, set

override __.WindowShowMessage(p) = sendServerNotification "window/showMessage" (box p) |> Async.Ignore

override __.WindowShowMessageRequest(p) = sendServerRequest.Send "window/showMessageRequest" (box p)
Expand All @@ -44,23 +48,42 @@ type FSharpLspClient(sendServerNotification: ClientNotificationSender, sendServe
sendServerNotification "textDocument/publishDiagnostics" (box p) |> Async.Ignore

///Custom notification for workspace/solution/project loading events
member __.NotifyWorkspace(p: PlainNotification) =
sendServerNotification "fsharp/notifyWorkspace" (box p) |> Async.Ignore
member x.NotifyWorkspace(p: PlainNotification) =
if x.SupportsCustomFSharpNotifications then
sendServerNotification "fsharp/notifyWorkspace" (box p) |> Async.Ignore
else
async { return () }

///Custom notification for initial workspace peek
member __.NotifyWorkspacePeek(p: PlainNotification) =
sendServerNotification "fsharp/notifyWorkspacePeek" (box p) |> Async.Ignore

member __.NotifyCancelledRequest(p: PlainNotification) =
sendServerNotification "fsharp/notifyCancel" (box p) |> Async.Ignore

member __.NotifyFileParsed(p: PlainNotification) = sendServerNotification "fsharp/fileParsed" (box p) |> Async.Ignore

member __.NotifyDocumentAnalyzed(p: DocumentAnalyzedNotification) =
sendServerNotification "fsharp/documentAnalyzed" (box p) |> Async.Ignore

member __.NotifyTestDetected(p: TestDetectedNotification) =
sendServerNotification "fsharp/testDetected" (box p) |> Async.Ignore
member x.NotifyWorkspacePeek(p: PlainNotification) =
if x.SupportsCustomFSharpNotifications then
sendServerNotification "fsharp/notifyWorkspacePeek" (box p) |> Async.Ignore
else
async { return () }

member x.NotifyCancelledRequest(p: PlainNotification) =
if x.SupportsCustomFSharpNotifications then
sendServerNotification "fsharp/notifyCancel" (box p) |> Async.Ignore
else
async { return () }

member x.NotifyFileParsed(p: PlainNotification) =
if x.SupportsCustomFSharpNotifications then
sendServerNotification "fsharp/fileParsed" (box p) |> Async.Ignore
else
async { return () }

member x.NotifyDocumentAnalyzed(p: DocumentAnalyzedNotification) =
if x.SupportsCustomFSharpNotifications then
sendServerNotification "fsharp/documentAnalyzed" (box p) |> Async.Ignore
else
async { return () }

member x.NotifyTestDetected(p: TestDetectedNotification) =
if x.SupportsCustomFSharpNotifications then
sendServerNotification "fsharp/testDetected" (box p) |> Async.Ignore
else
async { return () }

member __.NotifyTestDiscoveryUpdate(p: TestDiscoveryUpdateNotification) =
sendServerNotification "test/testDiscoveryUpdate" (box { Content = JsonSerializer.writeJson p })
Expand Down
2 changes: 2 additions & 0 deletions src/FsAutoComplete/LspServers/FSharpLspClient.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type FSharpLspClient =
new: sendServerNotification: ClientNotificationSender * sendServerRequest: ClientRequestSender -> FSharpLspClient
inherit LspClient
member ClientCapabilities: ClientCapabilities option with get, set
/// When true, the client supports Ionide-specific fsharp/ custom notifications.
member SupportsCustomFSharpNotifications: bool with get, set
override WindowShowMessage: ShowMessageParams -> Async<unit>
override WindowShowMessageRequest: ShowMessageRequestParams -> AsyncLspResult<MessageActionItem option>
override WindowLogMessage: LogMessageParams -> Async<unit>
Expand Down
Loading