Skip to content
This repository was archived by the owner on Jul 15, 2023. It is now read-only.

Commit 4aecaa6

Browse files
theSoenkeramya-rao-a
authored andcommitted
Add references codelens support (#933)
1 parent 5fab6f6 commit 4aecaa6

File tree

5 files changed

+97
-13
lines changed

5 files changed

+97
-13
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This extension adds rich language support for the Go language to VS Code, includ
1515
- Quick Info (using `gogetdoc` or `godef`+`godoc`)
1616
- Goto Definition (using `gogetdoc` or `godef`+`godoc`)
1717
- Find References (using `guru`)
18+
- References CodeLens
1819
- File outline (using `go-outline`)
1920
- Workspace symbol search (using `go-symbols`)
2021
- Rename (using `gorename`. Note: For Undo after rename to work in Windows you need to have `diff` tool in your path)
@@ -49,7 +50,7 @@ The Go extension is ready to use on the get go. If you want to customize the fea
4950

5051

5152
### Go Language Server (Experimental)
52-
Set `go.useLanguageServer` to `true` to use the Go language server from [Sourcegraph](https://github.com/sourcegraph/go-langserver) for features like Hover, Definition, Find All References, Signature Help, Go to Symbol in File and Workspace.
53+
Set `go.useLanguageServer` to `true` to use the Go language server from [Sourcegraph](https://github.com/sourcegraph/go-langserver) for features like Hover, Definition, Find All References, Signature Help, Go to Symbol in File and Workspace.
5354
* This is an experimental feature and is not available in Windows yet.
5455
* If set to true, you will be prompted to install the Go language server. Once installed, you will have to reload VS Code window. The language server will then be run by the Go extension in the background to provide services needed for the above mentioned features.
5556
* Everytime you change the value of the setting `go.useLanguageServer`, you need to reload the VS Code window for it to take effect.
@@ -112,7 +113,7 @@ For more read [Debugging Go Code Using VS Code](https://github.com/Microsoft/vsc
112113

113114
#### Remote Debugging
114115

115-
To remote debug using VS Code, read [Remote Debugging](https://github.com/Microsoft/vscode-go/wiki/Debugging-Go-code-using-VS-Code#remote-debugging)
116+
To remote debug using VS Code, read [Remote Debugging](https://github.com/Microsoft/vscode-go/wiki/Debugging-Go-code-using-VS-Code#remote-debugging)
116117

117118
## Building and Debugging the Extension
118119

package.json

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -510,16 +510,21 @@
510510
"default": false,
511511
"description": "If false, the import statements will be excluded while using the Go to Symbol in File feature"
512512
},
513+
"go.referencesCodeLens.enabled": {
514+
"type": "boolean",
515+
"default": false,
516+
"description": "Enable/disable references CodeLens"
517+
},
513518
"go.addTags": {
514519
"type": "object",
515520
"properties": {
516521
"promptForTags": {
517-
"type":"boolean",
522+
"type": "boolean",
518523
"default": false,
519524
"description": "If true, Go: Add Tags command will prompt the user to provide tags and options instead of using the configured values"
520525
},
521526
"tags": {
522-
"type":"string",
527+
"type": "string",
523528
"default": "json",
524529
"description": "Comma separated tags to be used by Go: Add Tags command"
525530
},
@@ -559,7 +564,7 @@
559564
"default": 500,
560565
"description": "The number of milliseconds to delay before execution. Resets with each keystroke."
561566
}
562-
},
567+
},
563568
"default": {
564569
"enabled": false,
565570
"delay": 500
@@ -570,12 +575,12 @@
570575
"type": "object",
571576
"properties": {
572577
"promptForTags": {
573-
"type":"boolean",
578+
"type": "boolean",
574579
"default": false,
575580
"description": "If true, Go: Remove Tags command will prompt the user to provide tags and options instead of using the configured values"
576581
},
577582
"tags": {
578-
"type":"string",
583+
"type": "string",
579584
"default": "json",
580585
"description": "Comma separated tags to be used by Go: Remove Tags command"
581586
},
@@ -624,7 +629,7 @@
624629
"type": "boolean",
625630
"default": true,
626631
"description": "If true, adds command to run all tests in the current package to the editor context menu"
627-
},
632+
},
628633
"generateTestForFunction": {
629634
"type": "boolean",
630635
"default": true,
@@ -701,7 +706,7 @@
701706
{
702707
"when": "editorTextFocus && config.go.editorContextMenuCommands.testPackage && resourceLangId == go",
703708
"command": "go.test.package"
704-
},
709+
},
705710
{
706711
"when": "editorTextFocus && config.go.editorContextMenuCommands.generateTestForFunction && resourceLangId == go",
707712
"command": "go.test.generate.function"

src/goCodelens.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
import vscode = require('vscode');
4+
import { CodeLensProvider, SymbolInformation, SymbolKind, TextDocument, CancellationToken, CodeLens, Range, Command, Location, commands } from 'vscode';
5+
import { documentSymbols, GoDocumentSymbolProvider } from './goOutline';
6+
import { GoReferenceProvider } from './goReferences';
7+
8+
export class GoCodeLensProvider implements CodeLensProvider {
9+
public provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable<CodeLens[]> {
10+
let codelensEnabled = vscode.workspace.getConfiguration('go').get('referencesCodeLens.enabled');
11+
if (!codelensEnabled) {
12+
return Promise.resolve([]);
13+
}
14+
15+
return this.provideDocumentSymbols(document, token).then(symbols => {
16+
let symbolReferences = symbols.map(symbol => this.provideSymbolReferences(document, symbol, token));
17+
return Promise.all(symbolReferences).then(values => {
18+
let codelenses = [];
19+
values.forEach(lens => {
20+
if (lens) {
21+
codelenses.push(lens);
22+
}
23+
});
24+
return codelenses;
25+
});
26+
});
27+
}
28+
29+
private provideDocumentSymbols(document: TextDocument, token: CancellationToken): Thenable<vscode.SymbolInformation[]> {
30+
let symbolProvider = new GoDocumentSymbolProvider();
31+
return symbolProvider.provideDocumentSymbols(document, token).then(symbols => {
32+
return symbols.filter(symbol =>
33+
symbol.kind === vscode.SymbolKind.Function ||
34+
symbol.kind === vscode.SymbolKind.Interface);
35+
});
36+
}
37+
38+
private provideSymbolReferences(document: TextDocument, symbol: SymbolInformation, token: CancellationToken): Thenable<CodeLens> {
39+
if (token.isCancellationRequested) {
40+
return Promise.resolve(null);
41+
}
42+
43+
let options = {
44+
includeDeclaration: false
45+
};
46+
let position = symbol.location.range.start;
47+
48+
// Add offset for functions due to go parser returns always 1 as the start character in a line
49+
if (symbol.kind === vscode.SymbolKind.Function) {
50+
position = position.translate(0, 5);
51+
}
52+
let referenceProvider = new GoReferenceProvider();
53+
return referenceProvider.provideReferences(document, position, options, token).then(references => {
54+
if (!references) {
55+
return Promise.resolve(null);
56+
}
57+
58+
let showReferences: Command = {
59+
title: references.length === 1
60+
? '1 reference'
61+
: references.length + ' references',
62+
command: 'editor.action.showReferences',
63+
arguments: [document.uri, position, references]
64+
};
65+
return new CodeLens(symbol.location.range, showReferences);
66+
});
67+
}
68+
}

src/goMain.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { LanguageClient } from 'vscode-languageclient';
3333
import { clearCacheForTools } from './goPath';
3434
import { addTags, removeTags } from './goModifytags';
3535
import { parseLiveFile } from './goLiveErrors';
36+
import { GoCodeLensProvider } from './goCodelens';
3637

3738
export let errorDiagnosticCollection: vscode.DiagnosticCollection;
3839
let warningDiagnosticCollection: vscode.DiagnosticCollection;
@@ -82,6 +83,7 @@ export function activate(ctx: vscode.ExtensionContext): void {
8283
ctx.subscriptions.push(vscode.languages.registerDocumentFormattingEditProvider(GO_MODE, new GoDocumentFormattingEditProvider()));
8384
ctx.subscriptions.push(vscode.languages.registerRenameProvider(GO_MODE, new GoRenameProvider()));
8485
ctx.subscriptions.push(vscode.languages.registerCodeActionsProvider(GO_MODE, new GoCodeActionProvider()));
86+
ctx.subscriptions.push(vscode.languages.registerCodeLensProvider(GO_MODE, new GoCodeLensProvider()));
8587

8688
errorDiagnosticCollection = vscode.languages.createDiagnosticCollection('go-error');
8789
ctx.subscriptions.push(errorDiagnosticCollection);

src/goReferences.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ import { promptForMissingTool } from './goInstallTools';
1414
export class GoReferenceProvider implements vscode.ReferenceProvider {
1515

1616
public provideReferences(document: vscode.TextDocument, position: vscode.Position, options: { includeDeclaration: boolean }, token: vscode.CancellationToken): Thenable<vscode.Location[]> {
17-
return vscode.workspace.saveAll(false).then(() => {
18-
return this.doFindReferences(document, position, options, token);
19-
});
17+
return this.doFindReferences(document, position, options, token);
2018
}
2119

2220
private doFindReferences(document: vscode.TextDocument, position: vscode.Position, options: { includeDeclaration: boolean }, token: vscode.CancellationToken): Thenable<vscode.Location[]> {
@@ -41,10 +39,12 @@ export class GoReferenceProvider implements vscode.ReferenceProvider {
4139
promptForMissingTool('guru');
4240
return resolve(null);
4341
}
44-
if (err) {
42+
43+
if (err && (<any>err).killed !== true) {
4544
console.log(err);
4645
return resolve(null);
4746
}
47+
4848
let lines = stdout.toString().split('\n');
4949
let results: vscode.Location[] = [];
5050
for (let i = 0; i < lines.length; i++) {
@@ -53,6 +53,14 @@ export class GoReferenceProvider implements vscode.ReferenceProvider {
5353
if (!match) continue;
5454
let [_, file, lineStartStr, colStartStr, lineEndStr, colEndStr] = match;
5555
let referenceResource = vscode.Uri.file(path.resolve(cwd, file));
56+
57+
if (!options.includeDeclaration) {
58+
if (document.uri.fsPath === referenceResource.fsPath &&
59+
position.line === Number(lineStartStr) - 1) {
60+
continue;
61+
}
62+
}
63+
5664
let range = new vscode.Range(
5765
+lineStartStr - 1, +colStartStr - 1, +lineEndStr - 1, +colEndStr
5866
);

0 commit comments

Comments
 (0)