Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4667ff4

Browse files
committedJan 25, 2018
Add inline code lens.
It's off by default but if it works well it'll probably become default.
1 parent a6a84e2 commit 4667ff4

File tree

2 files changed

+84
-9
lines changed

2 files changed

+84
-9
lines changed
 

‎package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,11 @@
453453
"default": true,
454454
"description": "If true, code completion will trigger diagnostic updates."
455455
},
456+
"cquery.codeLens.renderInline": {
457+
"type": "boolean",
458+
"default": false,
459+
"description": "Enables a custom code lens renderer so code lens are displayed inline with code. This removes any vertical-space footprint at the cost of horizontal space."
460+
},
456461
"cquery.codeLens.onLocalVariables": {
457462
"type": "boolean",
458463
"default": false,

‎src/extension.ts

Lines changed: 79 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as path from 'path';
2-
import {commands, DecorationRangeBehavior, DecorationRenderOptions, ExtensionContext, Progress, ProgressLocation, QuickPickItem, Range, StatusBarAlignment, TextEditor, TextEditorDecorationType, Uri, window, workspace} from 'vscode';
2+
import {CodeLens, commands, DecorationOptions, DecorationRangeBehavior, DecorationRenderOptions, ExtensionContext, OverviewRulerLane, Position, Progress, ProgressLocation, ProviderResult, QuickPickItem, Range, StatusBarAlignment, TextDocument, TextEditor, TextEditorDecorationType, ThemeColor, Uri, window, workspace} from 'vscode';
33
import {Message} from 'vscode-jsonrpc';
4-
import {LanguageClient, LanguageClientOptions, RevealOutputChannelOn, ServerOptions} from 'vscode-languageclient/lib/main';
4+
import {CancellationToken, LanguageClient, LanguageClientOptions, Middleware, ProvideCodeLensesSignature, RevealOutputChannelOn, ServerOptions} from 'vscode-languageclient/lib/main';
55
import * as ls from 'vscode-languageserver-types';
66

77
import {CallTreeNode, CallTreeProvider} from './callTree';
@@ -148,10 +148,8 @@ export function activate(context: ExtensionContext) {
148148
JSON.stringify(clientConfig[key]) !=
149149
JSON.stringify(newConfig[key])) {
150150
const kReload = 'Reload'
151-
const message =
152-
`Please reload to apply the "cquery.${
153-
key
154-
}" configuration change.`;
151+
const message = `Please reload to apply the "cquery.${
152+
key}" configuration change.`;
155153

156154
window.showInformationMessage(message, kReload).then(selected => {
157155
if (selected == kReload)
@@ -177,6 +175,77 @@ export function activate(context: ExtensionContext) {
177175
console.log(
178176
`Starting ${serverOptions.command} in ${serverOptions.options.cwd}`);
179177

178+
179+
// Inline code lens.
180+
let decorationOpts: any = {};
181+
decorationOpts.rangeBehavior = DecorationRangeBehavior.ClosedClosed;
182+
decorationOpts.color = new ThemeColor('editorCodeLens.foreground');
183+
decorationOpts.fontStyle = 'italic';
184+
let codeLensDecoration = window.createTextEditorDecorationType(
185+
<DecorationRenderOptions>decorationOpts);
186+
187+
function displayCodeLens(document: TextDocument, allCodeLens: CodeLens[]) {
188+
for (let editor of window.visibleTextEditors) {
189+
if (editor.document != document)
190+
continue;
191+
192+
let opts: DecorationOptions[] = [];
193+
194+
for (let codeLens of allCodeLens) {
195+
// FIXME: show a real warning or disable on-the-side code lens.
196+
if (!codeLens.isResolved)
197+
console.error('Code lens is not resolved');
198+
199+
// Default to after the content.
200+
let position = codeLens.range.end;
201+
202+
// If multiline push to the end of the first line - works better for
203+
// functions.
204+
if (codeLens.range.start.line != codeLens.range.end.line)
205+
position = new Position(codeLens.range.start.line, 1000000);
206+
207+
let range = new Range(position, position);
208+
let opt: DecorationOptions = {
209+
range: range,
210+
renderOptions:
211+
{after: {contentText: ' ' + codeLens.command.title + ' '}}
212+
};
213+
214+
opts.push(opt);
215+
}
216+
217+
editor.setDecorations(codeLensDecoration, opts);
218+
}
219+
}
220+
221+
function provideCodeLens(
222+
document: TextDocument, token: CancellationToken,
223+
next: ProvideCodeLensesSignature): ProviderResult<CodeLens[]> {
224+
let config = workspace.getConfiguration('cquery');
225+
let enableInlineCodeLens = config.get('codeLens.renderInline', false);
226+
if (!enableInlineCodeLens)
227+
return next(document, token);
228+
229+
// We run the codeLens request ourselves so we can intercept the response.
230+
return languageClient
231+
.sendRequest('textDocument/codeLens', {
232+
textDocument: {
233+
uri: document.uri.toString(),
234+
},
235+
})
236+
.then(
237+
(a: ls.CodeLens[]):
238+
CodeLens[] => {
239+
let result: CodeLens[] =
240+
languageClient.protocol2CodeConverter.asCodeLenses(a);
241+
displayCodeLens(document, result);
242+
return [];
243+
},
244+
(reason) => {
245+
console.log(JSON.stringify(reason));
246+
});
247+
};
248+
180249
// Options to control the language client
181250
let clientOptions: LanguageClientOptions = {
182251
documentSelector: ['c', 'cpp', 'objective-c', 'objective-cpp'],
@@ -188,6 +257,7 @@ export function activate(context: ExtensionContext) {
188257
outputChannelName: 'cquery',
189258
revealOutputChannelOn: RevealOutputChannelOn.Never,
190259
initializationOptions: clientConfig,
260+
middleware: {provideCodeLenses: provideCodeLens},
191261
initializationFailedHandler: (e) => {
192262
console.log(e);
193263
return false;
@@ -425,7 +495,7 @@ export function activate(context: ExtensionContext) {
425495
},
426496
position: position
427497
})
428-
.then((typeEntry: TypeHierarchyNode | undefined) => {
498+
.then((typeEntry: TypeHierarchyNode|undefined) => {
429499
if (typeEntry) {
430500
typeHierarchyProvider.root = [typeEntry];
431501
typeHierarchyProvider.onDidChangeEmitter.fire();
@@ -483,7 +553,7 @@ export function activate(context: ExtensionContext) {
483553
// Common between tree views.
484554
(() => {
485555
commands.registerCommand(
486-
'cquery.gotoForTreeView', (node: TypeHierarchyNode | CallTreeNode) => {
556+
'cquery.gotoForTreeView', (node: TypeHierarchyNode|CallTreeNode) => {
487557
if (!node.location)
488558
return;
489559

@@ -497,7 +567,7 @@ export function activate(context: ExtensionContext) {
497567
let lastGotoClickTime: number
498568
commands.registerCommand(
499569
'cquery.hackGotoForTreeView',
500-
(node: TypeHierarchyNode | CallTreeNode, hasChildren: boolean) => {
570+
(node: TypeHierarchyNode|CallTreeNode, hasChildren: boolean) => {
501571
if (!node.location)
502572
return;
503573

0 commit comments

Comments
 (0)
Please sign in to comment.