I’d like to announce the first beta release of Julia Snail, an Emacs development environment for Julia. Snail provides a workflow for Julia similar to that of Common Lisp’s SLIME and Clojure’s CIDER. It enables convenient and dynamic REPL-driven development.
Please see the README for details and a short screencast showing off its features.
the first julia-snail (or C-c C-z) fails with open-network-stream: make client process failed: Connection refused, :name, julia-process, :buffer, *julia* process, :host, localhost, :service, 10011, :nowait, nil, :tls-parameters, nil. The second one works fine.
activation fails with julia-snail--send-to-server: Buffer *julia* process has no process, even though Julia is running fine and I can send stuff (lines etc) to it.
Also, I have not yet figured out how to “escape” the buffer capturing navigation so I can copy output from it (cf term-line-mode), but this is the first time I am using vterm. Found vterm-copy-mode, C-c C-t.
The Julia interaction side of the Snail server is single-threaded (using @async ). This means the interaction locks up while the REPL is working or running code. Unfortunately, Julia as of version 1.3 does not have user-accessible low-level multithreading primitives necessary to implement a truly multi-threaded Snail server.
I’m curious what about Threads.@spawn you found insufficient. It works very similarly to @async.
In any case, this is very cool. Thanks for sharing.
It looks like the synchronous REPL startup and Snail server initialization didn’t work right, which is a bit surprising. I just committed a workaround. Please update when MELPA picks up the change and let me know if that works.
Since send-to-server didn’t work for you, it means you were missing out on most of the cool features!
I clearly didn’t read the Julia 1.3 release notes carefully enough. Snail started under 1.2 when Threads.@spawn didn’t exist. I’ll have to give it a try. Thanks for pointing it out.
Yeah, the vterm dependency is pretty gnarly. It’s worth trying to see if it works on Windows, but I honestly doubt it. If interest in this project picks up, it would be great to just do the right thing and reimplement the Julia REPL in Elisp. It’s honestly not even that hard, but too time-consuming for me to commit to right now.
Relying on either the broken Emacs built-in terminal emulator, term.el, which has major display glitches and dreadful performance, or on an external library like vterm, which massively complicates the dependency story and probably locks out Windows users.
Complicates using a REPL running on a remote machine.
It’s just so much more user-friendly to have a native Emacs REPL. With enough interest, I feel that keeping up with Julia REPL features will be a smaller aggregate burden than asking users to deal with a terminal-based solution.
There’s something non-obvious going on. Mind opening a ticket on GitHub so we can track and discuss it without derailing this discussion? Also please post your platform info (OS, Emacs distribution, Julia version). If you have any interesting local firewall utilities, or some kind of security software that gets in the way of opening network ports, please include that too.
I would be happy to contribute if you get something started. I love programming in Julia and I still feel comfortable in (Emacs) Lisp, so from my perspective this would be easier to maintain than a solution involving yet another language or protocol.
That would be great, thanks! Meanwhile, I’d like to hear if there’s real interest in the features I tried to build out and if the UX works well for Julia hackers. It works pretty well for me, personally, but I currently only use Julia for side projects. It’d be good to have feedback from more intense users.
Fwiw, I just pushed the update to inferior-julia-mode that I’ve been tinkering with (based on comint-mode) to github. No completion support yet, but it does support the “?”, “]”, and “;” magics. It’s not quite implementing the REPL in elisp but it avoids some of the pitfalls you’re mentioning.
Yes, completion should work on everything loaded in the Julia environment with package activation and from loaded source files (i.e., code you’re working on). But judging from our discussion on the GitHub ticket, we still have some activation bugs to work through.
So now I have completion working, this is very nice!
I still have a question on the current limitations of code completion. From what I can tell I get completions either from:
Base + Packages that I am explicitly using in the REPL
Packages used in a file which I loaded using julia-snail-send-buffer-file (but these completions only seem to work in the file that was loaded where the using statement is and not in other files).
My typical workflow until now is is to put all code for some project inside a package MyPacakge, then using Revise; using MyPackage in the REPL.
Right now if I am working on some file which is part of the package it seems that I won’t get code completions for functions from other packages which are used by MyPackage, unless I load these packages myself in the REPL.
Also it seems to me that I won’t get completions for functions which are defined in some other file in MyPackage but not exported, even if I load MyPackage using julia-snail-send-buffer-file. Is this correct?