提交 3eddf716 编写于 作者: J Joao Moreno

scm: hide input box model from extension host

上级 d7382f0d
......@@ -8,7 +8,6 @@
import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window, workspace, QuickPickItem, OutputChannel } from 'vscode';
import { IRef, RefType } from './git';
import { Model, Resource, Status } from './model';
import { CommitController } from './commit';
import * as path from 'path';
import * as nls from 'vscode-nls';
......@@ -128,7 +127,6 @@ export class CommandCenter {
constructor(
private model: Model,
private commitController: CommitController,
private outputChannel: OutputChannel
) {
this.disposables = CommandCenter.Commands
......@@ -331,7 +329,7 @@ export class CommandCenter {
@CommandCenter.Command('git.commit')
@CommandCenter.CatchErrors
async commit(): Promise<void> {
const message = this.commitController.message;
const message = scm.inputBox.value;
const didCommit = await this._commit(async () => {
if (message) {
......@@ -345,17 +343,17 @@ export class CommandCenter {
});
if (message && didCommit) {
this.commitController.message = '';
scm.inputBox.value = '';
}
}
@CommandCenter.Command('git.commitWithInput')
@CommandCenter.CatchErrors
async commitWithInput(): Promise<void> {
const didCommit = await this._commit(async () => this.commitController.message);
const didCommit = await this._commit(async () => scm.inputBox.value);
if (didCommit) {
this.commitController.message = '';
scm.inputBox.value = '';
}
}
......
......@@ -43,7 +43,7 @@ async function init(disposables: Disposable[]): Promise<void> {
git.onOutput(str => outputChannel.append(str), null, disposables);
const commitHandler = new CommitController(model);
const commandCenter = new CommandCenter(model, commitHandler, outputChannel);
const commandCenter = new CommandCenter(model, outputChannel);
const provider = new GitSCMProvider(model, commandCenter);
const contentProvider = new GitContentProvider(git, rootPath, onGitChange);
const checkoutStatusBar = new CheckoutStatusBar(model);
......
......@@ -140,9 +140,16 @@ declare module 'vscode' {
drag?(resource: SCMResource, resourceGroup: SCMResourceGroup, token: CancellationToken): ProviderResult<void>;
}
export interface SCMInputBox {
value: string;
readonly onDidChange: Event<string>;
}
export namespace scm {
export const onDidChangeActiveProvider: Event<SCMProvider>;
export let activeProvider: SCMProvider | undefined;
export const inputBox: SCMInputBox;
export function getResourceFromURI(uri: Uri): SCMResource | SCMResourceGroup | undefined;
export function registerSCMProvider(id: string, provider: SCMProvider): Disposable;
}
......
......@@ -424,6 +424,11 @@ export function createApiFactory(initData: IInitData, threadService: IThreadServ
return extHostSCM.onDidChangeActiveProvider;
}
@proposed(extension)
get inputBox() {
return extHostSCM.inputBox;
}
@proposed(extension)
getResourceFromURI(uri) {
return extHostSCM.getResourceFromURI(uri);
......
......@@ -259,6 +259,7 @@ export abstract class MainThreadSCMShape {
$register(id: string, features: SCMProviderFeatures): void { throw ni(); }
$unregister(id: string): void { throw ni(); }
$onChange(id: string, resources: SCMRawResourceGroup[], count: number | undefined): void { throw ni(); }
$setInputBoxValue(value: string): void { throw ni(); }
}
// -- extension host
......@@ -394,6 +395,7 @@ export abstract class ExtHostSCMShape {
$open(id: string, resourceGroupId: string, uri: string): TPromise<void> { throw ni(); }
$drag(id: string, fromResourceGroupId: string, fromUri: string, toResourceGroupId: string): TPromise<void> { throw ni(); }
$getOriginalResource(id: string, uri: URI): TPromise<URI> { throw ni(); }
$onInputBoxValueChange(value: string): TPromise<void> { throw ni(); }
}
// --- proxy identifiers
......
......@@ -33,6 +33,39 @@ export interface Cache {
};
}
class ExtHostSCMInputBox {
private _value: string = '';
get value(): string {
return this._value;
}
set value(value: string) {
this._proxy.$setInputBoxValue(value);
this.updateValue(value);
}
private _onDidChange = new Emitter<string>();
get onDidChange(): Event<string> {
return this._onDidChange.event;
}
constructor(private _proxy: MainThreadSCMShape) {
// noop
}
$onInputBoxValueChange(value: string): void {
this.updateValue(value);
}
private updateValue(value: string): void {
this._value = value;
this._onDidChange.fire(value);
}
}
export class ExtHostSCM {
private _proxy: MainThreadSCMShape;
......@@ -44,10 +77,14 @@ export class ExtHostSCM {
private _activeProvider: vscode.SCMProvider;
get activeProvider(): vscode.SCMProvider | undefined { return this._activeProvider; }
private _inputBox: ExtHostSCMInputBox;
get inputBox(): vscode.SCMInputBox { return this._inputBox; }
private cache: Cache = Object.create(null);
constructor(threadService: IThreadService) {
this._proxy = threadService.get(MainContext.MainThreadSCM);
this._inputBox = new ExtHostSCMInputBox(this._proxy);
}
getResourceFromURI(uri: vscode.Uri): vscode.SCMResource | vscode.SCMResourceGroup | undefined {
......@@ -209,4 +246,9 @@ export class ExtHostSCM {
return asWinJsPromise(token => provider.getOriginalResource(uri, token));
}
$onInputBoxValueChange(value: string): TPromise<void> {
this._inputBox.$onInputBoxValueChange(value);
return TPromise.as(null);
}
}
......@@ -110,13 +110,19 @@ export class MainThreadSCM extends MainThreadSCMShape {
private proxy: ExtHostSCMShape;
private providers: { [id: string]: MainThreadSCMProvider; } = Object.create(null);
private inputBoxListener: IDisposable;
constructor(
@IThreadService threadService: IThreadService,
@IInstantiationService private instantiationService: IInstantiationService
@IInstantiationService private instantiationService: IInstantiationService,
@ISCMService private scmService: ISCMService
) {
super();
this.proxy = threadService.get(ExtHostContext.ExtHostSCM);
this.inputBoxListener = this.scmService.inputBoxModel.onDidChangeContent(e => {
this.proxy.$onInputBoxValueChange(this.scmService.inputBoxModel.getValue());
});
}
$register(id: string, features: SCMProviderFeatures): void {
......@@ -144,10 +150,15 @@ export class MainThreadSCM extends MainThreadSCMShape {
provider.$onChange(rawResourceGroups, count);
}
$setInputBoxValue(value: string): void {
this.scmService.inputBoxModel.setValue(value);
}
dispose(): void {
Object.keys(this.providers)
.forEach(id => this.providers[id].dispose());
this.providers = Object.create(null);
this.inputBoxListener = dispose(this.inputBoxListener);
}
}
......@@ -5,9 +5,7 @@
'use strict';
import { TPromise } from 'vs/base/common/winjs.base';
import { IModel, IEditorOptions, IDimension } from 'vs/editor/common/editorCommon';
import { memoize } from 'vs/base/common/decorators';
import { IEditorOptions, IDimension } from 'vs/editor/common/editorCommon';
import { EditorAction, CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions';
import { ICodeEditorService } from 'vs/editor/common/services/codeEditorService';
import { IEditorContributionCtor } from 'vs/editor/browser/editorBrowser';
......@@ -24,11 +22,10 @@ import { TabCompletionController } from 'vs/editor/contrib/suggest/browser/tabCo
import { ModesHoverController } from 'vs/editor/contrib/hover/browser/hover';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import URI from 'vs/base/common/uri';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { ITextModelResolverService, ITextModelContentProvider } from 'vs/editor/common/services/resolverService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { ISCMService } from 'vs/workbench/services/scm/common/scm';
class SCMCodeEditorWidget extends CodeEditorWidget {
......@@ -62,23 +59,11 @@ class SCMCodeEditorWidget extends CodeEditorWidget {
export const InSCMInputContextKey = new RawContextKey<boolean>('inSCMInput', false);
export class SCMEditor implements ITextModelContentProvider {
export class SCMEditor {
private editor: SCMCodeEditorWidget;
private model: IModel;
private disposables: IDisposable[] = [];
@memoize
get onDidChangeContent(): Event<void> {
let listener: IDisposable;
const emitter = new Emitter<void>({
onFirstListenerAdd: () => listener = this.model.onDidChangeContent(() => emitter.fire()),
onLastListenerRemove: () => dispose(listener)
});
return emitter.event;
}
private get editorOptions(): IEditorOptions {
return {
wrappingColumn: 0,
......@@ -105,12 +90,11 @@ export class SCMEditor implements ITextModelContentProvider {
container: HTMLElement,
@IThemeService private themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService,
@IModeService private modeService: IModeService,
@IModelService private modelService: IModelService,
@IContextKeyService private contextKeyService: IContextKeyService,
@ITextModelResolverService private textModelResolverService: ITextModelResolverService
@ISCMService private scmService: ISCMService
) {
textModelResolverService.registerTextModelContentProvider('scm', this);
const scopedContextKeyService = this.contextKeyService.createScoped(container);
InSCMInputContextKey.bindTo(scopedContextKeyService).set(true);
this.disposables.push(scopedContextKeyService);
......@@ -122,10 +106,7 @@ export class SCMEditor implements ITextModelContentProvider {
this.editor = scopedInstantiationService.createInstance(SCMCodeEditorWidget, container, this.editorOptions);
this.themeService.onDidColorThemeChange(e => this.editor.updateOptions(this.editorOptions), null, this.disposables);
textModelResolverService.createModelReference(URI.parse('scm:input')).done(ref => {
this.model = ref.object.textEditorModel;
this.editor.setModel(this.model);
});
this.editor.setModel(this.scmService.inputBoxModel);
}
get lineHeight(): number {
......@@ -134,12 +115,9 @@ export class SCMEditor implements ITextModelContentProvider {
// TODO@joao TODO@alex isn't there a better way to get the number of lines?
get lineCount(): number {
if (!this.model) {
return 0;
}
const modelLength = this.model.getValueLength();
const lastPosition = this.model.getPositionAt(modelLength);
const model = this.scmService.inputBoxModel;
const modelLength = model.getValueLength();
const lastPosition = model.getPositionAt(modelLength);
const lastLineTop = this.editor.getTopForPosition(lastPosition.lineNumber, lastPosition.column);
const viewHeight = lastLineTop + this.lineHeight;
......@@ -154,14 +132,6 @@ export class SCMEditor implements ITextModelContentProvider {
this.editor.focus();
}
provideTextContent(resource: URI): TPromise<IModel> {
if (resource.toString() !== 'scm:input') {
return TPromise.as(null);
}
return TPromise.as(this.modelService.createModel('', null, resource));
}
dispose(): void {
this.disposables = dispose(this.disposables);
}
......
......@@ -190,9 +190,10 @@ export class SCMViewlet extends Viewlet {
const editorContainer = append(root, $('.scm-editor'));
this.editor = this.instantiationService.createInstance(SCMEditor, editorContainer);
this.editor.onDidChangeContent(() => this.layout(), null, this.disposables);
this.disposables.push(this.editor);
this.disposables.push(this.scmService.inputBoxModel.onDidChangeContent(() => this.layout()));
// this.inputBox = new InputBox(this.inputBoxContainer, this.contextViewService, {
// placeholder: localize('accept', "Message (press {0} to submit)", SCMViewlet.ACCEPT_KEYBINDING),
// ariaLabel: localize('acceptAria', "Changes: Type message and press {0} to accept the changes", SCMViewlet.ACCEPT_KEYBINDING),
......
......@@ -10,6 +10,7 @@ import URI from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import Event from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IModel } from 'vs/editor/common/editorCommon';
export interface IBaselineResourceProvider {
getBaselineResource(resource: URI): TPromise<URI>;
......@@ -53,6 +54,7 @@ export interface ISCMService {
readonly onDidChangeProvider: Event<ISCMProvider>;
readonly providers: ISCMProvider[];
activeProvider: ISCMProvider | undefined;
readonly inputBoxModel: IModel;
registerSCMProvider(provider: ISCMProvider): IDisposable;
}
\ No newline at end of file
......@@ -8,6 +8,12 @@
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import Event, { Emitter } from 'vs/base/common/event';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { IModel } from 'vs/editor/common/editorCommon';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { RawText } from 'vs/editor/common/model/textModel';
import { Model } from 'vs/editor/common/model/model';
import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry';
import { ISCMService, ISCMProvider } from './scm';
export class SCMService implements ISCMService {
......@@ -42,10 +48,23 @@ export class SCMService implements ISCMService {
private _onDidChangeProvider = new Emitter<ISCMProvider>();
get onDidChangeProvider(): Event<ISCMProvider> { return this._onDidChangeProvider.event; }
private _inputBoxModel: IModel;
get inputBoxModel(): IModel { return this._inputBoxModel; }
constructor(
@IContextKeyService private contextKeyService: IContextKeyService
@IContextKeyService contextKeyService: IContextKeyService,
@IModeService modeService: IModeService,
@IModelService modelService: IModelService
) {
this.activeProviderContextKey = contextKeyService.createKey<string | undefined>('scm.provider', void 0);
const options = modelService.getCreationOptions('git-commit');
const rawText = RawText.fromString('', options);
this._inputBoxModel = new Model(rawText, PLAINTEXT_LANGUAGE_IDENTIFIER);
modeService.getOrCreateMode('git-commit')
.done(mode => this._inputBoxModel.setMode(mode.getLanguageIdentifier()));
}
registerSCMProvider(provider: ISCMProvider): IDisposable {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册