All I wanted to do was use Vim and Python together

January 14, 2015

Reading time ~5 minutes

I decided to start using python a little more.

During the last Kaggle competition I participated in, there was a comment on the message board about throwing everything

1
scikit
had at the dataset. I googled and
1
scikit
refers to a package in python. It doesn’t surprise me that people trying to win at Kaggle are using python, most of them are computer science folks, what surprised me was the fact that he said “everything.”

This competition had 150 GB of data. It took days to throw one thing at the data with R. The thought of throwing even one thing at the data made me feel a little tired, much less throwing everything at the data. If Python is that much faster, how could I not start using it a little more.

##But I want to use Vim I love Vim. Vim and python should be perfect for each other since Vim is scriptable in python. So WHY OH WHY was setting up Vim for python so awful!

Do you like watching text editor do nothing for 10 or 15 seconds every time you save a file? Then vim-ipython is for you. It checks your code every time you save your file as a default. It must be doing a good job, because the entire editor just sits there while it does it. Thank, pyflakes!

Do you enjoy running an entire program from start to finish! If so, then you will be glad that so much work has gone into the popular Vim packages for python, because they don’t give you the option of doing anything but running the entire file, start to finish. No checking your results as you go, just check the whole program!

You can even use buggy, sloppy Conque! It hasn’t been updated since 2011, but that just means it’s finshed!

##That sinking feeling I spent most of the afternoon trying to find one add-on that did what I wanted: run python line by line while showing me the results, either in separate Vim window or in the terminal. This is what the Vim-R package does.

I must be doing it totally wrong or something.

Anyway, I wound up using screen and vim-slime. I tried making a leap to screen/tmux a few years ago, but just wasn’t up to it. It seems like a lot of people use screen as the basis of there computer use, and run Vim out of screen. I didn’t really get that at the time, and was more discouraged that Vim doesn’t work quite like the Vim GUI version when it’s running out of screen. However, thanks to vim-slime, it is possible to run screen out of Vim, and thus python out of Vim.

##The upshot Here are the key pieces of my python process right now:

  • Open the terminal
  • In the terminal enter
    1
    
    screen ipython
    to open an ipython session in Vim
  • name the screen session by entering
    1
    
    <C-a>:sessionname vimpy
  • Open the python code in Vim
  • 1
    
    <C-c><C-c>
    - i.e., while holding control double tap ‘c’
  • Prompted for the session name which you just started (‘vimpy’)
  • Prompted for the window number (I choose 0)

Once this process has been started, chunks of python code (paragraphs) can be sent to python using

1
<C-c><C-c>
. The results pop up on the terminal you just started.

The big issue is that you have to get the session name right. If the terminal is closed the wrong way it keeps running and the next session named “vimpy” will be indistiguishable to Vim from the first. Thus it is important to close the sessions in the “right way.” I wrote some vimscript that does this:

function! ScreenSessions(close_group)
   redir @s
   silent execute "!screen -ls"
   redir END

   let total = 0
   let screens = []
   while split(@s)[total] != 'Sockets' && split(@s)[total] != 'Socket'
      let screenchk = split(@s)[total]
      if strlen(substitute(screenchk,a:close_group,'','')) < strlen(screenchk)
         let screens = add(screens,split(@s)[total])
      endif
      let total += 1
   endwhile

   if len(screens) == 0
      echo "No screen session are open with name like ".a:close_group
      echo "Please create a session in the terminal by using:"
      echo "screen ipython"
      echo "and then changing the session name by using"
      echo "<C-a>:sessionname ".a:close_group
      execute "!open /Applications/Utilities/terminal.app"
   endif

   if len(screens) == 1
      echo "There is only one session with a name like ".a:close_group
      echo screens[0]
      echo "You are ready to edit and write python code"
   endif

   if len(screens) > 1
      let inc = 1
      while inc < len(screens)
         execute '!screen -X -S '.screens[eval(inc-1)].' quit'
         let inc += 1
      endwhile
   endif

endfunction

command! Vimpy call ScreenSessions('vimpy')

nnoremap <Leader>ip :call ScreenSessions('vimpy')<CR>
nnoremap <Leader>iq :execute '!screen -X -S vimpy quit'<CR>

Using

1
<Leader>ip
closes all but one of the screen sessions named ‘vimpy’ so that vim-slime knows exactly which session is being referred to.

So far, this is working pretty well. Line by line code is running, there are no hangs (once I set up my

1
.screenrc
the right way) and everything is awesome.

At least until I try to view a graph. Then it will all fall apart, I imagine.

Running R code in secure shell using Vim

Published on October 27, 2014

Vim as a blogging tool

Published on October 20, 2014