Skip to content

Commit

Permalink
fixup! Introduce SCM Plugin-Api
Browse files Browse the repository at this point in the history
  • Loading branch information
vinokurig committed Feb 11, 2019
1 parent a35aaf7 commit aa32ee9
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 158 deletions.
2 changes: 1 addition & 1 deletion examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
"@theia/filesystem": "^0.3.19",
"@theia/getting-started": "^0.3.19",
"@theia/git": "^0.3.19",
"@theia/scm": "^0.3.19",
"@theia/java": "^0.3.19",
"@theia/java-debug": "^0.3.19",
"@theia/json": "^0.3.19",
Expand All @@ -45,6 +44,7 @@
"@theia/preview": "^0.3.19",
"@theia/process": "^0.3.19",
"@theia/python": "^0.3.19",
"@theia/scm": "^0.3.19",
"@theia/search-in-workspace": "^0.3.19",
"@theia/task": "^0.3.19",
"@theia/terminal": "^0.3.19",
Expand Down
2 changes: 1 addition & 1 deletion packages/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"@theia/filesystem": "^0.3.19",
"@theia/languages": "^0.3.19",
"@theia/navigator": "^0.3.19",
"@theia/workspace": "^0.3.19",
"@theia/scm": "^0.3.19",
"@theia/workspace": "^0.3.19",
"@types/diff": "^3.2.2",
"@types/fs-extra": "^4.0.2",
"@types/p-queue": "^2.3.1",
Expand Down
9 changes: 5 additions & 4 deletions packages/git/src/browser/git-view-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { GitQuickOpenService, GitAction } from './git-quick-open-service';
import { GitSyncService } from './git-sync-service';
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { GitPrompt } from '../common/git-prompt';
import { ScmRepository, ScmService, ScmCommand } from '@theia/scm/lib/common';
import { ScmRepository, ScmService, ScmCommand } from '@theia/scm/lib/browser';
import { GitRepositoryProvider } from './git-repository-provider';

export const GIT_WIDGET_FACTORY_ID = 'git';
Expand Down Expand Up @@ -124,7 +124,7 @@ export class GitViewContribution extends AbstractViewContribution<GitWidget>
static GIT_REPOSITORY_STATUS = 'git-repository-status';
static GIT_SYNC_STATUS = 'git-sync-status';

static ID_HANDLE = 0;
private static ID_HANDLE = 0;

protected toDispose = new DisposableCollection();

Expand Down Expand Up @@ -167,7 +167,7 @@ export class GitViewContribution extends AbstractViewContribution<GitWidget>
if (this.hasMultipleRepositories()) {
const path = new URI(repository.localUri).path;
this.scmService.selectedRepositories.forEach(scmRepo => scmRepo.setSelected(false));
const scmRepository = this.scmService.repositories.find(scmRepo => scmRepo.provider.rootUri === repository.localUri);
const scmRepository = this.scmService.repositories.find(scmRepo => scmRepo.provider.rootUri === repository.localUri);
if (scmRepository) {
scmRepository.setSelected(true);
}
Expand Down Expand Up @@ -228,6 +228,7 @@ export class GitViewContribution extends AbstractViewContribution<GitWidget>
);
}

/** Detect and handle added or removed repositories. */
checkNewOrRemovedRepositories() {
const added =
this.repositoryProvider
Expand All @@ -248,7 +249,7 @@ export class GitViewContribution extends AbstractViewContribution<GitWidget>
this.dirtyRepositories = this.repositoryProvider.allRepositories;
}

