dart-lang / dart-pad

An online Dart editor with support for console, web, and Flutter apps
https://dartpad.dev
BSD 3-Clause "New" or "Revised" License
1.71k stars 553 forks source link

Experiment with using the monaco text editor (and / or codemirror 6) with dartpad #2743

Open devoncarew opened 11 months ago

devoncarew commented 11 months ago

We should experiment with using the monaco text editor (https://microsoft.github.io/monaco-editor/) with dartpad, esp. if we think it could help reduce maintenance costs here (rolling codemirror, ...). It would give us a look and feel similar to other flutter development environments, and may make it easier to do more sophisticated UIs for code completion, quick fixes, ...

At a first attempt at using it in a flutter hello world app, I ran into bootstrapping issues. Monaco uses require.js for its module system, which doesn't seem to work well with the module system used by DDC. The release build of dartpad would be compiled w/ dart2js (so may not have this issue?) but our dev cycle for developing dartpad won't work well w/o DDC.

It looks like DDC may move off of using require.js (https://github.com/dart-lang/dart-pad/issues/2695). That may solve the issue for us?

@ditman - do you have familiarity w/ the module systems / issues we may be running into when trying to use monaco? Any solutions or workarounds come to mind?

modulovalue commented 10 months ago

FYI:

Both migrated away from Monaco.

Codemirror appears to win when it comes to code size and mobile support.

Quote:

CodeMirror improved Replit's performance by a lot and by extension our retention. In fact, after releasing it to mobile in July[1] our weekly retention rate on mobile increased by a whopping 70%. That said, solve a lot of mobile usability issues so it's not all due to performance. On desktop however, it's a different story, we made sure to just have parity with Monaco and it still improved retention by %25, almost all due to performance!

parlough commented 10 months ago

Good point! I'm all for a better mobile experience. I think CodeMirror 6 is great, but there potentially are some extra development costs with it that will need to be considered. Particularly how there is currently no Dart support for Lezer or CodeMirror.

Due to CodeMirror 6's leaner nature, it could be even less work than Monaco. Definitely worth exploring at least.

Looking at the Java support, it doesn't seem like too much work. The hardest/most tedious part would be writing the lezer grammar. I wonder if we can just generate at least some of it from Dart's antlr grammar? Here's the Java lezer grammar as a reference.

As for the bindings, I'll have to look at what CodeMirror's API looks like. Looks like you can pick and choose what you need, which is nice.

modulovalue commented 10 months ago

We have a basic tree sitter grammar for Dart here: https://github.com/UserNobody14/tree-sitter-dart. There appears to be a basic tree sitter to lezer conversion tool here https://github.com/lezer-parser/import-tree-sitter.

devoncarew commented 10 months ago

I think that an easy-to-integrate codemirror 6 wrapper, w/ dart mode support, would be more than enough for this project.

If we do use codemirror 6, it would be nice to start with a lightweight package:web based wrapper, instead of the current (fairly comprehensive) wrapper that we have in package:codemirror.

ditman commented 10 months ago

Monaco uses require.js for its module system, which doesn't seem to work well with the module system used by DDC.

@devoncarew this has been a running issue for a while. As you said, requireJS is being actively removed right now (check with @Markzipan) and I did some hacks in the past for it to "remove/hide" requireJS after it loads, so this might be a race condition between the monaco JS and flutter's? If you still want to pursue this, try to make monaco load after flutter has fully initialized maybe? It may also be monaco detecting require.js slightly differently, and still finding remnants of our usage :)

modulovalue commented 10 months ago

@devoncarew what does "dart mode support" entail?

That is, is it only about syntax highlighting, and token-based highlighting would be enough, or are there other features that you want/need to support, that would require code-mirror to have access to the whole parse tree?

devoncarew commented 10 months ago

I was just thinking about syntax highlighting - the current level of dart support from codemirror 5.

I'm not really familiar enough w/ codemirror 6 to know what benefits we might get w/ a full parse tree for dart, but I suspect that most or all dart uses of codemirror would use it for syntax highlighting (and then rely on some analysis server integration for more sophisticated features).