mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-04-27 16:55:44 +08:00
Merge branch 'vnext'
This commit is contained in:
@ -11,13 +11,13 @@ It is not intended as a product quality extension.
|
||||
|
||||

|
||||
|
||||
# How it works
|
||||
# How it works, what it shows?
|
||||
|
||||
- The extension implements and registers a [`TextDocumentContentProvider`](http://code.visualstudio.com/docs/extensionAPI/vscode-api#TextDocumentContentProvider) for a particular URI scheme.
|
||||
- The content provider uses the [`vscode.executeReferenceProvider`](http://code.visualstudio.com/docs/extensionAPI/vscode-api-commands)-API command to delegate searching for references to the language extensions, like TypeScript, vscode-go, or C#
|
||||
- The generated document initially contains a caption only and incrementally updates as each reference location is resolved.
|
||||
- The content provider uses the decoration API to highlight matches inside the generated document
|
||||
|
||||
- Add links for each result in the virtual document pointing to the reference.
|
||||
- Add an entry to editor context menu via `package.json`
|
||||
|
||||
# How to run locally
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples/issues"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.0.0"
|
||||
"vscode": "^1.4.0"
|
||||
},
|
||||
"categories": [
|
||||
"Other"
|
||||
@ -28,6 +28,15 @@
|
||||
"title": "Show All References"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"editor/context": [
|
||||
{
|
||||
"command": "editor.printReferences",
|
||||
"when": "editorHasReferenceProvider",
|
||||
"group": "navigation@1.31"
|
||||
}
|
||||
]
|
||||
},
|
||||
"languages": [
|
||||
{
|
||||
"id": "locations",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.2 MiB After Width: | Height: | Size: 1.2 MiB |
@ -3,15 +3,19 @@
|
||||
*--------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import {workspace, window, commands, ExtensionContext} from 'vscode';
|
||||
import ContentProvider, {encodeLocation} from './contentProvider';
|
||||
import {workspace, languages, window, commands, ExtensionContext, Disposable} from 'vscode';
|
||||
import ContentProvider, {encodeLocation} from './provider';
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
|
||||
const contentProvider = new ContentProvider();
|
||||
const provider = new ContentProvider();
|
||||
|
||||
// register content provider for scheme `references`
|
||||
const providerRegistration = workspace.registerTextDocumentContentProvider(ContentProvider.scheme, contentProvider);
|
||||
// register document link provider for scheme `references`
|
||||
const providerRegistrations = Disposable.from(
|
||||
workspace.registerTextDocumentContentProvider(ContentProvider.scheme, provider),
|
||||
languages.registerDocumentLinkProvider({ scheme: ContentProvider.scheme }, provider)
|
||||
);
|
||||
|
||||
// register command that crafts an uri with the `references` scheme,
|
||||
// open the dynamic document, and shows it in the next editor
|
||||
@ -21,8 +25,8 @@ export function activate(context: ExtensionContext) {
|
||||
});
|
||||
|
||||
context.subscriptions.push(
|
||||
contentProvider,
|
||||
provider,
|
||||
commandRegistration,
|
||||
providerRegistration
|
||||
providerRegistrations
|
||||
);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
import * as vscode from 'vscode';
|
||||
import ReferencesDocument from './referencesDocument';
|
||||
|
||||
export default class ContentProvider implements vscode.TextDocumentContentProvider {
|
||||
export default class Provider implements vscode.TextDocumentContentProvider, vscode.DocumentLinkProvider {
|
||||
|
||||
static scheme = 'references';
|
||||
|
||||
@ -19,11 +19,7 @@ export default class ContentProvider implements vscode.TextDocumentContentProvid
|
||||
|
||||
// Listen to the following events:
|
||||
// * closeTextDocument - which means we must clear the corresponding model object - `ReferencesDocument`
|
||||
// * changeActiveEditor - do decorate with references information
|
||||
this._subscriptions = vscode.Disposable.from(
|
||||
vscode.workspace.onDidCloseTextDocument(doc => this._documents.delete(doc.uri.toString())),
|
||||
vscode.window.onDidChangeActiveTextEditor(this._decorateEditor, this)
|
||||
);
|
||||
this._subscriptions = vscode.workspace.onDidCloseTextDocument(doc => this._documents.delete(doc.uri.toString()));
|
||||
}
|
||||
|
||||
dispose() {
|
||||
@ -63,7 +59,7 @@ export default class ContentProvider implements vscode.TextDocumentContentProvid
|
||||
|
||||
// sort by locations and shuffle to begin from target resource
|
||||
let idx = 0;
|
||||
locations.sort(ContentProvider._compareLocations).find((loc, i) => loc.uri.toString() === target.toString() && (idx = i) && true);
|
||||
locations.sort(Provider._compareLocations).find((loc, i) => loc.uri.toString() === target.toString() && (idx = i) && true);
|
||||
locations.push(...locations.splice(0, idx));
|
||||
|
||||
// create document and return its early state
|
||||
@ -73,18 +69,6 @@ export default class ContentProvider implements vscode.TextDocumentContentProvid
|
||||
});
|
||||
}
|
||||
|
||||
private _decorateEditor(editor: vscode.TextEditor) {
|
||||
// When an editor opens, check if it shows a `location` document
|
||||
// and decorate the actual references
|
||||
if (!editor || !vscode.languages.match('locations', editor.document)) {
|
||||
return;
|
||||
}
|
||||
let doc = this._documents.get(editor.document.uri.toString());
|
||||
if (doc) {
|
||||
doc.join().then(() => editor.setDecorations(this._editorDecoration, doc.ranges));
|
||||
}
|
||||
}
|
||||
|
||||
private static _compareLocations(a: vscode.Location, b: vscode.Location): number {
|
||||
if (a.uri.toString() < b.uri.toString()) {
|
||||
return -1;
|
||||
@ -94,13 +78,23 @@ export default class ContentProvider implements vscode.TextDocumentContentProvid
|
||||
return a.range.start.compareTo(b.range.start)
|
||||
}
|
||||
}
|
||||
|
||||
provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.DocumentLink[] {
|
||||
// While building the virtual document we have already created the links.
|
||||
// Those are composed from the range inside the document and a target uri
|
||||
// to which they point
|
||||
const doc = this._documents.get(document.uri.toString());
|
||||
if (doc) {
|
||||
return doc.links;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let seq = 0;
|
||||
|
||||
export function encodeLocation(uri: vscode.Uri, pos: vscode.Position): vscode.Uri {
|
||||
const query = JSON.stringify([uri.toString(), pos.line, pos.character]);
|
||||
return vscode.Uri.parse(`${ContentProvider.scheme}:References.locations?${query}#${seq++}`);
|
||||
return vscode.Uri.parse(`${Provider.scheme}:References.locations?${query}#${seq++}`);
|
||||
}
|
||||
|
||||
export function decodeLocation(uri: vscode.Uri): [vscode.Uri, vscode.Position] {
|
||||
@ -12,7 +12,7 @@ export default class ReferencesDocument {
|
||||
private _locations: vscode.Location[];
|
||||
|
||||
private _lines: string[];
|
||||
private _ranges: vscode.Range[];
|
||||
private _links: vscode.DocumentLink[];
|
||||
private _join: Thenable<this>;
|
||||
|
||||
constructor(uri: vscode.Uri, locations: vscode.Location[], emitter: vscode.EventEmitter<vscode.Uri>) {
|
||||
@ -25,7 +25,7 @@ export default class ReferencesDocument {
|
||||
|
||||
// Start with printing a header and start resolving
|
||||
this._lines = [`Found ${this._locations.length} references`];
|
||||
this._ranges = [];
|
||||
this._links = [];
|
||||
this._join = this._populate();
|
||||
}
|
||||
|
||||
@ -33,8 +33,8 @@ export default class ReferencesDocument {
|
||||
return this._lines.join('\n');
|
||||
}
|
||||
|
||||
get ranges() {
|
||||
return this._ranges;
|
||||
get links() {
|
||||
return this._links;
|
||||
}
|
||||
|
||||
join(): Thenable<this> {
|
||||
@ -98,7 +98,7 @@ export default class ReferencesDocument {
|
||||
for (let i = 0; i < ranges.length; i++) {
|
||||
const {start: {line}} = ranges[i];
|
||||
this._appendLeading(doc, line, ranges[i - 1]);
|
||||
this._appendMatch(doc, line, ranges[i]);
|
||||
this._appendMatch(doc, line, ranges[i], uri);
|
||||
this._appendTrailing(doc, line, ranges[i + 1]);
|
||||
}
|
||||
|
||||
@ -115,17 +115,18 @@ export default class ReferencesDocument {
|
||||
}
|
||||
}
|
||||
|
||||
private _appendMatch(doc: vscode.TextDocument, line:number, match: vscode.Range) {
|
||||
private _appendMatch(doc: vscode.TextDocument, line:number, match: vscode.Range, target: vscode.Uri) {
|
||||
const text = doc.lineAt(line).text;
|
||||
const preamble = ` ${line + 1}: `;
|
||||
|
||||
// Append line, use new length of lines-array as line number
|
||||
// for decoration in the document (should really be a link)
|
||||
// for a link that point to the reference
|
||||
const len = this._lines.push(preamble + text);
|
||||
this._ranges.push(new vscode.Range(
|
||||
len - 1, preamble.length + match.start.character,
|
||||
len - 1, preamble.length + match.end.character)
|
||||
);
|
||||
|
||||
// Create a document link that will reveal the reference
|
||||
const linkRange = new vscode.Range(len - 1, preamble.length + match.start.character, len - 1, preamble.length + match.end.character);
|
||||
const linkTarget = target.with({ fragment: String(1 + match.start.line) });
|
||||
this._links.push(new vscode.DocumentLink(linkRange, linkTarget));
|
||||
}
|
||||
|
||||
private _appendTrailing(doc: vscode.TextDocument, line: number, next: vscode.Range): void {
|
||||
|
||||
@ -9,7 +9,7 @@ The purpose of the extension is to show a preview of the properties in the decla
|
||||
- Use `Show CSS Properties Preview`
|
||||
- Position the cursor inside the declaration block of the rule
|
||||
- The properties are rendered in the preview
|
||||
- Edit the propertis and the preview is updated
|
||||
- Edit the properties and the preview is updated
|
||||
|
||||

|
||||
|
||||
|
||||
Reference in New Issue
Block a user