helix-editor / helix

A post-modern modal text editor.
https://helix-editor.com
Mozilla Public License 2.0
32.54k stars 2.4k forks source link

Problems with Haxe Language Server #6176

Open BioBox opened 1 year ago

BioBox commented 1 year ago

Summary

I can't get the haxe language server to work. It seems to be due to helix not implementing the client/registerCapability response from the lsp server, but I'm fairly new to rust, this editor, and the LSP protocol itself, so it could be something wrong with my config for all I know.

Reproduction Steps

I tried this: 1. Follow the install instructions on the github page. 2. Fill in the `languages.toml` file. 3. Open up the log to see an error.
languages.toml ```toml [[language]] name = "haxe" scope = "source.haxe" injection-regex = "Haxe" file-types = ["hx"] roots = [ "build.hxml" ] indent = { tab-width = 4, unit = " " } language-server = { command = "node", args = ["/home/daniel/.node/haxe-server.js"] } [[grammar]] name = "haxe" source = { git = "https://github.com/vantreeseba/tree-sitter-haxe", rev = "ca7ed7931a93a0434cd1f5d6bb6c333865fe711a" } ```
### Helix log [helix.log](https://github.com/helix-editor/helix/files/10885964/helix.log) ### Platform Linux ### Terminal Emulator alacritty ### Helix Version helix 22.12
the-mikedavis commented 1 year ago

That log looks ok actually. I think the client/registerCapability is benign: the Haxe language server shouldn't be sending it but in practice I don't think I've ever seen that cause problems. Even running with #6058 (where we respond to that request with an error) I don't see any difference in behavior. I think this one is especially benign because it sends [] for the registrations.

I see errors when trying to use any LSP feature though:

