Merge remote-tracking branch 'origin/master' into keybindings-service

This commit is contained in:
Alex Dima 2016-08-12 17:55:27 +02:00
commit 38e0840fb4
5 changed files with 67 additions and 78 deletions

View file

@ -17,6 +17,7 @@ import { EditorBrowserRegistry } from 'vs/editor/browser/editorBrowserExtensions
import { getSnippetController } from 'vs/editor/contrib/snippet/common/snippet';
import { Context as SuggestContext } from 'vs/editor/contrib/suggest/common/suggest';
import { SuggestModel } from '../common/suggestModel';
import { CompletionItem } from '../common/completionModel';
import { SuggestWidget } from './suggestWidget';
export class SuggestController implements IEditorContribution {
@ -29,18 +30,23 @@ export class SuggestController implements IEditorContribution {
private model: SuggestModel;
private widget: SuggestWidget;
private triggerCharacterListeners: IDisposable[];
private toDispose: IDisposable[];
private toDispose: IDisposable[] = [];
constructor(
private editor: ICodeEditor,
@IInstantiationService instantiationService: IInstantiationService
) {
this.model = new SuggestModel(this.editor);
this.widget = instantiationService.createInstance(SuggestWidget, this.editor, this.model);
this.widget = instantiationService.createInstance(SuggestWidget, this.editor);
this.toDispose.push(this.model.onDidTrigger(e => this.widget.showTriggered(e)));
this.toDispose.push(this.model.onDidSuggest(e => this.widget.showSuggestions(e)));
this.toDispose.push(this.model.onDidCancel(e => this.widget.showDidCancel(e)));
this.toDispose.push(this.widget.onDidSelect(this.onDidSelectItem, this));
this.triggerCharacterListeners = [];
this.toDispose = [];
this.toDispose.push(editor.onDidChangeConfiguration(() => this.update()));
this.toDispose.push(editor.onDidChangeModel(() => this.update()));
this.toDispose.push(editor.onDidChangeModelMode(() => this.update()));
@ -69,6 +75,15 @@ export class SuggestController implements IEditorContribution {
}
}
private onDidSelectItem(item: CompletionItem): void {
if (!item) {
this.model.cancel();
return;
}
const {overwriteBefore, overwriteAfter} = item.suggestion;
this.model.accept(item.suggestion, overwriteBefore, overwriteAfter);
}
private update(): void {
this.triggerCharacterListeners = dispose(this.triggerCharacterListeners);
@ -126,7 +141,8 @@ export class SuggestController implements IEditorContribution {
acceptSelectedSuggestion(): void {
if (this.widget) {
this.widget.acceptSelectedSuggestion();
const item = this.widget.getFocusedItem();
this.onDidSelectItem(item);
}
}

View file

@ -8,6 +8,7 @@
import 'vs/css!./suggest';
import * as nls from 'vs/nls';
import * as strings from 'vs/base/common/strings';
import Event, { Emitter } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
@ -23,7 +24,7 @@ import { IConfigurationChangedEvent } from 'vs/editor/common/editorCommon';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { Context as SuggestContext } from '../common/suggest';
import { CompletionItem, CompletionModel } from '../common/completionModel';
import { ICancelEvent, ISuggestEvent, ITriggerEvent, SuggestModel } from '../common/suggestModel';
import { ICancelEvent, ISuggestEvent, ITriggerEvent } from '../common/suggestModel';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@ -323,13 +324,14 @@ export class SuggestWidget implements IContentWidget, IDisposable {
private suggestWidgetMultipleSuggestions: IContextKey<boolean>;
private suggestionSupportsAutoAccept: IContextKey<boolean>;
private onDidSelectEmitter = new Emitter<CompletionItem>();
private editorBlurTimeout: TPromise<void>;
private showTimeout: TPromise<void>;
private toDispose: IDisposable[];
constructor(
private editor: ICodeEditor,
private model: SuggestModel,
@ITelemetryService private telemetryService: ITelemetryService,
@IContextKeyService contextKeyService: IContextKeyService,
@IInstantiationService instantiationService: IInstantiationService
@ -361,10 +363,7 @@ export class SuggestWidget implements IContentWidget, IDisposable {
editor.onDidBlurEditorText(() => this.onEditorBlur()),
this.list.onSelectionChange(e => this.onListSelection(e)),
this.list.onFocusChange(e => this.onListFocus(e)),
this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged()),
this.model.onDidTrigger(e => this.onDidTrigger(e)),
this.model.onDidSuggest(e => this.onDidSuggest(e)),
this.model.onDidCancel(e => this.onDidCancel(e))
this.editor.onDidChangeCursorSelection(() => this.onCursorSelectionChanged())
];
this.suggestWidgetVisible = SuggestContext.Visible.bindTo(contextKeyService);
@ -411,8 +410,7 @@ export class SuggestWidget implements IContentWidget, IDisposable {
}
const item = e.elements[0];
const {overwriteBefore, overwriteAfter} = item.suggestion;
this.model.accept(item.suggestion, overwriteBefore, overwriteAfter);
this.onDidSelectEmitter.fire(item);
alert(nls.localize('suggestionAriaAccepted', "{0}, accepted", item.suggestion.label));
@ -544,7 +542,11 @@ export class SuggestWidget implements IContentWidget, IDisposable {
}
}
private onDidTrigger(e: ITriggerEvent) {
get onDidSelect():Event<CompletionItem> {
return this.onDidSelectEmitter.event;
}
showTriggered(e: ITriggerEvent) {
if (this.state !== State.Hidden) {
return;
}
@ -559,7 +561,7 @@ export class SuggestWidget implements IContentWidget, IDisposable {
}
}
private onDidSuggest(e: ISuggestEvent): void {
showSuggestions(e: ISuggestEvent): void {
if (this.loadingTimeout) {
clearTimeout(this.loadingTimeout);
this.loadingTimeout = null;
@ -623,7 +625,7 @@ export class SuggestWidget implements IContentWidget, IDisposable {
}
}
private onDidCancel(e: ICancelEvent) {
showDidCancel(e: ICancelEvent) {
if (this.loadingTimeout) {
clearTimeout(this.loadingTimeout);
this.loadingTimeout = null;
@ -694,22 +696,12 @@ export class SuggestWidget implements IContentWidget, IDisposable {
}
}
acceptSelectedSuggestion(): boolean {
switch (this.state) {
case State.Hidden:
return false;
case State.Empty:
return false;
case State.Loading:
return !this.isAuto;
default:
const focus = this.list.getFocusedElements()[0];
if (focus) {
this.list.setSelection(this.completionModel.items.indexOf(focus));
} else {
this.model.cancel();
}
return true;
getFocusedItem(): CompletionItem {
if (this.state !== State.Hidden
&& this.state !== State.Empty
&& this.state !== State.Loading) {
return this.list.getFocusedElements()[0];
}
}
@ -752,7 +744,7 @@ export class SuggestWidget implements IContentWidget, IDisposable {
if (this.state === State.Details) {
this.toggleDetails();
} else {
this.model.cancel();
this.showDidCancel({ retrigger: false });
}
}

View file

@ -169,7 +169,7 @@ export class FileTracker implements IWorkbenchContribution {
let before = e.getBefore();
let after = e.getAfter();
this.handleMovedFileInVisibleEditors(before ? before.resource : null, after ? after.resource : null, after ? after.mime : null);
this.handleMovedFileInOpenedEditors(before ? before.resource : null, after ? after.resource : null, after ? after.mime : null);
}
// Dispose all known inputs passed on resource if deleted or moved
@ -279,47 +279,29 @@ export class FileTracker implements IWorkbenchContribution {
return input instanceof FileEditorInput && (<FileEditorInput>input).getResource().toString() === resource.toString();
}
private handleMovedFileInVisibleEditors(oldResource: URI, newResource: URI, mimeHint?: string): void {
let stacks = this.editorGroupService.getStacksModel();
let editors = this.editorService.getVisibleEditors();
editors.forEach(editor => {
let group = stacks.groupAt(editor.position);
let input = editor.input;
if (input instanceof DiffEditorInput) {
input = (<DiffEditorInput>input).modifiedInput;
}
private handleMovedFileInOpenedEditors(oldResource: URI, newResource: URI, mimeHint?: string): void {
const stacks = this.editorGroupService.getStacksModel();
stacks.groups.forEach(group => {
group.getEditors().forEach(input => {
if (input instanceof FileEditorInput) {
const resource = input.getResource();
let inputResource: URI;
if (input instanceof FileEditorInput) {
inputResource = (<FileEditorInput>input).getResource();
}
// Update Editor if file (or any parent of the input) got renamed or moved
if (paths.isEqualOrParent(resource.fsPath, oldResource.fsPath)) {
let reopenFileResource: URI;
if (oldResource.toString() === resource.toString()) {
reopenFileResource = newResource; // file got moved
} else {
let index = resource.fsPath.indexOf(oldResource.fsPath);
reopenFileResource = URI.file(paths.join(newResource.fsPath, resource.fsPath.substr(index + oldResource.fsPath.length + 1))); // parent folder got moved
}
// Editor Input with associated Resource
if (inputResource) {
// Update Editor if file (or any parent of the input) got renamed or moved
let updateInput = false;
if (paths.isEqualOrParent(inputResource.fsPath, oldResource.fsPath)) {
updateInput = true;
}
// Do update from move
if (updateInput) {
let reopenFileResource: URI;
if (oldResource.toString() === inputResource.toString()) {
reopenFileResource = newResource;
} else {
let index = inputResource.fsPath.indexOf(oldResource.fsPath);
reopenFileResource = URI.file(paths.join(newResource.fsPath, inputResource.fsPath.substr(index + oldResource.fsPath.length + 1))); // update the path by changing the old path value to the new one
}
// Reopen File Input
if (input instanceof FileEditorInput) {
// Reopen
const editorInput = this.instantiationService.createInstance(FileEditorInput, reopenFileResource, mimeHint || MIME_UNKNOWN, void 0);
this.editorService.openEditor(editorInput, { preserveFocus: true, pinned: group.isPinned(input), index: group.indexOf(input) }, editor.position).done(null, errors.onUnexpectedError);
this.editorService.openEditor(editorInput, { preserveFocus: true, pinned: group.isPinned(input), index: group.indexOf(input), inactive: !group.isActive(input) }, stacks.positionOfGroup(group)).done(null, errors.onUnexpectedError);
}
}
}
});
});
}
@ -358,7 +340,7 @@ export class FileTracker implements IWorkbenchContribution {
return null;
}
private handleDeleteOrMove(resource: URI, movedTo?: URI): void {
public handleDeleteOrMove(resource: URI, movedTo?: URI): void {
if (this.textFileService.isDirty(resource)) {
return; // never dispose dirty resources from a delete
}

View file

@ -164,11 +164,11 @@ suite('Files - FileEditorInput', () => {
let sameOtherInput = instantiationService.createInstance(FileEditorInput, toResource('/fooss5/bar/file2.js'), 'text/javascript', void 0);
return editorService.resolveEditorModel(inputToResolve).then(function (resolved) {
return editorService.resolveEditorModel(sameOtherInput).then(function (resolved) {
(<any>tracker).handleDelete(toResource('/bar'), []);
tracker.handleDeleteOrMove(toResource('/bar'), []);
assert(!inputToResolve.isDisposed());
assert(!sameOtherInput.isDisposed());
(<any>tracker).handleDelete(toResource('/fooss5/bar/file2.js'), []);
tracker.handleDeleteOrMove(toResource('/fooss5/bar/file2.js'), []);
assert(inputToResolve.isDisposed());
assert(sameOtherInput.isDisposed());
@ -206,11 +206,11 @@ suite('Files - FileEditorInput', () => {
let sameOtherInput = instantiationService.createInstance(FileEditorInput, toResource('/foo6/bar/file.js'), 'text/javascript', void 0);
return editorService.resolveEditorModel(inputToResolve, true).then(function (resolved) {
return editorService.resolveEditorModel(sameOtherInput, true).then(function (resolved) {
(<any>tracker).handleDelete(toResource('/bar'), []);
tracker.handleDeleteOrMove(toResource('/bar'), []);
assert(!inputToResolve.isDisposed());
assert(!sameOtherInput.isDisposed());
(<any>tracker).handleDelete(toResource('/foo6'), []);
tracker.handleDeleteOrMove(toResource('/foo6'), []);
assert(inputToResolve.isDisposed());
assert(sameOtherInput.isDisposed());

View file

@ -62,10 +62,9 @@ export class TerminalPanel extends Panel {
if (!dimension) {
return;
}
let activeIndex = this.terminalService.getActiveTerminalIndex();
if (activeIndex !== -1 && this.terminalInstances.length > 0) {
this.terminalInstances[this.terminalService.getActiveTerminalIndex()].layout(dimension);
}
this.terminalInstances.forEach((t) => {
t.layout(dimension);
});
}
public getActions(): IAction[] {