no magic – just tricks

Like Slime, for Vim

I started reading Practical Common Lisp yesterday. No discussion about Lisp can be complete without talking about Slime. Slime basically turns Emacs into an IDE for Lisp development. Peter Seibel thinks this is important enough to dedicate the second chapter to it. He even repackaged Lisp + Emacs + Slime as Lispbox to help people get started faster. For an excellent book (so far), available for free, and Lispbox, thank you Mr.Seibel.

After actually downloading, installing, and running Lispbox, I can see the advantages. Slime solves the problems you would have with any interactive REPL-type environment.

Let’s take Ruby’s irb as an example more people are going to relate to:

you start irb

you start a text editor (vim, textmate, emacs, …)

you do a few tests in irb

you copy and paste to a text editor

you clean things up in the text editor

you copy and paste back to irb

you make a mistake

you fix things up in the text editor

you hesitate copying and pasting, because it’s painful now

you write some tests

you exit irb and run the tests to do your experiments

Let me present the dilemma another way: irb is great to get answers quick but it is also temporary because you know nothing you do in irb will be saved. However, the moment you start living in a text editor, you give up a lot of the power of REPL. Or, at least, your REPL becomes 10 seconds instead of 1 second. That changes the way you work. And that explains why Slime exists.

Slime creates a new interactive session with Lisp and you are able to copy and paste text from a text buffer to the session with one keyboard shortcut. That’s great! Now you can type, organize, pretty-print your code in a text editor, type C-c C-c to “refresh” the interactive session. This does not close and create a new session, the function definitions are reloaded into the current session. So, all your testing objects, those carefully crafted lists and hashes of objects (or whatnots) still exist—the world just changed around them.

Yeah, Slime is great. I’m just not an Emacs fan.

I did some research and Vim has no mode to support asynchronous sessions like Emacs. In essence, all that’s needed is a software that will spawn what you really want to run, say irb, control stdin/stdout/stderr, capture its own stdin/stdout/stderr and tunnel those to the child process. Also, it would be nice if it could open a port to receive external commands to be able to script stdin…

That’s when I remembered an article I read about scripting gnu-screen. To make a long story short, screen does everything we want, and more.

Here’s what we want to accomplish:

start a named screen

name the screen window

start irb

start another terminal

start vim

define a function/class/object

have it “transported” to irb

Here are the instructions:

screen -S session01

C-a A—window01

irb

vim

(type code)

vip (select paragraph)

“ry (copy to register r)

:call system(“screen -S session01 -p window01 -X stuff ’” . @r . ”’”)

And BLAM, you just did some magic!

At this point, you are coming to 2 realizations:

this is WAY cool

you want this automated

Thankfully, I can help with the automation. Get slime.vim and put it in ~/.vim/plugin/ .

A few notes:

the magic key is C-c C-c (like Slime, surprise!)

the first time, you’ll be prompted for the “session name” and the “window name”

subsequent times will be automated

you can reprompt for “session name” and “window name” with C-c v

by default, C-c C-c will select the current paragraph and copy-paste it

but you can make your own selection first, and send it over with C-c C-c

…

As a final note, I’d like to drive the point that this can automate ANYTHING running in a screen:

bash

top

irb

python

any lisp/scheme REPL

mysql

…

One thing is for sure, this will definitely change the way I work.

(For extra points, write your own Textmate plugin … this hack is not limited to Vim!!)

I agree with the other comments, this is a great addition to Vim which will definitely make my life easier. Would you consider posting your plugin to vim.org? Thanks a lot for sharing this great script.

Just wanted to add another tip/request:
If you do this: C-a Shift-S you get screen to split the shell. Press C-a TAB then C-a C-a until you get vim on top and irb in the lower shell… voila! You now don’t need C-a C-a EVER again :D instant results.
Can it be implemented within the plugin? Something like to start a screen session automatically if not started, then start 2 shells then put vim in one and leave the second one alone (or start irb there). is this a good idea?

[…] big thing? Screencast: Like Slime, for Vim October 17, 2008 A year ago, I posted Like Slime, for Vim. There was a lot of interest in sticking with Vim but having a way to get something similar to […]

This is crazy wild; great job! The only suggestion I would make is that some might change the keystroke mappings since Control-C is used by Vim to revert from insert mode to command mode. I realize it is my bad habit, but there are times when I will tap Control-C multiple times in my PHP / Java programming and I worry that it will fire off especially if I am not in screen.

Anyhow, this is great; I definitely want to post a link on my blog and get my cubemates using this!

Just came across this the other day, and must say thanks…this is great! Only thing from having me rip through Lisp (or at least, attempt to) was stumbling through Emacs when I’ve always been a VIMer. Much appreciated!

Thanks for your reply. Probably it is better that I rephrase the question I have. If I like to select the whole class or function to the python shell at once, how do I accomplish that in a step by step manner? I can select the text with the key: vip, but I can’t seem to find the way to send the selected files over to the shell. Right now, I have to select line by line which is very inconvenient at best. Thanks for your help.

Thank you for your reply. Really appreciate your help. I look at the error again and I see that it is actually working but the spaces does not get sent over correctly. And there I get the IndentationError: unexpected indent. I am sorry for the confusion as I am stepping up my coding in Python. I hope you don’t mind I ask if there is anything that I have to set to be able to do get the screen to get the spaces over correctly? Thanks for your help.

Hey, this works great! Just what I need and yet it’s so simple. I just changed three things: If you always use the same name for your screen session and window, you can hardcode it into slime.vim.
Another more substantial thing: I noticed with python that it doesn’t work as expected since python will faithfully accept the input but then wait for more. Since its based on indent it will not notice that the input is over. Here is an easy fix: just add a trailing new line like this:

nmap vip”ry :call Send_to_Screen(@r.”\n”)

I believe that will help all python users and not hurt anybody else. There is also another feature that might come in handy — execute the one line of text under the cursor:

another thing that annoyed me: after using C-c C-c it will always jump to the position on top of the block that was just executed instead of going back to where the cursor orignally was.
Thus I might some more minor changes and put the thing here:http://n.ethz.ch/~hroest/download/slime.vim

I use the VimClojure plugin for hacking clojure code in Vim, and it works pretty well. You get true slime like functionality too, including a variety of macro expansion and in-buffer expression evaluation features. Definitely worth it. Oh, and Clojure is about 1000 times cooler than Common Lisp, especially if you are interested in concurrency and lazy sequences.

It integrates fully with Emacs. So when you “C-c C-c” you’re actually calling a function to send the form previous to where your cursor is to the Lisp REPL which compiles it. If there are errors during compilation, the relevant forms will be highlighted in a color-appropriate manner (warnings will be yellow, fatal errors red, etc). You then get a couple of keybindings to jump from error to error and get the exception text in the mini-buffer.

Or you can jump right into the stack-frames and interact with the debugger… all while still in emacs.

It seems go get rid of empty lines (given they contain no space). Also, I wish I could get the + to work, but \n\n* will, essentially, give the same result.

Keep in mind that slime.vim sends your data to a command. As such, you could make a proxy command that takes the same argument, cleans up the text, and forwards it to screen. At that point, there’s no limit to what you can do.

I have posted the cygwin version here(formatting would be screwed; haven’t figured out how to post code).

I made following minor changes:
1) The expression is ‘\n\s*\n\+’. It deletes only vacant lines and accounts for spaces.
2) I am appending a newline at the end of register. Python repl needs it for completing declaration.

This vacant line breaking the repl is an issue only with Python whose syntax is based on structure and the repl takes the newline as end of function definition. Ruby, Lisp et al. has explicit end markers.

Screen_Vars has a nice place to set default values for the session and window names, but the prompt does not currently auto-populate session name field. May I suggest that you you use g:screen_sessionname, rather than a hard-coded empty string, in the call to input()?

I’ve been trying this in windows XP using cygwin and I can’t quite get it to work. I think is a permission thing or a path problem. I What I’m getting is an error “E484: Can’t open file C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\VIo316.tmp”

note that I’m able to send a command like in the example from one screen to the other. I just can’t do it in vim. Also how do you get the ^M? I have to literally send the enter command by pressing the Enter key before closing the quote.

Aw, this was a very nice post. In thought I want to put in writing like this moreover – taking time and precise effort to make an excellent article… but what can I say… I procrastinate alot and by no means seem to get something done.

[…] I am somehow using sreen for a long time. Except traditional usage like window multiplexer for one terminal or process deatacher, I used it for making Vim a CLI IDE for Python, SQL, or what so ever language using CLI. See Slime plugin […]

I find your plugin to be the best because it is so versatile. It works for ANY lisp – including racket, which I prefer.
I request permission to copy the entire wording of this blog post as it stands in a text file as documentation, including the date and the author. Let me know if I may do so. Thanks.

I’m currently re-evauluating Vim as my default editor for choice. I actually started using Vim, but never really became a “power user”; I then moved on to Kate (I still love its Regex composer–which is available separate from Kate, by the way), and then moved on to Emacs as I started to try to learn Lisp.

I kindof like Emacs, but I’m by no means a “power user” of that, either. And now, I’m again beginning to be attracted to the power and simplicity of Vim. Reading about this gives me something to look forward to!

Perhaps “SLIME” should be re-acronymed to “Superior Language Interaction Mode for Everything”. :-)

Also, you were going to award extra bonus points for anyone who does this with TextMate. How many bonus points will someone get, if they do this with Emacs? (What really blows my mind is, that it probably will work, and may even be simpler to set up than SLIME itself. While one commenter pointed out that SLIME provides more than just instant compilation, I would point out that this sounds simpler to set up, and is probably more versatile, than Emacs + SLIME…)

After exploring a handful of the articles on your web site, I seriously
appreciate your way of blogging. I book-marked it to my bookmark website list and will be checking back soon.
Please check out my website too and let me know your
opinion.

Hello, Neat post. There’s an issue together with your site in internet explorer, would check this? IE nonetheless is the marketplace leader and a large portion of other people will pass over your excellent writing due to this problem.

[…] for a Vim version. What I found was vim-slime by Jonathan Palardy which was originally introduced here. Vim-slime relies on the GNU screen command for the heavy lifting, I’m not too familiar with […]

[…] vim-slime is absolutely great, it’s a plugin for vim that lets you send text to screen or tmux. This is perfect for programming any language that has an REPL, simply load a session up in a tmux, open up vim, tell it what tmux window and session you want to send text to and away you go. This will work for any language! A great post can be found here. […]