Point to new VSCode extension

This commit is contained in:
Tim
2021-12-24 09:52:41 +00:00
parent 2e260eb54c
commit c0941227f0
14 changed files with 1 additions and 2116 deletions

View File

@@ -18,16 +18,7 @@ In general, you will need to know where to find the `sourcekit-lsp` server exect
## Visual Studio Code
To use SourceKit-LSP with Visual Studio Code, you will need the [SourceKit-LSP
Visual Studio Code extension](vscode). Documentation for [Building and Installing](vscode/README.md#building-and-installing-the-extension) is in the extension's README. There is also information about [Configuration](vscode/README.md#configuration). The most common settings are listed below.
After installing the extension, settings for SourceKit-LSP can be found in `Preferences > Settings` under
`Extensions > SourceKit-LSP` or by searching for the setting prefix
`sourcekit-lsp.`.
* `sourcekit-lsp.serverPath`: The path to sourcekit-lsp executable
* `sourcekit-lsp.toolchainPath`: (optional) The path of the swift toolchain (sets `SOURCEKIT_TOOLCHAIN_PATH`). By default, sourcekit-lsp uses the toolchain it is installed in.
* `sourcekit-lsp.tracing.server`: Traces the communication between VS Code and the SourceKit-LSP language server
The [Swift for Visual Studio Code extension](https://marketplace.visualstudio.com/items?itemName=sswg.swift-lang) uses SourceKit-LSP for code completion, jump to definition and error annotations. Install the extension from the marketplace to add it to your VSCode environment.
## Atom

View File

@@ -1,3 +0,0 @@
# Set default behavior to automatically normalize line endings.
* text=auto

View File

@@ -1,4 +0,0 @@
out
node_modules
.vscode-test/
*.vsix

View File

@@ -1,36 +0,0 @@
// A launch configuration that compiles the extension and then opens it inside a new window
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
{
"version": "0.2.0",
"configurations": [
{
"name": "Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js"
],
"preLaunchTask": "npm: watch"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test"
],
"outFiles": [
"${workspaceFolder}/out/test/**/*.js"
],
"preLaunchTask": "npm: watch"
}
]
}

View File

@@ -1,11 +0,0 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
"typescript.tsc.autoDetect": "off"
}

View File

@@ -1,20 +0,0 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": {
"kind": "build",
"isDefault": true
}
}
]
}

View File

@@ -1,6 +0,0 @@
**/*.ts
**/tsconfig.json
.gitignore
.vscode/
.vscode-test/
node_modules/

View File

