Skip to content
This repository has been archived by the owner on Jun 20, 2018. It is now read-only.

Introduce new namespace for current environment in Plugins API #29

Merged
merged 1 commit into from
Jun 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/

import { createProxyIdentifier, ProxyIdentifier } from './rpc-protocol';
import * as theia from '@theia/plugin';
import { PluginLifecycle, PluginModel, PluginMetadata } from '../common/plugin-protocol';
import { QueryParameters } from '../common/env';
import { TextEditorCursorStyle } from '../common/editor-options';
import { TextEditorLineNumbersStyle, EndOfLine, OverviewRulerLane } from '../plugin/types-impl';
import { UriComponents } from '../common/uri-components';
Expand Down Expand Up @@ -369,21 +371,31 @@ export interface DocumentsMain {
$trySaveDocument(uri: UriComponents): Promise<boolean>;
}

export interface EnvMain {
$getEnvVariable(envVarName: string): Promise<string | undefined>;
}

export interface EnvExt {
$setQueryParameters(queryParams: QueryParameters): void;
}

export const PLUGIN_RPC_CONTEXT = {
COMMAND_REGISTRY_MAIN: <ProxyIdentifier<CommandRegistryMain>>createProxyIdentifier<CommandRegistryMain>('CommandRegistryMain'),
QUICK_OPEN_MAIN: createProxyIdentifier<QuickOpenMain>('QuickOpenMain'),
MESSAGE_REGISTRY_MAIN: <ProxyIdentifier<MessageRegistryMain>>createProxyIdentifier<MessageRegistryMain>('MessageRegistryMain'),
TEXT_EDITORS_MAIN: createProxyIdentifier<TextEditorsMain>('TextEditorsMain'),
DOCUMENTS_MAIN: createProxyIdentifier<DocumentsMain>('DocumentsMain'),
STATUS_BAR_MESSAGE_REGISTRY_MAIN: <ProxyIdentifier<StatusBarMessageRegistryMain>>createProxyIdentifier<StatusBarMessageRegistryMain>('StatusBarMessageRegistryMain'),
ENV_MAIN: createProxyIdentifier<EnvMain>('EnvMain')
};

export const MAIN_RPC_CONTEXT = {
HOSTED_PLUGIN_MANAGER_EXT: createProxyIdentifier<HostedPluginManagerExt>('HostedPluginManagerExt'),
COMMAND_REGISTRY_EXT: createProxyIdentifier<CommandRegistryExt>('CommandRegistryExt'),
QUICK_OPEN_EXT: createProxyIdentifier<QuickOpenExt>('QuickOpenExt'),
WINDOW_STATE_EXT: createProxyIdentifier<WindowStateExt>('WindowStateExt'),
TEXT_EDITORS_EXT: createProxyIdentifier<TextEditorsExt>('TextEditorsExt'),
EDITORS_AND_DOCUMENTS_EXT: createProxyIdentifier<EditorsAndDocumentsExt>('EditorsAndDocumentsExt'),
DOCUMENTS_EXT: createProxyIdentifier<DocumentsExt>('DocumentsExt'),
WINDOW_STATE_EXT: createProxyIdentifier<WindowStateExt>('WindowStateExt'),
ENV_EXT: createProxyIdentifier<EnvExt>('EnvExt')
};
10 changes: 10 additions & 0 deletions packages/plugin-ext/src/common/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright (C) 2018 Red Hat, Inc. and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/

export type QueryParameters = {
[key: string]: string | string[]
};
72 changes: 72 additions & 0 deletions packages/plugin-ext/src/main/browser/env-main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright (C) 2018 Red Hat, Inc. and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/

import { interfaces } from "inversify";
import { EnvVariablesServer } from "@theia/core/lib/common/env-variables";
import { RPCProtocol } from "../../api/rpc-protocol";
import { EnvMain, EnvExt, MAIN_RPC_CONTEXT } from "../../api/plugin-api";
import { QueryParameters } from "../../common/env";

export class EnvMainImpl implements EnvMain {
private proxy: EnvExt;
private envVariableServer: EnvVariablesServer;

constructor(rpc: RPCProtocol, container: interfaces.Container) {
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.ENV_EXT);

this.envVariableServer = container.get(EnvVariablesServer);

this.proxy.$setQueryParameters(this.getQueryParameters());
}

