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

move things around a little bit

上级 6e2c5735
......@@ -30,7 +30,7 @@ import {tokenizeToHtmlContent} from 'vs/editor/common/modes/textToHtmlTokenizer'
import {ICodeEditor, IEditorMouseEvent, IMouseTarget} from 'vs/editor/browser/editorBrowser';
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration';
import {ReferencesController} from 'vs/editor/contrib/referenceSearch/browser/referenceSearch';
import {ReferencesController} from 'vs/editor/contrib/referenceSearch/browser/referencesController';
export class DefinitionActionConfig {
......
......@@ -5,21 +5,13 @@
'use strict';
import * as nls from 'vs/nls';
import {isFalsyOrEmpty} from 'vs/base/common/arrays';
import {onUnexpectedError} from 'vs/base/common/errors';
import {KeyCode, KeyMod} from 'vs/base/common/keyCodes';
import {cAll} from 'vs/base/common/lifecycle';
import Severity from 'vs/base/common/severity';
import URI from 'vs/base/common/uri';
import {TPromise} from 'vs/base/common/winjs.base';
import {IEditorService} from 'vs/platform/editor/common/editor';
import {IInstantiationService, optional} from 'vs/platform/instantiation/common/instantiation';
import {ICommandHandler, IKeybindingContextKey, IKeybindingService, KbExpr} from 'vs/platform/keybinding/common/keybindingService';
import {optional} from 'vs/platform/instantiation/common/instantiation';
import {ICommandHandler, IKeybindingService, KbExpr} from 'vs/platform/keybinding/common/keybindingService';
import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegistry';
import {IMessageService} from 'vs/platform/message/common/message';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IStorageService} from 'vs/platform/storage/common/storage';
import {Position} from 'vs/editor/common/core/position';
import {Range} from 'vs/editor/common/core/range';
import {EditorAction} from 'vs/editor/common/editorAction';
......@@ -27,19 +19,12 @@ import {Behaviour} from 'vs/editor/common/editorActionEnablement';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions';
import {IReference, ReferenceSearchRegistry} from 'vs/editor/common/modes';
import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {IPeekViewService, getOuterEditor} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {findReferences} from '../common/referenceSearch';
import {ReferencesModel, OneReference} from './referenceSearchModel';
import {ReferenceWidget, LayoutData} from './referenceSearchWidget';
import {ReferenceWidget} from './referencesWidget';
import {ReferencesController, RequestOptions, ctxReferenceSearchVisible} from './referencesController';
import {ServicesAccessor} from 'vs/platform/instantiation/common/instantiation';
export interface RequestOptions {
getMetaTitle(references: IReference[]): string;
onGoto(reference: IReference): TPromise<any>;
}
const defaultReferenceSearchOptions: RequestOptions = {
getMetaTitle(references: IReference[]) {
return references.length > 1 && nls.localize('meta.titleReference', " – {0} references", references.length);
......@@ -47,221 +32,6 @@ const defaultReferenceSearchOptions: RequestOptions = {
onGoto: undefined
};
export class ReferencesController implements editorCommon.IEditorContribution {
public static ID = 'editor.contrib.referencesController';
private _editor: ICodeEditor;
private _widget: ReferenceWidget;
private _model: ReferencesModel;
private _requestIdPool = 0;
private _callOnClear: Function[] = [];
private _ignoreModelChangeEvent = false;
private _startTime: number = -1;
private _referenceSearchVisible: IKeybindingContextKey<boolean>;
static getController(editor:editorCommon.ICommonCodeEditor): ReferencesController {
return <ReferencesController> editor.getContribution(ReferencesController.ID);
}
public constructor(
editor: ICodeEditor,
@IKeybindingService keybindingService: IKeybindingService,
@IEditorService private _editorService: IEditorService,
@ITelemetryService private _telemetryService: ITelemetryService,
@IMessageService private _messageService: IMessageService,
@IInstantiationService private _instantiationService: IInstantiationService,
@IWorkspaceContextService private _contextService: IWorkspaceContextService,
@IStorageService private _storageService: IStorageService,
@optional(IPeekViewService) private _peekViewService: IPeekViewService
) {
this._editor = editor;
this._referenceSearchVisible = keybindingService.createKey(CONTEXT_REFERENCE_SEARCH_VISIBLE, false);
}
public getId(): string {
return ReferencesController.ID;
}
public dispose(): void {
if (this._widget) {
this._widget.dispose();
this._widget = null;
}
this._editor = null;
}
public isInPeekView() : boolean {
return this._peekViewService && this._peekViewService.isActive;
}
public closeReferenceSearch(): void {
this.clear();
}
public processRequest(range: editorCommon.IEditorRange, referencesPromise: TPromise<IReference[]>, options: RequestOptions) : void {
var widgetPosition = !this._widget ? null : this._widget.position;
// clean up from previous invocation
var widgetClosed = this.clear();
// Close if the position is still the same
if(widgetClosed && !!widgetPosition && range.containsPosition(widgetPosition)) {
return null;
}
this._referenceSearchVisible.set(true);
// close the widget on model/mode changes
this._callOnClear.push(this._editor.addListener(editorCommon.EventType.ModelModeChanged, () => { this.clear(); }));
this._callOnClear.push(this._editor.addListener(editorCommon.EventType.ModelChanged, () => {
if(!this._ignoreModelChangeEvent) {
this.clear();
}
}));
const storageKey = 'peekViewLayout';
const data = <LayoutData> JSON.parse(this._storageService.get(storageKey, undefined, '{}'));
this._widget = new ReferenceWidget(this._editor, data, this._editorService, this._contextService, this._instantiationService);
this._widget.setTitle(nls.localize('labelLoading', "Loading..."));
this._widget.show(range);
this._callOnClear.push(this._widget.onDidClose(() => {
referencesPromise.cancel();
this._storageService.store(storageKey, JSON.stringify(this._widget.layoutData));
this._widget = null;
this.clear();
}).dispose);
this._callOnClear.push(this._widget.onDidSelectReference(event => {
let {element, kind} = event;
switch (kind) {
case 'side':
case 'open':
this._openReference(element, kind === 'side');
break;
case 'goto':
if (options.onGoto) {
options.onGoto(element);
} else {
this._gotoReference(element);
}
break;
}
}).dispose);
var requestId = ++this._requestIdPool,
editorModel = this._editor.getModel();
var timer = this._telemetryService.timedPublicLog('findReferences', {
mode: editorModel.getMode().getId()
});
referencesPromise.then(references => {
// still current request? widget still open?
if(requestId !== this._requestIdPool || !this._widget) {
timer.stop();
return;
}
// has a result
if (isFalsyOrEmpty(references)) {
this._widget.showMessage(nls.localize('noResults', "No results"));
timer.stop();
return;
}
// create result model
this._model = new ReferencesModel(references, this._editorService);
// show widget
this._startTime = Date.now();
if (this._widget) {
this._widget.setMetaTitle(options.getMetaTitle(references));
this._widget.setModel(this._model);
}
timer.stop();
}, (error:any) => {
this._messageService.show(Severity.Error, error);
timer.stop();
});
}
private clear(): boolean {
if (this._startTime !== -1) {
this._telemetryService.publicLog('zoneWidgetShown', {
mode: 'reference search',
elapsedTime: Date.now() - this._startTime
});
this._startTime = -1;
}
var result = false;
if (this._widget) {
this._widget.dispose();
this._widget = null;
result = true;
}
this._referenceSearchVisible.reset();
cAll(this._callOnClear);
this._model = null;
this._editor.focus();
this._requestIdPool += 1; // Cancel pending requests
return result;
}
private _gotoReference(ref: OneReference): void {
this._ignoreModelChangeEvent = true;
const {resource, range} = ref;
this._editorService.openEditor({
resource,
options: { selection: range }
}).done(openedEditor => {
this._ignoreModelChangeEvent = false;
if (!openedEditor || openedEditor.getControl() !== this._editor) {
// TODO@Alex TODO@Joh
// when opening the current reference we might end up
// in a different editor instance. that means we also have
// a different instance of this reference search controller
// and cannot hold onto the widget (which likely doesn't
// exist). Instead of bailing out we should find the
// 'sister' action and pass our current model on to it.
this.clear();
return;
}
this._widget.show(range);
this._widget.focus();
}, (err) => {
this._ignoreModelChangeEvent = false;
onUnexpectedError(err);
});
}
private _openReference(ref: OneReference, sideBySide: boolean): void {
const {resource, range} = ref;
this._editorService.openEditor({
resource,
options: { selection: range }
}, sideBySide);
// clear stage
if (!sideBySide) {
this.clear();
}
}
}
export class ReferenceAction extends EditorAction {
public static ID = 'editor.action.referenceSearch.trigger';
......@@ -359,10 +129,10 @@ let showReferencesCommand: ICommandHandler = (accessor:ServicesAccessor, resourc
});
};
var CONTEXT_REFERENCE_SEARCH_VISIBLE = 'referenceSearchVisible';
// register action
EditorBrowserRegistry.registerEditorContribution(ReferencesController);
CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(ReferenceAction, ReferenceAction.ID, nls.localize('references.action.name', "Show References"), {
context: ContextKey.EditorTextFocus,
primary: KeyMod.Shift | KeyCode.F12
......@@ -403,7 +173,7 @@ KeybindingsRegistry.registerCommandDesc({
weight: CommonEditorRegistry.commandWeight(50),
primary: KeyCode.Escape,
secondary: [KeyMod.Shift | KeyCode.Escape],
when: KbExpr.and(KbExpr.has(CONTEXT_REFERENCE_SEARCH_VISIBLE), KbExpr.has('config.editor.dismissPeekOnEsc')),
when: KbExpr.and(KbExpr.has(ctxReferenceSearchVisible), KbExpr.has('config.editor.dismissPeekOnEsc')),
handler: closeActiveReferenceSearch
});
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as nls from 'vs/nls';
import {isFalsyOrEmpty} from 'vs/base/common/arrays';
import {onUnexpectedError} from 'vs/base/common/errors';
import {cAll} from 'vs/base/common/lifecycle';
import Severity from 'vs/base/common/severity';
import {TPromise} from 'vs/base/common/winjs.base';
import {IEditorService} from 'vs/platform/editor/common/editor';
import {IInstantiationService, optional} from 'vs/platform/instantiation/common/instantiation';
import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {IMessageService} from 'vs/platform/message/common/message';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IStorageService} from 'vs/platform/storage/common/storage';
import * as editorCommon from 'vs/editor/common/editorCommon';
import {IReference} from 'vs/editor/common/modes';
import {ICodeEditor} from 'vs/editor/browser/editorBrowser';
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {IPeekViewService} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {ReferencesModel, OneReference} from './referencesModel';
import {ReferenceWidget, LayoutData} from './referencesWidget';
export var ctxReferenceSearchVisible = 'referenceSearchVisible';
export interface RequestOptions {
getMetaTitle(references: IReference[]): string;
onGoto(reference: IReference): TPromise<any>;
}
export class ReferencesController implements editorCommon.IEditorContribution {
public static ID = 'editor.contrib.referencesController';
private _editor: ICodeEditor;
private _widget: ReferenceWidget;
private _model: ReferencesModel;
private _requestIdPool = 0;
private _callOnClear: Function[] = [];
private _ignoreModelChangeEvent = false;
private _startTime: number = -1;
private _referenceSearchVisible: IKeybindingContextKey<boolean>;
static getController(editor:editorCommon.ICommonCodeEditor): ReferencesController {
return <ReferencesController> editor.getContribution(ReferencesController.ID);
}
public constructor(
editor: ICodeEditor,
@IKeybindingService keybindingService: IKeybindingService,
@IEditorService private _editorService: IEditorService,
@ITelemetryService private _telemetryService: ITelemetryService,
@IMessageService private _messageService: IMessageService,
@IInstantiationService private _instantiationService: IInstantiationService,
@IWorkspaceContextService private _contextService: IWorkspaceContextService,
@IStorageService private _storageService: IStorageService,
@optional(IPeekViewService) private _peekViewService: IPeekViewService
) {
this._editor = editor;
this._referenceSearchVisible = keybindingService.createKey(ctxReferenceSearchVisible, false);
}
public getId(): string {
return ReferencesController.ID;
}
public dispose(): void {
if (this._widget) {
this._widget.dispose();
this._widget = null;
}
this._editor = null;
}
public isInPeekView() : boolean {
return this._peekViewService && this._peekViewService.isActive;
}
public closeReferenceSearch(): void {
this.clear();
}
public processRequest(range: editorCommon.IEditorRange, referencesPromise: TPromise<IReference[]>, options: RequestOptions) : void {
var widgetPosition = !this._widget ? null : this._widget.position;
// clean up from previous invocation
var widgetClosed = this.clear();
// Close if the position is still the same
if(widgetClosed && !!widgetPosition && range.containsPosition(widgetPosition)) {
return null;
}
this._referenceSearchVisible.set(true);
// close the widget on model/mode changes
this._callOnClear.push(this._editor.addListener(editorCommon.EventType.ModelModeChanged, () => { this.clear(); }));
this._callOnClear.push(this._editor.addListener(editorCommon.EventType.ModelChanged, () => {
if(!this._ignoreModelChangeEvent) {
this.clear();
}
}));
const storageKey = 'peekViewLayout';
const data = <LayoutData> JSON.parse(this._storageService.get(storageKey, undefined, '{}'));
this._widget = new ReferenceWidget(this._editor, data, this._editorService, this._contextService, this._instantiationService);
this._widget.setTitle(nls.localize('labelLoading', "Loading..."));
this._widget.show(range);
this._callOnClear.push(this._widget.onDidClose(() => {
referencesPromise.cancel();
this._storageService.store(storageKey, JSON.stringify(this._widget.layoutData));
this._widget = null;
this.clear();
}).dispose);
this._callOnClear.push(this._widget.onDidSelectReference(event => {
let {element, kind} = event;
switch (kind) {
case 'side':
case 'open':
this._openReference(element, kind === 'side');
break;
case 'goto':
if (options.onGoto) {
options.onGoto(element);
} else {
this._gotoReference(element);
}
break;
}
}).dispose);
var requestId = ++this._requestIdPool,
editorModel = this._editor.getModel();
var timer = this._telemetryService.timedPublicLog('findReferences', {
mode: editorModel.getMode().getId()
});
referencesPromise.then(references => {
// still current request? widget still open?
if(requestId !== this._requestIdPool || !this._widget) {
timer.stop();
return;
}
// has a result
if (isFalsyOrEmpty(references)) {
this._widget.showMessage(nls.localize('noResults', "No results"));
timer.stop();
return;
}
// create result model
this._model = new ReferencesModel(references);
// show widget
this._startTime = Date.now();
if (this._widget) {
this._widget.setMetaTitle(options.getMetaTitle(references));
this._widget.setModel(this._model);
}
timer.stop();
}, (error:any) => {
this._messageService.show(Severity.Error, error);
timer.stop();
});
}
private clear(): boolean {
if (this._startTime !== -1) {
this._telemetryService.publicLog('zoneWidgetShown', {
mode: 'reference search',
elapsedTime: Date.now() - this._startTime
});
this._startTime = -1;
}
var result = false;
if (this._widget) {
this._widget.dispose();
this._widget = null;
result = true;
}
this._referenceSearchVisible.reset();
cAll(this._callOnClear);
this._model = null;
this._editor.focus();
this._requestIdPool += 1; // Cancel pending requests
return result;
}
private _gotoReference(ref: OneReference): void {
this._ignoreModelChangeEvent = true;
const {resource, range} = ref;
this._editorService.openEditor({
resource,
options: { selection: range }
}).done(openedEditor => {
this._ignoreModelChangeEvent = false;
if (!openedEditor || openedEditor.getControl() !== this._editor) {
// TODO@Alex TODO@Joh
// when opening the current reference we might end up
// in a different editor instance. that means we also have
// a different instance of this reference search controller
// and cannot hold onto the widget (which likely doesn't
// exist). Instead of bailing out we should find the
// 'sister' action and pass our current model on to it.
this.clear();
return;
}
this._widget.show(range);
this._widget.focus();
}, (err) => {
this._ignoreModelChangeEvent = false;
onUnexpectedError(err);
});
}
private _openReference(ref: OneReference, sideBySide: boolean): void {
const {resource, range} = ref;
this._editorService.openEditor({
resource,
options: { selection: range }
}, sideBySide);
// clear stage
if (!sideBySide) {
this.clear();
}
}
}
EditorBrowserRegistry.registerEditorContribution(ReferencesController);
\ No newline at end of file
......@@ -97,7 +97,7 @@ export class FileReferences {
private _preview: FilePreview;
private _resolved: boolean;
constructor(private _parent: ReferencesModel, private _resource: URI, private _editorService: IEditorService) {
constructor(private _parent: ReferencesModel, private _resource: URI) {
this._children = [];
}
......@@ -129,13 +129,13 @@ export class FileReferences {
return this._preview;
}
public resolve(): TPromise<FileReferences> {
public resolve(editorService: IEditorService): TPromise<FileReferences> {
if (this._resolved) {
return TPromise.as(this);
}
return this._editorService.resolveEditorModel({ resource: this._resource }).then(model => {
return editorService.resolveEditorModel({ resource: this._resource }).then(model => {
this._preview = new FilePreview((<IModel>model.textEditorModel).getValue());
this._resolved = true;
return this;
......@@ -150,7 +150,7 @@ export class ReferencesModel {
onDidChangeReferenceRange: Event<OneReference> = fromEventEmitter<OneReference>(this._eventBus, 'ref/changed');
constructor(references: IReference[], editorService: IEditorService) {
constructor(references: IReference[]) {
let referencesByFile: { [n: string]: FileReferences } = Object.create(null);
let seen: { [n: string]: boolean } = Object.create(null);
......@@ -162,7 +162,7 @@ export class ReferencesModel {
seen[hash] = true;
let resource = reference.resource;
let fileReferences = new FileReferences(this, resource, editorService);
let fileReferences = new FileReferences(this, resource);
fileReferences = collections.lookupOrInsert(referencesByFile, fileReferences.id, fileReferences);
fileReferences.children.push(new OneReference(fileReferences, reference.range, this._eventBus));
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./referenceSearchWidget';
import 'vs/css!./referencesWidget';
import * as nls from 'vs/nls';
import * as collections from 'vs/base/common/collections';
import {onUnexpectedError} from 'vs/base/common/errors';
......@@ -36,7 +36,7 @@ import {Model} from 'vs/editor/common/model/model';
import {ICodeEditor, IMouseTarget} from 'vs/editor/browser/editorBrowser';
import {EmbeddedCodeEditorWidget} from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
import {PeekViewWidget, IPeekViewService} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget';
import {FileReferences, OneReference, ReferencesModel} from './referenceSearchModel';
import {FileReferences, OneReference, ReferencesModel} from './referencesModel';
class DecorationsManager implements IDisposable {
......@@ -163,6 +163,12 @@ class DecorationsManager implements IDisposable {
class DataSource implements tree.IDataSource {
constructor(
@IEditorService private _editorService: IEditorService
) {
//
}
public getId(tree:tree.ITree, element:any):string {
if(element instanceof ReferencesModel) {
return 'root';
......@@ -181,7 +187,7 @@ class DataSource implements tree.IDataSource {
if(element instanceof ReferencesModel) {
return TPromise.as((<ReferencesModel> element).children);
} else if(element instanceof FileReferences) {
return (<FileReferences> element).resolve().then(val => val.children);
return (<FileReferences> element).resolve(this._editorService).then(val => val.children);
} else {
return TPromise.as([]);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册