@@ -1,56 +0,0 @@
# SourceKit-LSP for Visual Studio Code
This extension adds support to Visual Studio Code for using SourceKit-LSP, a
language server for Swift and C/C++/Objective-C languages.
**Note**: SourceKit-LSP is under heavy development and this should be considered
a preview. Users will need to provide the `sourcekit-lsp` executable
and Swift toolchain.
## Building and Installing the Extension
Currently, the way to get the extension is to build and install it from source.
You will also need the `sourcekit-lsp` language server executable and a Swift
toolchain. For more information about sourcekit-lsp, see [here](https://github.com/apple/sourcekit-lsp).
**Prerequisite**: To build the extension, you will need Node.js and npm: https://www.npmjs.com/get-npm.
The following commands build the extension and creates a `.vsix` package in the `out` directory.
```
$ cd Editors/vscode
$ npm install
$ npm run dev-package
```
You can install the package from the command-line using the `code` command if available (see [Launching from the command line](https://code.visualstudio.com/docs/setup/mac#_launching-from-the-command-line)).
```
code --install-extension sourcekit-lsp-development.vsix
```
Or you can install from within the application using the `Extensions > Install from VSIX...` command from the command palette.
### Developing the Extension in Visual Studio Code
As an alternative, you can open the extension directory from Visual Studio Code and build it from within the application.
1. Run `npm install` inside the extension directory to install dependencies.
2. Open the extension directory in Visual Studio Code.
3. Hit `F5` to build the extension and launch an editor window that uses it.
This will start debugging a special instance of Visual Studio Code that will have "[Extension Development Host]" in the window title and use the new extension.
There is extensive documentation for developing extensions from within Visual Studio Code at https://code.visualstudio.com/docs/extensions/overview.
## Configuration
Settings for SourceKit-LSP can be found in `Preferences > Settings` under
`Extensions > SourceKit-LSP` or by searching for the setting prefix
`sourcekit-lsp.`.
* Server Path: The path of the sourcekit-lsp executable
* Toolchain Path: (optional) The path of the swift toolchain (sets `SOURCEKIT_TOOLCHAIN_PATH`). By default, sourcekit-lsp uses the toolchain it is installed in.
The extension will find the `sourcekit-lsp` executable automatically if it is in
`PATH`, or it can be provided manually using this setting.

File diff suppressed because it is too large Load Diff

View File

@@ -1,82 +0,0 @@
{
"name": "sourcekit-lsp",
"displayName": "SourceKit-LSP",
"description": "Language server for Swift and C/C++/Objective-C",
"version": "0.0.1",
"publisher": "unpublished",
"repository": "https://github.com/apple/sourcekit-lsp",
"license": "SEE LICENSE IN LICENSE.txt",
"engines": {
"vscode": "^1.52.0"
},
"categories": [
"Programming Languages"
],
"activationEvents": [
"onLanguage:swift",
"onLanguage:cpp",
"onLanguage:c",
"onLanguage:objective-c",
"onLanguage:objective-cpp"
],
"main": "./out/main",
"scripts": {
"vscode:prepublish": "npm run -S esbuild-base -- --minify",
"esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node",
"esbuild": "npm run -S esbuild-base -- --sourcemap",
"esbuild-watch": "npm run -S esbuild-base -- --sourcemap --watch",
"package": "vsce package",
"dev-package": "vsce package -o sourcekit-lsp-development.vsix"
},
"dependencies": {
"vscode-languageclient": "^7.0.0"
},
"devDependencies": {
"@types/node": "^14.14.13",
"@types/vscode": "^1.52.0",
"esbuild": "^0.12.9",
"typescript": "^4.1.3",
"vsce": "^1.81.1"
},
"contributes": {
"configuration": {
"type": "object",
"title": "SourceKit-LSP",
"properties": {
"sourcekit-lsp.serverPath": {
"type": "string",
"default": "sourcekit-lsp",
"description": "The path of the sourcekit-lsp executable"
},
"sourcekit-lsp.serverArguments": {
"type": "array",
"default": [],
"items": {
"type": "string"
},
"description": "Arguments to pass to sourcekit-lsp. Argument keys and values should be provided as separate entries in the array e.g. ['--log-level', 'debug']"
},
"sourcekit-lsp.toolchainPath": {
"type": "string",
"default": "",
"description": "(optional) The path of the swift toolchain. By default, sourcekit-lsp uses the toolchain it is installed in."
},
"sourcekit-lsp.inlayHints.enabled": {
"type": "boolean",
"default": false,
"description": "(experimental) Render inlay type annotations in the editor."
},
"sourcekit-lsp.trace.server": {
"type": "string",
"default": "off",
"enum": [
"off",
"messages",
"verbose"
],
"description": "Traces the communication between VS Code and the SourceKit-LSP language server."
}
}
}
}
}

View File

@@ -1,44 +0,0 @@
'use strict';
import * as vscode from 'vscode';
import * as langclient from 'vscode-languageclient/node';
import { activateInlayHints } from './inlayHints';
export async function activate(context: vscode.ExtensionContext): Promise<void> {
const config = vscode.workspace.getConfiguration('sourcekit-lsp');
const sourcekit: langclient.Executable = {
command: config.get<string>('serverPath', 'sourcekit-lsp'),
args: config.get<string[]>('serverArguments', [])
};
const toolchain = config.get<string>('toolchainPath', '');
if (toolchain) {
sourcekit.options = { env: { ...process.env, SOURCEKIT_TOOLCHAIN_PATH: toolchain } };
}
const serverOptions: langclient.ServerOptions = sourcekit;
let clientOptions: langclient.LanguageClientOptions = {
documentSelector: [
'swift',
'cpp',
'c',
'objective-c',
'objective-cpp'
],
synchronize: undefined,
revealOutputChannelOn: langclient.RevealOutputChannelOn.Never
};
const client = new langclient.LanguageClient('sourcekit-lsp', 'SourceKit Language Server', serverOptions, clientOptions);
context.subscriptions.push(client.start());
console.log('SourceKit-LSP is now active!');
await client.onReady();
activateInlayHints(context, client);
}
export function deactivate() {
}

View File

@@ -1,202 +0,0 @@
'use strict';
import * as vscode from 'vscode';
import * as langclient from 'vscode-languageclient/node';
import { InlayHint, InlayHintsParams, inlayHintsRequest } from './lspExtensions';
// The implementation is loosely based on the rust-analyzer implementation
// of inlay hints: https://github.com/rust-analyzer/rust-analyzer/blob/master/editors/code/src/inlay_hints.ts
// Note that once support for inlay hints is officially added to LSP/VSCode,
// this module providing custom decorations will no longer be needed!
export async function activateInlayHints(
context: vscode.ExtensionContext,
client: langclient.LanguageClient
): Promise<void> {
let updater: HintsUpdater | null = null;
const onConfigChange = async () => {
const config = vscode.workspace.getConfiguration('sourcekit-lsp');
const wasEnabled = updater !== null;
const isEnabled = config.get<boolean>('inlayHints.enabled', false);
if (wasEnabled !== isEnabled) {
updater?.dispose();
if (isEnabled) {
updater = new HintsUpdater(client);
} else {
updater = null;
}
}
};
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(onConfigChange));
context.subscriptions.push({ dispose: () => updater?.dispose() });
onConfigChange().catch(console.error);
}
interface InlayHintStyle {
decorationType: vscode.TextEditorDecorationType;
makeDecoration(hint: InlayHint, converter: langclient.Protocol2CodeConverter): vscode.DecorationOptions;
}
const hintStyle: InlayHintStyle = {
decorationType: vscode.window.createTextEditorDecorationType({
after: {
color: new vscode.ThemeColor('editorCodeLens.foreground'),
fontStyle: 'normal',
fontWeight: 'normal'
}
}),
makeDecoration: (hint, converter) => ({
range: converter.asRange({
start: { ...hint.position, character: hint.position.character - 1 },
end: hint.position
}),
renderOptions: {
after: {
// U+200C is a zero-width non-joiner to prevent the editor from
// forming a ligature between the code and an inlay hint.
contentText: `\u{200c}: ${hint.label}`
}
}
})
};
interface SourceFile {
/** Source of the token for cancelling in-flight inlay hint requests. */
inFlightInlayHints: null | vscode.CancellationTokenSource;
/** Most recently applied decorations. */
cachedDecorations: null | vscode.DecorationOptions[];
/** The source file document in question. */
document: vscode.TextDocument;
}
class HintsUpdater implements vscode.Disposable {
private readonly disposables: vscode.Disposable[] = [];
private sourceFiles: Map<string, SourceFile> = new Map(); // uri -> SourceFile
constructor(private readonly client: langclient.LanguageClient) {
// Register listeners
vscode.window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
vscode.workspace.onDidChangeTextDocument(this.onDidChangeTextDocument, this, this.disposables);
// Set up initial cache
this.visibleSourceKitLSPEditors.forEach(editor => this.sourceFiles.set(
editor.document.uri.toString(),
{
document: editor.document,
inFlightInlayHints: null,
cachedDecorations: null
}
));
this.syncCacheAndRenderHints();
}
private onDidChangeVisibleTextEditors(): void {
const newSourceFiles = new Map<string, SourceFile>();
// Rerender all, even up-to-date editors for simplicity
this.visibleSourceKitLSPEditors.forEach(async editor => {
const uri = editor.document.uri.toString();
const file = this.sourceFiles.get(uri) ?? {
document: editor.document,
inFlightInlayHints: null,
cachedDecorations: null
};
newSourceFiles.set(uri, file);
// No text documents changed, so we may try to use the cache
if (!file.cachedDecorations) {
const hints = await this.fetchHints(file);
file.cachedDecorations = this.hintsToDecorations(hints);
}
this.renderDecorations(editor, file.cachedDecorations);
});
// Cancel requests for no longer visible (disposed) source files
this.sourceFiles.forEach((file, uri) => {
if (!newSourceFiles.has(uri)) {
file.inFlightInlayHints?.cancel();
}
});
this.sourceFiles = newSourceFiles;
}
private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent): void {
if (event.contentChanges.length !== 0 && this.isSourceKitLSPDocument(event.document)) {
this.syncCacheAndRenderHints();
}
}
private syncCacheAndRenderHints(): void {
this.sourceFiles.forEach(async (file, uri) => {
const hints = await this.fetchHints(file);
const decorations = this.hintsToDecorations(hints);
file.cachedDecorations = decorations;
this.visibleSourceKitLSPEditors.forEach(editor => {
if (editor.document.uri.toString() === uri) {
this.renderDecorations(editor, decorations);
}
});
});
}
private get visibleSourceKitLSPEditors(): vscode.TextEditor[] {
return vscode.window.visibleTextEditors.filter(e => this.isSourceKitLSPDocument(e.document));
}
private isSourceKitLSPDocument(document: vscode.TextDocument): boolean {
// TODO: Add other SourceKit-LSP languages if/once we forward inlay
// hint requests to clangd.
return document.languageId === 'swift' && document.uri.scheme === 'file';
}
private renderDecorations(editor: vscode.TextEditor, decorations: vscode.DecorationOptions[]): void {
editor.setDecorations(hintStyle.decorationType, decorations);
}
private hintsToDecorations(hints: InlayHint[]): vscode.DecorationOptions[] {
const converter = this.client.protocol2CodeConverter;
return hints.map(h => hintStyle.makeDecoration(h, converter));
}
private async fetchHints(file: SourceFile): Promise<InlayHint[]> {
file.inFlightInlayHints?.cancel();
const tokenSource = new vscode.CancellationTokenSource();
file.inFlightInlayHints = tokenSource;
// TODO: Specify a range
const params: InlayHintsParams = {
textDocument: { uri: file.document.uri.toString() }
}
try {
return await this.client.sendRequest(inlayHintsRequest, params, tokenSource.token);
} catch (e) {
this.client.outputChannel.appendLine(`Could not fetch inlay hints: ${e}`);
return [];
} finally {
if (file.inFlightInlayHints.token === tokenSource.token) {
file.inFlightInlayHints = null;
}
}
}
dispose(): void {
this.sourceFiles.forEach(file => file.inFlightInlayHints?.cancel());
this.visibleSourceKitLSPEditors.forEach(editor => this.renderDecorations(editor, []));
this.disposables.forEach(d => d.dispose());
}
}

View File

@@ -1,45 +0,0 @@
'use strict';
import * as langclient from 'vscode-languageclient/node';
// Definitions for non-standard requests used by sourcekit-lsp
export interface InlayHintsParams {
/**
* The text document.
*/
textDocument: langclient.TextDocumentIdentifier;
/**
* If set, the reange for which inlay hints are
* requested. If unset, hints for the entire document
* are returned.
*/
range?: langclient.Range;
/**
* The categories of inlay hints that are requested.
* If unset, all categories are returned.
*/
only?: string[];
}
export interface InlayHint {
/**
* The position within the code that this hint is
* attached to.
*/
position: langclient.Position;
/**
* The hint's kind, used for more flexible client-side
* styling of the hint.
*/
category?: string;
/**
* The hint's rendered label.
*/
label: string;
}
export const inlayHintsRequest = new langclient.RequestType<InlayHintsParams, InlayHint[], unknown>('sourcekit-lsp/inlayHints');

View File

@@ -1,23 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"outDir": "out",
"lib": [
"es6"
],
"sourceMap": true,
"rootDir": "src",
/* Strict Type-Checking Option */
"strict": true, /* enable all strict type-checking options */
/* Additional Checks */
"noUnusedLocals": true /* Report errors on unused locals. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
},
"exclude": [
"node_modules",
".vscode-test"
]
}