Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with coc.nvim on windows #55

Open
s-cerevisiae opened this issue Apr 17, 2021 · 8 comments
Open

Error with coc.nvim on windows #55

s-cerevisiae opened this issue Apr 17, 2021 · 8 comments

Comments

@s-cerevisiae
Copy link

I tried to use racket-langserver with coc.nvim, but it doesn't seem to work.
(I'm on windows with racket 8.0)
Log:

Caught exn:
current-load-relative-directory: contract violation
  expected: (or/c (and/c path-string? complete-path?) #f)
  given: #<path:g%3A/Programming/Racket/misc/>
  context...:
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\check-syntax.rkt:82:0: check-syntax
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:86:0: did-open!
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   [repeats 1 more time]
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

Caught exn:
hash-ref: no value found for key
  key: 'file:///g%3A/Programming/Racket/misc/test.rkt
  context...:
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:102:0: did-change!
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   [repeats 1 more time]
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

The incorrectly encoded colon (%3A) is suspicious but I couldn't find where it is produced.

PS: Everything works fine for me with VSCode and Magic Racket.

@jeapostrophe
Copy link
Owner

Can you grab a log of the JSON/LSP requests that are being sent? I have a theory that there's a URL that is being encoded by the client and not decoded by server

@s-cerevisiae
Copy link
Author

The verbose mode output with JSON requests and responses:

[Trace - 下午1:35:45] Sending request 'initialize - (0)'.
Params: {
    "processId": 25664,
    "rootPath": "g:\\Programming\\Racket\\misc",
    "rootUri": "file:///g%3A/Programming/Racket/misc",
    "capabilities": {
        "workspace": {
            "applyEdit": true,
            "workspaceEdit": {
                "documentChanges": true,
                "resourceOperations": [
                    "create",
                    "rename",
                    "delete"
                ],
                "failureHandling": "textOnlyTransactional"
            },
            "didChangeConfiguration": {
                "dynamicRegistration": true
            },
            "didChangeWatchedFiles": {
                "dynamicRegistration": true
            },
            "symbol": {
                "dynamicRegistration": true,
                "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
                    ]
                },
                "tagSupport": {
                    "valueSet": [
                        1
                    ]
                }
            },
            "executeCommand": {
                "dynamicRegistration": true
            },
            "configuration": true,
            "workspaceFolders": true
        },
        "textDocument": {
            "publishDiagnostics": {
                "relatedInformation": true,
                "versionSupport": false,
                "tagSupport": {
                    "valueSet": [
                        1,
                        2
                    ]
                }
            },
            "synchronization": {
                "dynamicRegistration": true,
                "willSave": true,
                "willSaveWaitUntil": true,
                "didSave": true
            },
            "completion": {
                "dynamicRegistration": true,
                "contextSupport": true,
                "completionItem": {
                    "snippetSupport": true,
                    "commitCharactersSupport": true,
                    "documentationFormat": [
                        "markdown",
                        "plaintext"
                    ],
                    "deprecatedSupport": true,
                    "preselectSupport": true,
                    "tagSupport": {
                        "valueSet": [
                            1
                        ]
                    }
                },
                "completionItemKind": {
                    "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
                    ]
                }
            },
            "hover": {
                "dynamicRegistration": true,
                "contentFormat": [
                    "markdown",
                    "plaintext"
                ]
            },
            "signatureHelp": {
                "dynamicRegistration": true,
                "contextSupport": true,
                "signatureInformation": {
                    "documentationFormat": [
                        "markdown",
                        "plaintext"
                    ],
                    "activeParameterSupport": true,
                    "parameterInformation": {
                        "labelOffsetSupport": true
                    }
                }
            },
            "definition": {
                "dynamicRegistration": true
            },
            "references": {
                "dynamicRegistration": true
            },
            "documentHighlight": {
                "dynamicRegistration": true
            },
            "documentSymbol": {
                "dynamicRegistration": true,
                "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,
                "tagSupport": {
                    "valueSet": [
                        1
                    ]
                }
            },
            "codeAction": {
                "dynamicRegistration": true,
                "isPreferredSupport": true,
                "codeActionLiteralSupport": {
                    "codeActionKind": {
                        "valueSet": [
                            "",
                            "quickfix",
                            "refactor",
                            "refactor.extract",
                            "refactor.inline",
                            "refactor.rewrite",
                            "source",
                            "source.organizeImports"
                        ]
                    }
                }
            },
            "codeLens": {
                "dynamicRegistration": true
            },
            "formatting": {
                "dynamicRegistration": true
            },
            "rangeFormatting": {
                "dynamicRegistration": true
            },
            "onTypeFormatting": {
                "dynamicRegistration": true
            },
            "rename": {
                "dynamicRegistration": true,
                "prepareSupport": true
            },
            "documentLink": {
                "dynamicRegistration": true,
                "tooltipSupport": true
            },
            "typeDefinition": {
                "dynamicRegistration": true
            },
            "implementation": {
                "dynamicRegistration": true
            },
            "declaration": {
                "dynamicRegistration": true
            },
            "colorProvider": {
                "dynamicRegistration": true
            },
            "foldingRange": {
                "dynamicRegistration": true,
                "rangeLimit": 5000,
                "lineFoldingOnly": true
            },
            "selectionRange": {
                "dynamicRegistration": true
            }
        },
        "window": {
            "workDoneProgress": true
        }
    },
    "initializationOptions": {},
    "trace": "verbose",
    "workspaceFolders": [
        {
            "uri": "file:///g%3A/Programming/Racket/misc",
            "name": "misc"
        }
    ],
    "clientInfo": {
        "name": "coc.nvim",
        "version": "0.0.80"
    },
    "workDoneToken": "547fe8d9-a9f9-4bec-ace5-09abf23e221d"
}


