mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #104
104: Add vscode extension to CI r=aochagavia a=DJMcNab Note that this testing is only done on travis - we are only running formatting and linting, so feature parity on appveyor is not required. CC @aochagavia. Fixes? #100 Co-authored-by: Daniel McNab <36049421+djmcnab@users.noreply.github.com>
This commit is contained in:
commit
c9798c0e6d
25 changed files with 803 additions and 492 deletions
13
.travis.yml
13
.travis.yml
|
@ -1,19 +1,24 @@
|
||||||
language: rust
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- rust: stable
|
- language: rust
|
||||||
|
rust: stable
|
||||||
script:
|
script:
|
||||||
- cargo gen-kinds --verify
|
- cargo gen-kinds --verify
|
||||||
- cargo gen-tests --verify
|
- cargo gen-tests --verify
|
||||||
- cargo test
|
- cargo test
|
||||||
# - rust: nightly
|
# - language: rust
|
||||||
|
# rust: nightly
|
||||||
# before_script:
|
# before_script:
|
||||||
# - rustup component add clippy-preview
|
# - rustup component add clippy-preview
|
||||||
# - rustup component add rustfmt-preview
|
# - rustup component add rustfmt-preview
|
||||||
# script:
|
# script:
|
||||||
# - cargo fmt --all -- --check || true
|
# - cargo fmt --all -- --check || true
|
||||||
# - cargo clippy
|
# - cargo clippy
|
||||||
|
- language: node_js
|
||||||
|
node_js: node
|
||||||
|
before_script: false
|
||||||
|
script:
|
||||||
|
- cd editors/code && npm ci && npm run travis; cd ../..
|
||||||
|
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- rust nightly
|
- rust nightly
|
||||||
|
|
14
editors/code/.vscode/launch.json
vendored
14
editors/code/.vscode/launch.json
vendored
|
@ -3,19 +3,15 @@
|
||||||
// Hover to view descriptions of existing attributes.
|
// Hover to view descriptions of existing attributes.
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "Extension",
|
"name": "Extension",
|
||||||
"type": "extensionHost",
|
"type": "extensionHost",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"runtimeExecutable": "${execPath}",
|
"runtimeExecutable": "${execPath}",
|
||||||
"args": [
|
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
|
||||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
"outFiles": ["${workspaceFolder}/out/**/*.js"],
|
||||||
],
|
|
||||||
"outFiles": [
|
|
||||||
"${workspaceFolder}/out/**/*.js"
|
|
||||||
],
|
|
||||||
"preLaunchTask": "npm: watch"
|
"preLaunchTask": "npm: watch"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -27,9 +23,7 @@
|
||||||
"--extensionDevelopmentPath=${workspaceFolder}",
|
"--extensionDevelopmentPath=${workspaceFolder}",
|
||||||
"--extensionTestsPath=${workspaceFolder}/out/test"
|
"--extensionTestsPath=${workspaceFolder}/out/test"
|
||||||
],
|
],
|
||||||
"outFiles": [
|
"outFiles": ["${workspaceFolder}/out/test/**/*.js"],
|
||||||
"${workspaceFolder}/out/test/**/*.js"
|
|
||||||
],
|
|
||||||
"preLaunchTask": "npm: watch"
|
"preLaunchTask": "npm: watch"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
946
editors/code/package-lock.json
generated
946
editors/code/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -17,17 +17,27 @@
|
||||||
"vscode:prepublish": "npm run compile",
|
"vscode:prepublish": "npm run compile",
|
||||||
"compile": "tsc -p ./",
|
"compile": "tsc -p ./",
|
||||||
"watch": "tsc -watch -p ./",
|
"watch": "tsc -watch -p ./",
|
||||||
"postinstall": "node ./node_modules/vscode/bin/install"
|
"postinstall": "node ./node_modules/vscode/bin/install",
|
||||||
|
"lint": "tslint --project .",
|
||||||
|
"prettier": "prettier **/*.{json,ts}",
|
||||||
|
"travis": "npm run compile && npm run lint && npm run prettier --list-different"
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"tabWidth": 4,
|
||||||
|
"singleQuote": true
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vscode-languageclient": "^4.4.0"
|
"vscode-languageclient": "^4.4.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/mocha": "^2.2.42",
|
||||||
|
"@types/node": "^8.10.34",
|
||||||
|
"prettier": "^1.14.3",
|
||||||
|
"tslint": "^5.11.0",
|
||||||
|
"tslint-config-prettier": "^1.15.0",
|
||||||
"typescript": "^2.6.1",
|
"typescript": "^2.6.1",
|
||||||
"vscode": "^1.1.21",
|
"vsce": "^1.51.1",
|
||||||
"vsce": "^1.42.0",
|
"vscode": "^1.1.21"
|
||||||
"@types/node": "^8.10.25",
|
|
||||||
"@types/mocha": "^2.2.42"
|
|
||||||
},
|
},
|
||||||
"activationEvents": [
|
"activationEvents": [
|
||||||
"onLanguage:rust"
|
"onLanguage:rust"
|
||||||
|
|
|
@ -20,8 +20,12 @@ export interface SourceChange {
|
||||||
export async function handle(change: SourceChange) {
|
export async function handle(change: SourceChange) {
|
||||||
const wsEdit = new vscode.WorkspaceEdit();
|
const wsEdit = new vscode.WorkspaceEdit();
|
||||||
for (const sourceEdit of change.sourceFileEdits) {
|
for (const sourceEdit of change.sourceFileEdits) {
|
||||||
const uri = Server.client.protocol2CodeConverter.asUri(sourceEdit.textDocument.uri);
|
const uri = Server.client.protocol2CodeConverter.asUri(
|
||||||
const edits = Server.client.protocol2CodeConverter.asTextEdits(sourceEdit.edits);
|
sourceEdit.textDocument.uri
|
||||||
|
);
|
||||||
|
const edits = Server.client.protocol2CodeConverter.asTextEdits(
|
||||||
|
sourceEdit.edits
|
||||||
|
);
|
||||||
wsEdit.set(uri, edits);
|
wsEdit.set(uri, edits);
|
||||||
}
|
}
|
||||||
let created;
|
let created;
|
||||||
|
@ -48,11 +52,19 @@ export async function handle(change: SourceChange) {
|
||||||
const doc = await vscode.workspace.openTextDocument(toOpen);
|
const doc = await vscode.workspace.openTextDocument(toOpen);
|
||||||
await vscode.window.showTextDocument(doc);
|
await vscode.window.showTextDocument(doc);
|
||||||
} else if (toReveal) {
|
} else if (toReveal) {
|
||||||
const uri = Server.client.protocol2CodeConverter.asUri(toReveal.textDocument.uri);
|
const uri = Server.client.protocol2CodeConverter.asUri(
|
||||||
const position = Server.client.protocol2CodeConverter.asPosition(toReveal.position);
|
toReveal.textDocument.uri
|
||||||
|
);
|
||||||
|
const position = Server.client.protocol2CodeConverter.asPosition(
|
||||||
|
toReveal.position
|
||||||
|
);
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (!editor || editor.document.uri.toString() !== uri.toString()) { return; }
|
if (!editor || editor.document.uri.toString() !== uri.toString()) {
|
||||||
if (!editor.selection.isEmpty) { return; }
|
return;
|
||||||
|
}
|
||||||
|
if (!editor.selection.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
editor!.selection = new vscode.Selection(position, position);
|
editor!.selection = new vscode.Selection(position, position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,19 @@ interface ExtendSelectionResult {
|
||||||
|
|
||||||
export async function handle() {
|
export async function handle() {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (editor == null || editor.document.languageId !== 'rust') { return; }
|
if (editor == null || editor.document.languageId !== 'rust') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const request: ExtendSelectionParams = {
|
const request: ExtendSelectionParams = {
|
||||||
selections: editor.selections.map((s) => {
|
selections: editor.selections.map(s => {
|
||||||
return Server.client.code2ProtocolConverter.asRange(s);
|
return Server.client.code2ProtocolConverter.asRange(s);
|
||||||
}),
|
}),
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: { uri: editor.document.uri.toString() }
|
||||||
};
|
};
|
||||||
const response = await Server.client.sendRequest<ExtendSelectionResult>('m/extendSelection', request);
|
const response = await Server.client.sendRequest<ExtendSelectionResult>(
|
||||||
|
'm/extendSelection',
|
||||||
|
request
|
||||||
|
);
|
||||||
editor.selections = response.selections.map((range: Range) => {
|
editor.selections = response.selections.map((range: Range) => {
|
||||||
const r = Server.client.protocol2CodeConverter.asRange(range);
|
const r = Server.client.protocol2CodeConverter.asRange(range);
|
||||||
return new vscode.Selection(r.start, r.end);
|
return new vscode.Selection(r.start, r.end);
|
||||||
|
|
|
@ -13,5 +13,5 @@ export {
|
||||||
matchingBrace,
|
matchingBrace,
|
||||||
parentModule,
|
parentModule,
|
||||||
runnables,
|
runnables,
|
||||||
syntaxTree,
|
syntaxTree
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,10 @@ import * as vscode from 'vscode';
|
||||||
|
|
||||||
import { Range, TextDocumentIdentifier } from 'vscode-languageclient';
|
import { Range, TextDocumentIdentifier } from 'vscode-languageclient';
|
||||||
import { Server } from '../server';
|
import { Server } from '../server';
|
||||||
import { handle as applySourceChange, SourceChange } from './apply_source_change';
|
import {
|
||||||
|
handle as applySourceChange,
|
||||||
|
SourceChange
|
||||||
|
} from './apply_source_change';
|
||||||
|
|
||||||
interface JoinLinesParams {
|
interface JoinLinesParams {
|
||||||
textDocument: TextDocumentIdentifier;
|
textDocument: TextDocumentIdentifier;
|
||||||
|
@ -11,11 +14,16 @@ interface JoinLinesParams {
|
||||||
|
|
||||||
export async function handle() {
|
export async function handle() {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (editor == null || editor.document.languageId !== 'rust') { return; }
|
if (editor == null || editor.document.languageId !== 'rust') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const request: JoinLinesParams = {
|
const request: JoinLinesParams = {
|
||||||
range: Server.client.code2ProtocolConverter.asRange(editor.selection),
|
range: Server.client.code2ProtocolConverter.asRange(editor.selection),
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: { uri: editor.document.uri.toString() }
|
||||||
};
|
};
|
||||||
const change = await Server.client.sendRequest<SourceChange>('m/joinLines', request);
|
const change = await Server.client.sendRequest<SourceChange>(
|
||||||
|
'm/joinLines',
|
||||||
|
request
|
||||||
|
);
|
||||||
await applySourceChange(change);
|
await applySourceChange(change);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,16 +10,23 @@ interface FindMatchingBraceParams {
|
||||||
|
|
||||||
export async function handle() {
|
export async function handle() {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (editor == null || editor.document.languageId !== 'rust') { return; }
|
if (editor == null || editor.document.languageId !== 'rust') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const request: FindMatchingBraceParams = {
|
const request: FindMatchingBraceParams = {
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: { uri: editor.document.uri.toString() },
|
||||||
offsets: editor.selections.map((s) => {
|
offsets: editor.selections.map(s => {
|
||||||
return Server.client.code2ProtocolConverter.asPosition(s.active);
|
return Server.client.code2ProtocolConverter.asPosition(s.active);
|
||||||
}),
|
})
|
||||||
};
|
};
|
||||||
const response = await Server.client.sendRequest<Position[]>('m/findMatchingBrace', request);
|
const response = await Server.client.sendRequest<Position[]>(
|
||||||
|
'm/findMatchingBrace',
|
||||||
|
request
|
||||||
|
);
|
||||||
editor.selections = editor.selections.map((sel, idx) => {
|
editor.selections = editor.selections.map((sel, idx) => {
|
||||||
const active = Server.client.protocol2CodeConverter.asPosition(response[idx]);
|
const active = Server.client.protocol2CodeConverter.asPosition(
|
||||||
|
response[idx]
|
||||||
|
);
|
||||||
const anchor = sel.isEmpty ? active : sel.anchor;
|
const anchor = sel.isEmpty ? active : sel.anchor;
|
||||||
return new vscode.Selection(anchor, active);
|
return new vscode.Selection(anchor, active);
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,13 +5,20 @@ import { Server } from '../server';
|
||||||
|
|
||||||
export async function handle() {
|
export async function handle() {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (editor == null || editor.document.languageId !== 'rust') { return; }
|
if (editor == null || editor.document.languageId !== 'rust') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const request: TextDocumentIdentifier = {
|
const request: TextDocumentIdentifier = {
|
||||||
uri: editor.document.uri.toString(),
|
uri: editor.document.uri.toString()
|
||||||
};
|
};
|
||||||
const response = await Server.client.sendRequest<Location[]>('m/parentModule', request);
|
const response = await Server.client.sendRequest<Location[]>(
|
||||||
|
'm/parentModule',
|
||||||
|
request
|
||||||
|
);
|
||||||
const loc = response[0];
|
const loc = response[0];
|
||||||
if (loc == null) { return; }
|
if (loc == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const uri = Server.client.protocol2CodeConverter.asUri(loc.uri);
|
const uri = Server.client.protocol2CodeConverter.asUri(loc.uri);
|
||||||
const range = Server.client.protocol2CodeConverter.asRange(loc.range);
|
const range = Server.client.protocol2CodeConverter.asRange(loc.range);
|
||||||
|
|
||||||
|
|
|
@ -41,39 +41,56 @@ function createTask(spec: Runnable): vscode.Task {
|
||||||
label: 'cargo',
|
label: 'cargo',
|
||||||
command: spec.bin,
|
command: spec.bin,
|
||||||
args: spec.args,
|
args: spec.args,
|
||||||
env: spec.env,
|
env: spec.env
|
||||||
};
|
};
|
||||||
|
|
||||||
const execCmd = `${definition.command} ${definition.args.join(' ')}`;
|
const execCmd = `${definition.command} ${definition.args.join(' ')}`;
|
||||||
const execOption: vscode.ShellExecutionOptions = {
|
const execOption: vscode.ShellExecutionOptions = {
|
||||||
cwd: '.',
|
cwd: '.',
|
||||||
env: definition.env,
|
env: definition.env
|
||||||
};
|
};
|
||||||
const exec = new vscode.ShellExecution(`clear; ${execCmd}`, execOption);
|
const exec = new vscode.ShellExecution(`clear; ${execCmd}`, execOption);
|
||||||
|
|
||||||
const f = vscode.workspace.workspaceFolders![0];
|
const f = vscode.workspace.workspaceFolders![0];
|
||||||
const t = new vscode.Task(definition, f, definition.label, TASK_SOURCE, exec, ['$rustc']);
|
const t = new vscode.Task(
|
||||||
|
definition,
|
||||||
|
f,
|
||||||
|
definition.label,
|
||||||
|
TASK_SOURCE,
|
||||||
|
exec,
|
||||||
|
['$rustc']
|
||||||
|
);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
let prevRunnable: RunnableQuickPick | undefined;
|
let prevRunnable: RunnableQuickPick | undefined;
|
||||||
export async function handle() {
|
export async function handle() {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (editor == null || editor.document.languageId !== 'rust') { return; }
|
if (editor == null || editor.document.languageId !== 'rust') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const textDocument: lc.TextDocumentIdentifier = {
|
const textDocument: lc.TextDocumentIdentifier = {
|
||||||
uri: editor.document.uri.toString(),
|
uri: editor.document.uri.toString()
|
||||||
};
|
};
|
||||||
const params: RunnablesParams = {
|
const params: RunnablesParams = {
|
||||||
textDocument,
|
textDocument,
|
||||||
position: Server.client.code2ProtocolConverter.asPosition(editor.selection.active),
|
position: Server.client.code2ProtocolConverter.asPosition(
|
||||||
|
editor.selection.active
|
||||||
|
)
|
||||||
};
|
};
|
||||||
const runnables = await Server.client.sendRequest<Runnable[]>('m/runnables', params);
|
const runnables = await Server.client.sendRequest<Runnable[]>(
|
||||||
|
'm/runnables',
|
||||||
|
params
|
||||||
|
);
|
||||||
const items: RunnableQuickPick[] = [];
|
const items: RunnableQuickPick[] = [];
|
||||||
if (prevRunnable) {
|
if (prevRunnable) {
|
||||||
items.push(prevRunnable);
|
items.push(prevRunnable);
|
||||||
}
|
}
|
||||||
for (const r of runnables) {
|
for (const r of runnables) {
|
||||||
if (prevRunnable && JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)) {
|
if (
|
||||||
|
prevRunnable &&
|
||||||
|
JSON.stringify(prevRunnable.runnable) === JSON.stringify(r)
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
items.push(new RunnableQuickPick(r));
|
items.push(new RunnableQuickPick(r));
|
||||||
|
|
|
@ -5,17 +5,25 @@ import { Server } from '../server';
|
||||||
|
|
||||||
export const syntaxTreeUri = vscode.Uri.parse('ra-lsp://syntaxtree');
|
export const syntaxTreeUri = vscode.Uri.parse('ra-lsp://syntaxtree');
|
||||||
|
|
||||||
export class TextDocumentContentProvider implements vscode.TextDocumentContentProvider {
|
export class TextDocumentContentProvider
|
||||||
|
implements vscode.TextDocumentContentProvider {
|
||||||
public eventEmitter = new vscode.EventEmitter<vscode.Uri>();
|
public eventEmitter = new vscode.EventEmitter<vscode.Uri>();
|
||||||
public syntaxTree: string = 'Not available';
|
public syntaxTree: string = 'Not available';
|
||||||
|
|
||||||
public provideTextDocumentContent(uri: vscode.Uri): vscode.ProviderResult<string> {
|
public provideTextDocumentContent(
|
||||||
|
uri: vscode.Uri
|
||||||
|
): vscode.ProviderResult<string> {
|
||||||
const editor = vscode.window.activeTextEditor;
|
const editor = vscode.window.activeTextEditor;
|
||||||
if (editor == null) { return ''; }
|
if (editor == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
const request: SyntaxTreeParams = {
|
const request: SyntaxTreeParams = {
|
||||||
textDocument: { uri: editor.document.uri.toString() },
|
textDocument: { uri: editor.document.uri.toString() }
|
||||||
};
|
};
|
||||||
return Server.client.sendRequest<SyntaxTreeResult>('m/syntaxTree', request);
|
return Server.client.sendRequest<SyntaxTreeResult>(
|
||||||
|
'm/syntaxTree',
|
||||||
|
request
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get onDidChange(): vscode.Event<vscode.Uri> {
|
get onDidChange(): vscode.Event<vscode.Uri> {
|
||||||
|
@ -34,5 +42,9 @@ type SyntaxTreeResult = string;
|
||||||
// The contents of the file come from the `TextDocumentContentProvider`
|
// The contents of the file come from the `TextDocumentContentProvider`
|
||||||
export async function handle() {
|
export async function handle() {
|
||||||
const document = await vscode.workspace.openTextDocument(syntaxTreeUri);
|
const document = await vscode.workspace.openTextDocument(syntaxTreeUri);
|
||||||
return vscode.window.showTextDocument(document, vscode.ViewColumn.Two, true);
|
return vscode.window.showTextDocument(
|
||||||
|
document,
|
||||||
|
vscode.ViewColumn.Two,
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ export class Config {
|
||||||
public highlightingOn = true;
|
public highlightingOn = true;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
vscode.workspace.onDidChangeConfiguration((_) => this.userConfigChanged());
|
vscode.workspace.onDidChangeConfiguration(_ =>
|
||||||
|
this.userConfigChanged()
|
||||||
|
);
|
||||||
this.userConfigChanged();
|
this.userConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,19 @@ import { Decoration } from '../highlighting';
|
||||||
import { Server } from '../server';
|
import { Server } from '../server';
|
||||||
|
|
||||||
export async function handle(editor: TextEditor | undefined) {
|
export async function handle(editor: TextEditor | undefined) {
|
||||||
if (!Server.config.highlightingOn || !editor || editor.document.languageId !== 'rust') { return; }
|
if (
|
||||||
|
!Server.config.highlightingOn ||
|
||||||
|
!editor ||
|
||||||
|
editor.document.languageId !== 'rust'
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const params: TextDocumentIdentifier = {
|
const params: TextDocumentIdentifier = {
|
||||||
uri: editor.document.uri.toString(),
|
uri: editor.document.uri.toString()
|
||||||
};
|
};
|
||||||
const decorations = await Server.client.sendRequest<Decoration[]>('m/decorationsRequest', params);
|
const decorations = await Server.client.sendRequest<Decoration[]>(
|
||||||
|
'm/decorationsRequest',
|
||||||
|
params
|
||||||
|
);
|
||||||
Server.highlighter.setHighlights(editor, decorations);
|
Server.highlighter.setHighlights(editor, decorations);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
|
||||||
import { syntaxTreeUri, TextDocumentContentProvider } from '../commands/syntaxTree';
|
import {
|
||||||
|
syntaxTreeUri,
|
||||||
|
TextDocumentContentProvider
|
||||||
|
} from '../commands/syntaxTree';
|
||||||
|
|
||||||
export function createHandler(textDocumentContentProvider: TextDocumentContentProvider) {
|
export function createHandler(
|
||||||
|
textDocumentContentProvider: TextDocumentContentProvider
|
||||||
|
) {
|
||||||
return (event: vscode.TextDocumentChangeEvent) => {
|
return (event: vscode.TextDocumentChangeEvent) => {
|
||||||
const doc = event.document;
|
const doc = event.document;
|
||||||
if (doc.languageId !== 'rust') { return; }
|
if (doc.languageId !== 'rust') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
afterLs(() => {
|
afterLs(() => {
|
||||||
textDocumentContentProvider.eventEmitter.fire(syntaxTreeUri);
|
textDocumentContentProvider.eventEmitter.fire(syntaxTreeUri);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import * as changeActiveTextEditor from './change_active_text_editor';
|
import * as changeActiveTextEditor from './change_active_text_editor';
|
||||||
import * as changeTextDocument from './change_text_document';
|
import * as changeTextDocument from './change_text_document';
|
||||||
|
|
||||||
export {
|
export { changeActiveTextEditor, changeTextDocument };
|
||||||
changeActiveTextEditor,
|
|
||||||
changeTextDocument,
|
|
||||||
};
|
|
||||||
|
|
|
@ -23,26 +23,34 @@ export function activate(context: vscode.ExtensionContext) {
|
||||||
registerCommand('ra-lsp.joinLines', commands.joinLines.handle);
|
registerCommand('ra-lsp.joinLines', commands.joinLines.handle);
|
||||||
registerCommand('ra-lsp.parentModule', commands.parentModule.handle);
|
registerCommand('ra-lsp.parentModule', commands.parentModule.handle);
|
||||||
registerCommand('ra-lsp.run', commands.runnables.handle);
|
registerCommand('ra-lsp.run', commands.runnables.handle);
|
||||||
registerCommand('ra-lsp.applySourceChange', commands.applySourceChange.handle);
|
registerCommand(
|
||||||
|
'ra-lsp.applySourceChange',
|
||||||
|
commands.applySourceChange.handle
|
||||||
|
);
|
||||||
|
|
||||||
// Notifications are events triggered by the language server
|
// Notifications are events triggered by the language server
|
||||||
const allNotifications: Iterable<[string, lc.GenericNotificationHandler]> = [
|
const allNotifications: Iterable<
|
||||||
['m/publishDecorations', notifications.publishDecorations.handle],
|
[string, lc.GenericNotificationHandler]
|
||||||
];
|
> = [['m/publishDecorations', notifications.publishDecorations.handle]];
|
||||||
|
|
||||||
// The events below are plain old javascript events, triggered and handled by vscode
|
// The events below are plain old javascript events, triggered and handled by vscode
|
||||||
vscode.window.onDidChangeActiveTextEditor(events.changeActiveTextEditor.handle);
|
vscode.window.onDidChangeActiveTextEditor(
|
||||||
|
events.changeActiveTextEditor.handle
|
||||||
|
);
|
||||||
|
|
||||||
const textDocumentContentProvider = new TextDocumentContentProvider();
|
const textDocumentContentProvider = new TextDocumentContentProvider();
|
||||||
disposeOnDeactivation(vscode.workspace.registerTextDocumentContentProvider(
|
disposeOnDeactivation(
|
||||||
'ra-lsp',
|
vscode.workspace.registerTextDocumentContentProvider(
|
||||||
textDocumentContentProvider,
|
'ra-lsp',
|
||||||
));
|
textDocumentContentProvider
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
vscode.workspace.onDidChangeTextDocument(
|
vscode.workspace.onDidChangeTextDocument(
|
||||||
events.changeTextDocument.createHandler(textDocumentContentProvider),
|
events.changeTextDocument.createHandler(textDocumentContentProvider),
|
||||||
null,
|
null,
|
||||||
context.subscriptions);
|
context.subscriptions
|
||||||
|
);
|
||||||
|
|
||||||
// Start the language server, finally!
|
// Start the language server, finally!
|
||||||
Server.start(allNotifications);
|
Server.start(allNotifications);
|
||||||
|
|
|
@ -9,15 +9,24 @@ export interface Decoration {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Highlighter {
|
export class Highlighter {
|
||||||
private static initDecorations(): Map<string, vscode.TextEditorDecorationType> {
|
private static initDecorations(): Map<
|
||||||
const decor = (color: string) => vscode.window.createTextEditorDecorationType({ color });
|
string,
|
||||||
|
vscode.TextEditorDecorationType
|
||||||
|
> {
|
||||||
|
const decor = (color: string) =>
|
||||||
|
vscode.window.createTextEditorDecorationType({ color });
|
||||||
|
|
||||||
const decorations: Iterable<[string, vscode.TextEditorDecorationType]> = [
|
const decorations: Iterable<
|
||||||
|
[string, vscode.TextEditorDecorationType]
|
||||||
|
> = [
|
||||||
['background', decor('#3F3F3F')],
|
['background', decor('#3F3F3F')],
|
||||||
['error', vscode.window.createTextEditorDecorationType({
|
[
|
||||||
borderColor: 'red',
|
'error',
|
||||||
borderStyle: 'none none dashed none',
|
vscode.window.createTextEditorDecorationType({
|
||||||
})],
|
borderColor: 'red',
|
||||||
|
borderStyle: 'none none dashed none'
|
||||||
|
})
|
||||||
|
],
|
||||||
['comment', decor('#7F9F7F')],
|
['comment', decor('#7F9F7F')],
|
||||||
['string', decor('#CC9393')],
|
['string', decor('#CC9393')],
|
||||||
['keyword', decor('#F0DFAF')],
|
['keyword', decor('#F0DFAF')],
|
||||||
|
@ -26,13 +35,16 @@ export class Highlighter {
|
||||||
['builtin', decor('#DD6718')],
|
['builtin', decor('#DD6718')],
|
||||||
['text', decor('#DCDCCC')],
|
['text', decor('#DCDCCC')],
|
||||||
['attribute', decor('#BFEBBF')],
|
['attribute', decor('#BFEBBF')],
|
||||||
['literal', decor('#DFAF8F')],
|
['literal', decor('#DFAF8F')]
|
||||||
];
|
];
|
||||||
|
|
||||||
return new Map<string, vscode.TextEditorDecorationType>(decorations);
|
return new Map<string, vscode.TextEditorDecorationType>(decorations);
|
||||||
}
|
}
|
||||||
|
|
||||||
private decorations: (Map<string, vscode.TextEditorDecorationType> | null) = null;
|
private decorations: Map<
|
||||||
|
string,
|
||||||
|
vscode.TextEditorDecorationType
|
||||||
|
> | null = null;
|
||||||
|
|
||||||
public removeHighlights() {
|
public removeHighlights() {
|
||||||
if (this.decorations == null) {
|
if (this.decorations == null) {
|
||||||
|
@ -47,10 +59,7 @@ export class Highlighter {
|
||||||
this.decorations = null;
|
this.decorations = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setHighlights(
|
public setHighlights(editor: vscode.TextEditor, highlights: Decoration[]) {
|
||||||
editor: vscode.TextEditor,
|
|
||||||
highlights: Decoration[],
|
|
||||||
) {
|
|
||||||
// Initialize decorations if necessary
|
// Initialize decorations if necessary
|
||||||
//
|
//
|
||||||
// Note: decoration objects need to be kept around so we can dispose them
|
// Note: decoration objects need to be kept around so we can dispose them
|
||||||
|
@ -68,13 +77,15 @@ export class Highlighter {
|
||||||
if (!byTag.get(d.tag)) {
|
if (!byTag.get(d.tag)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
byTag.get(d.tag)!.push(
|
byTag
|
||||||
Server.client.protocol2CodeConverter.asRange(d.range),
|
.get(d.tag)!
|
||||||
);
|
.push(Server.client.protocol2CodeConverter.asRange(d.range));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const tag of byTag.keys()) {
|
for (const tag of byTag.keys()) {
|
||||||
const dec = this.decorations.get(tag) as vscode.TextEditorDecorationType;
|
const dec = this.decorations.get(
|
||||||
|
tag
|
||||||
|
) as vscode.TextEditorDecorationType;
|
||||||
const ranges = byTag.get(tag)!;
|
const ranges = byTag.get(tag)!;
|
||||||
editor.setDecorations(dec, ranges);
|
editor.setDecorations(dec, ranges);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import * as publishDecorations from './publish_decorations';
|
import * as publishDecorations from './publish_decorations';
|
||||||
|
|
||||||
export {
|
export { publishDecorations };
|
||||||
publishDecorations,
|
|
||||||
};
|
|
||||||
|
|
|
@ -10,11 +10,10 @@ export interface PublishDecorationsParams {
|
||||||
|
|
||||||
export function handle(params: PublishDecorationsParams) {
|
export function handle(params: PublishDecorationsParams) {
|
||||||
const targetEditor = vscode.window.visibleTextEditors.find(
|
const targetEditor = vscode.window.visibleTextEditors.find(
|
||||||
(editor) => editor.document.uri.toString() === params.uri,
|
editor => editor.document.uri.toString() === params.uri
|
||||||
);
|
|
||||||
if (!Server.config.highlightingOn || !targetEditor) { return; }
|
|
||||||
Server.highlighter.setHighlights(
|
|
||||||
targetEditor,
|
|
||||||
params.decorations,
|
|
||||||
);
|
);
|
||||||
|
if (!Server.config.highlightingOn || !targetEditor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Server.highlighter.setHighlights(targetEditor, params.decorations);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,24 +8,26 @@ export class Server {
|
||||||
public static config = new Config();
|
public static config = new Config();
|
||||||
public static client: lc.LanguageClient;
|
public static client: lc.LanguageClient;
|
||||||
|
|
||||||
public static start(notificationHandlers: Iterable<[string, lc.GenericNotificationHandler]>) {
|
public static start(
|
||||||
|
notificationHandlers: Iterable<[string, lc.GenericNotificationHandler]>
|
||||||
|
) {
|
||||||
const run: lc.Executable = {
|
const run: lc.Executable = {
|
||||||
command: 'ra_lsp_server',
|
command: 'ra_lsp_server',
|
||||||
options: { cwd: '.' },
|
options: { cwd: '.' }
|
||||||
};
|
};
|
||||||
const serverOptions: lc.ServerOptions = {
|
const serverOptions: lc.ServerOptions = {
|
||||||
run,
|
run,
|
||||||
debug: run,
|
debug: run
|
||||||
};
|
};
|
||||||
const clientOptions: lc.LanguageClientOptions = {
|
const clientOptions: lc.LanguageClientOptions = {
|
||||||
documentSelector: [{ scheme: 'file', language: 'rust' }],
|
documentSelector: [{ scheme: 'file', language: 'rust' }]
|
||||||
};
|
};
|
||||||
|
|
||||||
Server.client = new lc.LanguageClient(
|
Server.client = new lc.LanguageClient(
|
||||||
'ra-lsp',
|
'ra-lsp',
|
||||||
'rust-analyzer languge server',
|
'rust-analyzer languge server',
|
||||||
serverOptions,
|
serverOptions,
|
||||||
clientOptions,
|
clientOptions
|
||||||
);
|
);
|
||||||
Server.client.onReady().then(() => {
|
Server.client.onReady().then(() => {
|
||||||
for (const [type, handler] of notificationHandlers) {
|
for (const [type, handler] of notificationHandlers) {
|
||||||
|
|
|
@ -3,15 +3,10 @@
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"outDir": "out",
|
"outDir": "out",
|
||||||
"lib": [
|
"lib": ["es6"],
|
||||||
"es6"
|
|
||||||
],
|
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"strict": true
|
"strict": true
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": ["node_modules", ".vscode-test"]
|
||||||
"node_modules",
|
|
||||||
".vscode-test"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
{
|
{
|
||||||
"defaultSeverity": "error",
|
"defaultSeverity": "error",
|
||||||
"extends": [
|
"extends": ["tslint:recommended", "tslint-config-prettier"],
|
||||||
"tslint:recommended"
|
|
||||||
],
|
|
||||||
"jsRules": {},
|
|
||||||
"rules": {
|
"rules": {
|
||||||
"quotemark": [true, "single"],
|
"quotemark": [true, "single"],
|
||||||
"interface-name": false,
|
"interface-name": false,
|
||||||
"object-literal-sort-keys": false
|
"object-literal-sort-keys": false
|
||||||
},
|
}
|
||||||
"rulesDirectory": []
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue