Skip to content

Commit 1dd6ea3

Browse files
committed
Convert IOutlineSupport to DocumentSymbolProvider
1 parent 3ca51f6 commit 1dd6ea3

16 files changed

Lines changed: 416 additions & 354 deletions

File tree

src/vs/editor/common/modes.ts

Lines changed: 120 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -427,21 +427,127 @@ export interface DefinitionProvider {
427427
provideDefinition(model:editorCommon.IReadOnlyModel, position:editorCommon.IEditorPosition, token:CancellationToken): Definition | Thenable<Definition>;
428428
}
429429

430+
export enum SymbolKind {
431+
File,
432+
Module,
433+
Namespace,
434+
Package,
435+
Class,
436+
Method,
437+
Property,
438+
Field,
439+
Constructor,
440+
Enum,
441+
Interface,
442+
Function,
443+
Variable,
444+
Constant,
445+
String,
446+
Number,
447+
Boolean,
448+
Array,
449+
Object,
450+
Key,
451+
Null
452+
}
453+
export namespace SymbolKind {
454+
455+
export function from(kind: number | SymbolKind): string {
456+
switch (kind) {
457+
case SymbolKind.Method:
458+
return 'method';
459+
case SymbolKind.Function:
460+
return 'function';
461+
case SymbolKind.Constructor:
462+
return 'constructor';
463+
case SymbolKind.Variable:
464+
return 'variable';
465+
case SymbolKind.Class:
466+
return 'class';
467+
case SymbolKind.Interface:
468+
return 'interface';
469+
case SymbolKind.Namespace:
470+
return 'namespace';
471+
case SymbolKind.Package:
472+
return 'package';
473+
case SymbolKind.Module:
474+
return 'module';
475+
case SymbolKind.Property:
476+
return 'property';
477+
case SymbolKind.Enum:
478+
return 'enum';
479+
case SymbolKind.String:
480+
return 'string';
481+
case SymbolKind.File:
482+
return 'file';
483+
case SymbolKind.Array:
484+
return 'array';
485+
case SymbolKind.Number:
486+
return 'number';
487+
case SymbolKind.Boolean:
488+
return 'boolean';
489+
case SymbolKind.Object:
490+
return 'object';
491+
case SymbolKind.Key:
492+
return 'key';
493+
case SymbolKind.Null:
494+
return 'null';
495+
}
496+
return 'property';
497+
}
430498

431-
/**
432-
* Interface used to compute an outline
433-
*/
434-
export interface IOutlineEntry {
435-
label: string;
436-
containerLabel?: string;
437-
type: string;
438-
icon?: string; // icon class or null to use the default images based on the type
439-
range: editorCommon.IRange;
440-
children?: IOutlineEntry[];
499+
export function to(type: string): SymbolKind {
500+
switch (type) {
501+
case 'method':
502+
return SymbolKind.Method;
503+
case 'function':
504+
return SymbolKind.Function;
505+
case 'constructor':
506+
return SymbolKind.Constructor;
507+
case 'variable':
508+
return SymbolKind.Variable;
509+
case 'class':
510+
return SymbolKind.Class;
511+
case 'interface':
512+
return SymbolKind.Interface;
513+
case 'namespace':
514+
return SymbolKind.Namespace;
515+
case 'package':
516+
return SymbolKind.Package;
517+
case 'module':
518+
return SymbolKind.Module;
519+
case 'property':
520+
return SymbolKind.Property;
521+
case 'enum':
522+
return SymbolKind.Enum;
523+
case 'string':
524+
return SymbolKind.String;
525+
case 'file':
526+
return SymbolKind.File;
527+
case 'array':
528+
return SymbolKind.Array;
529+
case 'number':
530+
return SymbolKind.Number;
531+
case 'boolean':
532+
return SymbolKind.Boolean;
533+
case 'object':
534+
return SymbolKind.Object;
535+
case 'key':
536+
return SymbolKind.Key;
537+
case 'null':
538+
return SymbolKind.Null;
539+
}
540+
return SymbolKind.Property;
541+
}
441542
}
442-
443-
export interface IOutlineSupport {
444-
getOutline(resource:URI):TPromise<IOutlineEntry[]>;
543+
export interface SymbolInformation {
544+
name: string;
545+
containerName?: string;
546+
kind: SymbolKind;
547+
location: Location;
548+
}
549+
export interface DocumentSymbolProvider {
550+
provideDocumentSymbols(model:editorCommon.IReadOnlyModel, token: CancellationToken): SymbolInformation[] | Thenable<SymbolInformation[]>;
445551
}
446552

447553
/**
@@ -691,7 +797,7 @@ export const SignatureHelpProviderRegistry = new LanguageFeatureRegistry<Signatu
691797

692798
export const HoverProviderRegistry = new LanguageFeatureRegistry<HoverProvider>();
693799

694-
export const OutlineRegistry = new LanguageFeatureRegistry<IOutlineSupport>();
800+
export const DocumentSymbolProviderRegistry = new LanguageFeatureRegistry<DocumentSymbolProvider>();
695801

696802
export const DocumentHighlightProviderRegistry = new LanguageFeatureRegistry<DocumentHighlightProvider>();
697803

src/vs/editor/contrib/outlineMarker/browser/outlineMarker.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle';
1212
import {TPromise} from 'vs/base/common/winjs.base';
1313
import {Range} from 'vs/editor/common/core/range';
1414
import * as editorCommon from 'vs/editor/common/editorCommon';
15-
import {IOutlineEntry, OutlineRegistry} from 'vs/editor/common/modes';
15+
import {SymbolInformation, SymbolKind, DocumentSymbolProviderRegistry} from 'vs/editor/common/modes';
1616
import {ICodeEditor, IViewZone, IViewZoneChangeAccessor} from 'vs/editor/browser/editorBrowser';
1717
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
18-
import {getOutlineEntries, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
18+
import {getDocumentSymbols, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
1919

2020
class OutlineViewZone implements IViewZone {
2121

@@ -25,15 +25,14 @@ class OutlineViewZone implements IViewZone {
2525

2626
public domNode:HTMLElement;
2727

28-
constructor(range:editorCommon.IRange, outlineType:string)
29-
{
28+
constructor(range:editorCommon.IRange, outlineType:SymbolKind) {
3029
this.afterLineNumber = range.startLineNumber-1;
3130
this.heightInPx = 4;
3231
this.suppressMouseDown = true;
3332

3433
this.domNode = document.createElement('div');
3534
var hr = document.createElement('hr');
36-
hr.className = 'outlineRule ' + outlineType;
35+
hr.className = 'outlineRule ' + SymbolKind.from(outlineType);
3736
this.domNode.appendChild(hr);
3837
}
3938
}
@@ -78,8 +77,7 @@ class OutlineMarker {
7877
private _editor:ICodeEditor;
7978

8079

81-
public constructor(range:editorCommon.IRange, outlineType:string, _editor:ICodeEditor, helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor)
82-
{
80+
public constructor(range:editorCommon.IRange, outlineType:SymbolKind, _editor:ICodeEditor, helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor) {
8381
this._editor = _editor;
8482
this._viewZone = new OutlineViewZone(range, outlineType);
8583
this._viewZoneId = viewZoneChangeAccessor.addZone(this._viewZone);
@@ -177,7 +175,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
177175
return;
178176
}
179177

180-
if (!OutlineRegistry.has(model)) {
178+
if (!DocumentSymbolProviderRegistry.has(model)) {
181179
return;
182180
}
183181

@@ -186,7 +184,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
186184
this._currentOutlinePromise.cancel();
187185
}
188186

189-
this._currentOutlinePromise = getOutlineEntries(model);
187+
this._currentOutlinePromise = getDocumentSymbols(model);
190188

191189
this._currentOutlinePromise.then((result) => {
192190
this.renderOutlines(result.entries);
@@ -224,7 +222,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
224222
scheduler.schedule();
225223
}
226224

227-
private renderOutlines(entries: IOutlineEntry[]): void {
225+
private renderOutlines(entries: SymbolInformation[]): void {
228226
var centeredRange = this._editor.getCenteredRangeInViewport();
229227
var oldMarkersCount = this._markers.length;
230228
this._editor.changeDecorations((decorationsAccessor) => {
@@ -244,18 +242,16 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi
244242
}
245243
}
246244

247-
private renderOutlinesRecursive(entries: IOutlineEntry[], helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor): void {
245+
private renderOutlinesRecursive(entries: SymbolInformation[], helper:OutlineMarkerHelper, viewZoneChangeAccessor:IViewZoneChangeAccessor): void {
248246
if (entries) {
249247
entries.forEach((outline) => {
250-
if (outline.type === 'class' || outline.type === 'method' || outline.type === 'function') {
251-
var range = Range.lift(outline.range);
248+
if (outline.kind === SymbolKind.Class || outline.kind === SymbolKind.Method || outline.kind === SymbolKind.Function) {
249+
var range = Range.lift(outline.location.range);
252250
if (!this.alreadyHasMarkerAtRange(range)) {
253-
var marker = new OutlineMarker(range, outline.type, this._editor, helper, viewZoneChangeAccessor);
251+
var marker = new OutlineMarker(range, outline.kind, this._editor, helper, viewZoneChangeAccessor);
254252
this._markers.push(marker);
255253
}
256254
}
257-
258-
this.renderOutlinesRecursive(outline.children, helper, viewZoneChangeAccessor);
259255
});
260256
}
261257
}

src/vs/editor/contrib/quickOpen/browser/quickOutline.ts

Lines changed: 11 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
import 'vs/css!./quickOutline';
1010
import * as nls from 'vs/nls';
11-
import * as arrays from 'vs/base/common/arrays';
1211
import {onUnexpectedError} from 'vs/base/common/errors';
1312
import {matchesFuzzy} from 'vs/base/common/filters';
1413
import * as strings from 'vs/base/common/strings';
@@ -17,9 +16,9 @@ import {IContext, IHighlight, QuickOpenEntryGroup, QuickOpenModel} from 'vs/base
1716
import {IAutoFocus, Mode} from 'vs/base/parts/quickopen/common/quickOpen';
1817
import {Behaviour} from 'vs/editor/common/editorActionEnablement';
1918
import {ICommonCodeEditor, IEditorActionDescriptorData, IRange} from 'vs/editor/common/editorCommon';
20-
import {IOutlineEntry, OutlineRegistry} from 'vs/editor/common/modes';
19+
import {SymbolInformation, SymbolKind, DocumentSymbolProviderRegistry} from 'vs/editor/common/modes';
2120
import {BaseEditorQuickOpenAction, IDecorator} from './editorQuickOpen';
22-
import {getOutlineEntries, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
21+
import {getDocumentSymbols, IOutline} from 'vs/editor/contrib/quickOpen/common/quickOpen';
2322

2423
let SCOPE_PREFIX = ':';
2524

@@ -108,19 +107,11 @@ class SymbolEntry extends QuickOpenEntryGroup {
108107
}
109108
}
110109

111-
interface OutlineNode {
112-
label: string;
113-
type: string;
114-
range: IRange;
115-
children?: OutlineNode[];
116-
parentScope?: string[];
117-
}
118-
119110
export class QuickOutlineAction extends BaseEditorQuickOpenAction {
120111

121112
public static ID = 'editor.action.quickOutline';
122113

123-
private cachedResult: IOutlineEntry[];
114+
private cachedResult: SymbolInformation[];
124115

125116
constructor(descriptor: IEditorActionDescriptorData, editor: ICommonCodeEditor) {
126117
super(descriptor, editor, nls.localize('QuickOutlineAction.label', "Go to Symbol..."), Behaviour.WidgetFocus | Behaviour.ShowInContextMenu);
@@ -131,18 +122,18 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
131122
}
132123

133124
public isSupported(): boolean {
134-
return (OutlineRegistry.has(this.editor.getModel()) && super.isSupported());
125+
return (DocumentSymbolProviderRegistry.has(this.editor.getModel()) && super.isSupported());
135126
}
136127

137128
public run(): TPromise<boolean> {
138129
let model = this.editor.getModel();
139130

140-
if (!OutlineRegistry.has(model)) {
131+
if (!DocumentSymbolProviderRegistry.has(model)) {
141132
return null;
142133
}
143134

144135
// Resolve outline
145-
let promise = getOutlineEntries(model);
136+
let promise = getDocumentSymbols(model);
146137
return promise.then((result: IOutline) => {
147138
if (result.entries.length > 0) {
148139

@@ -180,15 +171,9 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
180171
return nls.localize('quickOutlineActionInput', "Type the name of an identifier you wish to navigate to");
181172
}
182173

183-
private toQuickOpenEntries(outline: OutlineNode[], searchValue: string): SymbolEntry[] {
174+
private toQuickOpenEntries(flattened: SymbolInformation[], searchValue: string): SymbolEntry[] {
184175
let results: SymbolEntry[] = [];
185176

186-
// Flatten
187-
let flattened: OutlineNode[] = [];
188-
if (outline) {
189-
this.flatten(outline, flattened);
190-
}
191-
192177
// Convert to Entries
193178
let normalizedSearchValue = searchValue;
194179
if (searchValue.indexOf(SCOPE_PREFIX) === 0) {
@@ -197,20 +182,20 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
197182

198183
for (let i = 0; i < flattened.length; i++) {
199184
let element = flattened[i];
200-
let label = strings.trim(element.label);
185+
let label = strings.trim(element.name);
201186

202187
// Check for meatch
203188
let highlights = matchesFuzzy(normalizedSearchValue, label);
204189
if (highlights) {
205190

206191
// Show parent scope as description
207192
let description: string = null;
208-
if (element.parentScope) {
209-
description = arrays.tail(element.parentScope);
193+
if (element.containerName) {
194+
description = element.containerName;
210195
}
211196

212197
// Add
213-
results.push(new SymbolEntry(label, element.type, description, element.range, highlights, this.editor, this));
198+
results.push(new SymbolEntry(label, SymbolKind.from(element.kind), description, element.location.range, highlights, this.editor, this));
214199
}
215200
}
216201

@@ -284,27 +269,6 @@ export class QuickOutlineAction extends BaseEditorQuickOpenAction {
284269
return type;
285270
}
286271

287-
private flatten(outline: OutlineNode[], flattened: OutlineNode[], parentScope?: string[]): void {
288-
for (let i = 0; i < outline.length; i++) {
289-
let element = outline[i];
290-
flattened.push(element);
291-
292-
if (parentScope) {
293-
element.parentScope = parentScope;
294-
}
295-
296-
if (element.children) {
297-
let elementScope: string[] = [];
298-
if (parentScope) {
299-
elementScope = parentScope.slice(0);
300-
}
301-
elementScope.push(element.label);
302-
303-
this.flatten(element.children, flattened, elementScope);
304-
}
305-
}
306-
}
307-
308272
private sortNormal(searchValue: string, elementA: SymbolEntry, elementB: SymbolEntry): number {
309273
let elementAName = elementA.getLabel().toLowerCase();
310274
let elementBName = elementB.getLabel().toLowerCase();

0 commit comments

Comments
 (0)