2023-03-04T12:12:35.947 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"initialize","params":{"capabilities":{"general":{"positionEncodings":["utf-32","utf-8","utf-16"]},"textDocument":{"codeAction":{"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}}},"completion":{"completionItem":{"deprecatedSupport":true,"insertReplaceSupport":true,"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":true,"tagSupport":{"valueSet":[1]}},"completionItemKind":{}},"hover":{"contentFormat":["markdown"]},"publishDiagnostics":{},"rename":{"dynamicRegistration":false,"honorsChangeAnnotations":false,"prepareSupport":false},"signatureHelp":{"signatureInformation":{"activeParameterSupport":true,"documentationFormat":["markdown"],"parameterInformation":{"labelOffsetSupport":true}}}},"window":{"workDoneProgress":true},"workspace":{"applyEdit":true,"configuration":true,"didChangeConfiguration":{"dynamicRegistration":false},"executeCommand":{"dynamicRegistration":false},"symbol":{"dynamicRegistration":false},"workspaceFolders":true}},"clientInfo":{"name":"helix","version":"22.12"},"processId":59047,"rootPath":"/home/michael/src/helix/haxe-language-server","rootUri":"file:///home/michael/src/helix/haxe-language-server","workspaceFolders":[{"name":"haxe-language-server","uri":"file:///home/michael/src/helix/haxe-language-server"}]},"id":0}
2023-03-04T12:12:36.005 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","id":0,"result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{"includeText":false}},"completionProvider":{"triggerCharacters":[".","@",":"," ",">","$"],"resolveProvider":true},"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"hoverProvider":true,"referencesProvider":true,"documentSymbolProvider":true,"workspaceSymbolProvider":true,"documentFormattingProvider":true,"documentRangeFormattingProvider":true,"renameProvider":true,"foldingRangeProvider":true,"colorProvider":true,"inlayHintProvider":true}}}
2023-03-04T12:12:36.005 helix_lsp::transport [INFO] <- {"capabilities":{"colorProvider":true,"completionProvider":{"resolveProvider":true,"triggerCharacters":[".","@",":"," ",">","$"]},"definitionProvider":true,"documentFormattingProvider":true,"documentRangeFormattingProvider":true,"documentSymbolProvider":true,"foldingRangeProvider":true,"hoverProvider":true,"inlayHintProvider":true,"referencesProvider":true,"renameProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"textDocumentSync":{"change":2,"openClose":true,"save":{"includeText":false}},"workspaceSymbolProvider":true}}
2023-03-04T12:12:36.005 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"initialized","params":{}}
2023-03-04T12:12:36.005 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","id":0,"method":"client/registerCapability","params":{"registrations":[]}}
2023-03-04T12:12:36.005 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"languageId":"haxe","text":"package haxeLanguageServer;\n\nimport js.Node.process;\nimport jsonrpc.Protocol;\nimport jsonrpc.node.MessageReader;\nimport jsonrpc.node.MessageWriter;\n\nfunction main() {\n\tfinal reader = new MessageReader(process.stdin);\n\tfinal writer = new MessageWriter(process.stdout);\n\tfinal languageServerProtocol = new Protocol(writer.write);\n\tlanguageServerProtocol.logError = message -> languageServerProtocol.sendNotification(LogMessageNotification.type, {type: Warning, message: message});\n\tsetupTrace(languageServerProtocol);\n\tfinal context = new Context(languageServerProtocol);\n\treader.listen(languageServerProtocol.handleMessage);\n\n\tfunction log(method:String, data:Dynamic) {\n\t\tif (context.config.sendMethodResults) {\n\t\t\tlanguageServerProtocol.sendNotification(LanguageServerMethods.DidRunMethod, {\n\t\t\t\tkind: Lsp,\n\t\t\t\tmethod: method,\n\t\t\t\tdebugInfo: null,\n\t\t\t\tresponse: {\n\t\t\t\t\tresult: data\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\tlanguageServerProtocol.didRespondToRequest = function(request, response) {\n\t\tlog(request.method, {\n\t\t\trequest: request,\n\t\t\tresponse: response\n\t\t});\n\t}\n\tlanguageServerProtocol.didSendNotification = function(notification) {\n\t\tif (notification.method != LogMessageNotification.type && !notification.method.startsWith(\"haxe/\")) {\n\t\t\tlog(notification.method, notification);\n\t\t}\n\t}\n}\n\nprivate function setupTrace(languageServerProtocol:Protocol) {\n\thaxe.Log.trace = function(v, ?i) {\n\t\tfinal r = [Std.string(v)];\n\t\tif (i != null && i.customParams != null) {\n\t\t\tfor (v in i.customParams)\n\t\t\t\tr.push(Std.string(v));\n\t\t}\n\t\tlanguageServerProtocol.sendNotification(LogMessageNotification.type, {type: Log, message: r.join(\" \")});\n\t}\n}\n","uri":"file:///home/michael/src/helix/haxe-language-server/src/haxeLanguageServer/Main.hx","version":0}}}
2023-03-04T12:12:36.005 helix_term::application [ERROR] Language Server: Method client/registerCapability not found in request 0
2023-03-04T12:12:36.006 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found: client/registerCapability"},"id":0}
2023-03-04T12:12:36.006 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","method":"window/logMessage","params":{"type":4,"message":"{\n\tcode : -32601, \n\tmessage : Method not found: client/registerCapability\n}"}}
2023-03-04T12:12:36.006 helix_term::application [INFO] window/logMessage: LogMessageParams { typ: Log, message: "{\n\tcode : -32601, \n\tmessage : Method not found: client/registerCapability\n}" }
2023-03-04T12:12:48.450 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"textDocument/hover","params":{"position":{"character":10,"line":8},"textDocument":{"uri":"file:///home/michael/src/helix/haxe-language-server/src/haxeLanguageServer/Main.hx"}},"id":1}
2023-03-04T12:12:48.451 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Unhandled method textDocument/hover"}}
2023-03-04T12:12:48.451 helix_lsp::transport [ERROR] <- MethodNotFound: Unhandled method textDocument/hover
2023-03-04T12:12:48.451 helix_view::editor [ERROR] editor error: Async job failed: protocol error: MethodNotFound: Unhandled method textDocument/hover
2023-03-04T12:13:03.802 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"textDocument/signatureHelp","params":{"position":{"character":33,"line":8},"textDocument":{"uri":"file:///home/michael/src/helix/haxe-language-server/src/haxeLanguageServer/Main.hx"}},"id":2}
2023-03-04T12:13:03.802 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"Unhandled method textDocument/signatureHelp"}}
2023-03-04T12:13:03.802 helix_lsp::transport [ERROR] <- MethodNotFound: Unhandled method textDocument/signatureHelp
2023-03-04T12:13:03.802 helix_view::editor [ERROR] editor error: Async job failed: protocol error: MethodNotFound: Unhandled method textDocument/signatureHelp
2023-03-04T12:13:04.053 helix_lsp::transport [INFO] -> {"jsonrpc":"2.0","method":"textDocument/completion","params":{"position":{"character":33,"line":8},"textDocument":{"uri":"file:///home/michael/src/helix/haxe-language-server/src/haxeLanguageServer/Main.hx"}},"id":3}
2023-03-04T12:13:04.053 helix_lsp::transport [INFO] <- {"jsonrpc":"2.0","id":3,"error":{"code":-32601,"message":"Unhandled method textDocument/completion"}}
2023-03-04T12:13:04.053 helix_lsp::transport [ERROR] <- MethodNotFound: Unhandled method textDocument/completion
2023-03-04T12:13:04.053 helix_view::editor [ERROR] editor error: Async job failed: protocol error: MethodNotFound: Unhandled method textDocument/completion

It looks like the server has a bug where it needs the a didChangeConfiguration notification to start up (https://github.com/vshaxe/vshaxe/issues/359). You can add the config key to the languages.toml configuration to set this up:

[[language]]
name = "haxe"
scope = "source.haxe"
injection-regex = "Haxe"
file-types = ["hx"]
roots = [ "build.hxml" ]
indent = { tab-width = 4, unit = "    " }
language-server = { command = "node", args = ["/home/daniel/.node/haxe-server.js"] }
config = { displayArguments = ["build.hxml"] }

[[grammar]]
name = "haxe"
source = { git = "https://github.com/vantreeseba/tree-sitter-haxe", rev = "ca7ed7931a93a0434cd1f5d6bb6c333865fe711a" }

Some other notes I saw in vshaxe's issue tracker:

the-mikedavis commented 1 year ago

We may want to always send configuration in the initial didChangeConfiguration to unblock servers like this when the config key isn't provided in the languages.toml configuration: https://github.com/the-mikedavis/helix/commit/c95dbcb5cffebf3fac57d382ed9b5b3c0f4a8032. On the other hand, the didChangeConfiguration isn't a mandatory part of the spec as far as I know so we shouldn't have to send it for a server to work.

From https://github.com/vshaxe/vshaxe/issues/359#issuecomment-1363891962 it sounds like the contributors for vshaxe are interested in refactoring to use workspace/configuration which I think is a good long-term fix.