[ANN] Julia Snail, an Emacs development environment — version 1.1.0 release

In March 2020, I announced an early version of Julia Snail, an Emacs development environment for Julia. A lot of work has gone into Snail since then, and it has matured tremendously. Today, I released version 1.1.0, with several major additions:

  • Julia multimedia support — render plots without leaving the comfort of Emacs.
  • Support for remote REPLs over SSH.
  • A vastly improved code awareness engine — Snail now uses CSTParser to understand code, replacing the original version’s slow and buggy parser. This makes cross-references and autocomplete more reliable than previously.


Many thanks to everyone who contributed to Snail by submitting bug reports, feature suggestions, and especially code!


I hope this project will get the support it deserves.

I have been using Atom for the last 2 years for all my Julia dev. Apart from some intermittent problems when code was executing fine in the REPL but not in Atom (due to Atom julia packages messing up with the julia session) I was very happy with it : code completion was working as well in the editor as in the REPL, source code navigation was working fine (from the editor and from the REPL).
Now Juno is being discontinued and we are encouraged to work with VSCode.
I have tried for a few days and as of today it is not a viable option for someone like me that does julia development 100% of his time. There are too many problems especially with code completion and code navigation.

I find that the pitfall of the julia extensions for IDEs is that they they fail in reproducing the robustness of the REPL. I wonder if the culprit is LanguageServer.jl.

An emacs based julia IDE might be a savior. My personal need is minimal:

  • Code completion in the editor
  • Code execution from the editor
  • Code navigation from the editor
  • Code navigation from the REPL (from the error messages)
  • Variable display in the editor with folding capabilities (like in Atom)

Is Snail based on LanguageServer.jl or you have tried another approach?


I am not the author of the package, but I have been using Julia Snail for several months now. It’s not based on LanguageServer.jl and I believe currently has all the features you’re needing, excepting the variable display. I really like it.


Has anyone been able to get this working over an SSH double hop?

Here is my use case: I have a login node activated slurm server. I’d like to be able to run a REPL inside the server using a double hop. I can use TRAMP using /ssh:login|ssh:user@n1337:file/path.el. But starting snail gives me this error: user-error: The vterm buffer is inactive; double-check julia-snail-executable path.

Everything works on just the login node, but I can’t seem to get the double hop to play nice.

Works for me at least if I do the jump in my .ssh/config file, i.e.:

Host remote.server.url
  User myusername
  proxyJump jump.server.url

I haven’t tried by doing the jump via Tramp.

1 Like

Looks like the issue is on my computing cluster’s side of things. I will contact and see what’s causing the issue.

How do I compile a system image to make the vterm REPL load faster? It takes only about 5 seconds, but still it would be nice to be able to restart the REPL faster when it’s necessary. The difficulty I encounter is that JuliaSnail.jl is buried inside the Emacs package and does not follow the standard directory structure of a Julia package, so I’m not sure how to properly use PackageCompiler.

A discussion along with a preliminary guide for doing this is on the julia-snail GitHub ticket tracker: How to use with PackageCompiler? · Issue #84 · gcv/julia-snail · GitHub

I myself failed to get it working properly. Every time I tried, I hit problems with PackageCompiler. But several people have successfully been using Snail with custom images, so YMMV.

1 Like

Thanks, I managed to compile a system image. Now the REPL starts almost instantly. There is a small error in the very helpful instructions by the github user nlw0: the command
julia preco.jl --startup-file=no --trace-compile=myprecostatements.jl
does not produce any precompile output, at least for Julia 1.7.3, because the command-line switches must appear before the script name, otherwise they get interpreted as command-line arguments for the script instead of Julia itself. So you need instead
julia --startup-file=no --trace-compile=myprecostatements.jl preco.jl

After going through the steps, I also have to modify julia-snail.el to start Julia using the newly compiled system image.

It would be nice if JuliaSnail.jl is distributed as a standalone Julia package, which would make it easier for users to generate system images.

1 Like

Great, thanks for that correction! I’ll give it another try sometime.

As far as distributing JuliaSnail.jl as a normal Julia package, I’ll just copy-paste what I wrote on GitHub about it:

Making any part of Snail installable through normal Julia packaging channels introduces headaches. Version compatibility checks, extra steps to cut releases, extra installation steps for users, undoubtedly more support questions, and generally more work for me. So I’m not very interested in doing that.

But, I do want to simplify the process of making system images. If I can get it to work manually, I will think about how to add a high-level feature for making images to Snail itself. It would be a wrapper for PackageCompiler.

If I start a long-running computation by julia-snail-send-region, how do I interrupt it? Ctrl-c in the vterm window doesn’t work, since the computation wasn’t started by typing in the terminal.

Since I always do that sort of thing in the REPL, it hadn’t even occurred to me. Not possible right now, but I opened a ticket to track this feature request: Allow interrupting long-running Julia tasks · Issue #104 · gcv/julia-snail · GitHub

1 Like

As a workaround, you could use julia-snail-send-region with two prefix arguments (e.g. C-u C-u C-c C-r using default keybindings) to copy the region to the REPL, from where you can run it and use Ctrl-C to interrupt. On the downside, you lose module context since the Julia REPL does not support it. You can deal with that (to some extent) by using fully-qualified identifiers in those parts of the code that may result in long runs.