Skip to content

Commit 8139b11

Browse files
Documentation Preview Editor (#1181)
1 parent af3a22a commit 8139b11

25 files changed

+1017
-67
lines changed

.eslintrc.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@
2626
]
2727
},
2828
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
29-
"ignorePatterns": ["out", "dist", "**/*.d.ts"]
29+
"ignorePatterns": ["assets", "out", "dist", "**/*.d.ts"]
3030
}

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,7 @@ default.profraw
77
*.vsix
88
.vscode-test
99
.build
10+
.DS_Store
11+
assets/documentation-webview
1012
assets/test/**/Package.resolved
11-
assets/swift-docc-render
13+
assets/swift-docc-render

.vscode/launch.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"VSCODE_DEBUG": "1"
1515
},
1616
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
17-
"preLaunchTask": "build"
17+
"preLaunchTask": "Build Extension"
1818
},
1919
{
2020
"name": "Extension Tests",

.vscode/settings.json

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
},
99
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
1010
"typescript.tsc.autoDetect": "off",
11+
// Tell VS Code to use the same version of TypeScript as the build
12+
"typescript.tsdk": "node_modules/typescript/lib",
1113

1214
// Configure Prettier
1315
"editor.formatOnSave": true,

.vscode/tasks.json

+52-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@
44
"version": "2.0.0",
55
"tasks": [
66
{
7-
"label": "build",
7+
"label": "Build Extension",
8+
"dependsOn": ["compile", "compile-documentation-webview"],
9+
"group": {
10+
"kind": "build",
11+
"isDefault": true
12+
}
13+
},
14+
{
15+
"label": "compile",
816
"type": "npm",
917
"script": "watch",
1018
"problemMatcher": "$tsc-watch",
@@ -13,8 +21,49 @@
1321
},
1422
"isBackground": true,
1523
"group": {
16-
"kind": "build",
17-
"isDefault": true
24+
"kind": "build"
25+
}
26+
},
27+
{
28+
"label": "compile-documentation-webview",
29+
"type": "npm",
30+
"script": "watch-documentation-webview",
31+
"problemMatcher": [
32+
{
33+
"owner": "esbuild",
34+
"severity": "error",
35+
"source": "esbuild",
36+
"fileLocation": "relative",
37+
"background": {
38+
"activeOnStart": true,
39+
"beginsPattern": {
40+
"regexp": "\\[watch\\] build started"
41+
},
42+
"endsPattern": {
43+
"regexp": "\\[watch\\] build finished"
44+
}
45+
},
46+
"pattern": [
47+
{
48+
"regexp": "^[✘▲] \\[([A-Z]+)\\] (.+)",
49+
"severity": 1,
50+
"message": 2
51+
},
52+
{
53+
"regexp": "^(?:\\t| {4})(?!\\s)([^:]+)(?::([0-9]+))?(?::([0-9]+))?:$",
54+
"file": 1,
55+
"line": 2,
56+
"column": 3
57+
}
58+
]
59+
}
60+
],
61+
"presentation": {
62+
"reveal": "never"
63+
},
64+
"isBackground": true,
65+
"group": {
66+
"kind": "build"
1867
}
1968
},
2069
{

package.json

+25-3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@
5959
".swiftinterface",
6060
".swift"
6161
]
62+
},
63+
{
64+
"id": "tutorial",
65+
"aliases": [
66+
"Tutorial"
67+
],
68+
"filenamePatterns": [
69+
"*.tutorial"
70+
]
6271
}
6372
],
6473
"snippets": [
@@ -76,6 +85,11 @@
7685
}
7786
],
7887
"commands": [
88+
{
89+
"command": "swift.previewDocumentation",
90+
"title": "Preview Documentation",
91+
"category": "Swift"
92+
},
7993
{
8094
"command": "swift.createNewProject",
8195
"title": "Create New Project...",
@@ -663,6 +677,10 @@
663677
}
664678
],
665679
"commandPalette": [
680+
{
681+
"command": "swift.previewDocumentation",
682+
"when": "swift.supportsDocumentationLivePreview"
683+
},
666684
{
667685
"command": "swift.createNewProject",
668686
"when": "!swift.isActivated || swift.createNewProjectAvailable"
@@ -1274,9 +1292,13 @@
12741292
],
12751293
"scripts": {
12761294
"vscode:prepublish": "npm run bundle",
1277-
"bundle": "del-cli ./dist && esbuild ./src/extension.ts --bundle --outfile=dist/src/extension.js --external:vscode --format=cjs --platform=node --target=node18 --minify --sourcemap",
1278-
"compile": "del-cli ./dist && tsc",
1279-
"watch": "del-cli ./dist && tsc --watch",
1295+
"bundle": "del-cli ./dist && npm run bundle-extension && npm run bundle-documentation-webview",
1296+
"bundle-extension": "del-cli ./dist && esbuild ./src/extension.ts --bundle --outfile=dist/src/extension.js --external:vscode --format=cjs --platform=node --target=node18 --minify --sourcemap",
1297+
"bundle-documentation-webview": "npm run compile-documentation-webview -- --minify",
1298+
"compile": "del-cli ./dist/ && tsc --build",
1299+
"watch": "npm run compile -- --watch",
1300+
"compile-documentation-webview": "del-cli ./assets/documentation-webview && esbuild ./src/documentation/webview/webview.ts --bundle --outfile=assets/documentation-webview/index.js --format=cjs --sourcemap",
1301+
"watch-documentation-webview": "npm run compile-documentation-webview -- --watch",
12801302
"lint": "eslint ./ --ext ts && tsc --noEmit",
12811303
"update-swift-docc-render": "tsx ./scripts/update_swift_docc_render.ts",
12821304
"format": "prettier --check .",

src/WorkspaceContext.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { DebugAdapter, LaunchConfigType } from "./debugger/debugAdapter";
3333
import { SwiftBuildStatus } from "./ui/SwiftBuildStatus";
3434
import { SwiftToolchain } from "./toolchain/toolchain";
3535
import { DiagnosticsManager } from "./DiagnosticsManager";
36+
import { DocumentationManager } from "./documentation/DocumentationManager";
3637

3738
/**
3839
* Context for whole workspace. Holds array of contexts for each workspace folder
@@ -49,10 +50,12 @@ export class WorkspaceContext implements vscode.Disposable {
4950
public diagnostics: DiagnosticsManager;
5051
public subscriptions: vscode.Disposable[];
5152
public commentCompletionProvider: CommentCompletionProviders;
53+
public documentation: DocumentationManager;
5254
private lastFocusUri: vscode.Uri | undefined;
5355
private initialisationFinished = false;
5456

5557
private constructor(
58+
extensionContext: vscode.ExtensionContext,
5659
public tempFolder: TemporaryFolder,
5760
public outputChannel: SwiftOutputChannel,
5861
public toolchain: SwiftToolchain
@@ -62,6 +65,7 @@ export class WorkspaceContext implements vscode.Disposable {
6265
this.languageClientManager = new LanguageClientManager(this);
6366
this.tasks = new TaskManager(this);
6467
this.diagnostics = new DiagnosticsManager(this);
68+
this.documentation = new DocumentationManager(extensionContext, this);
6569
this.currentDocument = null;
6670
this.commentCompletionProvider = new CommentCompletionProviders();
6771

@@ -163,6 +167,7 @@ export class WorkspaceContext implements vscode.Disposable {
163167
onChangeConfig,
164168
this.tasks,
165169
this.diagnostics,
170+
this.documentation,
166171
this.languageClientManager,
167172
this.outputChannel,
168173
this.statusItem,
@@ -192,11 +197,12 @@ export class WorkspaceContext implements vscode.Disposable {
192197

193198
/** Get swift version and create WorkspaceContext */
194199
static async create(
200+
extensionContext: vscode.ExtensionContext,
195201
outputChannel: SwiftOutputChannel,
196202
toolchain: SwiftToolchain
197203
): Promise<WorkspaceContext> {
198204
const tempFolder = await TemporaryFolder.create();
199-
return new WorkspaceContext(tempFolder, outputChannel, toolchain);
205+
return new WorkspaceContext(extensionContext, tempFolder, outputChannel, toolchain);
200206
}
201207

202208
/**
@@ -224,11 +230,18 @@ export class WorkspaceContext implements vscode.Disposable {
224230
contextKeys.currentTargetType = undefined;
225231
}
226232

227-
// LSP can be configured per workspace to support reindexing
233+
// Set context keys that depend on features from SourceKit-LSP
228234
this.languageClientManager.useLanguageClient(async client => {
229235
const experimentalCaps = client.initializeResult?.capabilities.experimental;
236+
if (!experimentalCaps) {
237+
contextKeys.supportsReindexing = false;
238+
contextKeys.supportsDocumentationLivePreview = false;
239+
return;
240+
}
230241
contextKeys.supportsReindexing =
231-
experimentalCaps && experimentalCaps["workspace/triggerReindex"] !== undefined;
242+
experimentalCaps["workspace/triggerReindex"] !== undefined;
243+
contextKeys.supportsDocumentationLivePreview =
244+
experimentalCaps["textDocument/convertDocumentation"] !== undefined;
232245
});
233246

234247
setSnippetContextKey(this);

src/commands.ts

+5
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ export enum Commands {
7575
USE_LOCAL_DEPENDENCY = "swift.useLocalDependency",
7676
UNEDIT_DEPENDENCY = "swift.uneditDependency",
7777
RUN_PLUGIN_TASK = "swift.runPluginTask",
78+
PREVIEW_DOCUMENTATION = "swift.previewDocumentation",
7879
}
7980

8081
/**
@@ -155,5 +156,9 @@ export function register(ctx: WorkspaceContext): vscode.Disposable[] {
155156
"swift.runAllTestsParallel",
156157
async () => await runAllTestsParallel(ctx)
157158
),
159+
vscode.commands.registerCommand(
160+
Commands.PREVIEW_DOCUMENTATION,
161+
async () => await ctx.documentation.launchDocumentationPreview()
162+
),
158163
];
159164
}

0 commit comments

Comments
 (0)