Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Added Matlab-like cell behavior #41

Open
wants to merge 16 commits into from

2 participants

@wmvanvliet

I've added a cell mode like Matlab has, where %% marks delimit cells, which can be executed one by one. In Python, the marker is # <codecell> to be compatible with IPython notebook cells. You can now do stuff like:

# <codecell> Preprocessing

filter()
another-filter()

# <codecell> Plot it!

plot(data)
...

And execute cells one by one by moving the cursor inside and pressing Ctrl-Alt-S

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 6, 2012
  1. Added Matlab-like cell behavior

    Marijn van Vliet authored
Commits on May 15, 2013
  1. @wmvanvliet

    Merge https://github.com/ivanov/vim-ipython

    wmvanvliet authored
    Conflicts:
    	ftplugin/python/ipy.vim
Commits on May 27, 2013
  1. @wmvanvliet

    Added folding for cell mode

    wmvanvliet authored
Commits on Dec 6, 2013
  1. @wmvanvliet
Commits on Jan 2, 2014
  1. @wmvanvliet

    Merged ivanov changes

    wmvanvliet authored
  2. @wmvanvliet

    Merged ivanov changes

    wmvanvliet authored
Commits on Feb 18, 2014
  1. @wmvanvliet
Commits on Apr 25, 2014
  1. @z0rch
  2. @z0rch
  3. @wmvanvliet

    Merge pull request #1 from z0rch/master

    wmvanvliet authored
    Made cells compatible with IPython notebooks
Commits on Apr 28, 2014
  1. @z0rch
Commits on Jun 4, 2014
  1. @wmvanvliet

    Merge branch 'master' of https://github.com/ivanov/vim-ipython

    wmvanvliet authored
    Conflicts:
    	ftplugin/python/ipy.vim
  2. @wmvanvliet
  3. @wmvanvliet

    Merge branch 'master' of https://github.com/z0rch/vim-ipython

    wmvanvliet authored
    Wrapped cell folding in a function
    
    Conflicts:
    	ftplugin/python/ipy.vim
Commits on Dec 4, 2014
  1. @wmvanvliet

    Merge branch 'master' of https://github.com/ivanov/vim-ipython

    wmvanvliet authored
    Conflicts:
    	ftplugin/python/ipy.vim
Commits on Dec 10, 2014
  1. @wmvanvliet
This page is out of date. Refresh to see the latest.
View
14 README.rst
@@ -109,6 +109,20 @@ Then, go to the qtconsole and run this line::
You can also send whole files to IPython's ``%run`` magic using ``<F5>``.
+Finally, you can define Matlab-like cells using either ``##`` or ``# <codecell>`` markers and execute it
+by moving the cursor somewhere within the cell and pressing ``<Ctrl-Alt-S>``::
+
+ ## Some imports
+ import numpy as np
+
+ # <codecell> IPython notebook compatible cell marker
+ # Print some messages
+ print 'You can define cells,'
+ print 'just like in Matlab!'
+
+Cells are two-way compatible with IPython notebooks,
+so you can easily switch between browser and Vim without loosing them.
+
**NEW in IPython 0.12**!
If you're trying to do run code fragments that have leading whitespace, use
``<Alt-S>`` instead - it will dedent a single line, and remove the leading
View
39 ftplugin/python/ipy.vim
@@ -29,6 +29,11 @@ if !exists('g:ipy_perform_mappings')
let g:ipy_perform_mappings = 1
endif
+" Enable cell folding
+if !exists('g:ipy_cell_folding')
+ let g:ipy_cell_folding = 1
+endif
+
" Register IPython completefunc
" 'global' -- for all of vim (default).
" 'local' -- only for the current buffer.
@@ -44,6 +49,8 @@ endif
python << EOF
import vim
import sys
+
+
vim_ipython_path = vim.eval("expand('<sfile>:h')")
sys.path.append(vim_ipython_path)
from vim_ipython import *
@@ -95,6 +102,7 @@ au BufEnter vim-ipython :python if update_subchannel_msgs(): echo("vim-ipython s
noremap <Plug>(IPython-RunFile) :python run_this_file()<CR>
noremap <Plug>(IPython-RunLine) :python run_this_line()<CR>
noremap <Plug>(IPython-RunLines) :python run_these_lines()<CR>
+noremap <Plug>(IPython-RunCell) :python run_this_cell()<CR>
noremap <Plug>(IPython-OpenPyDoc) :python get_doc_buffer()<CR>
noremap <Plug>(IPython-UpdateShell) :python if update_subchannel_msgs(force=True): echo("vim-ipython shell updated",'Operator')<CR>
noremap <Plug>(IPython-ToggleReselect) :python toggle_reselect()<CR>
@@ -108,11 +116,13 @@ noremap <Plug>(IPython-PlotClearCurrent) :python run_command("plt.clf()")<CR>
noremap <Plug>(IPython-PlotCloseAll) :python run_command("plt.close('all')")<CR>
noremap <Plug>(IPython-RunLineAsTopLevel) :python dedent_run_this_line()<CR>
xnoremap <Plug>(IPython-RunLinesAsTopLevel) :python dedent_run_these_lines()<CR>
+noremap <Plug>(IPython-EnableFoldByCell) :call EnableFoldByCell()<CR>
if g:ipy_perform_mappings != 0
map <buffer> <silent> <F5> <Plug>(IPython-RunFile)
map <buffer> <silent> <S-F5> <Plug>(IPython-RunLine)
map <buffer> <silent> <F9> <Plug>(IPython-RunLines)
+ map <buffer> <silent> <C-M-F5> <Plug>(IPython-RunCell)
map <buffer> <silent> <LocalLeader>d <Plug>(IPython-OpenPyDoc)
map <buffer> <silent> <LocalLeader>s <Plug>(IPython-UpdateShell)
map <buffer> <silent> <S-F9> <Plug>(IPython-ToggleReselect)
@@ -124,6 +134,7 @@ if g:ipy_perform_mappings != 0
imap <buffer> <C-F5> <C-o><Plug>(IPython-RunFile)
imap <buffer> <S-F5> <C-o><Plug>(IPython-RunLines)
imap <buffer> <silent> <F5> <C-o><Plug>(IPython-RunFile)
+ imap <buffer> <silent> <C-M-F5> <C-o><Plug>(IPython-RunCell)
map <buffer> <C-F5> <Plug>(IPython-ToggleSendOnSave)
"" Example of how to quickly clear the current plot with a keystroke
"map <buffer> <silent> <F12> <Plug>(IPython-PlotClearCurrent)
@@ -131,12 +142,13 @@ if g:ipy_perform_mappings != 0
"map <buffer> <silent> <F11> <Plug>(IPython-PlotCloseAll)
"pi custom
- map <buffer> <silent> <C-Return> <Plug>(IPython-RunFile)
+ "map <buffer> <silent> <C-Return> <Plug>(IPython-RunFile)
map <buffer> <silent> <C-s> <Plug>(IPython-RunLine)
imap <buffer> <silent> <C-s> <C-o><Plug>(IPython-RunLine)
map <buffer> <silent> <M-s> <Plug>(IPython-RunLineAsTopLevel)
xmap <buffer> <silent> <C-S> <Plug>(IPython-RunLines)
xmap <buffer> <silent> <M-s> <Plug>(IPython-RunLinesAsTopLevel)
+ map <buffer> <silent> <C-Return> <Plug>(IPython-RunCell)
noremap <buffer> <silent> <M-c> I#<ESC>
xnoremap <buffer> <silent> <M-c> I#<ESC>
@@ -201,7 +213,30 @@ completions = [s.encode(vim_encoding) for s in matches]
for c in completions:
vim.command('call add(res,"'+c+'")')
endpython
- "call extend(res,completions)
+ "call extend(res,completions)
return res
endif
endfun
+
+
+" Custom folding function to fold cells
+function! FoldByCell(lnum)
+ let pattern = '\v^\s*(##|' . escape('# <codecell>', '<>') . ').*$'
+ if getline(a:lnum) =~? pattern
+ return '>1'
+ elseif getline(a:lnum+1) =~? pattern
+ return '<1'
+ else
+ return '='
+ endif
+endfunction
+
+function! EnableFoldByCell()
+ setlocal foldmethod=expr
+ setlocal foldexpr=FoldByCell(v:lnum)
+endfunction
+
+if g:ipy_cell_folding != 0
+ call EnableFoldByCell()
+endif
+
View
63 ftplugin/python/vim_ipython.py
@@ -609,6 +609,69 @@ def dedent_run_this_line():
def dedent_run_these_lines():
run_these_lines(True)
+def is_cell_separator(line):
+ cell_sep = ['##', '# <codecell>']
+ for sep in cell_sep:
+ if line.strip().startswith(sep):
+ return True
+ return False
+
+@with_subchannel
+def run_this_cell():
+ b = vim.current.buffer
+ (cur_line, cur_col) = vim.current.window.cursor
+ cur_line -= 1
+
+ # Search upwards for cell separator
+ upper_bound = cur_line
+ while upper_bound > 0 and not is_cell_separator(vim.current.buffer[upper_bound]):
+ upper_bound -= 1
+
+ # Skip past the first cell separator if it exists
+ if is_cell_separator(vim.current.buffer[upper_bound]):
+ upper_bound += 1
+
+ # Search downwards for cell separator
+ lower_bound = min(upper_bound+1, len(vim.current.buffer)-1)
+
+ while lower_bound < len(vim.current.buffer)-1 and not is_cell_separator(vim.current.buffer[lower_bound]):
+ lower_bound += 1
+
+ # Move before the last cell separator if it exists
+ if is_cell_separator(vim.current.buffer[lower_bound]):
+ lower_bound -= 1
+
+ # Make sure bounds are within buffer limits
+ upper_bound = max(0, min(upper_bound, len(vim.current.buffer)-1))
+ lower_bound = max(0, min(lower_bound, len(vim.current.buffer)-1))
+
+ # Make sure of proper ordering of bounds
+ lower_bound = max(upper_bound, lower_bound)
+
+ # Calculate minimum indentation level of entire cell
+ shiftwidth = vim.eval('&shiftwidth')
+ count = lambda x: int(vim.eval('indent(%d)/%s' % (x,shiftwidth)))
+
+ min_indent = count(upper_bound+1)
+ for i in range(upper_bound+1, lower_bound):
+ indent = count(i)
+ if i < min_indent:
+ min_indent = i
+
+ # Perform dedent
+ if min_indent > 0:
+ vim.command('%d,%d%s' % (upper_bound+1, lower_bound+1, '<'*min_indent))
+
+ # Execute cell
+ lines = "\n".join(vim.current.buffer[upper_bound:lower_bound+1])
+ msg_id = send(lines)
+ prompt = "lines %d-%d "% (upper_bound+1,lower_bound+1)
+ print_prompt(prompt, msg_id)
+
+ # Re-indent
+ if min_indent > 0:
+ vim.command("silent undo")
+
#def set_this_line():
# # not sure if there's a way to do this, since we have multiple clients
# send("get_ipython().shell.set_next_input(\'%s\')" % vim.current.line.replace("\'","\\\'"))
Something went wrong with that request. Please try again.