Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions plugin/ipy.vim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ command! -nargs=* IJulia :call IPyConnect("--kernel", "julia-0.4")

nnoremap <Plug>(IPy-Run) :call IPyRun(getline('.'))<cr>
vnoremap <Plug>(IPy-Run) :<c-u>call IPyRun(<SID>get_visual_selection())<cr>
noremap <Plug>(IPyRunCell) :call IPyRunCell()<cr>
inoremap <Plug>(IPy-Complete) <c-o>:<c-u>call IPyComplete()<cr>
noremap <Plug>(IPy-WordObjInfo) :call IPyObjInfo(<SID>get_current_word(), 0)<cr>
noremap <Plug>(IPy-Interrupt) :call IPyInterrupt()<cr>
Expand Down Expand Up @@ -45,6 +46,7 @@ let g:ipy_status = ""

if g:nvim_ipy_perform_mappings
map <silent> <F5> <Plug>(IPy-Run)
map <leader>c <Plug>(IPy-Run-Cell)
imap <silent> <C-F> <Plug>(IPy-Complete)
map <silent> <F8> <Plug>(IPy-Interrupt)
map <silent> <leader>? <Plug>(IPy-WordObjInfo)
Expand Down
72 changes: 72 additions & 0 deletions rplugin/python3/nvim_ipy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,78 @@ def ipy_run(self, args):
# TODO: if this is long, open separate window
self.append_outbuf(p['text'])

@neovim.function("IPyRunCell")
def ipy_run_cell(self, silent):
'''Runs all the code in between two cell separators

taken from https://github.com/wmvanvliet/vim-ipython'''
cur_buf = self.vim.current.buffer
(cur_line, cur_col) = self.vim.current.window.cursor
cur_line -= 1
def is_cell_separator(line):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably be implemented much simpler vimL-side, where we can use ordinary regex search(). Instead we should probably have a Python function IPyRunLines which takes a line range.

'''Determines whether a given line is a cell separator'''
cell_sep = ['##', '#%%%%', '# <codecell>']
for sep in cell_sep:
if line.strip().startswith(sep):
return True
return False

# Search upwards for cell separator
upper_bound = cur_line
while upper_bound > 0 and not is_cell_separator(cur_buf[upper_bound]):
upper_bound -= 1

# Skip past the first cell separator if it exists
if is_cell_separator(cur_buf[upper_bound]):
upper_bound += 1

# Search downwards for cell separator
lower_bound = min(upper_bound+1, len(cur_buf)-1)

while lower_bound < len(cur_buf)-1 and not is_cell_separator(cur_buf[lower_bound]):
lower_bound += 1

# Move before the last cell separator if it exists
if is_cell_separator(cur_buf[lower_bound]):
lower_bound -= 1

# Make sure bounds are within buffer limits
upper_bound = max(0, min(upper_bound, len(cur_buf)-1))
lower_bound = max(0, min(lower_bound, len(cur_buf)-1))

# Make sure of proper ordering of bounds
lower_bound = max(upper_bound, lower_bound)

# Calculate minimum indentation level of entire cell
shiftwidth = self.vim.eval('&shiftwidth')
count = lambda x: int(self.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 indent < min_indent:
min_indent = indent

# Perform dedent
if min_indent > 0:

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary, IPython kernel will strip off largest common indent of a cell automatically.

self.vim.command('%d,%d%s' % (upper_bound+1, lower_bound+1, '<'*min_indent))

# Execute cell
lines = "\n".join(cur_buf[upper_bound:lower_bound+1])
reply = self.waitfor(self.kc.execute(lines, silent=silent))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here instead just call self.ipy_run

content = reply['content']
payload = content.get('payload', ())
for p in payload:
if p.get("source") == "page":
# TODO: if this is long, open separate window
self.append_outbuf(p['text'])
# prompt = "lines %d-%d "% (upper_bound+1, lower_bound+1)
# print_prompt(prompt, msg_id)

# Re-indent
if min_indent > 0:
self.vim.command("silent undo")

@neovim.function("IPyComplete")
def ipy_complete(self,args):
line = self.vim.current.line
Expand Down