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

[vscode] Support EnvironmentVariableCollection description #12696 #12838

Merged
merged 6 commits into from
Aug 25, 2023

Conversation

jfaltermeier
Copy link
Contributor

@jfaltermeier jfaltermeier commented Aug 17, 2023

What it does

The first commit adds the new description field to EnvironmentVariableCollection . This will be enough to be compatible with VSCode 1.80.

Further commits add ui that shows the descriptions to the user.
VSCode does it like this: https://code.visualstudio.com/updates/v1_80#_environmentvariablecollectiondescription
As far as I know we did not have a similar ui yet, so I've started to implement one. The results looks like this atm:

Peek 2023-08-24 09-44

This is an enhanced preview for the terminal widget that shows the descriptions on hover, similar to VSCode. I've also included PID and Command Line like in VSCode.

Fixes #12696

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier jfaltermeier@eclipsesource.com

How to test

I've prepared three extensions that set either an undefined description, a string description, or a markdown description.

Sources:
env-description-sources.zip

Extensions:
env-description-extensions.zip

Review checklist

Reminder for reviewers

* add new field to EnvironmentVariableCollection and implement interface

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
@jfaltermeier jfaltermeier force-pushed the jf/EnvironmentVariableCollection.description branch from 60625a5 to 085c0e9 Compare August 17, 2023 09:26
@jfaltermeier jfaltermeier changed the title [vscode] Support EnvironmentVariableCollection description #12696 [WIP] [vscode] Support EnvironmentVariableCollection description #12696 Aug 17, 2023
@jfaltermeier jfaltermeier force-pushed the jf/EnvironmentVariableCollection.description branch from 085c0e9 to f8adc0a Compare August 17, 2023 10:13
* show information in UI

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
@jfaltermeier jfaltermeier force-pushed the jf/EnvironmentVariableCollection.description branch from f8adc0a to 10df2a8 Compare August 17, 2023 10:17
@jfaltermeier jfaltermeier changed the title [WIP] [vscode] Support EnvironmentVariableCollection description #12696 [vscode] Support EnvironmentVariableCollection description #12696 Aug 17, 2023
@jfaltermeier jfaltermeier marked this pull request as ready for review August 17, 2023 10:48
@jfaltermeier jfaltermeier requested a review from tsmaeder August 17, 2023 10:48
@vince-fugnitto vince-fugnitto added the vscode issues related to VSCode compatibility label Aug 18, 2023
@tsmaeder
Copy link
Contributor

@jfaltermeier it's not clear to me how I can test this: (having no familiarity with EnvVar collections. Do I just open a terminal?

* fix toolbar item visibility

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
@jfaltermeier
Copy link
Contributor Author

jfaltermeier commented Aug 23, 2023

@jfaltermeier it's not clear to me how I can test this: (having no familiarity with EnvVar collections. Do I just open a terminal?

@tsmaeder VSCode Extension may change the env variables in a new terminal. E.g. the builtin git extension will set GIT_ASKPASS:

echo $GIT_ASKPASS
/usr/share/code/resources/app/extensions/git/dist/askpass.sh

This functionality was existing in Theia already. So I haven't tested this part much.
The added VSCode API allows to describe the changes made to the environment to the users.

In the three test extensions I attached I am changing FOO, BAR, and FOOBAR.

So you may start with some default values and look at them in the terminal before installing the extensions.

# in terminal used for launching theia:
export FOO=hello
export BAR=world
export FOOBAR=123

# yarn electron start
# open terminal in started Theia and run

echo $FOO
echo $BAR
echo $FOOBAR

Then install the extensions, close and reopen a terminal. This should now show changed values:

$ echo $FOO
echo $BAR
echo $FOOBAR
markdown
string
undefined

The new toolbar item shows the description strings on hover, one being a markdown string, one a regular string, and one being a missing undefined description.

Please note that I pushed one additional commit, because I noticed to toolbar item was showing in too many locations.

@tsmaeder
Copy link
Contributor

I don't think I like the toolbar button as a UI here: in VS Code, I can press the button and it produces a drop-down menu. Toolbars are for actions, not pure hover targets: as a user, I would think something is broken if I have a toolbar button with no function.
In VS Code, as soon as you have more than one terminal, you get a "tab bar" with an entry for each open terminal. Since we open a new tab for each terminal, I think showing the descriptions as a hover on the tab would be more logical. I think with the "enhancecd preview" support for tabs we have, this should be possible. WDYT?

@@ -404,7 +404,8 @@ export interface TerminalServiceMain {
*/
$disposeByTerminalId(id: number, waitOnExit?: boolean | string): void;

$setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: SerializableEnvironmentVariableCollection | undefined): void;
$setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: SerializableEnvironmentVariableCollection | undefined,
Copy link
Contributor

Choose a reason for hiding this comment

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

The descriptions seems part of the SerializableEnvironmentCollection to me. Why not change the typing to be a proper object?

Copy link
Contributor Author

@jfaltermeier jfaltermeier Aug 23, 2023

Choose a reason for hiding this comment

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

I am not sure if I understand this, because there is no SerializableEnvironmentCollection. Are you referring to SerializableEnvironmentVariableCollection? This type is also used used in SerializableExtensionEnvironmentVariableCollection, which is actually persisted using the storageService. So I think changing this type/interface would break reading existing data.

But I guess we could add the description to SerializableExtensionEnvironmentVariableCollection and use $setEnvironmentVariableCollection(persistent: boolean, collection: SerializableExtensionEnvironmentVariableCollection): void; as a signature, if this does not count as an API break.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've went with $setEnvironmentVariableCollection(persistent: boolean, collection: SerializableExtensionEnvironmentVariableCollection): void in the updated PR. Please let me know what you think.

