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

VS Code 1.39 custom editor status and feedback #82115

Closed
mjbvz opened this issue Oct 8, 2019 · 11 comments
Closed

VS Code 1.39 custom editor status and feedback #82115

mjbvz opened this issue Oct 8, 2019 · 11 comments
Assignees
Labels
api on-testplan under-discussion Issue is under discussion for relevance, priority, approach
Milestone

Comments

@mjbvz
Copy link
Collaborator

mjbvz commented Oct 8, 2019

This thread details the current state of the custom editor proposal delivered with VS Code 1.39.


The custom editor API will provide a framework for extensions to create fully customizable read/write editors that are used in place of VS Code's standard text editor for specific resources. A XAML custom editor, for example, could show a WYSIWYG style editor for your .xaml files. Our end goal is to give extensions the most flexibility possible while keeping VS Code fast, lean, and consistent.

This iteration, we are sharing the first pieces of the custom editor API proposal: readonly, webview-based custom editors. Here's a quick overview of the currently proposed API:

Contributing a custom editor

A webview-based custom editor binds a resource (a file) to a webview provided by an extension. This webview replaces VS Code's default text/binary editor for that resource.

Consider an extension that previews images. To create webview-based editor, our extension first uses the proposed webviewEditors contribution point to tell VS Code about the custom editors it provides:

"contributes": {
  "webviewEditors": [
    {
      "viewType": "myExtension.imagePreview",
      "displayName": "My Image Preview",
      "priority": "default",
      "selector": [
        {
          "filenamePattern": "*.{jpg,jpe,jpeg,png,bmp,gif,ico,tga,webp}",
          "mime": "image/*"
        }
      ]
    }
  ]
},
"activationEvents": [
  "onWebviewEditor:myExtension.imagePreview"
]

The important properties are:

  • viewType - Unique identifier for the editor. This is also used in the extension code later. Note this identifier is also used in the activation event.
  • displayName - Human readable name of the custom editor.
  • priority - Determines if the custom editor should be enabled by default.
  • selector- Specifies when the editor should be enabled.
    • filenamePattern - A glob pattern to identify file names that enable the editor.
    • mime - A glob pattern for mime types that enable the editor (this is used if you open a data URI resource, such as from Git history).

The onWebviewEditor:myExtension.imagePreview activationEvent ensures that our extension is activated whenever VS Code determines it should show our custom image preview editor.

We then use the proposed registerWebviewEditorProvider API to bind our viewType to a resolver that takes a resource and a webview editor. This resolve is invoked whenever a resource that matches the selector for the custom editor is opened:

import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    context.subscriptions.push(vscode.window.registerWebviewEditorProvider(
        'myExtension.imagePreview',
        {
            async resolveWebviewEditor(resource: vscode.Uri, editor: vscode.WebviewEditor): Promise<void> {
                // Take ownership of webview and create its content
                editor.webview.html = `...`;
            }
        })
    );
}

That's it! At this point, our extension can use the editor just like a normal webview.

Custom editor UX

We've also added proposed UX for managing custom editors.

The new Reopen With command allows you to change which editor is used for the current resource. This will close the existing editor and reopen it with the selected editor.

Additionally, the workbench.experimental.editorAssociations setting lets you control which custom editor is used for a given resource. It is a list of file selectors bound to the editor viewType that should be opened when a resource matches the selector:

"workbench.experimental.editorAssociations": [
  {
    "filenamePattern": "*.png",
    "viewType": "myExtension.imagePreview",
  }
]

Note that default is also a valid viewType and can be used to force VS Code to open its normal text/binary editor instead of any default custom editor:

"workbench.experimental.editorAssociations": [
  {
    "filenamePattern": "*.png",
    "viewType": "default",
  }
]

Next steps for custom editors

Custom editors are an exciting and potentially powerful new extension point. We want to be sure we that we get the API right so that extensions can build new experiences without degrading VS Code's performance or deviating from some of our core UX principles.

The current proposal is only a first step and will likely be heavily revised. We will continue to iterate on the custom editor API over the coming months.

@mjbvz mjbvz added this to the October 2019 milestone Oct 8, 2019
@mjbvz mjbvz self-assigned this Oct 8, 2019
@mjbvz mjbvz added api under-discussion Issue is under discussion for relevance, priority, approach labels Oct 8, 2019
@anorborg
Copy link

anorborg commented Oct 9, 2019

Does this support virtual documents as well for scenarios like #10547?

@DanTup
Copy link
Contributor

DanTup commented Oct 10, 2019

@mjbvz is this only for completely custom editors, or will there be any way to extend existing editors? Eg. if I wanted the normal code editing experience, but to overlay some random HTML over the top - will that ever be a possibility?