/**
* Returns query parameters from current page.
*/
private getQueryParameters(): QueryParameters {
const queryParameters: QueryParameters = {};
if (window.location.search !== '') {
const queryParametersString = window.location.search.substr(1); // remove question mark
const params = queryParametersString.split('&');
for (const pair of params) {
if (pair === '') {
continue;
}

const keyValue = pair.split('=');
let key: string = keyValue[0];
let value: string = keyValue[1] ? keyValue[1] : '';
try {
key = decodeURIComponent(key);
if (value !== '') {
value = decodeURIComponent(value);
}
} catch (error) {
// skip malformed URI sequence
continue;
}

const existedValue = queryParameters[key];
if (existedValue) {
if (existedValue instanceof Array) {
existedValue.push(value);
} else {
// existed value is string
queryParameters[key] = [existedValue, value];
}
} else {
queryParameters[key] = value;
}
}
}
return queryParameters;
}

$getEnvVariable(envVarName: string): Promise<string | undefined> {
return this.envVariableServer.getValue(envVarName).then(result => result ? result.value : undefined);
}

}
5 changes: 5 additions & 0 deletions packages/plugin-ext/src/main/browser/main-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/

import { interfaces } from 'inversify';
import { CommandRegistryMainImpl } from './command-registry-main';
import { QuickOpenMainImpl } from './quick-open-main';
Expand All @@ -12,6 +13,7 @@ import { PLUGIN_RPC_CONTEXT } from '../../api/plugin-api';
import { MessageRegistryMainImpl } from './message-registry-main';
import { WindowStateMain } from './window-state-main';
import { StatusBarMessageRegistryMainImpl } from './status-bar-message-registry-main';
import { EnvMainImpl } from './env-main';
import { EditorsAndDocumentsMain } from './editors-and-documents-main';

export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container): void {
Expand All @@ -34,4 +36,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container

const statusBarMessageRegistryMain = new StatusBarMessageRegistryMainImpl(container);
rpc.set(PLUGIN_RPC_CONTEXT.STATUS_BAR_MESSAGE_REGISTRY_MAIN, statusBarMessageRegistryMain);

const envMain = new EnvMainImpl(rpc, container);
rpc.set(PLUGIN_RPC_CONTEXT.ENV_MAIN, envMain);
}
40 changes: 40 additions & 0 deletions packages/plugin-ext/src/plugin/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2018 Red Hat, Inc. and others.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*/

import { RPCProtocol } from '../api/rpc-protocol';
import { EnvMain, EnvExt, PLUGIN_RPC_CONTEXT } from '../api/plugin-api';
import { QueryParameters } from '../common/env';

export class EnvExtImpl implements EnvExt {
private proxy: EnvMain;
private queryParameters: QueryParameters;

constructor(rpc: RPCProtocol) {
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.ENV_MAIN);
}

getEnvVariable(envVarName: string): Promise<string | undefined> {
return this.proxy.$getEnvVariable(envVarName).then(x => {
if (x === null) {
return undefined;
}
return x;
});
}

getQueryParameter(queryParamName: string): string | string[] | undefined {
return this.queryParameters[queryParamName];
}

getQueryParameters(): QueryParameters {
return this.queryParameters;
}

