Skip to content
This repository was archived by the owner on Jun 22, 2024. It is now read-only.

Commit 49def7b

Browse files
committed
Default to Xcode's sourcekit-lsp on macOS instead of sourcekite
1 parent a4d1256 commit 49def7b

File tree

4 files changed

+94
-57
lines changed

4 files changed

+94
-57
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 2.10.0
4+
5+
- Default to Xcode's sourcekit-lsp on macOS instead of sourcekite
6+
- README.md instruction improvements #70 by [@fxn](https://github.com/fxn).
7+
38
## 2.9.1
49

510
- Support iOS for sourcekit-lsp #64 by [@haifengkao](https://github.com/haifengkao)

README.md

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@
1212

1313
You have the choice between three different language server implementations.
1414

15-
| `sde.languageServerMode` | Comments | Swift Versions | Install |
16-
| ------------------------ | ----------------------------------------- | ------------------------------ | -------------------------------------------------- |
17-
| `sourcekit-lsp` | Apple's official one. Activley developed. | 4 and 5 | [#Using sourcekit-lsp](#Using-sourcekit-lsp) |
18-
| `sourcekite` _default_ | SDE's one. Actively maintained. | 5 and older versions 3.1 and 4 | [#Using sourcekite](#Using-sourcekite) |
19-
| `langserver` | RLovelett's LSP. Not maintained. | 4.1, macOS only | [#Using Langserver Swift](#Using-Langserver-Swift) |
15+
| `sde.languageServerMode` | Comments | Swift Versions | Install |
16+
| ------------------------- | ----------------------------------------- | ------------------------------ | -------------------------------------------------- |
17+
| `sourcekit-lsp` _default_ | Apple's official one. Activley developed. | 4 and 5 | [#Using sourcekit-lsp](#Using-sourcekit-lsp) |
18+
| `sourcekite` | SDE's one. Actively maintained. | 5 and older versions 3.1 and 4 | [#Using sourcekite](#Using-sourcekite) |
19+
| `langserver` | RLovelett's LSP. Not maintained. | 4.1, macOS only | [#Using Langserver Swift](#Using-Langserver-Swift) |
2020

2121
sourcekit-lsp is easier to install and will be updated more frequently. On the other hand sourcekite treats standalone files, Xcode projects and SwiftPM modules differently and is more configurable. If you can't decide, you can install both and swap out the used LSP by setting `sde.languageServerMode` to `sourcekite`, `sourcekit-lsp` or `langserver`.
2222

