julia-vscode / LanguageServer.jl

An implementation of the Microsoft Language Server Protocol for the Julia language.
Other
368 stars 81 forks source link

LanguageClient-neovim can't talk to LanguageServer.jl #730

Closed ExpandingMan closed 4 years ago

ExpandingMan commented 4 years ago

I'm not sure why, all I can see is [LC] Sending on a disconnected channel and soon times out.

I'm running the following

let g:LanguageClient_serverCommands = {
\   'julia': ['julia', '--startup-file=no', '--history-file=no', '-e', '
\       using LanguageServer;
\       using Pkg;
\       import StaticLint;
\       import SymbolServer;
\       env_path = dirname(Pkg.Types.Context().env.project_file);
\       server = LanguageServer.LanguageServerInstance(stdin, stdout, env_path);
\       server.runlinter = true;
\       run(server);
\   ']
\ }

I've checked that this script runs fine in Julia directly, but I really have no idea how to see what's going on through neovim or diagnose what's happening.

Any suggestions? I'd be happy to provide more information, but I've gotten rather stuck here as I really can't figure out where to look.

davidanthoff commented 4 years ago

I don't know whether that is it, but in the VS Code extension we redirect stdout like this.

ExpandingMan commented 4 years ago

Hm, well I've tried that trick by changing the script to

let g:LanguageClient_serverCommands = {
\   'julia': ['julia', '--startup-file=no', '--history-file=no', '-e', '
\       using LanguageServer;
\       using Pkg;
\       import StaticLint;
\       import SymbolServer;
\       cnxn = stdout
\       redirect_stdout()
\       env_path = dirname(Pkg.Types.Context().env.project_file);
\       server = LanguageServer.LanguageServerInstance(stdin, cnxn, env_path);
\       server.runlinter = true;
\       run(server);
\   ']
\ }

I've also gotten some dumps of logs from LanguageClient-neovim, although I still don't know what to make of them, the error lines are

20:51:33 ERROR reader-Some("julia") src/rpcclient.rs:35 Thread reader-Some("julia") exited with error: ErrorMessage { msg: "Unable to read from language server" }
20:52:03 ERROR writer-Some("julia") src/rpcclient.rs:46 Thread writer-Some("julia") exited with error: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
20:52:18 ERROR unnamed src/rpchandler.rs:13 Error handling message: sending on a disconnected channel
```20:51:33 ERROR reader-Some("julia") src/rpcclient.rs:35 Thread reader-Some("julia") exited with error: ErrorMessage { msg: "Unable to read from language server" }
20:52:03 ERROR writer-Some("julia") src/rpcclient.rs:46 Thread writer-Some("julia") exited with error: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
20:52:18 ERROR unnamed src/rpchandler.rs:13 Error handling message: sending on a disconnected channelIUU

This might be related to #611, but the errors do look different.

And, for thoroughness sake, here's its full log dump

#######
LanguageClient 0.1.157 
#######
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"eval","params":["[!!get(g:, 'LanguageClient_autoStart', 1), s:GetVar('LanguageClient_serverCommands', {}), get(g:, 'LanguageClient_selectionUI', v:null), get(g:, 'LanguageClient_trace', v:null), expand(get(g:, 'LanguageClient_settingsPath', '.vim/settings.json')), !!get(g:, 'LanguageClient_loadSettings', 1), get(g:, 'LanguageClient_rootMarkers', v:null), get(g:, 'LanguageClient_changeThrottle', v:null), get(g:, 'LanguageClient_waitOutputTimeout', v:null), !!get(g:, 'LanguageClient_diagnosticsEnable', 1), get(g:, 'LanguageClient_diagnosticsList', 'Quickfix'), get(g:, 'LanguageClient_diagnosticsDisplay', {}), get(g:, 'LanguageClient_windowLogMessageLevel', 'Warning'), get(g:, 'LanguageClient_hoverPreview', 'Auto'), get(g:, 'LanguageClient_completionPreferTextEdit', 0), has('nvim')]"],"id":6}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 5, "jsonrpc": "2.0", "result": [1, {"julia": ["julia", "--startup-file=no", "--history-file=no", "-e", "       using LanguageServer;       using Pkg;       import StaticLint;       import SymbolServer;       cnxn = stdout       redirect_stdout()       env_path = dirname(Pkg.Types.Context().env.project_file);       server = LanguageServer.LanguageServerInstance(stdin, cnxn, env_path);       server.runlinter = true;       run(server);   "]}, null, null, ".vim/settings.json", 1, null, null, 60, 1, "Quickfix", {}, "Warning", "Auto", 0, 1]}
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"eval","params":["[get(g:, 'LanguageClient_diagnosticsSignsMax', v:null), get(g:, 'LanguageClient_diagnosticsMaxSeverity', 'Hint'), get(g:, 'LanguageClient_documentHighlightDisplay', {}), !!s:GetVar('LanguageClient_selectionUI_autoOpen', 1), s:useVirtualText(), !!s:GetVar('LanguageClient_echoProjectRoot', 1), s:GetVar('LanguageClient_semanticHighlightMaps', {}), s:GetVar('LanguageClient_semanticScopeSeparator', ':'), get(g:, 'LanguageClient_applyCompletionAdditionalTextEdits', 1), get(g:, 'LanguageClient_preferredMarkupKind', v:null)]"],"id":7}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 6, "jsonrpc": "2.0", "result": [1, {"julia": ["julia", "--startup-file=no", "--history-file=no", "-e", "       using LanguageServer;       using Pkg;       import StaticLint;       import SymbolServer;       cnxn = stdout       redirect_stdout()       env_path = dirname(Pkg.Types.Context().env.project_file);       server = LanguageServer.LanguageServerInstance(stdin, cnxn, env_path);       server.runlinter = true;       run(server);   "]}, null, null, ".vim/settings.json", 1, null, null, 60, 1, "Quickfix", {}, "Warning", "Auto", 0, 1]}
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"eval","params":["[get(g:, 'LanguageClient_diagnosticsSignsMax', v:null), get(g:, 'LanguageClient_diagnosticsMaxSeverity', 'Hint'), get(g:, 'LanguageClient_documentHighlightDisplay', {}), !!s:GetVar('LanguageClient_selectionUI_autoOpen', 1), s:useVirtualText(), !!s:GetVar('LanguageClient_echoProjectRoot', 1), s:GetVar('LanguageClient_semanticHighlightMaps', {}), s:GetVar('LanguageClient_semanticScopeSeparator', ':'), get(g:, 'LanguageClient_applyCompletionAdditionalTextEdits', 1), get(g:, 'LanguageClient_preferredMarkupKind', v:null)]"],"id":8}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 7, "jsonrpc": "2.0", "result": [null, "Hint", {}, 1, "All", 1, {}, ":", 1, null]}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 8, "jsonrpc": "2.0", "result": [null, "Hint", {}, 1, "All", 1, {}, ":", 1, null]}
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"eval","params":["get(g:, 'loaded_fzf')"],"id":9}
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"eval","params":["get(g:, 'loaded_fzf')"],"id":10}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 9, "jsonrpc": "2.0", "result": 1}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 10, "jsonrpc": "2.0", "result": 1}
20:51:32 DEBUG unnamed src/language_client.rs:66 state.wait_output_timeout.secs: 10 ==> 60
20:51:32 DEBUG unnamed src/language_client.rs:66 state.selectionUI: "LocationList" ==> "FZF"
20:51:32 DEBUG unnamed src/language_client.rs:66 state.is_nvim: false ==> true
20:51:32 DEBUG unnamed src/language_client.rs:66 state.loadSettings: false ==> true
20:51:32 DEBUG unnamed src/language_client.rs:66 state.trace: null ==> "off"
20:51:32 DEBUG unnamed src/language_client.rs:66 state.serverCommands.julia: null ==> ["julia","--startup-file=no","--history-file=no","-e","       using LanguageServer;       using Pkg;       import StaticLint;       import SymbolServer;       cnxn = stdout       redirect_stdout()       env_path = dirname(Pkg.Types.Context().env.project_file);       server = LanguageServer.LanguageServerInstance(stdin, cnxn, env_path);       server.runlinter = true;       run(server);   "]
20:51:32 INFO unnamed src/language_server_protocol.rs:269 End sync settings
20:51:32 INFO unnamed src/language_server_protocol.rs:3717 settings synced
20:51:32 WARN unnamed src/language_server_protocol.rs:2915 Failed to start language server automatically. No language server commands found for filetype: lisp
20:51:32 INFO unnamed src/language_server_protocol.rs:2920 End languageClient/handleFileType
20:51:32 INFO unnamed src/language_server_protocol.rs:269 End sync settings
20:51:32 INFO unnamed src/language_server_protocol.rs:3717 settings synced
20:51:32 WARN unnamed src/utils.rs:78 Unknown project type. Fallback to use dir as project root: Ok("/home/expandingman/src")
20:51:32 INFO unnamed src/language_server_protocol.rs:3743 Project root: /home/expandingman/src
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"s:EchomsgEllipsis","params":["Project root: /home/expandingman/src"]}
20:51:32 DEBUG unnamed src/language_client.rs:66 state.roots.julia: null ==> "/home/expandingman/src"
20:51:32 INFO unnamed src/language_server_protocol.rs:3822 End languageClient/startServer
20:51:32 INFO unnamed src/language_server_protocol.rs:288 Defining signs
20:51:32 INFO unnamed src/language_server_protocol.rs:1118 Begin initialize
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"s:command","params":["sign define LanguageClientInformation text=ℹ texthl=ALEInfoSign","sign define LanguageClientError text=✖ texthl=ALEErrorSign","sign define LanguageClientHint text=➤ texthl=ALEInfoSign","sign define LanguageClientWarning text=⚠ texthl=ALEWarningSign"]}
20:51:32 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"eval","params":["s:hasSnippetSupport()"],"id":11}
20:51:32 INFO reader-None src/rpcclient.rs:162 <= None {"id": 11, "jsonrpc": "2.0", "result": 0}
20:51:32 WARN unnamed src/language_server_protocol.rs:1130 Failed to get initializationOptions: Failed to read file (/home/expandingman/src/.vim/settings.json): No such file or directory (os error 2)
20:51:32 INFO writer-Some("julia") src/rpcclient.rs:208 => Some("julia") {"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"textDocument":{"codeLens":{"dynamicRegistration":true},"colorProvider":null,"completion":{"completionItem":{"snippetSupport":false}},"declaration":{"linkSupport":true},"definition":{"linkSupport":true},"hover":{},"implementation":{"linkSupport":true},"publishDiagnostics":{"relatedInformation":true},"semanticHighlightingCapabilities":{"semanticHighlighting":true},"signatureHelp":{"signatureInformation":{"parameterInformation":{"labelOffsetSupport":true}}},"typeDefinition":{"linkSupport":true}},"workspace":{"applyEdit":true,"didChangeWatchedFiles":{"dynamicRegistration":true}}},"clientInfo":{"name":"LanguageClient-neovim","version":"0.1.157 "},"processId":177354,"rootPath":"/home/expandingman/src","rootUri":"file:///home/expandingman/src","trace":"off"},"id":0}
20:51:33 ERROR reader-Some("julia") src/rpcclient.rs:35 Thread reader-Some("julia") exited with error: ErrorMessage { msg: "Unable to read from language server" }
20:51:47 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 1}, "filename": "/home/expandingman/src/joins.jl"}}
20:51:47 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:51:47 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 0}, "filename": "/home/expandingman/src/joins.jl"}}
20:51:47 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:51:49 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 1}, "filename": "/home/expandingman/src/joins.jl"}}
20:51:49 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:02 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 0}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:02 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:02 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 1}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:02 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:02 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 2}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:02 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:02 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 3}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:02 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:03 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleBufWritePost", "jsonrpc": "2.0", "params": {"bufnr": 1, "languageId": "julia", "filename": "/home/expandingman/src/joins.jl"}}
20:52:03 INFO unnamed src/language_server_protocol.rs:2953 Begin languageClient/handleBufWritePost
20:52:03 INFO unnamed src/language_server_protocol.rs:2216 Begin textDocument/didSave
20:52:03 INFO unnamed src/language_server_protocol.rs:2232 End textDocument/didSave
20:52:03 INFO unnamed src/language_server_protocol.rs:2955 End languageClient/handleBufWritePost
20:52:03 INFO writer-Some("julia") src/rpcclient.rs:208 => Some("julia") {"jsonrpc":"2.0","method":"textDocument/didSave","params":{"textDocument":{"uri":"file:///home/expandingman/src/joins.jl"}}}
20:52:03 ERROR writer-Some("julia") src/rpcclient.rs:46 Thread writer-Some("julia") exited with error: Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
20:52:11 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 4}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:11 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:11 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 5}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:11 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:11 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 6}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:11 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:11 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 7}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:11 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:11 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 2, "line": 8}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:11 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:12 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 7}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:12 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:12 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 6}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:12 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:12 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 5}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:12 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:12 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 7, "line": 4}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:12 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:13 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 3}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:13 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:13 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 8, "line": 2}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:13 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
20:52:18 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleBufEnter", "jsonrpc": "2.0", "params": {"bufnr": 1, "languageId": "julia", "filename": "/home/expandingman/src/joins.jl"}}
20:52:18 INFO unnamed src/language_server_protocol.rs:2868 Begin languageClient/handleBufEnter
20:52:18 INFO unnamed src/language_server_protocol.rs:2885 End languageClient/handleBufEnter
20:52:18 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"setbufvar","params":["/home/expandingman/src/joins.jl","LanguageClient_isServerRunning",1]}
20:52:18 INFO reader-None src/rpcclient.rs:162 <= None {"id": 1, "jsonrpc": "2.0", "method": "languageClient/findLocations", "params": {"bufnr": 1, "handle": true, "languageId": "julia", "gotoCmd": null, "method": "textDocument/implementation", "position": {"character": 4, "line": 2}, "filename": "/home/expandingman/src/joins.jl"}}
20:52:18 INFO unnamed src/language_server_protocol.rs:2154 Begin textDocument/didChange
20:52:18 INFO unnamed src/language_server_protocol.rs:2158 Not opened yet. Switching to didOpen.
20:52:18 INFO unnamed src/language_server_protocol.rs:2113 Begin textDocument/didOpen
20:52:18 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","method":"LSP#text","params":["/home/expandingman/src/joins.jl"],"id":12}
20:52:18 INFO reader-None src/rpcclient.rs:162 <= None {"id": 12, "jsonrpc": "2.0", "result": ["using DataFrames, BenchmarkTools, Random", "", "Random.seed!(999)", "", "const RAND_STRINGS = [randstring(rand(0:12)) for i ∈ 1:32]", "", "function testdf(N=10^5)", "    DataFrame(A=rand(0:9, N), B=rand(RAND_STRINGS, N), C=rand(N), D=rand(N))", "end", "", "df1 = testdf()", "df2 = testdf()", "", ""]}
20:52:18 DEBUG unnamed src/language_client.rs:66 state.text_documents./home/expandingman/src/joins.jl: null ==> {"languageId":"julia","text":"using DataFrames, BenchmarkTools, Random\n\nRandom.seed!(999)\n\nconst RAND_STRINGS = [randstring(rand(0:12)) for i ∈ 1:32]\n\nfunction testdf(N=10^5)\n    DataFrame(A=rand(0:9, N), B=rand(RAND_STRINGS, N), C=rand(N), D=rand(N))\nend\n\ndf1 = testdf()\ndf2 = testdf()\n\n","uri":"file:///home/expandingman/src/joins.jl","version":0}
20:52:18 ERROR unnamed src/rpchandler.rs:13 Error handling message: sending on a disconnected channel

Message: {"jsonrpc":"2.0","method":"languageClient/findLocations","params":{"bufnr":1,"filename":"/home/expandingman/src/joins.jl","gotoCmd":null,"handle":true,"languageId":"julia","method":"textDocument/implementation","position":{"character":4,"line":2}},"id":1}

Error: "SendError(..)"
20:52:18 INFO writer-None src/rpcclient.rs:208 => None {"jsonrpc":"2.0","error":{"code":-32603,"message":"sending on a disconnected channel"},"id":1}
20:52:32 WARN unnamed src/language_server_protocol.rs:2915 Failed to start language server automatically. timed out waiting on receive operation
20:52:32 INFO unnamed src/language_server_protocol.rs:2920 End languageClient/handleFileType
20:52:32 INFO unnamed src/language_server_protocol.rs:2920 End languageClient/handleFileType
20:53:00 INFO reader-None src/rpcclient.rs:162 <= None {"method": "languageClient/handleCursorMoved", "jsonrpc": "2.0", "params": {"bufnr": 1, "viewport": {"end": 14, "start": 0}, "languageId": "julia", "buftype": "", "position": {"character": 0, "line": 1}, "filename": "/home/expandingman/src/joins.jl"}}
20:53:00 INFO unnamed src/language_server_protocol.rs:2980 Begin languageClient/handleCursorMoved
non-Jedi commented 4 years ago

Could you please collect the stderr output from the language server? See the LanguageClient-neovim help for how to do so. This might be a crash on the server-side, and the stacktrace is helpful for debugging those.

ExpandingMan commented 4 years ago

Got it

ERROR: MethodError: Cannot `convert` an object of type Nothing to an object of type Bool
Closest candidates are:
  convert(::Type{T}, !Matched::T) where T<:Number at number.jl:6
  convert(::Type{T}, !Matched::Number) where T<:Number at number.jl:7
  convert(::Type{T}, !Matched::Ptr) where T<:Integer at pointer.jl:23
  ...
Stacktrace:
 [1] convert(::Type{Union{Missing, Bool}}, ::Nothing) at ./missing.jl:69
 [2] LanguageServer.DocumentColorClientCapabilities(::Nothing) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/protocol/features.jl:130
 [3] LanguageServer.TextDocumentClientCapabilities(::Dict{String,Any}) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/protocol/protocol.jl:36
 [4] LanguageServer.ClientCapabilities(::Dict{String,Any}) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/protocol/protocol.jl:36
 [5] LanguageServer.InitializeParams(::Dict{String,Any}) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/protocol/initialize.jl:111
 [6] parse_params(::Type{Val{:initialize}}, ::Dict{String,Any}) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/requests/init.jl:123
 [7] parse(::Type{LanguageServer.JSONRPC.Request}, ::Dict{String,Any}) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/jsonrpc.jl:46
 [8] run(::LanguageServerInstance) at /home/expandingman/.julia/packages/LanguageServer/mpNvN/src/languageserverinstance.jl:246
 [9] top-level scope at none:1

It appears that DocumentColorClientCapabilities is being passed nothing when it's expecting only true, false, or missing. Taking a look at the macro, it seems this can only happen if the dict being passed to it actual contains the value as a nothing. I take it this is a case of JSON reading in dicts in a way that's unexpected. If you can think of a simple fix, I can test... I might be able to hack it and just see if it works by editing the macro...

Update: I tried changing the macro to check if the value of the dict is nothing (and return missing in that case) but still get the same error, so there's probably something going on here that's not immediately apparent to me.

Also, my neovim config can be found here (may not always be updated with all my debugging efforts).

davidanthoff commented 4 years ago

Could it be that the client here send a null for the field colorProvider in TextDocumentClientCapabilities? I think that would not be spec conform. Or do we have a problem in our JSON->types code here?

non-Jedi commented 4 years ago

I agree that null is an invalid value for the colorProvider field per the spec. You should file an issue with LanguageClient-neovim. Per the spec, the field (if included) should be of type DocumentColorClientCapabilities which is an object with a single optional field dynamicRegistration.

ExpandingMan commented 4 years ago

Well, I don't know which of those is the case here (i.e. whether a null is being passed or there is a bug in the JSON parsing) but I had it do a dump to stderr of every dict that was being passed to a struct with @dict_readable and there is only one value being passed as nothing:

Dict{String,Any}("publishDiagnostics" => Dict{String,Any}("relatedInformation" => true),"codeLens" => Dict{String,Any}("dynamicRegistration" => true),"semanticHighlightingCapabilities" => Dict{String,Any}("semanticHighlighting" => true),"signatureHelp" => Dict{String,Any}("signatureInformation" => Dict{String,Any}("parameterInformation" => Dict{String,Any}("labelOffsetSupport" => true))),"colorProvider" => nothing,"declaration" => Dict{String,Any}("linkSupport" => true),"hover" => Dict{String,Any}(),"implementation" => Dict{String,Any}("linkSupport" => true),"definition" => Dict{String,Any}("linkSupport" => true),"completion" => Dict{String,Any}("completionItem" => Dict{String,Any}("snippetSupport" => false)),"typeDefinition" => Dict{String,Any}("linkSupport" => true))

So it definitely seems like getting "colorProvider"=>nothing is causing the error, but I'm still not sure what the source of it is.

Could somebody suggest to me where to intercept this and print so that we can check which of these is the case?

non-Jedi commented 4 years ago

You can actually see the json rpc the client is sending in the log dump you included above. The colorProvider field is already set to null when the client sends it, so the bug is on the client-side in this case. In fact, there's already an open bug describing exactly this problem although their proposed fix still wouldn't actually be spec-compliant. https://github.com/autozimu/LanguageClient-neovim/issues/940

Looks like this issue is actually a dupe of #454. Given that there hasn't been resolution on the client-side for 5 months, would it be acceptable to carry a workaround for this bug in the server until the client is fixed if someone were to PR it?

ExpandingMan commented 4 years ago

Ah, didn't notice that, thanks.

I can do a PR, but I'm pretty unfamiliar with the protocol. What do you think is the correct course of action here? Should we always check for null values? I'm a little hesitant to make a change that just tries to handle every conceivable edge case of clients that don't conform with the spec.

non-Jedi commented 4 years ago

717 has an example of working around a non-compliant client. This one is a bit trickier since the non-compliant part is during the first initialize request.

davidanthoff commented 4 years ago

It looks like there has just been progress on fixing this in the client: https://github.com/gluon-lang/lsp-types/pull/160, so maybe we don't even need a workaround?

ExpandingMan commented 4 years ago

Yeah, the PR was just closed on my suggestion. The interaction with neovim seems pretty broken, it looks like it would take quite some effort to get it working.

I think probably the best thing to do would be to wait for neovim 0.5.0 which will have more native language client integration and revisit this then. Unfortunately that means we'll likely be waiting quite a while for Julia code analysis in neovim.

davidanthoff commented 4 years ago

That sounds good to me, but if you have some other idea how to get things working in the meantime, let us know!

ExpandingMan commented 4 years ago

Actually, on this topic, it would make debugging WAY easier to investigate if I could hook neovim into a LanguageServerInstance from a running REPL. I don't suppose it's obvious to you how to do that? I guess I probably have to tell LanguageClient-neovim to hook into the socket provided by the instance in the REPL rather than starting it's own, which I don't think it provides any transparent options for.

davidanthoff commented 4 years ago

I guess you couldn't use stdout/stdin for the communication in that case, but maybe you could just use a named pipe or socket? I think on our end that should work just fine.

non-Jedi commented 4 years ago

I'm going to close this since it wasn't a LanguageServer.jl bug. Feel free to create other issues as you try to get LanguageClient-neovim working. :)