[Trace - 下午1:35:49] Received response 'initialize - (0)' in 3813ms.
Result: {
    "capabilities": {
        "completionProvider": {
            "triggerCharacters": [
                "("
            ]
        },
        "definitionProvider": true,
        "documentFormattingProvider": true,
        "documentHighlightProvider": true,
        "documentOnTypeFormattingProvider": {
            "firstTriggerCharacter": ")",
            "moreTriggerCharacter": [
                "\n",
                "]"
            ]
        },
        "documentRangeFormattingProvider": true,
        "documentSymbolProvider": true,
        "hoverProvider": true,
        "referencesProvider": true,
        "renameProvider": {
            "prepareProvider": true
        },
        "signatureHelpProvider": {
            "triggerCharacters": [
                " ",
                ")",
                "]"
            ]
        },
        "textDocumentSync": {
            "change": 2,
            "openClose": true,
            "willSave": false,
            "willSaveWaitUntil": false
        }
    }
}


[Trace - 下午1:35:49] Sending notification 'initialized'.
Params: {}


[Trace - 下午1:35:49] Sending notification 'textDocument/didOpen'.
Params: {
    "textDocument": {
        "uri": "file:///g%3A/Programming/Racket/misc/test.rkt",
        "languageId": "racket",
        "version": 1,
        "text": "#lang racket\n\n(define hello\n  \"hello world\")\n"
    }
}



