On Sat 22 Jun 2013 at 12:18:54AM -0700, Ed Babcock wrote:
> Because this uses tmux, there are also more options for how to edit
> projects. A tmux session can be run on a remote computer to allow for
> changing client workstations while still running the same session.
> Multiple clients can connect to a tmux server to collaborate on a
> project (haven't tested this yet). REPLs + vim can run in separate
> windows and sessions too.
…
> Hopefully this can help make vim easier to use with Clojure,
> ClojureScript, ClojureCLR, [insert Clojure sub-language here]. Does
> this sound very good? Should it have a special plugin to add more
> Clojure REPL specific features? Does it need a mini tutorial for tmux
> or vim-tmuxify? I'm interested to hear what you guys think!
tl;dr
It's workable and a great fallback, but you're going to want more.
I used to use a very similar setup with screen.vim when I first started
Clojure, but I eventually moved on to VimClojure, and now fireplace.vim.
There are a few clear advantages of using a dedicated vim plugin with a
networked REPL:
* No need to manually manage *ns*
With the tmux approach, you are in charge of the REPL's state.
This means that before evaluating forms from a new file you must
either manually evaluate the file's ns form, or determine the file's
namespace and call `in-ns` or wrap your expressions in a
`(binding [*ns* …] …)`
VimClojure and fireplace.vim do this for you, and it's a big win.
* No terminal IO issues
nREPL and lein REPL before it have line-buffered inputs because they
expect that commands are being issued from a keyboard. This means
that the REPL prints the value of each independent expression that
is terminated by a newline.
When evaluating multiple expressions, therefore, it's possible that
an input buffer will overflow while the REPL is printing responses,
resulting in corrupted input.
Another possibility is that tmux will become unresponsive while the
REPL is printing a copious amount of text.
Interactive features of the REPL can also get in the way. For
instance, readline has a optional matchparen blink feature that
slows down buffer pasting tremedously. If the REPL does anything
fancy like pipe long responses into a pager, or attempt to do syntax
coloring, these must be turned off. Readline macros should also be
turned off to prevent accidental activation by the pasted input.
Using nREPL's network protocol avoids all these issues.
* Easy access to evaluation results
VimClojure and fireplace.vim return values back to the editor, which
can be viewed with the editor's syntax coloring, manipulated with
the full power of the editor, and then re-evaluated in turn.
To do the same with the tmux approach, the eval results must
either be copied and pasted into the editor, or the REPL's output
redirected into a file, then reloaded in vim¹.
This is a large context switch, and quickly frustrating. Even
just doing a simple (clojure.repl/doc …) to view docstrings is
distracting with the tmux REPL approach.
Beyond all this, the editor -> tmux -> REPL workflow is a strict subset
of what can be accomplished with vim + fireplace.vim + tmux. For
instance:
* SSH into your beefy development machine from your laptop in a tmux
pane, then run `lein repl`
* Split the tmux pane and zoom it for fullscreen editing (this is
a new tmux feature)
* Connect to the remote nREPL with fireplace.vim's Connect command
* Now you have three methods of interacting with the remote REPL:
1. Fireplace's builtin eval²
2. Eval via a tmux REPL plugin
3. Type your commands directly into the REPL running in your
alternate pane
This is how I work, and it is very enjoyable. Having something like
vim-tmuxify, screen.vim and others like it is a great fallback, but I
find it is an inferior experience for regular Clojure projects.
guns
¹ Vim lacking Emacs' beautiful async features.
² Fireplace is quite flexible and it is easy to build your own higher
level features on top of fireplace#session_eval(). I've managed to
reimplement most of my favorite features from VimClojure and more on
top of fireplace.vim with just a little work.