Hello, I have recently added using sourcekit-lsp to a newer editor named Helix, however noticed a behavior that I would like to make a suggestion to change. I believe I understand this doesn't happen in sourcekit-lsp, and seems to be more of a sourcekitd (not sure exactly what that is) issue but didn't see a better place to report it.
Basically, when selecting an option through sourcekit-lsp, snippets aren't supported in Helix so the text for say String -> append turns into append(contentsOf: ) and puts the cursor at the end of the parenthesis. I would like to make the suggestion if snippets aren't supported at all it only returns the method name (in this case, append, and lets the user enter all of the above information. Currently, the response from sourcekitd appears to be something such as append(<#T##contentsOf: #String#>), so I believe that would need to change first before this could be changed (give more hints to replacement text, such as wrapping the parenthesis a well [or potentially not doing this and just matching to the first parenthesis?]), but before diving deeper I wanted to see if this seems like a more straight forward approach/makes sense and would be wanted by other editors.
Currently I only see how vscode does it which is nice, but for editors that don't support selecting the text it feels painful to backspace or click back to each parameter. Let me know what you think. Thanks!
For some background: sourcekitd is the library that provides semantic language functionality for Swift in Xcode and SourceKit-LSP by integrating with the compiler for source code analysis. Because it uses the compiler, it sees the Swift source code in exactly the way the compiler does and is thus able to provide accurate semantic information.
You are correct that sourcekitd returns code completion results with placeholders for e.g. arguments. These are represented by the <#content#> syntax. SourceKit-LSP rewrites those into LSP placeholders.
I don’t think we will make a change in sourcekitd to facilitate editors without placeholders anytime soon, because AFAICT it’s a fairly niece use case. What I think might be possible would be to handle the way SourceKit-LSP falls back if the editor doesn’t support placeholders. I think possible ideas would be
If we detect something that looks like a function call (i.e. contains parenthesis and a placeholder) only emit a completion text up to the parenthesis, like you suggested
Only emit code up to the first placeholder
Keep the current behavior
I am not entirely sure, though, that there is a one-size-fits all solution. Users might be expecting to get the argument labels inserted into the editor if they selected one particular overload so they remember. What do you think?
Also: Do you think it would be possible to implement one of the above solutions in your SourceKit-LSP <-> Helix integration easily? That would allow you to make the choice you think is best and still allows other editors to make different decisions.
I personally believe most editor's would want #1, but upon testing how other implementations handle it it doesn't seem to be very well defined, so I'm indifferent if it wanted to be multiple options.
Looking at C# (omnisharp) and JS/TS (typescript-language-server), they collapse all method overrides to 1:
which I was surprised about, and definitely prefer the general idea of what sourcekit-lsp does showing the multiple overrides instead of just collapsing, as there is no way to extend the overrides to select a separate one.
Rust doesn't support method overrides, so can't really test there.
Interestingly, I wanted to see how other editors support it, and neovim is the only other one I use and its behavior (mostly) matches what I expect:
(look at next post for this image)
although they do seem to support snippets, and after hitting enter it autofills the rest and places the cursor on Sequence. I don't know how it is removing everything >= ( before hitting enter, so I'm going to look more to see how it's doing that
If it wanted to be an option, we can pass cli args easily to the lsp from helix, so I'm perfectly happy with that direction
Thanks for your survey of other editors/languages. I think I agree that the neovim behavior most closely matches what I would expect from an editor that did support placeholders. I’m still not convinced that dropping everything after the ( from the completion’s insert text is the right thing to do because it would make picking one specific overload kind of pointless.
Are you maintaining/contributing to helix? If yes, I think it might be interesting to investigate adding “snippet support” to helix and implementing it in a way that drops all snippets and places the cursor at the first snippet. I imagine that’s what neovim is doing?