ENSIME: The Next Generation

I have started a completely fresh rewrite of ENSIME, the ENhanced Scala Interaction Mode for Emacs.

It is a private project but I would like to gauge interest from the community to see if it is something that people would be interested in. If that’s you, please respond to this post with a short message about how you’d like to contribute.

I’m limiting the features to:

  • dot completion
  • infer type
  • import class
  • jump to source

which is already implemented in Scala 2.{11,12,13} and Scala 3.1, with Emacs integration.

I am coding toward my own use-case (Emacs, JVM, GNU/Linux), so areas that could use contributions would be:

  • Windows
  • Vim (native vimscript)
  • LSP wrapper (for everything else, including VSCode)
  • older versions of Scala / Java
  • working in .sbt files
  • the Java language (needs the ability to run a compiler plugin)

Contributors who are willing to commit to contribute something of that nature may be given access to the private repo. I will make tarballs available if somebody commits to build an LSP on top of it.

18 Likes

what do you mean by ‘heavyweight’? are you talking about performance? in particular, performance in an emacs configured with ‘–with-native-compilation’?

what do you mean by ‘heavyweight’?

I’ve edited the post to remove that comment. I don’t want to get into comparisons with LSP and Metals, but we can continue that privately if you’re interested.

2 Likes

Sometimes people rename things after a rewrite, especially if it nails down the pronunciation and isn’t all caps.

How about “simean” for SIME plus “another”. (One could improve that.)

Plus side is that it’s not an actual word, down side is it may make people misspell simian.

(I pronounced ensime like a french word like a snob until I heard Martin Odersky say it.)

1 Like

Well, you’re both wrong. It is all caps because it is shouted in Doric.

1 Like

just looking for potential pitfalls. i’m leaning towards using emacs+metals more now that native compilation is so seamless.

I am happy to see ENSIME continuing.
I could test your use case: Emacs, GNU, JVM. I have the same setup.

2 Likes

What build tools are we planning? Also will there be a new github repo?

1 Like

enseamless might make a good project name.

2 Likes

it is build tool agnostic, just add an -Xplugin to the scalac options and Emacs picks up from there. All the plugin is doing is writing out the compiler’s classpath (and documenting reverse lookups between class directories and the input source files) so there is no performance penalty.

I already have a repo. It’s feature complete for Scala 2.{11,12,13}; I’m just debating the merits of making this a public resource vs keeping it to myself.

1 Like

I’m just debating the merits of making this a public resource vs keeping it to myself

I think there is enough interest in community to release it :slight_smile:

3 Likes

I’m not convinced. I would not say there has been a lot of interest on this official contributors forum: 8 likes from 1,000 views, is a resounding “meh”.

However, I’ve been seeing interest from private conversations. I’m starting to think that maybe the way to enjoy open source is via private invite-only groups, rather than in the public (which is quite toxic at the moment).

I have yet to decide; and it’s likely going to come down to the thoughts of private contributors.

2 Likes

…maybe the way to enjoy open source is via private invite-only groups, rather than in the public…

This is the first I have heard of it. It sure sounds very attractive. Would you mind elaborating a bit more about it?

1 Like

I’m starting to think that maybe the way to enjoy open source is via private invite-only groups

AKA the end of open source.

I personally think there is no need to have much buzz, simply open source it, if ppl find it useful enough they will show up and contribute otherwise you have just spent a couple of additional clicks…

6 Likes

so … you know the way repos on github are public and anybody can see them and comment on the issue tracker and raise pull requests? And then there’s usually an associated gitter/discord/slack channel where hundreds of users come to ask for help, instead of reading the docs (that you’re expected to maintain)? And then there’s a bunch of really angry people on reddit and twitter, and a competing group of developers, who absolutely hate everything about you?

Well, it’s just like that. Except it’s just the github repo and pull requests, and only people you invite are allowed to see it and propose changes (with code!). Maybe there’s a private chat room somewhere but more likely it’s just a bunch of private 1on1 correspondence.

3 Likes

Ah. Basically a private github repository and invite only. And you can be very liberal with your invitations. The fundamental upside is that you get to be the BDFL for that repository. And this includes uninviting those who are unable to control the compulsive toxicity.

That about right?

If so, I love Love LOVE it!

1 Like

I used ENSIME before ad was quite happy with it. Nowadays I use Metals and it works for me but, if you choose to release this, I will absolutely give it a try.

3 Likes

Hi Sam!

Great to see you’re still around! I would definitely be interested to take anything for a spin :slight_smile:

As many I’m currently using Metals for Scala work in vscode. It’s working pretty well for me and seems to be improving all the time.

I never actually got anywhere deep within the backend part of ensime, or metals for that part and my complaints with current state are mostly life-cycle based actually. So kind-of frontend focused. I still think I had a better way of managing the starting and stopping of the backing server with ensime for instance. But feature-wise I’m pretty set as long as stuff just works.

Concrete problems I have with vscode and metals:

  1. vscode-metals only support a single project per “workspace”. And by workspace, I mean window. So I have to start a separate window of vscode per project I’m using. That’s a big problem for me since I’m all for micro-module vs monorepo. I typically have around 10 projects running simultaneously, sometimes bound together with sbt-sriracha (or similar - think npm link)

This kind of kills any productivity gains I could get by leverages workspaces as concept in vscode with separate settings and all that. I basically just code . in a lot of project folders all the time.

  1. vscode starts the metals backend automatically which in turns starts an sbt bsp (or bloop) if there’s not already one there. This gives me lots of headache. Sometimes something dies and leaves off dangling sbt servers and then when I use my cli sbt it can’t start in server mode. I do a lot of ps ax | grep sbt and killing. Still don’t know how to pin-point the right sbt of 10’s running. Just learnt that I can do sbtn shutdown & sbt (https://github.com/scalameta/metals-feature-requests/issues/243) but still annoying. Up 'til now I have basically fallen back to killing all sbt and restarting my full “session”.

  2. still not sure about the right sequence of commands to run when doing build iterations. Example: trying to use something in code by autocomplete. ah, not in classpath. add it in build.sbt. I have sbt on auto-reload, but vscode doesn’t pick up. “connect to build server” doesn’t seem to pick it up either. I fallback to “reload window” in vscode which kills metals (i think) and starts a new that then reconnects to the sbt bsp with updated CP. Works but takes time. Just feels bad that I need to reload my editor to pick up a CP add.

A single source of truth is important to me though. I really like the sbt bsp because of this. It’s nice not having to go through generating separate project definitions.

But I basically want full control from cli separate of any editor, just using sbt and possibly starting a lang-server of some kind that I then can utilise from my editor. Or start it explicitly from my editor if need be. But then I really need to be able to control it there. Branching off a backend server process that I can’t pin-point just by the existence of a build.sbt is not playing nice with me.

Anyways, sorry for the essay. Super cool that you’re working on this! Would be very interested to hear more and understand what you’re missing with metals too.

5 Likes

I can help clarify a couple things you mention about Metals which might help.

Keep in mind that by default, when Metals starts up sbt as a BSP server, by design even when Metals exits and sends the shutdown to sbt, sbt server will stay alive for the default stay-alive time, which I believe is 7 days unless you change it.

In this situation, what you’ll want is actually “Build Import”. The wording is a bit weird, since historically it was focused on Bloop (which requires an import of your sbt build definition to bloop files), but if you trigger that it will actually under the hood when using sbt as a BSP server trigger a workspace reload, which tells sbt to reload everything. That should do what you want.

1 Like

Don’t be sorry at all, I love to hear the details.

I don’t want to get into comparisons between Metals and ENSIME because I will be accused of toxic marketing or trolling or something similar, even if I keep it purely factual. So I’ll stick to entirely how ENSIME:TNG works and the implications to the workflow:

ENSIME:TNG runs as a compiler plugin, extracting compiler settings in a build-tool agnostic manner.

The same plugin is invoked through its command line interface from your text editor (via nailgun for fast responses). It reads the output of the plugin to understand the dependencies and uses the Scala compiler’s internal APIs to answer semantic questions.

So there is exactly one server process per “working set” but it’s designed to shut it self off after 5 minutes of activity and to keep the memory footprint as low as possible: giving back to the OS aggressively.

There is no BSP or interaction with the build tool, that’s all expected to be handled via the regular mechanism in the text editor, e.g. sbt-mode or the new scala-compile (which uses sbtn or warm gradle or fury or mill or whatever). That means CPU cycles are kept really low… the project is never compiled in the background away from your control. That means power usage (very important on laptops) is kept to a minimum.

BTW I am giving access to the private repo for anybody who is committing to contributing anything at this stage. Will open it up to users / testers later. I am still undecided if my repo will ever be public, but I’m sure public versions will pop up (i.e. be leaked) and I won’t discourage that. That’s how I imagine an LSP wrapper working.

3 Likes