this.descriptionToDTO(collection.description));
}

private descriptionToDTO(value: string | theia.MarkdownString | undefined): string | MarkdownStringDTO | undefined {
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it make sense to move this to the Converter? Are there other locations that do the same conversion?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to converter as fromMarkdownOrString.

@@ -58,6 +59,9 @@ export abstract class TerminalWidget extends BaseWidget {
*/
abstract processInfo: Promise<TerminalProcessInfo>;

/** The extensions contributing to the environment of this terminal */
abstract contributingExtensions: Promise<Map<string, string | MarkdownString | undefined>>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the name is quite non-descriptive here: what is being held in this map?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Went with envVarCollectionDescriptionsByExtension

@@ -250,7 +263,7 @@ export class TerminalFrontendContribution implements FrontendApplicationContribu
this.storageService.getData<string>(ENVIRONMENT_VARIABLE_COLLECTIONS_KEY).then(data => {
if (data) {
const collectionsJson: SerializableExtensionEnvironmentVariableCollection[] = JSON.parse(data);
collectionsJson.forEach(c => this.shellTerminalServer.setCollection(c.extensionIdentifier, true, c.collection));
collectionsJson.forEach(c => this.shellTerminalServer.setCollection(c.extensionIdentifier, true, c.collection, undefined));
Copy link
Contributor

Choose a reason for hiding this comment

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

If we make the description part of the env var collection, we can serialize it at the same time, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added the description to SerializableExtensionEnvironmentVariableCollection now.

);
}

protected async onMouseEnter(
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems odd that we have to implement our own "show hover on mouse-over" support. Dont' we have this somewhere else already?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not that I am aware of. I think the reusable functionality is all in the HoverService. However we have to call hoverService.requestHover from somewhere. Here we have drawn the div over which the hover will appear ourself and the onMouseEnter only creates the custom hover ui and then calls the Hover Service. I don't think we could omit much of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Code removed because of usage of enhanced preview

): Promise<void> {
const currentTarget = event.currentTarget;
if (currentTerminal instanceof TerminalWidget) {
const extensions = await currentTerminal.contributingExtensions;
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it make more sense to let the TerminalWidget render (and cache) a Markdown string that we can just render with the markdow renderer instead of manipulating divs ourselves here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

When adapting the enhanced preview this definitely makes sense. So I will change this.

}

protected async onMouseLeave(toDispose: DisposableCollection): Promise<void> {
toDispose.dispose();
Copy link
Contributor

Choose a reason for hiding this comment

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

toDispose is too generic. How about hoverResources.dispose()

@@ -28,6 +29,7 @@ export interface IBaseTerminalServer extends RpcServer<IBaseTerminalClient> {
create(IBaseTerminalServerOptions: object): Promise<number>;
getProcessId(id: number): Promise<number>;
getProcessInfo(id: number): Promise<TerminalProcessInfo>;
getContributingExtensions(id: number): Promise<Map<string, string | MarkdownString | undefined>>;
Copy link
Contributor

Choose a reason for hiding this comment

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

envVarCollectionDescriptionsByExtension?

@jfaltermeier
Copy link
Contributor Author

I don't think I like the toolbar button as a UI here: in VS Code, I can press the button and it produces a drop-down menu. Toolbars are for actions, not pure hover targets: as a user, I would think something is broken if I have a toolbar button with no function. In VS Code, as soon as you have more than one terminal, you get a "tab bar" with an entry for each open terminal. Since we open a new tab for each terminal, I think showing the descriptions as a hover on the tab would be more logical. I think with the "enhancecd preview" support for tabs we have, this should be possible. WDYT?

Thanks for the review, I will have a look at the comments.

Regarding the Preview:
I had a look at the enhanced preview initially and imo the problem is that it just uses the widget title's label and caption, which are both strings:

protected renderEnhancedPreview = (title: Title<Widget>) => {

The env var collection's description may be a markdownstring however. Is there a way to transform this to a regular string while keeping the formatting?

We could probably try the visualPreview, but this seems hacky as we are showing something different that the visual preview

@tsmaeder
Copy link
Contributor

Why not just do the same thing as for the visual preview? Test whether the Widget supports rendering an "enhanced" title hover and if not fall back to the current code? We could then implement the protocol for the TerminalWidget.

* add description to SerializableExtensionEnvironmentVariableCollection
and use as DTO in $setEnvironmentVariableCollection
* add fromMarkdownOrString method to converter
* review comments

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
* allow widgets to customize the enhanced preview node

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
* implement enhanced preview for terminal widget
* remove terminal info toolbar item

Contributed on behalf of STMicroelectronics

Signed-off-by: Johannes Faltermeier <jfaltermeier@eclipsesource.com>
@jfaltermeier jfaltermeier force-pushed the jf/EnvironmentVariableCollection.description branch from 1c9b127 to bab13b9 Compare August 24, 2023 07:48
@jfaltermeier jfaltermeier requested a review from tsmaeder August 24, 2023 08:24
@jfaltermeier
Copy link
Contributor Author

I've addressed the comments in some follow up commits. The enhanced preview looks like this atm:
Peek 2023-08-24 09-44

Copy link
Contributor

@tsmaeder tsmaeder left a comment

Choose a reason for hiding this comment

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

Just one more question.

@jfaltermeier jfaltermeier merged commit 5720724 into master Aug 25, 2023
@jfaltermeier jfaltermeier deleted the jf/EnvironmentVariableCollection.description branch August 25, 2023 10:19
@github-actions github-actions bot added this to the 1.41.0 milestone Aug 25, 2023
@jfaltermeier jfaltermeier mentioned this pull request Aug 28, 2023
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
vscode issues related to VSCode compatibility
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[vscode] Support EnvironmentVariableCollection description
3 participants