Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce the Variable Resolver Extension #1581

Merged
merged 1 commit into from
Mar 28, 2018
Merged

Introduce the Variable Resolver Extension #1581

merged 1 commit into from
Mar 28, 2018

Conversation

azatsarynnyy
Copy link
Member

Signed-off-by: Artem Zatsarynnyi [email protected]

PR closes #1561

This PR introduces the variable-resolver extension which provides support of variable substitution mechanism inside strings. Extension adds:

  • a contribution point to provide a hook that allows any extensions to contribute its own variables e.g.:
export class EditorVariableContribution implements VariableContribution {
    registerVariables(variables: VariableRegistry): void {
        variables.registerVariable({
            name: 'lineNumber',
            description: 'The current line number in the current file',
            resolve: () => {
                const currentEditor = ...
                return Promise.resolve(`${currentEditor.cursor.line + 1}`);
            }
        });
    }
}
  • VariableResolverService allows to resolve all known variables in a string e.g.:
const resolved = await service.resolve('file: ${file}; line: ${lineNumber}');
expect(resolved).is.equal('file: package.json; line: 6');
  • VariableQuickOpenService allows to get list of all registered variables e.g.:

screenshot from 2018-03-26 17-20-30

Note, this PR doesn't contribute any variables. I'm going to provide a couple of separate PRs a bit later to add support for variables in tasks.json and add the VSCode's predefined variables to add a little bit more compatibility with VSCode Tasks.

import { ILogger } from '@theia/core/lib/common';
import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
import { Variable, VariableRegistry } from './variable';
import { Disposable } from 'vscode-jsonrpc';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know whether it was intentional or not, but we usually user @theia/core/common/disposable. I guess the tooling did it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was VSCode's work ))
Fixed import.

/**
* A unique name of this variable.
*/
name: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you omit the readonly on purpose or not? If by accident, please add it. Thank you!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just overlooked. Annotated both properties as readonly.

}

/**
* Get a variable for the given name or 'undefined' if none.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please use ` instead of '? The documentation looks better in VSCode. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely agree. Changed

}

run(mode: QuickOpenMode): boolean {
if (mode !== QuickOpenMode.OPEN) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, it is always false, isn't it?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Changed.


export const LIST_VARIABLES: Command = {
id: 'variable.list',
label: 'Variable: list all'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have Variable: List All instead? At least, that was the convention for instance in the Git extension so far.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

Copy link
Contributor

@kittaakos kittaakos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nice, clean code!

@epatpol
Copy link
Contributor

epatpol commented Mar 26, 2018

Looks very good! Maybe add a short example in the README on how you can use the substitutions i.e implement a contribution and inject the service?

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2018 Red Hat, Inc.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the copyright should be under Apache 2 license:

/*
 * Copyright (C) 2018 Read 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
 */

cc @svenefftinge

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated all files

* 'undefined' if variable cannot be resolved.
* Never reject.
*/
resolve(): Promise<string | undefined>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use MaybePromise here, that implementors does not deal with promises. You can resolve a maybe promise with await syntax or Promise.resolve.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, with MaybePromise it looks more flexible. I've updated it and also slightly refactored the VariableResolverService.
Thanks for the advice.

const quickOpenItems = this.variableRegistry.getVariables().map(
v => new VariableQuickOpenItem(v.name, v.description)
);
this.items = [...quickOpenItems];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this.items = quickOpenItems ? map fn creates a new array

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure ) Changed

@azatsarynnyy
Copy link
Member Author

@kittaakos @epatpol @akosyakov
Guys, thanks for the reviews. I've addressed all your comments and rebased the branch.
@epatpol I've updated the README with the examples of using.

@epatpol
Copy link
Contributor

epatpol commented Mar 27, 2018

Yes I didn't expect a readme that extensive, very well done thank you!

@azatsarynnyy
Copy link
Member Author

Guys, could someone give me the approval to merge this PR if it looks good for you?

@kittaakos
Copy link
Contributor

give me the approval

The PR looks great. @akosyakov, do you have any additional remarks on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support variable substitution inside strings
4 participants