$setQueryParameters(queryParams: QueryParameters): void {
this.queryParameters = queryParams;
}
}
17 changes: 16 additions & 1 deletion packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { getPluginId } from '../common/plugin-protocol';
import { MessageRegistryExt } from './message-registry';
import { StatusBarMessageRegistryExt } from './status-bar-message-registry';
import { WindowStateExtImpl } from './window-state';
import { EnvExtImpl } from './env';
import { QueryParameters } from '../common/env';
import {
Disposable,
Position,
Expand Down Expand Up @@ -47,6 +49,7 @@ export function createAPI(rpc: RPCProtocol): typeof theia {
const editors = rpc.set(MAIN_RPC_CONTEXT.TEXT_EDITORS_EXT, new TextEditorsExtImpl(rpc, editorsAndDocuments));
const documents = rpc.set(MAIN_RPC_CONTEXT.DOCUMENTS_EXT, new DocumentsExtImpl(rpc, editorsAndDocuments));
const statusBarMessageRegistryExt = new StatusBarMessageRegistryExt(rpc);
const envExt = rpc.set(MAIN_RPC_CONTEXT.ENV_EXT, new EnvExtImpl(rpc));

const commands: typeof theia.commands = {
// tslint:disable-next-line:no-any
Expand Down Expand Up @@ -140,7 +143,6 @@ export function createAPI(rpc: RPCProtocol): typeof theia {
};

const workspace: typeof theia.workspace = {

get textDocuments() {
return documents.getAllDocumentData().map(data => data.document);
},
Expand All @@ -155,10 +157,23 @@ export function createAPI(rpc: RPCProtocol): typeof theia {
},
};

const env: typeof theia.env = {
getEnvVariable(envVarName: string): PromiseLike<string | undefined> {
return envExt.getEnvVariable(envVarName);
},
getQueryParameter(queryParamName: string): string | string[] | undefined {
return envExt.getQueryParameter(queryParamName);
},
getQueryParameters(): QueryParameters {
return envExt.getQueryParameters();
}
};

return <typeof theia>{
commands,
window,
workspace,
env,
// Types
StatusBarAlignment: StatusBarAlignment,
Disposable: Disposable,
Expand Down
54 changes: 42 additions & 12 deletions packages/plugin/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ Any contributed command are available to any plugin, command can be invoked by [

Simple example that register command:

```javascript
```typescript
theia.commands.registerCommand({id:'say.hello.command'}, ()=>{
console.log("Hello World!");
});
```

Simple example that invoke command:

```javascript
```typescript
theia.commands.executeCommand('core.about');
```

Expand All @@ -38,7 +38,7 @@ Function to ask user select some value from the list.

Example of using:

```javascript
```typescript
//configure quick pick options
const option: theia.QuickPickOptions = {
machOnDescription: true,
Expand All @@ -63,13 +63,13 @@ theia.window.showQuickPick(["foo", "bar", "foobar"], option).then((val: string[]

Simple example that show an information message:

```javascript
```typescript
theia.window.showInformationMessage('Information message');
```

Simple example that show an information message with buttons:

```javascript
```typescript
theia.window.showInformationMessage('Information message', 'Btn1', 'Btn2').then(result => {
console.log("Click button", result);
});
Expand All @@ -79,27 +79,27 @@ theia.window.showInformationMessage('Information message', 'Btn1', 'Btn2').then(

It is possible to track state of the IDE window inside a plugin. Window state is defined as:

```javascript
```typescript
interface WindowState {
readonly focused: boolean;
}
```

To read a state on demand one can use readonly variable:

```javascript
```typescript
theia.window.state
```

To track window activity subscribe on `onDidChangeWindowState` event:

```javascript
```typescript
const disposable = theia.window.onDidChangeWindowState((windowState: theia.WindowState) => {
console.log('Window focus changed: ', windowState.focused);
console.log('Window focus changed: ', windowState.focused);
});
```

#### StatusBar API
#### Status Bar API

A status bar shows a message to users and supports icon substitution.

Expand All @@ -108,14 +108,44 @@ const disposable = theia.window.onDidChangeWindowState((windowState: theia.Windo

Simple example that show a status bar message:

```javascript
```typescript
theia.window.setStatusBarMessage('test status bar item');
```

Simple example that show a status bar message with statusBarItem:

```javascript
```typescript
const item = theia.window.createStatusBarItem(theia.StatusBarAlignment.Right, 99);
item.text = 'test status bar item';
item.show();
```

#### Environment API

Environment API allows reading of environment variables and query parameters of the IDE.

To get an environment variable by name one can use:

```typescript
theia.env.getEnvVariable('NAME_OF_ENV_VARIABLE').then(value => {
// process the value here
}
```

In case if environment variable doesn't exist `undefined` will be returned.

Also this part of API exposes all query parameters (already URI decoded) with which IDE page is loaded. One can get a query parameter by name:

```typescript
theia.env.getQueryParameter('NAME_OF_QUERY_PARAMETER');
```

In case if query parameter doesn't exist `undefined` will be returned.

Or it is possible to get a map of all query parameters:

```typescript
theia.env.getQueryParameters();
```

Note, that it is possible to have an array of values for single name, because it could be specified more than one time (for example `localhost:3000?foo=bar&foo=baz`).
Loading