Caught exn:
current-load-relative-directory: contract violation
  expected: (or/c (and/c path-string? complete-path?) #f)
  given: #<path:g%3A/Programming/Racket/misc/>
  context...:
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\check-syntax.rkt:82:0: check-syntax
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:86:0: did-open!
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   [repeats 1 more time]
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

[Trace - 下午1:35:55] Sending request 'textDocument/documentHighlight - (1)'.
Params: {
    "textDocument": {
        "uri": "file:///g%3A/Programming/Racket/misc/test.rkt"
    },
    "position": {
        "line": 0,
        "character": 0
    }
}


Caught exn in request "textDocument/documentHighlight"
hash-ref: no value found for key
  key: 'file:///g%3A/Programming/Racket/misc/test.rkt
  context...:
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:367:0: get-decl
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\text-document.rkt:291:0: document-highlight
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\methods.rkt:26:0: process-message
   D:\Racket\collects\racket\contract\private\arrow-val-first.rkt:486:18
   C:\Users\Spore\AppData\Roaming\Racket\8.0\pkgs\racket-langserver\main.rkt:53:2: consume

[Trace - 下午1:35:55] Received response 'textDocument/documentHighlight - (1)' in 2ms. Request failed: internal error in method "textDocument/documentHighlight" (-32603).
[Error  - 下午1:35:55] Request textDocument/documentHighlight failed.
  Message: internal error in method "textDocument/documentHighlight"
  Code: -32603 

@s-cerevisiae
Copy link
Author

Well, quite confirmed. I added uri-decode in uri->path function and it works (but only for coc.nvim) now.

(define (uri->path encoded-uri)
  (define uri (uri-decode encoded-uri))
  (cond
    [(eq? (system-type 'os) 'windows)
     ;; If a file URI begins with file:// or file:////, Windows translates it
     ;; as a UNC path. If it begins with file:///, it's translated to an MS-DOS
     ;; path. (https://en.wikipedia.org/wiki/File_URI_scheme#Windows_2)
     (cond
       [(string-prefix? uri "file:////") (substring uri 7)]
       [(string-prefix? uri "file:///") (substring uri 8)]
       [else (string-append "//" (substring uri 7))])]
    [else (substring uri 7)]))

It seems that Magic Racket's behavior (not encoding the uri) is the incorrect one according to the spec, and that's because it was influenced by racket-langserver... (See this issue.)

@Runi-c
Copy link
Contributor

Runi-c commented Apr 18, 2021

This seems to be a problem in vscode-uri (which is used by coc.nvim) with a long history: microsoft/vscode-languageserver-node#228, microsoft/vscode#75027, microsoft/vscode#2990

Since VSC stores lots of metadata by string URIs, they were never able to fix the default behavior, so instead they added a toString override toString(true) to get "correct" behavior. That is to say, sending the language server uri-encoded colons in drive letters is definitely not to spec (RFC-3986 defers to RFC-8089 for file scheme uris), but I guess most language servers uri decode anyway so it's not noticed.

Magic Racket uses the toString(true) override and most other language clients don't seem to contain this incorrect encoding, hence why the issue seems to only appear in coc.nvim (which uses the faulty behavior of vscode-uri but without an override option).

That all being said, we should just uri-decode anyway as it's correct to do so by the spec.

@s-cerevisiae
Copy link
Author

s-cerevisiae commented Apr 19, 2021

That's shocking. I had never thought of the official implementation could be incorrect...

just uri-decode anyway

But wouldn't this cause potential bug between "decoding server" and "not encoding clients" since "%" is allowed in file path?

@Runi-c
Copy link
Contributor

Runi-c commented Apr 19, 2021

Ah. I expected the official client to encode spaces and "%"s, but it appears to just send them as plaintext. So you're right, we shouldn't just uri-decode. I wonder how other language servers work with coc.nvim given this disparity? :/

Edit: Oops, turns out that toString() override I mentioned is literally just a switch to disable encoding the URI. That's why when I tested it the percent-sign etc. aren't encoded.

@s-cerevisiae
Copy link
Author

s-cerevisiae commented Apr 19, 2021

how other language servers work with coc.nvim given this disparity?

It seems that not only coc.nvim but also vscode default to this. Here're their solutions. For coc.nvim an extension can be made to alter the client's behavior though.

@egelja
Copy link

egelja commented Feb 2, 2023

I just had this same error with emacs and eglot. The fix with decode-uri worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants