提交 a54c02ae 编写于 作者: J Johannes Rieken

add setting: outline.symbolSortOrder

上级 51555021
...@@ -324,24 +324,37 @@ export class OutlineItemComparator implements ITreeSorter<OutlineItem> { ...@@ -324,24 +324,37 @@ export class OutlineItemComparator implements ITreeSorter<OutlineItem> {
private readonly _collator = new IdleValue<Intl.Collator>(() => new Intl.Collator(undefined, { numeric: true })); private readonly _collator = new IdleValue<Intl.Collator>(() => new Intl.Collator(undefined, { numeric: true }));
constructor( constructor(
public type: OutlineSortOrder = OutlineSortOrder.ByPosition private readonly _prefix: 'breadcrumbs' | 'outline',
@ITextResourceConfigurationService private readonly _textResourceConfigService: ITextResourceConfigurationService,
) { } ) { }
compare(a: OutlineItem, b: OutlineItem): number { compare(a: OutlineItem, b: OutlineItem): number {
if (a instanceof OutlineGroup && b instanceof OutlineGroup) { if (a instanceof OutlineGroup && b instanceof OutlineGroup) {
return a.order - b.order; return a.order - b.order;
} else if (a instanceof OutlineElement && b instanceof OutlineElement) { } else if (a instanceof OutlineElement && b instanceof OutlineElement) {
if (this.type === OutlineSortOrder.ByKind) { const type = this._getSortOrder(OutlineModel.get(a));
if (type === OutlineSortOrder.ByKind) {
return a.symbol.kind - b.symbol.kind || this._collator.value.compare(a.symbol.name, b.symbol.name); return a.symbol.kind - b.symbol.kind || this._collator.value.compare(a.symbol.name, b.symbol.name);
} else if (this.type === OutlineSortOrder.ByName) { } else if (type === OutlineSortOrder.ByName) {
return this._collator.value.compare(a.symbol.name, b.symbol.name) || Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range); return this._collator.value.compare(a.symbol.name, b.symbol.name) || Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range);
} else if (this.type === OutlineSortOrder.ByPosition) { } else if (type === OutlineSortOrder.ByPosition) {
return Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range) || this._collator.value.compare(a.symbol.name, b.symbol.name); return Range.compareRangesUsingStarts(a.symbol.range, b.symbol.range) || this._collator.value.compare(a.symbol.name, b.symbol.name);
} }
} }
return 0; return 0;
} }
private _getSortOrder(model: OutlineModel | undefined): OutlineSortOrder {
const uri = model?.textModel.uri;
const value = this._textResourceConfigService.getValue(uri, `${this._prefix}.symbolSortOrder`);
if (value === 'name') {
return OutlineSortOrder.ByName;
} else if (value === 'type') {
return OutlineSortOrder.ByKind;
} else {
return OutlineSortOrder.ByPosition;
}
}
} }
export class OutlineDataSource implements IDataSource<OutlineModel, OutlineItem> { export class OutlineDataSource implements IDataSource<OutlineModel, OutlineItem> {
......
...@@ -31,7 +31,7 @@ import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvent ...@@ -31,7 +31,7 @@ import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvent
import { IDataSource } from 'vs/base/browser/ui/tree/tree'; import { IDataSource } from 'vs/base/browser/ui/tree/tree';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { OutlineConfigKeys, OutlineSortOrder } from 'vs/editor/contrib/documentSymbols/outline'; import { OutlineConfigKeys } from 'vs/editor/contrib/documentSymbols/outline';
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService'; import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
import { MarkerSeverity } from 'vs/platform/markers/common/markers'; import { MarkerSeverity } from 'vs/platform/markers/common/markers';
...@@ -184,8 +184,6 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> { ...@@ -184,8 +184,6 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> {
keyboardNavigationLabelProvider: new OutlineNavigationLabelProvider(), keyboardNavigationLabelProvider: new OutlineNavigationLabelProvider(),
}; };
const breadcrumbsSorter = new OutlineItemComparator();
this.breadcrumbsConfig = { this.breadcrumbsConfig = {
breadcrumbsDataSource: this._breadcrumbsDataSource, breadcrumbsDataSource: this._breadcrumbsDataSource,
delegate, delegate,
...@@ -193,7 +191,7 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> { ...@@ -193,7 +191,7 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> {
treeDataSource, treeDataSource,
options: { options: {
...options, ...options,
sorter: breadcrumbsSorter, sorter: instantiationService.createInstance(OutlineItemComparator, 'breadcrumbs'),
filter: instantiationService.createInstance(OutlineFilter, 'breadcrumbs'), filter: instantiationService.createInstance(OutlineFilter, 'breadcrumbs'),
accessibilityProvider: new OutlineAccessibilityProvider(localize('breadcrumbs', "Breadcrumbs")), accessibilityProvider: new OutlineAccessibilityProvider(localize('breadcrumbs', "Breadcrumbs")),
} }
...@@ -205,7 +203,7 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> { ...@@ -205,7 +203,7 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> {
treeDataSource, treeDataSource,
options: { options: {
...options, ...options,
sorter: new OutlineItemComparator(), //todo@jrieken sorter: instantiationService.createInstance(OutlineItemComparator, 'outline'),
filter: instantiationService.createInstance(OutlineFilter, 'outline'), filter: instantiationService.createInstance(OutlineFilter, 'outline'),
accessibilityProvider: new OutlineAccessibilityProvider(localize('outline', "Outline")), accessibilityProvider: new OutlineAccessibilityProvider(localize('outline', "Outline")),
} }
...@@ -215,22 +213,6 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> { ...@@ -215,22 +213,6 @@ class DocumentSymbolsOutline implements IOutline<DocumentSymbolItem> {
quickPickDataSource: { getQuickPickElements: () => { throw new Error('not implemented'); } } quickPickDataSource: { getQuickPickElements: () => { throw new Error('not implemented'); } }
}; };
// special sorting for breadcrumbs
const updateSort = () => {
const uri = this._outlineModel?.textModel.uri;
const value = textResourceConfigurationService.getValue(uri, `breadcrumbs.symbolSortOrder`);
if (value === 'name') {
breadcrumbsSorter.type = OutlineSortOrder.ByName;
} else if (value === 'type') {
breadcrumbsSorter.type = OutlineSortOrder.ByKind;
} else {
breadcrumbsSorter.type = OutlineSortOrder.ByPosition;
}
};
this._disposables.add(textResourceConfigurationService.onDidChangeConfiguration(() => updateSort()));
updateSort();
// update as language, model, providers changes // update as language, model, providers changes
this._disposables.add(DocumentSymbolProviderRegistry.onDidChange(_ => this._createOutline())); this._disposables.add(DocumentSymbolProviderRegistry.onDidChange(_ => this._createOutline()));
this._disposables.add(this._editor.onDidChangeModel(_ => this._createOutline())); this._disposables.add(this._editor.onDidChangeModel(_ => this._createOutline()));
......
...@@ -44,6 +44,18 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis ...@@ -44,6 +44,18 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
'type': 'boolean', 'type': 'boolean',
'default': true 'default': true
}, },
'outline.symbolSortOrder': {
description: localize('symbolSortOrder', "Controls how symbols are sorted in the outline view."),
type: 'string',
default: 'position',
// scope: ConfigurationScope.LANGUAGE_OVERRIDABLE,
enum: ['position', 'name', 'type'],
enumDescriptions: [
localize('symbolSortOrder.position', "Show symbol outline in file position order."),
localize('symbolSortOrder.name', "Show symbol outline in alphabetical order."),
localize('symbolSortOrder.type', "Show symbol outline in symbol type order."),
]
},
[OutlineConfigKeys.problemsEnabled]: { [OutlineConfigKeys.problemsEnabled]: {
'description': localize('outline.showProblem', "Show Errors & Warnings on Outline Elements."), 'description': localize('outline.showProblem', "Show Errors & Warnings on Outline Elements."),
'type': 'boolean', 'type': 'boolean',
......
...@@ -11,7 +11,7 @@ import { IDisposable, toDisposable, DisposableStore, MutableDisposable } from 'v ...@@ -11,7 +11,7 @@ import { IDisposable, toDisposable, DisposableStore, MutableDisposable } from 'v
import { LRUCache } from 'vs/base/common/map'; import { LRUCache } from 'vs/base/common/map';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ContextKeyEqualsExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ContextKeyEqualsExpr, ContextKeyExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
...@@ -22,7 +22,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; ...@@ -22,7 +22,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ViewAction, ViewPane } from 'vs/workbench/browser/parts/views/viewPane'; import { ViewAction, ViewPane } from 'vs/workbench/browser/parts/views/viewPane';
import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet'; import { IViewletViewOptions } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { OutlineViewFocused, OutlineViewFiltered, OutlineViewId, OutlineSortOrder } from 'vs/editor/contrib/documentSymbols/outline'; import { OutlineViewFocused, OutlineViewFiltered, OutlineViewId } from 'vs/editor/contrib/documentSymbols/outline';
import { FuzzyScore } from 'vs/base/common/filters'; import { FuzzyScore } from 'vs/base/common/filters';
import { IDataTreeViewState } from 'vs/base/browser/ui/tree/dataTree'; import { IDataTreeViewState } from 'vs/base/browser/ui/tree/dataTree';
import { basename } from 'vs/base/common/resources'; import { basename } from 'vs/base/common/resources';
...@@ -58,7 +58,6 @@ export class OutlinePane extends ViewPane { ...@@ -58,7 +58,6 @@ export class OutlinePane extends ViewPane {
private readonly _ctxFiltered: IContextKey<boolean>; private readonly _ctxFiltered: IContextKey<boolean>;
private readonly _ctxFollowsCursor: IContextKey<boolean>; private readonly _ctxFollowsCursor: IContextKey<boolean>;
private readonly _ctxFilterOnType: IContextKey<boolean>; private readonly _ctxFilterOnType: IContextKey<boolean>;
private readonly _ctxSortMode: IContextKey<OutlineSortOrder>;
constructor( constructor(
options: IViewletViewOptions, options: IViewletViewOptions,
...@@ -78,21 +77,19 @@ export class OutlinePane extends ViewPane { ...@@ -78,21 +77,19 @@ export class OutlinePane extends ViewPane {
) { ) {
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, _instantiationService, openerService, themeService, telemetryService); super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, _instantiationService, openerService, themeService, telemetryService);
this._outlineViewState.restore(this._storageService); this._outlineViewState.restore(this._storageService);
this._ctxFocused = OutlineViewFocused.bindTo(contextKeyService); this._ctxFocused = OutlineViewFocused.bindTo(contextKeyService);
this._ctxFiltered = OutlineViewFiltered.bindTo(contextKeyService); this._ctxFiltered = OutlineViewFiltered.bindTo(contextKeyService);
this._ctxFollowsCursor = _ctxFollowsCursor.bindTo(contextKeyService);
this._ctxFilterOnType = _ctxFilterOnType.bindTo(contextKeyService);
this._disposables.add(this.onDidFocus(_ => this._ctxFocused.set(true))); this._disposables.add(this.onDidFocus(_ => this._ctxFocused.set(true)));
this._disposables.add(this.onDidBlur(_ => this._ctxFocused.set(false))); this._disposables.add(this.onDidBlur(_ => this._ctxFocused.set(false)));
this._ctxFollowsCursor = _ctxFollowsCursor.bindTo(contextKeyService); this._disposables.add(configurationService.onDidChangeConfiguration(e => {
this._ctxFilterOnType = _ctxFilterOnType.bindTo(contextKeyService); if (e.affectsConfiguration('outline.symbolSortOrder')) {
this._ctxSortMode = _ctxSortMode.bindTo(contextKeyService); this._tree?.resort();
const viewStateToContext = () => { }
this._ctxFollowsCursor.set(this._outlineViewState.followCursor); }));
this._ctxFilterOnType.set(this._outlineViewState.filterOnType);
this._ctxSortMode.set(this._outlineViewState.sortBy);
};
viewStateToContext();
this._outlineViewState.onDidChange(viewStateToContext, this);
} }
dispose(): void { dispose(): void {
...@@ -149,18 +146,19 @@ export class OutlinePane extends ViewPane { ...@@ -149,18 +146,19 @@ export class OutlinePane extends ViewPane {
} }
private _onDidChangeUserState(e: { followCursor?: boolean, sortBy?: boolean, filterOnType?: boolean }) { private _onDidChangeUserState(e: { followCursor?: boolean, sortBy?: boolean, filterOnType?: boolean }) {
this._outlineViewState.persist(this._storageService);
if (e.sortBy) { this._ctxFollowsCursor.set(this._outlineViewState.followCursor);
// todo@jrieken this._ctxFilterOnType.set(this._outlineViewState.filterOnType);
// this._treeComparator.type = this._outlineViewState.sortBy;
this._tree?.resort(); this._outlineViewState.persist(this._storageService);
}
if (e.filterOnType) { if (e.filterOnType) {
this._tree?.updateOptions({ this._tree?.updateOptions({
filterOnType: this._outlineViewState.filterOnType filterOnType: this._outlineViewState.filterOnType
}); });
} }
if (e.followCursor) {
}
} }
private _showMessage(message: string) { private _showMessage(message: string) {
...@@ -306,7 +304,6 @@ export class OutlinePane extends ViewPane { ...@@ -306,7 +304,6 @@ export class OutlinePane extends ViewPane {
const _ctxFollowsCursor = new RawContextKey('outlineFollowsCursor', false); const _ctxFollowsCursor = new RawContextKey('outlineFollowsCursor', false);
const _ctxFilterOnType = new RawContextKey('outlineFiltersOnType', false); const _ctxFilterOnType = new RawContextKey('outlineFiltersOnType', false);
const _ctxSortMode = new RawContextKey<OutlineSortOrder>('outlineSortMode', OutlineSortOrder.ByPosition);
// --- commands // --- commands
...@@ -379,7 +376,7 @@ registerAction2(class SortByPosition extends ViewAction<OutlinePane> { ...@@ -379,7 +376,7 @@ registerAction2(class SortByPosition extends ViewAction<OutlinePane> {
id: 'outline.sortByPosition', id: 'outline.sortByPosition',
title: localize('sortByPosition', "Sort By: Position"), title: localize('sortByPosition', "Sort By: Position"),
f1: false, f1: false,
toggled: _ctxSortMode.isEqualTo(OutlineSortOrder.ByPosition), toggled: ContextKeyExpr.equals('config.outline.symbolSortOrder', 'position'),
menu: { menu: {
id: MenuId.ViewTitle, id: MenuId.ViewTitle,
group: 'sort', group: 'sort',
...@@ -388,8 +385,8 @@ registerAction2(class SortByPosition extends ViewAction<OutlinePane> { ...@@ -388,8 +385,8 @@ registerAction2(class SortByPosition extends ViewAction<OutlinePane> {
} }
}); });
} }
runInView(_accessor: ServicesAccessor, view: OutlinePane) { runInView(accessor: ServicesAccessor) {
view.outlineViewState.sortBy = OutlineSortOrder.ByPosition; accessor.get(IConfigurationService).updateValue('outline.symbolSortOrder', 'position');
} }
}); });
...@@ -400,7 +397,7 @@ registerAction2(class SortByName extends ViewAction<OutlinePane> { ...@@ -400,7 +397,7 @@ registerAction2(class SortByName extends ViewAction<OutlinePane> {
id: 'outline.sortByName', id: 'outline.sortByName',
title: localize('sortByName', "Sort By: Name"), title: localize('sortByName', "Sort By: Name"),
f1: false, f1: false,
toggled: _ctxSortMode.isEqualTo(OutlineSortOrder.ByName), toggled: ContextKeyExpr.equals('config.outline.symbolSortOrder', 'name'),
menu: { menu: {
id: MenuId.ViewTitle, id: MenuId.ViewTitle,
group: 'sort', group: 'sort',
...@@ -409,8 +406,8 @@ registerAction2(class SortByName extends ViewAction<OutlinePane> { ...@@ -409,8 +406,8 @@ registerAction2(class SortByName extends ViewAction<OutlinePane> {
} }
}); });
} }
runInView(_accessor: ServicesAccessor, view: OutlinePane) { runInView(accessor: ServicesAccessor) {
view.outlineViewState.sortBy = OutlineSortOrder.ByName; accessor.get(IConfigurationService).updateValue('outline.symbolSortOrder', 'name');
} }
}); });
...@@ -421,7 +418,7 @@ registerAction2(class SortByKind extends ViewAction<OutlinePane> { ...@@ -421,7 +418,7 @@ registerAction2(class SortByKind extends ViewAction<OutlinePane> {
id: 'outline.sortByKind', id: 'outline.sortByKind',
title: localize('sortByKind', "Sort By: Category"), title: localize('sortByKind', "Sort By: Category"),
f1: false, f1: false,
toggled: _ctxSortMode.isEqualTo(OutlineSortOrder.ByKind), toggled: ContextKeyExpr.equals('config.outline.symbolSortOrder', 'type'),
menu: { menu: {
id: MenuId.ViewTitle, id: MenuId.ViewTitle,
group: 'sort', group: 'sort',
...@@ -430,7 +427,7 @@ registerAction2(class SortByKind extends ViewAction<OutlinePane> { ...@@ -430,7 +427,7 @@ registerAction2(class SortByKind extends ViewAction<OutlinePane> {
} }
}); });
} }
runInView(_accessor: ServicesAccessor, view: OutlinePane) { runInView(accessor: ServicesAccessor) {
view.outlineViewState.sortBy = OutlineSortOrder.ByKind; accessor.get(IConfigurationService).updateValue('outline.symbolSortOrder', 'type');
} }
}); });
...@@ -5,13 +5,11 @@ ...@@ -5,13 +5,11 @@
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { OutlineSortOrder } from 'vs/editor/contrib/documentSymbols/outline';
export class OutlineViewState { export class OutlineViewState {
private _followCursor = false; private _followCursor = false;
private _filterOnType = true; private _filterOnType = true;
private _sortBy = OutlineSortOrder.ByKind;
private readonly _onDidChange = new Emitter<{ followCursor?: boolean; sortBy?: boolean; filterOnType?: boolean; }>(); private readonly _onDidChange = new Emitter<{ followCursor?: boolean; sortBy?: boolean; filterOnType?: boolean; }>();
readonly onDidChange = this._onDidChange.event; readonly onDidChange = this._onDidChange.event;
...@@ -38,21 +36,9 @@ export class OutlineViewState { ...@@ -38,21 +36,9 @@ export class OutlineViewState {
} }
} }
set sortBy(value: OutlineSortOrder) {
if (value !== this._sortBy) {
this._sortBy = value;
this._onDidChange.fire({ sortBy: true });
}
}
get sortBy(): OutlineSortOrder {
return this._sortBy;
}
persist(storageService: IStorageService): void { persist(storageService: IStorageService): void {
storageService.store('outline/state', JSON.stringify({ storageService.store('outline/state', JSON.stringify({
followCursor: this.followCursor, followCursor: this.followCursor,
sortBy: this.sortBy,
filterOnType: this.filterOnType, filterOnType: this.filterOnType,
}), StorageScope.WORKSPACE, StorageTarget.USER); }), StorageScope.WORKSPACE, StorageTarget.USER);
} }
...@@ -69,7 +55,6 @@ export class OutlineViewState { ...@@ -69,7 +55,6 @@ export class OutlineViewState {
return; return;
} }
this.followCursor = data.followCursor; this.followCursor = data.followCursor;
this.sortBy = data.sortBy;
if (typeof data.filterOnType === 'boolean') { if (typeof data.filterOnType === 'boolean') {
this.filterOnType = data.filterOnType; this.filterOnType = data.filterOnType;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册