registerScmProvider(repository: Repository): ScmRepository {
private registerScmProvider(repository: Repository): ScmRepository {
const uri = repository.localUri;
const disposableCollection = new DisposableCollection();
const onDidChangeStatusBarCommandsEmitter = new Emitter<ScmCommand[]>();
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-sch
import { DebuggerDescription } from '@theia/debug/lib/common/debug-service';
import { DebugProtocol } from 'vscode-debugprotocol';
import { SymbolInformation } from 'vscode-languageserver-types';
import { ScmCommand } from '@theia/scm/lib/common';
import { ScmCommand } from '@theia/scm/lib/browser';

export interface PluginInitData {
plugins: PluginMetadata[];
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/main/browser/scm-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
ScmResourceGroup,
ScmService,
ScmCommand
} from '@theia/scm/lib/common';
} from '@theia/scm/lib/browser';
import { RPCProtocol } from '../../api/rpc-protocol';
import { interfaces } from 'inversify';
import { CancellationToken, DisposableCollection, Emitter, Event } from '@theia/core';
Expand Down
3 changes: 1 addition & 2 deletions packages/plugin-ext/src/plugin/scm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import * as theia from '@theia/plugin';
import { CommandRegistryExt, Plugin as InternalPlugin, PLUGIN_RPC_CONTEXT, ScmExt, ScmMain } from '../api/plugin-api';
import { RPCProtocol } from '../api/rpc-protocol';
import { ScmCommand } from '@theia/scm/lib/common';
import { CancellationToken } from '@theia/core';
import { UriComponents } from '../common/uri-components';
import URI from '@theia/core/lib/common/uri';
Expand Down Expand Up @@ -183,7 +182,7 @@ class SourceControlImpl implements theia.SourceControl {
this._acceptInputCommand = acceptInputCommand;

if (acceptInputCommand) {
const command: ScmCommand = {
const command = {
id: acceptInputCommand.id,
text: acceptInputCommand.label ? acceptInputCommand.label : ''
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

export * from './scm';
export * from './scm-service';
14 changes: 12 additions & 2 deletions packages/scm/src/browser/scm-contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,14 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import { inject, injectable } from 'inversify';
import { FrontendApplicationContribution, StatusBar, StatusBarAlignment, StatusBarEntry } from '@theia/core/lib/browser';
import { ScmCommand, ScmService } from '../common/scm';
import {
FrontendApplication,
FrontendApplicationContribution,
StatusBar,
StatusBarAlignment,
StatusBarEntry
} from '@theia/core/lib/browser';
import { ScmCommand, ScmService } from './scm-service';

@injectable()
export class ScmContribution implements FrontendApplicationContribution {
Expand All @@ -41,4 +47,8 @@ export class ScmContribution implements FrontendApplicationContribution {
}
});
}

onStop(app: FrontendApplication): void {
this.scmService.dispose();
}
}
3 changes: 1 addition & 2 deletions packages/scm/src/browser/scm-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@

import { ContainerModule } from 'inversify';
import { ScmContribution } from './scm-contribution';
import { ScmServiceImpl } from './scm-service-impl';
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { ScmService } from '../common/scm';
import { ScmService, ScmServiceImpl } from './scm-service';

export default new ContainerModule(bind => {
bind(ScmContribution).toSelf().inSingletonScope();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,138 @@
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
import {
InputValidator,
ScmInput,
ScmProvider,
ScmRepository,
ScmService
} from '../common/scm';
import { Disposable, Emitter, Event } from '@theia/core/lib/common';
import { Disposable, DisposableCollection, Emitter, Event } from '@theia/core/lib/common';
import { injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';

export const ScmService = Symbol('ScmService');
export interface ScmService extends Disposable {

readonly onDidAddRepository: Event<ScmRepository>;
readonly onDidRemoveRepository: Event<ScmRepository>;

readonly repositories: ScmRepository[];
readonly selectedRepositories: ScmRepository[];
readonly onDidChangeSelectedRepositories: Event<ScmRepository[]>;

registerScmProvider(provider: ScmProvider): ScmRepository;
}

export interface ScmProvider extends Disposable {
readonly label: string;
readonly id: string;
readonly contextValue: string;

readonly groups: ScmResourceGroup[];

readonly onDidChangeResources: Event<void>;

readonly rootUri?: string;
readonly count?: number;
readonly commitTemplate?: string;
readonly onDidChangeCommitTemplate?: Event<string>;
readonly onDidChangeStatusBarCommands?: Event<ScmCommand[]>;
readonly acceptInputCommand?: ScmCommand;
readonly statusBarCommands?: ScmCommand[];
readonly onDidChange: Event<void>;

getOriginalResource(uri: URI): Promise<URI | undefined>;
}

export interface ScmResourceGroup {
readonly resources: ScmResource[];
readonly provider: ScmProvider;
readonly label: string;
readonly id: string;
readonly hideWhenEmpty: boolean | undefined;
readonly onDidChange: Event<void>;
}

export interface ScmResource {
readonly resourceGroup: ScmResourceGroup;
readonly sourceUri: URI;
readonly decorations?: ScmResourceDecorations;

open(): Promise<void>;
}

export interface ScmResourceDecorations {
icon?: URI;
tooltip?: string;
strikeThrough?: boolean;
faded?: boolean;

source?: string;
letter?: string;
}

export interface ScmCommand {
id: string;
text: string;
tooltip?: string;
command?: string;
}

export const enum InputValidationType {
Error = 0,
Warning = 1,
Information = 2
}

export interface InputValidation {
message: string;
type: InputValidationType;
}

export interface InputValidator {
(value: string, cursorPosition: number): Promise<InputValidation | undefined>;
}

export interface ScmInput {
value: string;
readonly onDidChange: Event<string>;

placeholder: string;
readonly onDidChangePlaceholder: Event<string>;

validateInput: InputValidator;
readonly onDidChangeValidateInput: Event<void>;

visible: boolean;
readonly onDidChangeVisibility: Event<boolean>;
}

export interface ScmRepository extends Disposable {
readonly onDidFocus: Event<void>;
readonly selected: boolean;
readonly onDidChangeSelection: Event<boolean>;
readonly provider: ScmProvider;
readonly input: ScmInput;

focus(): void;

setSelected(selected: boolean): void;
}

@injectable()
export class ScmServiceImpl implements ScmService {
private providerIds = new Set<string>();
private _repositories: ScmRepository[] = [];
private _selectedRepositories: ScmRepository[] = [];

private disposableCollection: DisposableCollection = new DisposableCollection();
private onDidChangeSelectedRepositoriesEmitter = new Emitter<ScmRepository[]>();
private onDidAddProviderEmitter = new Emitter<ScmRepository>();
private onDidRemoveProviderEmitter = new Emitter<ScmRepository>();

readonly onDidChangeSelectedRepositories: Event<ScmRepository[]> = this.onDidChangeSelectedRepositoriesEmitter.event;

constructor() {
this.disposableCollection.push(this.onDidChangeSelectedRepositoriesEmitter);
this.disposableCollection.push(this.onDidAddProviderEmitter);
this.disposableCollection.push(this.onDidRemoveProviderEmitter);
}

get repositories(): ScmRepository[] {
return [...this._repositories];
}
Expand All @@ -47,7 +157,9 @@ export class ScmServiceImpl implements ScmService {
return this.onDidAddProviderEmitter.event;
}

get onDidRemoveRepository(): Event<ScmRepository> { return this.onDidRemoveProviderEmitter.event; }
get onDidRemoveRepository(): Event<ScmRepository> {
return this.onDidRemoveProviderEmitter.event;
}

registerScmProvider(provider: ScmProvider): ScmRepository {

Expand All @@ -57,10 +169,7 @@ export class ScmServiceImpl implements ScmService {

this.providerIds.add(provider.id);

function toDisposable(fn: () => void): Disposable {
return { dispose() { fn(); } };
}
const disposable: Disposable = toDisposable(() => {
const disposable: Disposable = Disposable.create(() => {
const index = this._repositories.indexOf(repository);
if (index < 0) {
return;
Expand All @@ -72,7 +181,7 @@ export class ScmServiceImpl implements ScmService {
this.onDidChangeSelection();
});

const repository = new SCMRepositoryImpl(provider, disposable);
const repository = new ScmRepositoryImpl(provider, disposable);
const selectedDisposable = repository.onDidChangeSelection(this.onDidChangeSelection, this);

this._repositories.push(repository);
Expand All @@ -90,9 +199,13 @@ export class ScmServiceImpl implements ScmService {
this._selectedRepositories = this._repositories.filter(r => r.selected);
this.onDidChangeSelectedRepositoriesEmitter.fire(this.selectedRepositories);
}

dispose(): void {
this.disposableCollection.dispose();
}
}

class SCMRepositoryImpl implements ScmRepository {
class ScmRepositoryImpl implements ScmRepository {

private _onDidFocus = new Emitter<void>();
readonly onDidFocus: Event<void> = this._onDidFocus.event;
Expand All @@ -105,7 +218,7 @@ class SCMRepositoryImpl implements ScmRepository {
private _onDidChangeSelection = new Emitter<boolean>();
readonly onDidChangeSelection: Event<boolean> = this._onDidChangeSelection.event;

readonly input: ScmInput = new SCMInputImpl();
readonly input: ScmInput = new ScmInputImpl();

constructor(
public readonly provider: ScmProvider,
Expand All @@ -127,7 +240,7 @@ class SCMRepositoryImpl implements ScmRepository {
}
}

class SCMInputImpl implements ScmInput {
class ScmInputImpl implements ScmInput {

private _value = '';

Expand Down
Loading

0 comments on commit aa32ee9

Please sign in to comment.