Interesting discussion, thanks for the link.
My overall impression is that implementing a vim/neovim plugin to run the REPL is a great idea, but is outside of the scope I set out to achieve with VimBindings.jl and not something I’m looking for myself. In my view, vim great for text editing, and the REPL is great for interacting with Julia. Merging the two in a way which is intuitive is more nuanced than running one within the other.
I’ll respond to your Zulip messages here:
It look like the authors are building a thin vim simulating layer on top. This introduces massive implementation overhead since every vim features has to be reimplemented. Moreover all my vim configuration is useless in this term. I still think efforts toward a vim plugin that works well with julia REPL would be more sustainable, powerful and customizable.
I don’t view VimBindings.jl as a full drop in replacement for vim or neovim, or their full set of capabilities, in the same way that vi mode in bash, fish, or zsh are not full vi implementations; I would not expect to convince a hardcore vim user that VimBindings.jl is vim. Instead, my goal is to take ideas from vim and integrate them into the Julia REPL. In other words, I want VimBindings.jl to enhance the Julia REPL with a vim flavor for anyone using the REPL (a “REPL-based” plugin), not to wrap the Julia REPL in vim (a “vim-based” plugin) just for vim users. I use the REPL from many places, not solely through vim. I hope this makes sense.
In zulip you said:
To be fair VimBindings.jl implements history integration and undo/redo functionality which is not readily available in neovim’s term. But the fact that doesn’t mean it’s the best way forward.
Resolving these corner-case problems is, in fact, my main goal. I don’t think that re-implementing every function of vim is particularly valuable, and there may be an approach which negates the need for re-implementing so many features altogether for VimBindings.jl (and I’ll expand on this shortly). What I do think is valuable is a set of vim-like enhancements which is intentionally designed for its context. Enhancements which clear away roadblocks for the user by removing the need for them to think in two paradigms (vim and the REPL), at least as much as is practical.
If we look at marrying vim to the REPL, there are instances where the two designs clash. These questions would need to be solved in both a “REPL-based” plugin as well as a “vim-based” plugin. They also can’t be solved objectively; one must decide which paradigm to favor, or when to ignore both paradigms altogether. To enable a good user experience one must make an opinionated decision. For example:
- when hitting “Enter” from Normal mode, should the vim mode be Normal or Insert on a new prompt? Vim says no; the user never entered insert mode. VimBindings.jl says yes.
- when the user finishes entering code in Insert mode and presses Enter, should the text buffer be saved as a part of the “undo” history? In Vim the answer would be no; the user never left insert mode, which is when undo history is saved. VimBindings.jl says yes.
- what does a “mark” mean in the Julia REPL? Vim doesn’t have an answer, because the REPL is not a text file; vim is a text editor, not a shell. VimBindings.jl says that a vim mark it ought to mean an entry in the REPL history. In other words, a user ought to be able to mark a specific entry and recall it later. (not implemented yet, but something I’d like to do soon)
The point I’m trying to make is that vim is not a REPL, it is a text editor. Thus, features which make sense in vim (undo/redo, marks, newline, etc), lose their meaning or become ambiguous when mapped to a REPL. The value in VimBindings.jl is not just replicating the vim commands on text in a buffer, but specifically doing the work to integrate vim features to the REPL experience in a way which feels coherent. That VimBindings.jl does history and undo/redo well isn’t just an implementation detail; they are precisely the type of problem I’m trying to solve with VimBindings.jl.
That isn’t to say this couldn’t be achieved from the other side, as a “vim-based” plugin. I just believe that implementing it on the REPL makes it accessible from a wider array of users, instead of just being usable within vim. I also think that integrating with the Julia REPL code is best done in pure Julia.
As for the text operations themselves, there may be something to your idea to improve that with neovim. The alternate approach I mentioned earlier is is a route that I explored early on with VimBindings.jl, doing what the vs-code neovim plugin does. That is, embedding neovim under the hood - starting up a neovim instance and then synchronizing the neovim buffer with the REPL contents, and sending key strokes to neovim. I don’t think it would be as simple as wiring up the buffer to neovim, for the design reasons mentioned above (I put together a prototype a few years ago and it was quite fragile). Still, it would be a clearer path to getting nearly all of vim’s functionality including configuration and plugins.
If there was demand for a fully featured vim implementation within the REPL, I think that would be the right way to go. I’ve returned to that idea a few times, it just comes with a whole host of new design questions that I haven’t had time time to look into. I think it’s a pretty daunting task. My only reference is vs-code neovim, which looks anything but trivial.