tslime_ipython is a vim plugin to send cells of code from vim to ipython using tslime. This attempts to bring some of the benefits of the IPython notebook's cells to vim. For example, if my code looks like the following, with marks on lines 3 and 4:
1: import my_module 2: a 3: # do an operation that takes a long time 4: result = my_function(foo, bar, baz) 5: b 6: # examine the result 7: print(result) 8: x = 5 9: print(result + x)
then I can send everything up to line 3 by hitting <C-b>
while my cursor is above line 3. Lines 3 through 5 (inclusive)
can be sent by positioning my cursor in that cell and hitting <C-b>
, and so on. The code is pasted into ipython
using the %cpaste
magic function, so everything looks tidy and neat.
You can also use comment tags to delimit cells. For instance:
1: import my_module 2: 3: ## 4: result = my_function(foo, bar, baz) 5: 6: ## 7: print(result) 8: x = 5 9: print(result + x)
will act the same as the previous example. Here the tags are ##
, though they can be set to whatever you'd like.
By default, delimiting cells by tags is turned off. See below on how to configure this behavior.
vim compiled with python support, tslime, and ipython.
By default, tslime_ipython works by treating any lowercase mark as the boundary of a cell. Once a cell is sent, the cursor is moved to the start of the next cell if one exists, otherwise the cursor remains in its current position.
There are two ways to modify these settings. First, the default setting can be changed by editing the appropriate
configuration line in tslime_ipython. Second, these settings may be passed as keyword arguments to slime_cell()
.
This is powerful, as it enables you to set different keybindings for different tslime_ipython behaviors.
By default the entire alphabet is considered when looking for delimiting marks, upper
and lower cases. For users who would rather use a subset of the alphabet as cell boundaries, this option may
be set by changing the DEFAULT_VALID_MARKS
option in tslime_ipython.vim, or by setting valid_marks
as a keyword
argument in the keybinding.
Example:
# change the keybinding so that only marks 'a-f' are used as cell delimiters noremap <C-b> :python slime_cell(valid_marks='abcdef') <CR>
Set this option in the plugin file by editing DEFAULT_DELIMIT_CELL_BY
or by setting the keyword argument delimit_cell_by
. Valid options are marks
and tags
.
Tags are comments inserted directly into the python source, used
to delimit blocks of code. The default tag is ##
, though other tags may be set (see below). When tslime_ipython
is invoked, lines that entirely match the tag are searched for. This means that if tag='##'
, then a line containing
## this is not a cell
will not be considered as cell delimiters.
Example:
# use tags instead of marks noremap <C-b> :python slime_cell(delimit_cell_by='tags') <CR>
By default, tslime_ipython looks for lines that contain only ##
when searching for tag delimiters. You
may modify this however you like, though only lines containing #
as their first characters will be valid
python code. This setting is DEFAULT_TAG
in the plugin file, or the tag
keyword in the keybinding.
Note that if DEFAULT_DELIMIT_CELL_BY
is set to marks
, then it is not sufficient to pass only the tag
keyword
to delimit by tags. You must also set delimit_cell_by
to tags
.
Example:
# delimit by tags, where a tag is a line containing only '## cell' noremap <C-b> :python slime_cell(delimit_cell_by='tags', tag='## cell') <CR>
By default, tslime_ipython takes you to the start of the next cell after you have send the current one. If you are in the last cell of a source file, the cursor will stay put, since you are most likely going to edit the current cell more.
To change this behavior, set DEFAULT_MOVE_TO_NEXT
or the keyword argument move_to_next
to False
.
The keybinding is set at the bottom of tslime_ipython.vim
. By default it is <C-b>
.
Why is this useful? Suppose you have some code that takes a long time to run, and now you want to write some code to visualize the results:
# do a long calculation result = my_function(foo, bar, baz) # examine the result plot(result)
If I just run
this from the ipython interpreter, every time I rerun my script the calculation will
be repeated. This will obviously be wasteful, and prevents me from quickly analyzing my results.
There are two obvious ways to get around this. First, I could use ipython's run -i
command to share the namespace
of the interpreter with the script, so that I can check to see if the result is defined. If it isn't, I can
simply run the calculation:
# do a long calculation, but only if the result variable isn't in my scope try: result except NameError: result = my_function(foo, bar, baz) # examine the result plot(result)
This works, but is kludgy. An alternative is to use the ipython notebook, which is excellently suited for this type of task, as you may run individual cells. The downside of the notebook, of course, is that it takes you out of your favorite editor.
By marking off cells in our code, we get the notebook's cell functionality, but get to stay in vim. Therefore, I can simply run the cell containing my calculation once, and then run my visualization code several times without recomputing my result by sending only that cell to ipython.