23+
### Using sourcekit-lsp
24+
25+
> **Note:** on macOS SDE defaults to using your Xcode's Swift and sourcekit-lsp. In that case, [SDE](https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-swift-development-environment) should work out of the box!
26+
27+
1. Install [SDE](https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-swift-development-environment).
28+
2. Recent versions of Xcode ship with `sourcekit-lsp`, you can check its path running `xcrun -f sourcekit-lsp`. If not found, please [install sourcekit-lsp](https://github.com/apple/sourcekit-lsp#building-sourcekit-lsp).
29+
3. Set `"swift.languageServerPath": "absolute path to the sourcekit-lsp executable"` and `"sde.languageServerMode": "sourcekit-lsp"`.
30+
2331
### Using sourcekite
2432

2533
1. sourcekite does only work with [SDE](https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-swift-development-environment). Make sure you have it installed.
@@ -44,12 +52,6 @@ sourcekit-lsp is easier to install and will be updated more frequently. On the o
4452

4553
If you experience any problems during installation, file an issue. All kind of feedback helps especially when trying to automate this.
4654

47-
### Using sourcekit-lsp
48-
49-
1. Install [SDE](https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-swift-development-environment).
50-
2. Recent versions of Xcode ship with `sourcekit-lsp`, you can check its path running `xcrun -f sourcekit-lsp`. If not found, please [install sourcekit-lsp](https://github.com/apple/sourcekit-lsp#building-sourcekit-lsp).
51-
3. Set `"swift.languageServerPath": "absolute path to the sourcekit-lsp executable"` and `"sde.languageServerMode": "sourcekit-lsp"`.
52-
5355
### Using Langserver Swift
5456

5557
Besides sourcekit-lsp and sourcekite SDE allows you to use [RLovelett/langserver-swift](https://github.com/RLovelett/langserver-swift).
@@ -122,47 +124,49 @@ With sourcekite, you can add new autocompletion targets through your configurati
122124
```
123125

124126
Since Xcode 11.4, you may use its built-in support for sourcekit-lsp
127+
125128
```json
126129
// .vscode/settings.json example for iOS
127130
{
128-
"sde.languageservermode": "sourcekit-lsp",
129-
"sourcekit-lsp.serverPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp",
130-
"sourcekit-lsp.toolchainPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
131-
"sde.swiftBuildingParams" : [
132-
"build",
133-
"-Xswiftc",
134-
"-sdk",
135-
"-Xswiftc",
136-
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk",
137-
"-Xswiftc",
138-
"-target",
139-
"-Xswiftc",
140-
"arm64-apple-ios11.0"
141-
]
131+
"sde.languageservermode": "sourcekit-lsp",
132+
"sourcekit-lsp.serverPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp",
133+
"sourcekit-lsp.toolchainPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
134+
"sde.swiftBuildingParams": [
135+
"build",
136+
"-Xswiftc",
137+
"-sdk",
138+
"-Xswiftc",
139+
"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk",
140+
"-Xswiftc",
141+
"-target",
142+
"-Xswiftc",
143+
"arm64-apple-ios11.0"
144+
]
142145
}
143146
```
144147

145148
```json
146149
// .vscode/settings.json example for WatchOS
147150
{
148-
"sde.languageservermode": "sourcekit-lsp",
149-
"sourcekit-lsp.serverPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp",
150-
"sourcekit-lsp.toolchainPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
151-
"sde.swiftBuildingParams" : [
152-
"build",
153-
"-Xswiftc",
154-
"-sdk",
155-
"-Xswiftc",
156-
"/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk",
157-
"-Xswiftc",
158-
"-target",
159-
"-Xswiftc",
160-
"armv7k-apple-watchos4.0"
161-
]
151+
"sde.languageservermode": "sourcekit-lsp",
152+
"sourcekit-lsp.serverPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp",
153+
"sourcekit-lsp.toolchainPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
154+
"sde.swiftBuildingParams": [
155+
"build",
156+
"-Xswiftc",
157+
"-sdk",
158+
"-Xswiftc",
159+
"/Applications/Xcode.app/Contents/Developer/Platforms/WatchOS.platform/Developer/SDKs/WatchOS.sdk",
160+
"-Xswiftc",
161+
"-target",
162+
"-Xswiftc",
163+
"armv7k-apple-watchos4.0"
164+
]
162165
}
163166
```
164167

165168
### Build failed! What should I do?
169+
166170
Go to vscode `OUTPUT` window, then select `SPM`. The `OUTPUT` window will tell you what's wrong.
167171

168172
### Other questions?

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"url": "https://github.com/vknabel"
99
},
1010
"license": "Apache-2.0",
11-
"version": "2.9.1",
11+
"version": "2.10.0",
1212
"publisher": "vknabel",
1313
"icon": "icons/icon.png",
1414
"galleryBanner": {
@@ -60,11 +60,11 @@
6060
"properties": {
6161
"sourcekit-lsp.serverPath": {
6262
"type": "string",
63-
"description": "The path of the sourcekit-lsp executable"
63+
"description": "The path of the sourcekit-lsp executable\nIn SDE: defaults to the toolchain's sourcekit-lsp."
6464
},
6565
"sourcekit-lsp.toolchainPath": {
6666
"type": "string",
67-
"description": "The path of the swift toolchain"
67+
"description": "The path of the swift toolchain.\nIn SDE: defaults to Xcode's default toolchain."
6868
},
6969
"swift.languageServerPath": {
7070
"type": "string",

src/clientMain.ts

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
Executable
2424
} from "vscode-languageclient";
2525
import { absolutePath } from "./AbsolutePath";
26+
import { promisify } from "util";
2627

2728
let swiftBinPath: string | null = null;
2829
let swiftBuildParams: string[] = ["build"];
@@ -43,7 +44,9 @@ function shouldBuildOnSave(): boolean {
4344
}
4445
}
4546

46-
function currentServerOptions(context: ExtensionContext) {
47+
async function currentServerOptions(
48+
context: ExtensionContext
49+
): Promise<ServerOptions> {
4750
function sourcekiteServerOptions() {
4851
// The server is implemented in node
4952
const serverModule = context.asAbsolutePath(
@@ -90,32 +93,57 @@ function currentServerOptions(context: ExtensionContext) {
9093
return serverOptions;
9194
}
9295

93-
function sourcekitLspServerOptions() {
94-
// Load the path to the language server from settings
95-
const executableCommand =
96-
workspace.getConfiguration("sourcekit-lsp").get<string>("serverPath") ||
97-
workspace
98-
.getConfiguration("swift")
99-
.get("languageServerPath", "/usr/local/bin/sourcekit-lsp");
96+
async function sourcekitLspServerOptions() {
10097
const toolchain = workspace
10198
.getConfiguration("sourcekit-lsp")
10299
.get<string>("toolchainPath");
103100

101+
async function sourceKitLSPLocation() {
102+
const explicit = workspace
103+
.getConfiguration("sourcekit-lsp")
104+
.get<string | null>("serverPath", null);
105+
if (explicit) return explicit;
106+
107+
const sourcekitLSPPath = path.resolve(
108+
toolchain ||
109+
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
110+
"usr/bin/sourcekit-lsp"
111+
);
112+
const isPreinstalled = await promisify(fs.exists)(
113+
path.resolve(toolchain, "usr/bin/sourcekit-lsp")
114+
);
115+
if (isPreinstalled) {
116+
return sourcekitLSPPath;
117+
}
118+
119+
return workspace
120+
.getConfiguration("swift")
121+
.get("languageServerPath", "/usr/local/bin/sourcekit-lsp");
122+
}
123+
104124
// sourcekit-lsp takes -Xswiftc arguments like "swift build", but it doesn't need "build" argument
105-
let sourceKitArgs = (<string[]>(
106-
workspace.getConfiguration().get("sde.swiftBuildingParams")
107-
) || []).filter(param => param !== "build")
125+
let sourceKitArgs = (
126+
<string[]>workspace.getConfiguration().get("sde.swiftBuildingParams") ||
127+
[]
128+
).filter(param => param !== "build");
108129

109130
const env: NodeJS.ProcessEnv = toolchain
110131
? { ...process.env, SOURCEKIT_TOOLCHAIN_PATH: toolchain }
111132
: process.env;
112133

113-
const run: Executable = { command: executableCommand, options: { env }, args: sourceKitArgs};
134+
const run: Executable = {
135+
command: await sourceKitLSPLocation(),
136+
options: { env },
137+
args: sourceKitArgs
138+
};
114139
const serverOptions: ServerOptions = run;
115140
return serverOptions;
116141
}
117142

118-
const lspMode = workspace.getConfiguration("sde").get("languageServerMode");
143+
const lspMode = workspace
144+
.getConfiguration("sde")
145+
.get("languageServerMode", "sourcekit-lsp");
146+
119147
if (lspMode === "sourcekit-lsp") {
120148
return sourcekitLspServerOptions();
121149
} else if (lspMode === "langserver") {
@@ -139,7 +167,7 @@ function currentClientOptions(
139167
}
140168
}
141169

142-
export function activate(context: ExtensionContext) {
170+
export async function activate(context: ExtensionContext) {
143171
if (workspace.getConfiguration().get<boolean>("sde.enable") === false) {
144172
return;
145173
}
@@ -178,7 +206,7 @@ export function activate(context: ExtensionContext) {
178206
// Create the language client and start the client.
179207
const langClient = new LanguageClient(
180208
"Swift",
181-
currentServerOptions(context),
209+
await currentServerOptions(context),
182210
clientOptions
183211
);
184212
let disposable = langClient.start();

0 commit comments

Comments
 (0)