For example - see #73780 (which has never had any feedback fwiw, so it's unclear whether Code is open to anything like this). We just want to draw over the top of the editor but the current decorations API is too limited and brittle for this sort of feature. There are other extensions (like rainbow indent guides) that also have strange quirks for similar reasons.

@mjbvz
Copy link
Collaborator Author

mjbvz commented Oct 10, 2019

@DanTup No, that is out of scope of custom editors. For stability, performance, and UX reasons, we do not want to allow extensions to directly effect text editors.

You may be interested in the webview inset proposal but they are also intentionally quite limited: #66418

@letmaik
Copy link
Member

letmaik commented Oct 10, 2019

I can't figure out how to enable script usage. Trying to set editor.webview.options.enableScripts = true doesn't work as the property is readonly. Looks a bit like such options are missing in registerWebviewEditorProvider.

@mjbvz
Copy link
Collaborator Author

mjbvz commented Oct 10, 2019

@letmaik You need to set the entire options object:

webviewEditor.webview.options = {

@letmaik
Copy link
Member

letmaik commented Oct 10, 2019

I made a little tech demo visualising ML model files: https://github.com/letmaik/vscode-netron. This would always be read only, so from my point of view it works great already.

@DanTup
Copy link
Contributor

DanTup commented Oct 14, 2019

@mjbvz

No, that is out of scope of custom editors. For stability, performance, and UX reasons, we do not want to allow extensions to directly effect text editors.

But in theory if I built myself a whole HTML editor that worked the same as VS Codes, I could then also draw extra stuff over it? So having some way to reuse your editor code in a custom editor would allow us to do that without reimplementing the wheel.

There are features being built in other editors that uses love, that it seems VS Code will never be able to have without something better here (see the gif of IntelliJ at #73780 (comment) - this is a feature VS Code users really want, but our current implementation is terrible and could never be shipped on by default).

@mjbvz
Copy link
Collaborator Author

mjbvz commented Oct 14, 2019

@DanTup I understand the desire, however there are a lot of reasons why people have migrated to VS Code over other editors that come packed with all sorts of fanciness. We take a very deliberate approach to extensibility because we want to maintain the core qualities that drew people to VS Code and keep them using it day to day. Allowing extensions to add arbitrary html overlays would let extensions effect our core text editing experience in some really big ways, many of which are probably not good in the long run

Maybe we'll eventually be able to come up with an approach that does allow more editor visual extensibility while still preserving performance and consistency, but that's beyond the scope of webview editors. I think the far more likely outcome of #73780 is that we build in this feature.

(PS: don't embed code editors in webviews; it's just a whole lot of work to create a bad user experience)

@DanTup
Copy link
Contributor

DanTup commented Oct 15, 2019

however there are a lot of reasons why people have migrated to VS Code over other editors that come packed with all sorts of fanciness. We take a very deliberate approach to extensibility because we want to maintain the core qualities that drew people to VS Code and keep them using it day to day.

I don't think those people migrated to VS Code "because it's not very extensible". VS Code is fast and light. Being extensible does not change that - you get to choose what extensions you use. The big IDEs people moved from have built-in bloat. VS Code already warns users when extensions take a long time to load (or block the extension host) so it seems like a relatively solved problem.

(That said, extensions can already cause crippling performance issues in the editor - see #75627)

I think the far more likely outcome of #73780 is that we build in this feature.

That issue has 223 👍 's but hasn't had any response from the Code team, so I really have no idea what your opinion of it is (which is why I bring it up now and then 😄). A lot of issues that don't get responses sit around for a while then get closed as out-of-scope, so it's hard to tell when something is considered a good idea that might get implemented, or a bad idea that's waiting to die.

That's not the only in-editor feature I'd like to build though, so supporting it natively will still leave other exciting features unavailable to VS Code users. I haven't opened issues for anything else yet, as it wasn't clear what would happen with #73780 (I deliberately left that vague so it might cover many use cases rather than just the one shown in the example screenshots). If more-specific issues would be better, I can do that.

PS: Sorry for derailing what turned out to be an unrelated thread :-)

@tamuratak
Copy link
Contributor

FYI: the discussion continues in #77131.

@mjbvz
Copy link
Collaborator Author

mjbvz commented Dec 2, 2019

Closing out this item. Please continue discussions in #77131

@mjbvz mjbvz closed this as completed Dec 2, 2019
@vscodebot vscodebot bot locked and limited conversation to collaborators Jan 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api on-testplan under-discussion Issue is under discussion for relevance, priority, approach
Projects
None yet
Development

No branches or pull requests

5 participants