[ANN] REPLSmuggler.jl: Send code to your Julia REPL, and get Neo-Vim diagnostics in return

Hi there!
I have worked a lot with NeoVim and vim-slime during my PhD. This workflow is great, but I was missing some features, such as having the correct line numbering in exceptions. I have put together a small Julia package and its companion plugin for NeoVim that fixes this.

asciicast

It can probably be improved, and contributions are welcome!

8 Likes

This is great! I have also used vim-slime for a long time and incorrect source location is my main gripe too.

Here are some feedback from just playing around a bit:

  • When using vim-slime (or copy-pasting manually) with something like:
    function foo()
        x = 45
        y = x * 3
    end
    
    the Julia REPL look like this after:
    julia> function foo()
               x = 32
               y = x + foo(x)
               return y
           end
    foo (generic function with 1 method)
    
    whereas with REPLSmuggler the indentation is off and you end up with
    julia> function foo()
        x = 32
        y = x + foo(x)
        return y
    end
    foo (generic function with 1 method)
    
    Would it be possible to keep the paste-behavior also with REPLSmuggler?
  • When smuggling a visual range it would be great to let the cursor stay in its original position (see vim-slime#354 for the same issue in vim-slime).
  • One great thing with vim-slime is that you don’t need to do anything in the REPL before sending text. It would be amazing if, when trying to smuggle, using REPLSmuggler; smuggle() could be sent to the target REPL automatically somehow.
  • With vim-slime I often reconfigure the target window (e.g. two Julia REPLs with different Julia versions running). I have it configured so that :SlimeConfig automatically targets the last visited tmux pane. I see that you can reconfigure also with REPLSmuggler but you then have to remember which socket belong to which pane etc. It would be great to make switching like this easier.
  • There seem to be no way to clear the error diagnostics
  • I initially thought that calling functions manually in the REPL would also have errors hooked up to show in the editor, do you think this would be possible?
  • Do you think REPLSmuggler can be used as a debugger frontend?
2 Likes

Hi, thank you for your interest!

  • Would it be possible to keep the paste-behavior also with REPLSmuggler?

Right now, the way REPLSmuggler displays things is a bit hacky: it prints the REPL’s prompt and adds the evaluated line (see REPLSmuggler.jl/src/eval.jl at 63d811900d4761aa1003ce2db6702155371fba07 · Klafyvel/REPLSmuggler.jl · GitHub). So we could simply offset each line knowing the length of the prompt. However, I wonder if it wouldn’t be better to define a new prompt for REPLSmuggler rather than hacking into julia’s default one. Sadly documentation is a bit lacking here (or I did not find it!). Maybe someone with more experience with Julia’s REPL could point me towards the correct solution here!

  • When smuggling a visual range it would be great to let the cursor stay in its original position (see vim-slime#354 for the same issue in vim-slime).

I am not able to reproduce this, and the selection of areas is done without moving the cursor within nvim-smuggler (I’m using neovim’s api). Can you give me a more specific example?

  • One great thing with vim-slime is that you don’t need to do anything in the REPL before sending text. It would be amazing if, when trying to smuggle, using REPLSmuggler; smuggle() could be sent to the target REPL automatically somehow.

The problem is nvim-smuggler cannot communicate with the REPL at all before these lines are executed. The simplest way to do it would be to add theses to your startup.jl file I guess?

  • With vim-slime I often reconfigure the target window (e.g. two Julia REPLs with different Julia versions running). I have it configured so that :SlimeConfig automatically targets the last visited tmux pane. I see that you can reconfigure also with REPLSmuggler but you then have to remember which socket belong to which pane etc. It would be great to make switching like this easier.
  • There seem to be no way to clear the error diagnostics

These are important features, could you open an issue please?

  • I initially thought that calling functions manually in the REPL would also have errors hooked up to show in the editor, do you think this would be possible?

That’s a current limitation. I think it is feasible, but we need to define our own REPL, or at least modify the default REPL to catch exceptions.

  • Do you think REPLSmuggler can be used as a debugger frontend?

The protocol used by REPLSmuggler.jl is fairly extensible (see here), so I think it could be achieved if we define the correct endpoints. However, some thoughts are needed to give a good user experience on the editor’s side: how do you mark breakpoints, how do you keep track of modifications… I am open to adding that, but I lack the experience to make it great (I am a physicist, not a software engineer!), so I would need help adding and maintaining such a feature.

2 Likes

Just offsetting the lines would be a nice improvement to begin with at least. Relatedly, it could be nice if smuggled code were inserted into the REPL history.

I am talking about :SmuggleRange from VISUAL or VISUAL-LINE mode; for example with my foo function above, entering visual mode on the first line, move down the the end line and then smuggle the selection. Afterwards the cursor moves back up to the first line.

Yea, or use another mechanism like vim-slime to send the code if there is no REPL server running.

Done, and done.

Another option could be to hack into the display system and smuggle back errors when they are being displayed.

Yea would probably take some work, but since you already have the two-way communication going it might not be too bad. Perhaps one can take inspiration from how the VS code plugin does it.

1 Like