Simplifying the life of a programmer with vim + vim-slime + tmux

This post talks about how to save development time for Clojure and NodeJS, as well as Bash scripts by sending text from vim to REPL using tmux + vim + vim-slime. Recipes with nodemon are also provided.

Most likely, vim-slime will work for other interpreted languages ​​(Ruby / Python / PHP / Perl ...). vim-slime also works with screen.
On a habr both vim, and tmux were sufficiently lit. I just wanted to show what can be obtained from their combination.
Addendum from Fikys : works with Ruby.

If you know vim and tmux, and you are only interested in vim-slime, jump directly to the second section.

Introduction


We all strive to be productive. After the code is written, we want to find out if it works and get feedback. We came up with many ways to speed up feedback: static type inference during compilation and in the IDE, unit tests, integration tests, REPL, LiveReload, etc.

For my small projects, I use a bunch of REPL and unit tests, which allows me to get feedback instantly.

I am a web developer. For work and in my project, I usually do the front-end and part of the back-end that joins it. During the working session I write PHP, phtml, Stylus, css, Coffeescript, Javascript, + sql queries and push to git; which is provided by a combination of tmux and vim. There are also a couple of small CoffeeScript projects that use the tmux + vim + vim-slime + Coffeescript REPL combo. In the project session, Clojure, CoffeeScript, Stylus are linked; tmux + vim + vim-slime + Clojure REPL. Under the cut, I will talk about three setups for three environments.

Setup 1 - “Worker”


At work, I write phtml templates, connect data from Zenda controllers to them, hang scripts and styles on the templates. In order not to get confused in several different contexts, I spread everything across several tmux windows. One window each and running wim for php / phtml, stylus, coffee, js. Four more helper windows for ssh, mysql, git and watching compilers (coffee, stylus).



I used to keep all tabs in one instance of vima. tmux allowed to run several vim instances and not get confused in them.

Setup 2 - Coffeescript


I am writing my feature set for JS. This is an AMD module that turns into CommonJS using “30 lines of code”. Freshly written CoffeeScript elementarily tests with a wim-slime and then goes under unit tests.

vim-slime

The vim-slime project, as described by its author Jonathan Palardi (jpalardy @ github), is a combination of a good editor (vim) with all the cool REPL. I very vaguely imagine how the real SLIME works, so I can not give help on the original. In addition, there is a solution closer to SLIME for vim , but not so easy to install. All I need vim-slime for is to send text from vim to REPL. You open tmux, divide the screen into two tabs - on the left you put vim, on the right your favorite REPL. You write the code, you press- The current paragraph flows into the REPL and is executed. Beauty.



Install and configure vim-slime

Vundle owners just need to add add to vimrc, and execute PluginInstall:

Plugin 'jpalardy/vim-slime'


The owners of Pathogen, respectively, clone their repository from the github.

By default, the plugin is configured to work with screen. For it to work with tmux, add the second line in vimrc:

let g:slime_target = "tmux"


When preparing the publication, it turned out that the plugin does not work with CoffeeScript out of the box (with JS all the rules). In my case, this was decided by including the second plugin:

Plugin 'kchmck/vim-coffee-script'


Sighting vim-slime

In work, it looks like this. We start tmux, divide the screen in two, open the favorite file in vim. In the second panel, run REPL, for example, Coffee or NodeJS.

Here are some ready-made pieces of code in case you are too lazy:

// js
function greeter(name) {
  console.log("Hey, " + name + "!")
}
greeter("Jude")
# coffee
greeter = (name) ->
  console.log "Hey, #{name}!"
greeter("Jude")


We select the piece of code that interests us through vim visual mode and . If nothing is allocated, thenwill send a paragraph to the REPL (block of text without blank lines) under the cursor.

When you first run the command for a session, vim-slime asks for the name of the tmux socket and in which `tmux-session: window, panel` send text. We answer the first question with `default`, the second with`: 0,1`. Enter! And the code appears in the REPL.

The configuration dialog can be called up independently through `: SlimeConfig`. You can also send the code to another terminal window, which can be convenient for people working with multiple monitors. Run the second window with tmux, open your REPL and in the first window with vim do:

:SlimeConfig
default
2:0,0


Where on the third line is indicated `session-name-tmux: window, tab`.



added: If you feel uncomfortable

You can use the advice from dkiyatkin.
In the official documentation there is advice on how to reassign a wim style combination:
let g:slime_no_mappings = 1
xmap s SlimeRegionSend
nmap s SlimeMotionSend
nmap ss SlimeLineSend


Unit testing

I covered the most complex and root (used by other functions) library functions with the simplest (but sufficient) assert tests.

To see the test results within seconds and not be distracted by the routine, there is nodemon. This is an npm package that feeds the js / coffee node a script at startup and every time the tracked files change. As a result, I learn about the test results every time I save a file.



To get such a live second tab, something like:

nodemon run-all-my-tests.coffee --watch my-changeable-files/*2


Setup 3 - Clojure


This publication would not have appeared if it had not come across some guy who described his setup .

Also for Clojure there is a vim-fireplace , which, among other things, can get documentation.

I preferred vim-slime for one simple reason - REPL.

The Klozhurovsky REPL server (nrepl) and the client (REPL-y, included with Leiningen) can do a lot of useful things by themselves. The behavior of vim-slime is as primitive and predictable as possible. Moreover, when REPL-y runs in the next tab, you see all the history and error traces, and in addition to the REPL-y features themselves, tmux text processing functionality is also available. You can switch to REPL and execute there that you do not want to write and erase in vime, and switch back.



In general, the experience with Clojure REPL is the same as with NodeJS. The main difference from NodeJS REPL is that Clojure REPL has a namespace concept. Therefore, every time you want to send a specific piece of code to REPL, you also have to manage to switch the namespace. This can be automated by adding to .vimrc:

function! SendNs ()
  let cpos = getpos('.')
  exec "1 SlimeSend"
  call setpos('.', cpos)
endfunction
autocmd BufWinEnter *.clj :call SendNs()
autocmd TabEnter *.clj :call SendNs()


Thus, each time you switch tabs in the REPL, the current namespace is set. Must be indicated by the first line in the file. Most likely it can be automated more elegantly.

Leftover Buns and Trivia


Bash & ssh

I am still delighted with the opportunity to open an ssh connection to Stuttgart (hetzner) on the next panel and send the text from Moscow there. Thus, you can simultaneously write code and debug remotely. This thing also works with bash. In the screenshot in the left hand is the local vim, in the right hand is the remote bash:



tmuxinator

To simplify the creation of tmux sessions, I use the ruby ​​project tmuxinator.

My .vimrc and tmux.conf

1. .vimrc
2. .tmux.conf

Honor


One cannot but mention the minimalist habrovchanin d3m1gd , who made his vim-slime . I would also like to thank all the educators who talk about vim, tmux, and other * -NIX tools.

Also popular now: