nridge created this revision.
Herald added subscribers: cfe-commits, kadircet, arphaman, jkorous, MaskRay,
ilya-biryukov.
Herald added a project: clang.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D67537
Files:
clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
clang-tools-extra/clangd/clients/clangd-vscode/src/inactive-regions.ts
Index: clang-tools-extra/clangd/clients/clangd-vscode/src/inactive-regions.ts
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/inactive-regions.ts
@@ -0,0 +1,83 @@
+import * as vscode from 'vscode';
+import * as vscodelc from 'vscode-languageclient';
+import * as vscodelct from 'vscode-languageserver-types';
+
+// Parameters for the inactive regions (server-side) push notification.
+// Mirrors the structure in the inactive regions proposal for LSP.
+interface InactiveRegionsParams {
+ // The text document that has to be decorated with the inactive regions
+ // information.
+ textDocument: vscodelct.VersionedTextDocumentIdentifier;
+ // An array of inactive regions.
+ regions: vscodelc.Range[];
+}
+
+// Language server push notification providing the inactive regions
+// information for a text document.
+export const NotificationType =
+ new vscodelc.NotificationType<InactiveRegionsParams, void>(
+ 'textDocument/inactiveRegions');
+
+export class InactiveRegionsFeature implements vscodelc.StaticFeature {
+ private decorationType: vscode.TextEditorDecorationType;
+ private p2c: vscodelc.Protocol2CodeConverter;
+ private files: Map<string, vscode.Range[]> = new Map();
+ private subscriptions: vscode.Disposable[] = [];
+
+ constructor(client: vscodelc.LanguageClient) {
+ this.p2c = client.protocol2CodeConverter;
+ }
+
+ fillClientCapabilities(capabilities: vscodelc.ClientCapabilities) {
+ // Extend the ClientCapabilities type and add inactive regions
+ // capability to the object.
+ const textDocumentCapabilities: vscodelc.TextDocumentClientCapabilities &
+ { inactiveRegionsCapabilities?: { inactiveRegions: boolean } } =
+ capabilities.textDocument;
+ textDocumentCapabilities.inactiveRegionsCapabilities = {
+ inactiveRegions: true,
+ };
+ }
+ initialize(capabilities: vscodelc.ServerCapabilities,
+ documentSelector: vscodelc.DocumentSelector | undefined) {
+ this.decorationType = vscode.window.createTextEditorDecorationType({
+ isWholeLine: true,
+ light: {
+ color: "rgb(100, 100, 100)",
+ backgroundColor: "rgba(220, 220, 220, 0.3)",
+ },
+ dark: {
+ color: "rgb(100, 100, 100)",
+ backgroundColor: "rgba(18, 18, 18, 0.3)",
+ }
+ });
+ this.subscriptions.push(vscode.window.onDidChangeVisibleTextEditors(
+ (editors) => editors.forEach(
+ (e) => this.applyHighlights(e.document.uri.toString()))));
+ }
+
+ handleNotification(params: InactiveRegionsParams) {
+ const fileUri = params.textDocument.uri;
+ const ranges = params.regions.map(this.p2c.asRange);
+ this.files.set(fileUri, ranges);
+ this.applyHighlights(fileUri);
+ }
+
+ applyHighlights(fileUri: string) {
+ if (!this.files.has(fileUri)) {
+ return;
+ }
+ const ranges = this.files.get(fileUri);
+ vscode.window.visibleTextEditors.forEach((e) => {
+ if (e.document.uri.toString() !== fileUri)
+ return;
+ e.setDecorations(this.decorationType, ranges);
+ });
+ }
+
+ // Disposes of all disposable resources used by this object.
+ public dispose() {
+ this.subscriptions.forEach((d) => d.dispose());
+ this.subscriptions = [];
+ }
+}
\ No newline at end of file
Index: clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
===================================================================
--- clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
+++ clang-tools-extra/clangd/clients/clangd-vscode/src/extension.ts
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';
import * as vscodelc from 'vscode-languageclient';
import * as semanticHighlighting from './semantic-highlighting';
+import * as inactiveRegions from './inactive-regions';
/**
* Method to get workspace configuration option
@@ -13,15 +14,15 @@
}
namespace SwitchSourceHeaderRequest {
-export const type =
- new vscodelc.RequestType<vscodelc.TextDocumentIdentifier, string|undefined,
- void, void>('textDocument/switchSourceHeader');
+ export const type =
+ new vscodelc.RequestType<vscodelc.TextDocumentIdentifier, string | undefined,
+ void, void>('textDocument/switchSourceHeader');
}
class FileStatus {
private statuses = new Map<string, any>();
private readonly statusBarItem =
- vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10);
+ vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 10);
onFileUpdated(fileStatus: any) {
const filePath = vscode.Uri.parse(fileStatus.uri);
@@ -58,7 +59,7 @@
// prompt up the failure to users.
logFailedRequest(rpcReply: vscodelc.RPCMessageType, error: any) {
if (error instanceof vscodelc.ResponseError &&
- rpcReply.method === "workspace/executeCommand")
+ rpcReply.method === "workspace/executeCommand")
vscode.window.showErrorMessage(error.message);
// Call default implementation.
super.logFailedRequest(rpcReply, error);
@@ -73,13 +74,13 @@
const syncFileEvents = getConfig<boolean>('syncFileEvents', true);
const clangd: vscodelc.Executable = {
- command : getConfig<string>('path'),
- args : getConfig<string[]>('arguments')
+ command: getConfig<string>('path'),
+ args: getConfig<string[]>('arguments')
};
const traceFile = getConfig<string>('trace');
if (!!traceFile) {
- const trace = {CLANGD_TRACE : traceFile};
- clangd.options = {env : {...process.env, ...trace}};
+ const trace = { CLANGD_TRACE: traceFile };
+ clangd.options = { env: { ...process.env, ...trace } };
}
const serverOptions: vscodelc.ServerOptions = clangd;
@@ -89,73 +90,80 @@
// However, VSCode does not have CUDA as a supported language yet, so we
// cannot add a corresponding activationEvent for CUDA files and clangd will
// *not* load itself automatically on '.cu' files.
- const cudaFilePattern: string = '**/*.{' + [ 'cu' ].join() + '}';
+ const cudaFilePattern: string = '**/*.{' + ['cu'].join() + '}';
const clientOptions: vscodelc.LanguageClientOptions = {
- // Register the server for c-family and cuda files.
- documentSelector: [
- { scheme: 'file', language: 'c' },
- { scheme: 'file', language: 'cpp' },
- { scheme: 'file', language: 'objective-c'},
- { scheme: 'file', language: 'objective-cpp'},
- { scheme: 'file', pattern: cudaFilePattern },
- ],
- synchronize: !syncFileEvents ? undefined : {
- // FIXME: send sync file events when clangd provides implemenatations.
- },
- initializationOptions: { clangdFileStatus: true },
- // Do not switch to output window when clangd returns output
- revealOutputChannelOn: vscodelc.RevealOutputChannelOn.Never
- };
+ // Register the server for c-family and cuda files.
+ documentSelector: [
+ { scheme: 'file', language: 'c' },
+ { scheme: 'file', language: 'cpp' },
+ { scheme: 'file', language: 'objective-c' },
+ { scheme: 'file', language: 'objective-cpp' },
+ { scheme: 'file', pattern: cudaFilePattern },
+ ],
+ synchronize: !syncFileEvents ? undefined : {
+ // FIXME: send sync file events when clangd provides implemenatations.
+ },
+ initializationOptions: { clangdFileStatus: true },
+ // Do not switch to output window when clangd returns output
+ revealOutputChannelOn: vscodelc.RevealOutputChannelOn.Never
+ };
const clangdClient = new ClangdLanguageClient('Clang Language Server',
- serverOptions, clientOptions);
+ serverOptions, clientOptions);
const semanticHighlightingFeature =
- new semanticHighlighting.SemanticHighlightingFeature();
+ new semanticHighlighting.SemanticHighlightingFeature();
+ const inactiveRegionsFeature = new inactiveRegions.InactiveRegionsFeature(clangdClient);
+ context.subscriptions.push(
+ vscode.Disposable.from(semanticHighlightingFeature));
context.subscriptions.push(
- vscode.Disposable.from(semanticHighlightingFeature));
+ vscode.Disposable.from(inactiveRegionsFeature));
clangdClient.registerFeature(semanticHighlightingFeature);
+ clangdClient.registerFeature(inactiveRegionsFeature);
console.log('Clang Language Server is now active!');
context.subscriptions.push(clangdClient.start());
context.subscriptions.push(vscode.commands.registerCommand(
- 'clangd-vscode.switchheadersource', async () => {
- const uri =
- vscode.Uri.file(vscode.window.activeTextEditor.document.fileName);
- if (!uri) {
- return;
- }
- const docIdentifier =
- vscodelc.TextDocumentIdentifier.create(uri.toString());
- const sourceUri = await clangdClient.sendRequest(
- SwitchSourceHeaderRequest.type, docIdentifier);
- if (!sourceUri) {
- return;
- }
- const doc = await vscode.workspace.openTextDocument(
- vscode.Uri.parse(sourceUri));
- vscode.window.showTextDocument(doc);
- }));
+ 'clangd-vscode.switchheadersource', async () => {
+ const uri =
+ vscode.Uri.file(vscode.window.activeTextEditor.document.fileName);
+ if (!uri) {
+ return;
+ }
+ const docIdentifier =
+ vscodelc.TextDocumentIdentifier.create(uri.toString());
+ const sourceUri = await clangdClient.sendRequest(
+ SwitchSourceHeaderRequest.type, docIdentifier);
+ if (!sourceUri) {
+ return;
+ }
+ const doc = await vscode.workspace.openTextDocument(
+ vscode.Uri.parse(sourceUri));
+ vscode.window.showTextDocument(doc);
+ }));
const status = new FileStatus();
context.subscriptions.push(vscode.Disposable.from(status));
context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(
- () => { status.updateStatus(); }));
- context.subscriptions.push(clangdClient.onDidChangeState(({newState}) => {
+ () => { status.updateStatus(); }));
+ context.subscriptions.push(clangdClient.onDidChangeState(({ newState }) => {
if (newState == vscodelc.State.Running) {
// clangd starts or restarts after crash.
clangdClient.onNotification(
- 'textDocument/clangd.fileStatus',
- (fileStatus) => { status.onFileUpdated(fileStatus); });
+ 'textDocument/clangd.fileStatus',
+ (fileStatus) => { status.onFileUpdated(fileStatus); });
clangdClient.onNotification(
- semanticHighlighting.NotificationType,
- semanticHighlightingFeature.handleNotification.bind(
- semanticHighlightingFeature));
+ semanticHighlighting.NotificationType,
+ semanticHighlightingFeature.handleNotification.bind(
+ semanticHighlightingFeature));
+ clangdClient.onNotification(inactiveRegions.NotificationType,
+ inactiveRegionsFeature.handleNotification.bind(inactiveRegionsFeature));
} else if (newState == vscodelc.State.Stopped) {
// Clear all cached statuses when clangd crashes.
status.clear();
semanticHighlightingFeature.dispose();
+ inactiveRegionsFeature.dispose();
}
}));
// An empty place holder for the activate command, otherwise we'll get an
// "command is not registered" error.
context.subscriptions.push(vscode.commands.registerCommand(
- 'clangd-vscode.activate', async () => {}));
+ 'clangd-vscode.activate', async () => { }));
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits