Skip to content

textDocumentSync coming back as 0/None #162

Closed
@tom-bowles

Description

@tom-bowles

When using OmniSharp LSP from emacs lsp-mode, the initialize handshake is as shown at the bottom. The server response contains "textDocumentSync": 0, so lsp-mode sends no textDocument/didChange notifications.

The relevant code in LanguageServer.cs is also shown below. The check for ccp.HasStaticHandler(textDocumentCapabilities.Synchronization) returns false because although there is a TextDocumentSyncHandler registered (specifically OmnisharpTextDocumentSyncHandler), TextDocumentSyncHandler doesn't provide IWillSaveTextDocumentHandler or IWillSaveWaitUntilTextDocumentHandler, both of which are linked to SynchronizationCapability.

Removing the check causes the server to return a textDocumentSync options block, but the change item is set to 1 (full) rather than 2 (incremental). This appears to be because there are two OmnisharpTextDocumentSyncHandlers registered, one for cake and one for cs/csx, and the cake one doesn't handle incremental. Not sure if that should be a separate issue for omnisharp-roslyn, but it means you can't send incremental changes for cs/csx files because the Min() call in the code below means it picks up kind 1.

            if (ccp.HasStaticHandler(textDocumentCapabilities.Synchronization))
            {
                var textDocumentSyncKind = _collection.ContainsHandler(typeof(IDidChangeTextDocumentHandler))
                    ? _collection
                        .Select(x => x.Handler)
                        .OfType<IDidChangeTextDocumentHandler>()
                        .Where(x => x.GetRegistrationOptions()?.SyncKind != TextDocumentSyncKind.None)
                        .Min(z => z.GetRegistrationOptions()?.SyncKind)
                    : TextDocumentSyncKind.None;

                if (_clientVersion == ClientVersion.Lsp2)
                {
                    serverCapabilities.TextDocumentSync = textDocumentSyncKind;
                }
                else
                {
                    serverCapabilities.TextDocumentSync = new TextDocumentSyncOptions()
                    {
                        Change = textDocumentSyncKind ?? TextDocumentSyncKind.None,
                        OpenClose = _collection.ContainsHandler(typeof(IDidOpenTextDocumentHandler)) || _collection.ContainsHandler(typeof(IDidCloseTextDocumentHandler)),
                        Save = _collection.ContainsHandler(typeof(IDidSaveTextDocumentHandler)) ?
                            new SaveOptions() { IncludeText = true /* TODO: Make configurable */ } :
                            null,
                        WillSave = _collection.ContainsHandler(typeof(IWillSaveTextDocumentHandler)),
                        WillSaveWaitUntil = _collection.ContainsHandler(typeof(IWillSaveWaitUntilTextDocumentHandler))
                    };
                }
            }

[Trace - 12:19:49 PM] Sending request 'initialize - (55)'.
Params: {
  "processId": 33868,
  "rootPath": "p:/experiments/LspTest/",
  "rootUri": "file:///p:/experiments/LspTest/",
  "capabilities": {
    "workspace": {
      "workspaceEdit": {
        "documentChanges": true,
        "resourceOperations": [
          "create",
          "rename",
          "delete"
        ]
      },
      "applyEdit": true,
      "symbol": {
        "symbolKind": {
          "valueSet": [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26
          ]
        }
      },
      "executeCommand": {
        "dynamicRegistration": false
      },
      "didChangeWatchedFiles": {
        "dynamicRegistration": true
      },
      "workspaceFolders": true,
      "configuration": true
    },
    "textDocument": {
      "declaration": {
        "linkSupport": true
      },
      "definition": {
        "linkSupport": true
      },
      "implementation": {
        "linkSupport": true
      },
      "typeDefinition": {
        "linkSupport": true
      },
      "synchronization": {
        "didSave": true,
        "willSaveWaitUntil": true
      },
      "documentSymbol": {
        "symbolKind": {
          "valueSet": [
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26
          ]
        },
        "hierarchicalDocumentSymbolSupport": true
      },
      "formatting": {
        "dynamicRegistration": true
      },
      "codeAction": {
        "dynamicRegistration": true,
        "codeActionLiteralSupport": {
          "codeActionKind": {
            "valueSet": [
              "",
              "quickfix",
              "refactor",
              "refactor.extract",
              "refactor.inline",
              "refactor.rewrite",
              "source",
              "source.organizeImports"
            ]
          }
        }
      },
      "completion": {
        "completionItem": {
          "snippetSupport": true,
          "documentationFormat": [
            "markdown"
          ]
        },
        "contextSupport": true
      },
      "signatureHelp": {
        "signatureInformation": {
          "parameterInformation": {
            "labelOffsetSupport": true
          }
        }
      },
      "documentLink": {
        "dynamicRegistration": true
      },
      "hover": {
        "contentFormat": [
          "markdown",
          "plaintext"
        ]
      },
      "foldingRange": {
        "dynamicRegistration": true,
        "rangeLimit": null,
        "lineFoldingOnly": false
      }
    }
  },
  "initializationOptions": null
}


[Trace - 12:20:01 PM] Received response 'initialize - (55)' in 753ms.
Result: {
  "capabilities": {
    "experimental": {
    },
    "renameProvider": {
      "prepareProvider": null
    },
    "documentOnTypeFormattingProvider": {
      "moreTriggerCharacter": [
        "}",
        ")"
      ],
      "firstTriggerCharacter": ";"
    },
    "documentRangeFormattingProvider": true,
    "documentFormattingProvider": null,
    "codeLensProvider": {
      "resolveProvider": true
    },
    "workspaceSymbolProvider": null,
    "documentSymbolProvider": true,
    "documentHighlightProvider": null,
    "referencesProvider": true,
    "definitionProvider": true,
    "signatureHelpProvider": {
      "triggerCharacters": [
        ".",
        "?",
        "["
      ]
    },
    "completionProvider": {
      "triggerCharacters": [
        "."
      ],
      "resolveProvider": null
    },
    "hoverProvider": true,
    "textDocumentSync": 0
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions