Who would help creating an embeddable mini-IDE?


#1

Hi there,

I wonder if there are people out there who would be interested to help with the creation of a “sufficiently comfortable” embeddable mini-IDE for Scala. By this, I understand a project that can be used as a library to add IDE-like functionality to applications (in my case, desktop applications, but it could be generic and include the possibility of web applications as well), such as embedding an editor component for Scala code.

So far I have used a library called ScalaInterpreterPane which wraps SyntaxPane (formerly JSyntaxPane), using a JFlex based lexer, and coupling to an IMain for interpreter type functionality and auto-completion. This works “ok” but doesn’t satisfy the “sufficiently comfortable” criterion. From my point of view, the goals and features should include:

  • must be usable as library, thrown into a project using standard libraryDependencies += ...
  • must be usable with a virtual file system (e.g. in-memory source code)
  • must have basic syntax highlight
  • must have auto-completion
  • must be able to handle “framing”, i.e. massage the source code with surrounding scaffold before compilation (scastie and scala-fiddle do this AFAIK)
  • should have semantic highlight (e.g. extended colour coding and font attributes depending on the symbol at hand)
  • should have diagnostics (“red squiggles” and/or possibility to navigate from compile errors to source locations)
  • should have go-to-symbol (within the same source code, perhaps also into libraries)
  • should have documentation hover or look-up (scaladoc or similar)
  • should have basic refactoring (e.g. rename symbol, add explicit type)
  • should have decent editor formatting and navigation functionality (e.g. auto indentation, matching brackets)
  • should work with Scala 2.11, 2.12, 2.13
  • should support, at later point, hybrid editing such as worksheet, jupyter style notebook

For a descent starting point, I think Pavel Fatin’s ToyIDE is great. It mimicks multiple things we know from IntelliJ and has an acceptable editor component. If you are interested to join but do not want to be tied to Swing, we could introduce an abstraction layer so that both Swing and HTML/CSS could be the target UI.

When I say mini-IDE, it’s clear this is not intended to compete with a fully-fledged IDE, that’s also not doable with limited resources. But it should be modular so that specific assumptions are only served by higher-level layers. For example, if you need a build system with multiple source files etc., and this should go, e.g., through Bloop, then this would be an optional layer. I think a good image of what it could be would be the type of IDE you have for Processing or Arduino.

My assessment of the current situation is that:

  • Metals would probably be nice and interesting at some point
  • but currently the overhead of developing an LSP client and probably having to work on multiple
    PR to get the minimum layer working (e.g. without requiring a full build system with physical directory,
    being able to package everything into one library without other local installs, in-process communication)
    is too high. So we should observe its development, but not necessarily start with it.
  • Scala-IDE is a complex code base, but the principle idea of using the nsc.interactive.Global Scala
    presentation compiler is not wrong. It gives auto-completion and it probably the entry point for
    semantic highlight and refactoring.
  • We can probably learn some things from scastie, scala-fiddle, Scala-IDE, ammonite, etc.

Is anyone up for such a project?


#2

Hey, sounds interesting. I am in.


#3

I guess the best approach of getting started would be to set up a dedicated GitHub (is that still preference?) repository. We could use the wiki function to collect the necessary resources of inspiration, and who would be willing to work on which bit.

I looked briefly into the core module of Scala-IDE. It basically contains most of the IDE functions that would be needed, such as a semantic highlight scanner based on checking the compiler.Tree. Probably it would be good to create some pages describing how to access this source, also how the ToyIDE editor is structured and how it would have to be extended.

I’m not a professional software developer, so I have no formal training in software design process; I have written a vast amount of open source Scala libraries, but very few have been created as collaborative projects from the beginning, so we would have to figure out how to set it up in a good way. And then the discussion could move over to a dedicated gitter channel or just e-mails I guess. One of the early questions will probably be license - I tend to use LGPL for all my libraries, and chances are that we can re-use some bits, so my suggestion is to use LGPL, which in my opinion is a good balance of avoiding forks that do not contribute back, while allowing library use from all sorts of projects with different licenses.

Best,

…h.h…


#4

i am interested in it , but i am new to open source , so looking forward to your guidance


#5

How about integrating scalafiddle with an existing OSS web IDE


#6

I do need integration with desktop apps - so web interfaces don’t help, although as already stated, they could be a second front-end for the project. When using Java2D, that’ll work both in Swing and JavaFX.

Another project to look at is scaled, although that comes with the problem of requiring Java 9 and having invented its own build and packaging system which doesn’t work with sbt or maven, and an entire dependency injection etc. layer, which looks as complicated as drilling out the editors of IntelliJ-scala (which again is Java2D based).


#7

Sorry, not sure how I missed/forgot, your original message is pretty clear on that point.

Can you explain better what you mean by embeddable? What are the use cases?

You might want to build applications on top of eclipse, which is really a general-purpose application platform. Then you can use the Scala plugin as is.

Alternatively, you might look into reusing components from vscode, I think it lends itself to that. For instance some web IDEs, or maybe gitlab’s code editor, use components from it IIRC.

I’m not sure about intellij – I don’t think I know of any 3rd-party applications built on it, only that most jetbrains IDEs seem to be the same base application. That said, a lot of it is open source, so who knows.


#8

Sure. My main use case is Mellite, which is a computer music environment that combines graphical components with text components. I guess the mix is not unlike Praxis Live, Tough Designer, VVVV etc. for visual arts, although currently I don’t have a huge canvas that contains graphs, but rather a multi-window approach.

So I have a workspace that is essentially a key-value store with the “DOM” so to speak of the music elements. Some elements are generated from writing code snippets, all using Scala, mostly using DSLs for the use cases (e.g. for signal processing or patterns), adding invisible imports to the context. These snippets either “evaluate” to trees that are persisted (that’s the case for signal processing graphs), or they are serialized as plain-old Function (that’s currently the case for the Action component).

My experience is that having only a rather weak IDE makes it challenging to spend lots of time developing those snippets inside the Mellite IDE. Instead, I often fall back to using a full fledged IDE - IntelliJ - then paste back code into the snippet objects once a piece is complete or half complete. While IntelliJ (or Eclipse) are great IDEs, they are not live coding environments, i.e. where you can work on the sound while the sound is playing, and interact with it.

I did contemplate using any of the available platforms. Many years ago, I tried to integrate ScalaCollider with Eclipse; it was a horrible experience, plus I need to wrap all Swing components to work inside of SWT. Then I put some hope into NetBeans platform - Scala support was never fully developed and died off. I recently looked at IntelliJ Platform. It’s not too bad, I could probably make it work. But all this building on top of huge generic RCP platforms means you buy into their UI philosophy; and being a project for computer art, I would like to be a bit more free with that. Also clutter free. Plus again, you have to learn a lot of API and you have a lot of overhead developing and deploying IntelliJ plugins. While most of the time I would only need 5% of the functionality.


It has indeed been suggested that I embed an existing web-based IDE, using a web view in JavaFX. I don’t know if this would be feasible with VS Code; perhaps rather look at Monaco (as scalameta/metabrowse is apparently doing). On the other hand, in the long term, I would really like to have seemless drag-and-drop in my application and perhaps even embed custom objects inside the text editor. I think this will be very difficult when you simply have a wrapper around a huge JavaScript/HTML/CSS monster.

Swing-wise, there is also jEdit as an option, I guess. But after looking at all these projects since a while, my guts say it’s less effort to code up something from almost-scratch. ToyIDE is nice because it’s really reduced, I have a good feeling that one can build something from there in reasonable time and resources.


Going back to Mellite, a huge question is how a workspace could use extensions and additional libraries. So probably at some point I will need a tiny “build system” layer as well. I’m thinking of using Coursier to fetch artifacts and perhaps even save them inside the workspace database. Another huge question is Scala binary compatibility. Compiling code snippets ad-hoc is way too slow; using DSLs that generate easily serialisable object trees works very nicely (I simply store the source code separately in case one wants to re-edit the object), for actions I’m using POJO serialisation of the target Function class. This obviously breaks when Mellite moves from currently Scala 2.12 main-line to 2.13. A trick could be to store the binary version, and allow one to “clean” a workspace, re-compiling actions from their sources if the workspace had used an older Scala version before. Some hope there also in using one day TASTY as serialised format.


So my thoughts for next step is to create an org on GitHub (if there are no concerns from anyone that wants to participate), and then use Gitter for public chat, perhaps Mattermost (Framasoft hosted) for internal team communication.


Please do keep posting replies and ideas; I want to keep the discussion open for a while before making any decisions. Thanks!

Best, …h.h…


#9

Why involve JavaFX at all ? Couldn’t the UI components of mellite be written as one or more plugins to VSCode or Atom ? I don’t want to discourage anyone but the project you’re presenting here seems way to ambitious, and at the same time would fall short in several ways compared to using a “real” IDE. If you really think you need a custom editor, maybe build on an existing base like https://github.com/google/xi-editor (which is getting LSP support).


#10

No - because Mellite already exists, and it’s a desktop application based on Swing, with tons of UI code already written, and a nice look-and-feel. It also contains my live improvisation interface based on Java2D. So the only way would be to embed the editor in Mellite, not vice versa.

I think it’s really useful to imagine (despite all the differences) an environment like Touch Designer, Praxis LIVE or VVVV.


#11

Of course it would be nice to find an existing editor. But this again is Rust, I would need to fight with JNI, JNA, and then getting the whole thing on other platforms is going to be a pita. The nice thing of JVM and Swing is, it really runs on all the platforms I care for. You want to put it on a Raspberry Pi? sbt assembly and done.


#12

I think you should consider all these lines of code a sunk cost, the brutal truth is that Swing and all other Java toolkits are basically legacy technology today. Thanks to Scala.JS you may be able to write a plugin for VSCode/Atom/… without throwing away all your code. In any case I’m fairly sure that rewriting UI code is going to be way easier than inventing your own IDE from scratch.

I sugest taking a closer look at Xi. The server part is indeed written in Rust but clients can be written in any language, and you don’t need native bindings because the communication is done via JSON messages.


#13

Also, to be more positive, I’d like to note that I think that mellite/scalacollider/… are really cool projects and I hope they’ll continue to exist in one form or another ! I think there’s plenty of things we could to orient the language and its ecosystem to make it more interactive, so please keep experimenting! On my side, I’ve been working on debugging support for the Dotty Language Server, this includes support for expression evaluation, which already makes it possible to do some rudimentary live music coding, and I’m keen to see how this could be taken farther. I’ve also been working with a student on the first sketch of a “REPL Server Protocol” to have one common backend used by both the traditional cli REPL but also Jupyter notebooks, IDE worksheets, etc, I think this might be another piece of the puzzle. Hit me up on the dotty gitter channel if you want to discuss this more.


#14

Do you really need an IDE? Or just some kind of rich editor you can integrate with Metals?


#15

If you integrate a rich editor with Metals, you’ve just made an IDE :).


#16

Thanks Guillaume for your thoughts, and also of course for your and other’s work on Meta(ls). I do hope that this gets leveraged in my project at some point; as I have pointed out in the very beginning. So perhaps just some clarifications on the pragmatics:

  • so I use Mellite for creating sound works; I work as an artist and academic, so my having these systems operational is very important. Without an entire team working on Mellite, it’s simply not feasible at this stage to say, let’s just rewrite the entire UI (which is most of the code) based on a Web renderer.
  • for the time scale I have been working on this and intend to keep working with this, it’s not important that the current trend is to write web interfaces. Swing has been called dead already ten years ago. I’m pretty optimistic that it will be around in five to ten years time still. It may not be as fancy as newer toolkits such as JavaFX (which copies the CSS idea from web UI). My least concern is standard widgets in standard containers, but there are many custom editors, for sound files (waveforms, sonograms), timelines, break point functions, or indeed a zoom + pan interface for the live improv, and that’s just Java2D which is very similar to any other 2D API, e.g. SVG.
  • so in short, changing the UI toolkit is not in the cards for me, at least for the foreseeable future. There is simply no gain for me and a lot of effort necessary. I also don’t believe that professional users would want to operate on a web interface rather than in Adobe Premiere, Gimp, Photoshop, Inkscape, Reaper, Ardour etc. Just because some businesses now have to assume 80% of their user base uses a mobile phone, that doesn’t necessarily apply to a professional digital artist.

The second pragmatic part is time frame:

  • so have an existing functionality, thats ScalaInterpreterPane. I want to swap it out, and rather soon, so the missing bit is diagnostics, much better auto completion, and discoverability, such as integrated documentation look up. This is what I need when I write these snippets, and that’s what a new user coming from another environment, say SuperCollider, needs to learn the API on the go. I could focus on getting a LSP client to work, but as of now - correct me if I’m wrong - Metals does not help with any of these tasks: I still have to produce the syntax highlight myself, I have to write the auto-completion code myself. Go-to-definition is nice to have, but for small snippets it’s less important. Diagnostics is the main feature I can see right now being served by Metals. But (as I mentioned on the Gitter channel) if it means I have to write a Bloop back-end versus trying to adopt code based on the presentation compiler from the Scala-IDE project, I would probably opt for the latter, at least in the immediate term. That doesn’t rule out adding an LSP client implementation at a later point.

In any case, thanks also for the clarification on Xi; I will have a look at that. Indeed, I was also putting NeoVim on my list, which should also be designed to be embeddable.

I’m definitely interested to dicuss the possibilities of a “REPL Server Protocol”. I think work sheets and Jupyter are some of the most exciting things that have entered the picture in the recent years. Also it’s a good reminder to keep Dotty in the picture. It’s just again a question of my resources; Scala 2.12 is ready now, so I’m building on top of that; but obviously in two year’s time, I will be probably looking at migration to Dotty.


@nafg As to IDE versus editor; I think that’s a rather arbitrary division line. That’s why called it “mini-IDE”. Would you call Processing an editor or an IDE? Well it’s basically an editor, but also it integrates the whole process of creating visual pieces. In that sense, Mellite itself is part of the IDE, and the embeddable component is an “IDE-enabled editor” if you like.

Best, …h.h…


#17

Maybe, but for all these tasks but syntax highlighting (which I hope you can find a library to take care of for you), LSP is the answer even if metals doesn’t do it yet (if you’re feeling adventurous you could use the Dotty Language Server which does have auto-complete right now, Dotty works with Scala 2.12 libraries so you can use it with ScalaCollider without porting it).

Why would you need that ? If you have an sbt project for your code, you can get bloop to work with that. If you want to use some other build tool, you’d need to make it talk the build server protocol (and make metals independent of bloop but I assume that’ll happen eventually, at least I certainly don’t plan to make the dotty language server depend on bloop).

The “presentation compiler” is actually a small part of scalac: https://github.com/scala/scala/tree/2.13.x/src/interactive, scala-ide just wraps that (and add a lot of stuff on top), but I really don’t recommend trying to build anything on top of that: it’s going to be complicated, it might not work well enough, and you’ll have to throw away everything in the transition to Scala 3. Again, assuming you don’t need to call Scala 2 macros in your code, the simplest solution that will work right now might be to use the Dotty Language Server.


#18

Again thanks Guillaume. I guess you have me half-convinced that I should at least make one attempt at the most basic LSP interface to see how complicated it is (for me to implement) and how it feels. I agree of course that the idea of a small surface API and client/server is much more future-proof than the nsc API which constantly changes. Good point about running Dotty over Scala 2.12, that might indeed be a useful approach (it has to be tested).

So for now, I have the old syntax highlight working (jFlex), the new one with ToyIDE (using scalariform scanner like Scala-iDE), and auto-completion basically working with interactive.Global calls. If you tell me that I can get a fully qualified type hover with Metals, so I could poke the scaladoc for that and write my little online help integration, then I’ll give this a go.

P.S.: Is it possible now to link Metals as a libraryDependency and so I can spin up the server from my application? It would be quite important that I can package a fully self-contained application with one click installation, and no fiddling around with separate installations of servers (it’s already annoying enough that SuperCollider is difficult to bundle).


#19

Is it possible now to link Metals as a libraryDependency

Metals is published to Maven Central https://mvnrepository.com/artifact/org.scalameta/metals There is no public API however beyond the main function. Reusable components have public APIs and are published as separate modules, for example the Java/Scala source/outline indexers are published as org.scalameta:mtags https://scalameta.org/metals/blog/2018/12/12/fast-goto-definition.html#conclusion

make metals independent of bloop

They are already independent, Metals works with any build tool that supports BSP server discovery https://github.com/scalacenter/bsp/blob/master/docs/bsp.md#bsp-connection-protocol

From my point of view, the goals and features should include: [ … ]

The Scala presentation compiler has good support to implement most of that functionality: completions, virtual file systems, 2.11-2.13 support, syntactic + semantic token highlighting, framing/scaffolding. Some effort is required to make it work consistently across 2.11-2.13, high-level APIs may change between releases but core data structures like trees/symbols/types are pretty stable. The presentation compiler has limited support for refactoring/formatting/goto-definition-for-external-libraries but my understanding is that those features are less critical for you.


#20

Ok, so I created an umbrella org for this at https://github.com/dotterweide . The tentative name is German for “golden willow”, and simply is one that wasn’t already taken and that ends in IDE :slight_smile: And perhaps in the future it includes dotty support as well, so the name is probably ok. You pronounce it “dotter-why-de”.

The idea is to create some sub-projects there, beginning with -org as a starting point to collect ideas, assemble a list of existing tools and libraries etc., then probably create some experimental sub-projects, say dotterwide-exp-coursier to experiment with cursier, dotterwide-exp-meta to experiment with scalameta etc.

I don’t have super powers to “lead” this org or project, so simply ping me if you want to be added. Everyone is welcome to join, irrespective of background or level. Discussion can then go into its gitter channel https://gitter.im/dotterweide/dotterweide-org - I suggest to just work informally now, and depending on everyone’s time resources.

I will then add a standard code-of-conduct, such as the one used by scala discourse.

best, …h.h…