Skip to content

Isolate embedded/standalone Monaco Editors #15218

Open
@sdirix

Description

@sdirix

Overview

We use Monaco Editors not only for file editing, but also inline like in the chat input, console input, and breakpoint condition editing.

At the moment these inline editors are not decoupled from the global Monaco services. As a consequence there are unintended side effects, for example the popular vim extension interferes with these embedded editors, making it practically unusable.

Suggestion

  • Offer a way to create isolated inline editors, which behave as intended by the caller, without extensions interfering with it
  • Make sure to still offer a way for certain extensions to extend the behavior on a whitelist principle, for example code completion should work within the breakpoint condition editor
  • Switch all inline editors to this new functionality, whitelisting what is necessary for each use case

Optional goal:

  • Also offer the same mechanism for all non-inline editors

References

See #14957 for related changes.

Activity

tsmaeder

tsmaeder commented on Mar 18, 2025

@tsmaeder
Contributor

The Monaco CodeEditorWidget and derived classes can be very largely configured through services injected their constructor. If we subsitute only some services, we need to be careful about unintended interference, though. In any case, we should read through the analog usages in VS Code before we commit to an architecture here.

sdirix

sdirix commented on Mar 18, 2025

@sdirix
MemberAuthor

I had a quick look at VS Code:

This is how they instantiate the chat view editor and the breakpoint editor and its options. Takeaway: They specifically declare which services these "scoped instances" have access to.

Here you can see how they check the handed over contributions, instead of relying on the global registry. In the editor they then often check for the isSimpleWidget which is set to true for these "scoped" instances, see for example here.

colin-grant-work

colin-grant-work commented on Apr 2, 2025

@colin-grant-work
Contributor

It even looks like we've already done something like this for the notebook cell editors.

colin-grant-work

colin-grant-work commented on Apr 2, 2025

@colin-grant-work
Contributor

Re: the Vim extension, it looks like some of why it behaves nicely with certain non-main editors has to do with the plugin's implementation deliberately ignoring editors with certain URI's.

colin-grant-work

colin-grant-work commented on Apr 2, 2025

@colin-grant-work
Contributor

So it seems a significant motivation here was the way the Vim plugin affects things. The code that @sdirix linked was really at the heart of that, because it shows that a 'simple widget' carries out most basic input actions directly, whereas non-simple widgets instead execute commands, and it's those commands that Vim overrides to do its own thing.

I have a branch that basically replaces our current createInline strategy for Monaco editors with one that uses the SimpleMonacoEditor class I linked above, becauseStandaloneCodeEditors don't accept the isSimpleWidget option (though we were pretending that they did), and that cuts Vim out of the picture without any regressions that I noticed.

That basically delivers on

  • Offer a way to create isolated inline editors, which behave as intended by the caller, without extensions interfering with it
  • Make sure to still offer a way for certain extensions to extend the behavior on a whitelist principle, for example code completion should work within the breakpoint condition editor

But I haven't done much to cut out either unwanted services or unwanted editor contributions, since Vim, the most egregious offender, was actually acting mostly through an entirely separate mechanism. Are there other specific infelicities in particular contexts that we want to try to cut out?

sdirix

sdirix commented on Apr 3, 2025

@sdirix
MemberAuthor

@colin-grant-work Nice investigation!

Changing the inline strategy to be more similar to VS Code definitely makes sense to me. Even better that we already have such a simple editor in place.

I'm not aware of any other current issues.

@tsmaeder @msujew what do you think?

tsmaeder

tsmaeder commented on Apr 3, 2025

@tsmaeder
Contributor

The Monaco CodeEditorWidget and derived classes can be very largely configured through services injected their constructor

So I'm totally on board with the approach ;-) Where I seem to differ from @sdirix is maybe the terminology. If we look at what we want to do with the editors, there's the dimension of "is this editor part of the editor tab folder hierarchy"? In the case of the notebook editors that is clearly not the case. The other dimension is "do we want extensions to contribute services like autocomplete" to an editor. In the case of code cells in a notebook the answer is clearly yes. So there seem to be "inline" editors that do need interactions from extensions.
Note that the VIM extension explicitly excludes the "debug:input" editor from it's targets see here, so an approach based on configuring only needed services might work for widgets like the chat input (where we want to control everything), but not for stuff like code cells. (What is the behavior of a python code cell with the VIM Editor?).
With all that said, if editor commands are the problem, maybe simply configuring the editor to not accept certain commands from extensions might be enough?

colin-grant-work

colin-grant-work commented on Apr 3, 2025

@colin-grant-work
Contributor

Note that the VIM extension explicitly excludes the "debug:input"

I initially thought that this was part of the reason e.g. debug breakpoint widgets weren't affected by Vim, but it turns out that that's not what their URI's stringify to, so I'm not sure that that particular conditional ever kicks in.

Re: terminology, I agree it's worth being clearer. I have interpreted @sdirix's statements

...without extensions interfering with it.
...for example code completion should work within the breakpoint condition editor.

To mean what I think you're saying, @tsmaeder: there's Vim's very invasive overrides of basic functionality on the one hand (interference), and desirable extension contribution (code completion) on the other. The SimpleMonacoEditor seems to hit the sweetspot: it excludes Vim, but otherwise may use all of the services and contributions of normal editors, including extension-contributed completions, etc.

NB: that doesn't mean code completion is working great in e.g. breakpoint widgets, even on master. There it seems that TypeScript, at least, can see enough of the context propose contextually relevant variable completion, but it doesn't seem to be able to propose completions for fields of this in context, at least in the files / methods where I tried it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Participants

    @sdirix@tsmaeder@colin-grant-work

    Issue actions

      Isolate embedded/standalone Monaco Editors · Issue #15218 · eclipse-theia/theia