Closed alfadhela closed 6 years ago
Hi. Sorry for the late response. Actually just opening the project should be sufficient. I will have a look on this.
Hi, @vknabel just fyi, i am just playing around with this plugin as an alternative to Xcode for development on Vapor, and facing the samme issue with no autocomplete from dependencies (In this case various Vapor plugins)
I have experienced the same, too. Although this seems to depend on the external module itself. Some dependencies worked fine for me while others did not. This seems to reach back to SourceKit itself. But as we know of Xcode, this should definitely be possible.
Probably this is why langserver-swift has the same problem https://github.com/RLovelett/langserver-swift/issues/56 as @joscdk knows.
I think I can shed some light here. To have autocompletion for dependencies (and any SourceKit request working correctly for them), it's critical to have almost the same compiler arguments as compiler uses for building the project. Plus we need some additional args for taking dependencies into account. How can we achieve it:
Get the information from .yaml inside the build folder (same approach as nuclide-swift uses). Currently, it's the only way to get more or less complete list of compiler arguments for each file. Take the other-args
element as a first part of arguments.
Add "-module-name", "<module-name>", "-Onone",
. Use the module name from the .yaml for each file - for example, this way you can get a completion for Package.swift, cause here you need to submit a
Next, add the debug / release folder to this arguments array in the following way:
"-Xcc",
"-I",
"-Xcc",
"<project path>/.build/<debug or release>",
"-I",
"<project path>/.build/<debug or release>",
"-Xcc",
"-F",
"-Xcc",
"<project path>/.build/<debug or release>",
"-F",
"<project path>/.build/<debug or release>"
By "debug" or "release" here I mean the symlink, it's ok to submit it instead of the folder it points to.
That's basically how Xcode forms compiler arguments that tell the SourceKit the information about the project model (if we launch it with SOURCEKIT_LOGGING=3, we can see almost the same set of arguments for the completion request, the only difference will be using the DerivedData
instead of .build
directory). Not sure I took everything into account, but such approach works.
I was testing ide-swift
and this extension by submitting such combination of compiler arguments directly (by hardcoding them) with several projects using Vapor/Kitura both on macOS/Linux. The completion works much better.
Vapor/Kitura have a large number of dependencies, so I think it's safe to assume that such approach should work for other projects too.
Also, for some reason it works better with ide-swift
- for some reason some of the correct responses are not handled by SDE. As example - completion after import
. After typing "t" in the "import" on the top-level, I immediately have a response like
{
key.results: [
{
key.kind: source.lang.swift.decl.module,
key.name: "Accelerate",
key.sourcetext: "Accelerate",
key.description: "Accelerate",
key.typename: "Module",
key.context: source.codecompletion.context.othermodule,
key.num_bytes_to_erase: 0,
key.modulename: "Accelerate"
},
{
key.kind: source.lang.swift.decl.module,
key.name: "Accounts",
key.sourcetext: "Accounts",
key.description: "Accounts",
key.typename: "Module",
key.context: source.codecompletion.context.othermodule,
key.num_bytes_to_erase: 0,
key.modulename: "Accounts"
},
{
key.kind: source.lang.swift.decl.module,
key.name: "AddressBook",
key.sourcetext: "AddressBook",
key.description: "AddressBook",
key.typename: "Module",
key.context: source.codecompletion.context.othermodule,
key.num_bytes_to_erase: 0,
key.modulename: "AddressBook"
},
and none of module names are shown by the SDE in the completion. ide-swift
shows them correctly for the same project with the same compiler arguments. Same situation with some class methods and especially global vars.
Here is a proof-of-concept for this project on macOS. Hope it helps.
@yeswolf thank you a lot for your help! Sorry for the late response, but didm't enough time to actually work through your comment.
Once I have enough time, I will definitely dive deeper into this!
In order to apply the changes @yeswolf proposed, I needed to refactor how SDE handles modules/targets (otherwise it would've get too messy).
Additionally I added a new swift.targets
setting as described in 9510d22/CHANGELOG.md#2.5.0, which allows to declare and override completion targets (might be helpful for debugging and when using Xcode projects).
The nightly build including these changes: vscode-swift-development-environment-2.5.0.vsix.zip
Instead of adding <project path>/.build/<debug or release>
directly, I used import-paths
of the (debug|release).yaml
command.
Also, for some reason it works better with ide-swift - for some reason some of the correct responses are not handled by SDE. As example - completion after import. After typing "t" in the "import" on the top-level, I immediately have a response like and none of module names are shown by the SDE in the completion. ide-swift shows them correctly for the same project with the same compiler arguments. Same situation with some class methods and especially global vars.
I will have another look on this. If it takes some more time, I will create a dedicated issue.
- Add "-module-name", "
", "-Onone",. Use the module name from the .yaml for each file - for example, this way you can get a completion for Package.swift, cause here you need to submit a PackageDescription module name.
Just passing -module-name PackageDescription -Onone /path/to/Package.swift
did not solve the autocompletion problem. Probably an import path is still missing, which should be somewhere in the SPM project as it actually compiles the manifest. May deserve a separate issue, too.
I am using swift package (SPM) with dependencies such as PerfectHTTPServer. is there any configuration I need to do to make autocomplete work? Swift 4.1.2 and 4.0.3