├── .gitignore ├── README.md └── ftplugin └── python └── pyutils.vim /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | 3 | # Packages 4 | *.egg 5 | *.egg-info 6 | dist 7 | build 8 | eggs 9 | parts 10 | bin 11 | var 12 | sdist 13 | develop-eggs 14 | .installed.cfg 15 | 16 | # Installer logs 17 | pip-log.txt 18 | 19 | # Unit test / coverage reports 20 | .coverage 21 | .tox 22 | 23 | #Translations 24 | *.mo 25 | 26 | #Mr Developer 27 | .mr.developer.cfg 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Vimux-pyutils 2 | ============= 3 | 4 | **See https://github.com/julienr/vim-cellmode for new version of this plugin.** 5 | 6 | This is a vim bundle containing some additional, python-specific, functions 7 | on top of vimux : 8 | https://github.com/benmills/vimux/ 9 | 10 | This plugin allow to select a block of python code in vim and send it to the 11 | vimux tmux split. The assumption is that ipython (or python) is running in said 12 | tmux split and this allow to execute a file chunk-by-chunk. 13 | 14 | This is somewhat similar to the code block execution that can be found in 15 | scientific software (for example Matlab). 16 | 17 | Keys mapping 18 | ----------- 19 | By default, the following mappings are enabled : 20 | 21 | * *C-c* will paste and execute the currently selected block in ipython 22 | * *C-b* will execute the current cell in ipython 23 | A cell is similar to MATLAB's cell and is defined as the line ranging from 24 | the previous ## to the next ## 25 | 26 | Options 27 | ------- 28 | If you set *vimux_pyutils_use_tslime* to 1 in your vimrc, this script will use 29 | tslime instead of vimux. This has the advantage that the script will work 30 | from outside a tmux session (in GVim for example). 31 | 32 | Note that tslime has to be configured to target the correct session/pane : 33 | 34 | let g:tmux_sessionname='0' 35 | let g:tmux_windowname='./ipython.sh' 36 | let g:tmux_panenumber='0' 37 | 38 | let g:vimux_pyutils_use_tslime=1 39 | 40 | Difference with vim-ipython 41 | --------------------------- 42 | Note that if you want more advanced integration with IPython (using the new 43 | multi-client architecture), there is the vim-ipython project : 44 | https://github.com/ivanov/vim-ipython/ 45 | 46 | The main difference with vim-ipython is that this plugin simply emulate a paste 47 | as you would do it manually from vim to ipython. This allow to see the result 48 | of the execution directly in the ipython split whereas vim-ipython uses a 49 | separate vim buffer to show the results. 50 | 51 | -------------------------------------------------------------------------------- /ftplugin/python/pyutils.vim: -------------------------------------------------------------------------------- 1 | if !has('python') 2 | finish 3 | endif 4 | 5 | if !exists("g:vimux_pyutils_use_tslime") 6 | let g:vimux_pyutils_use_tslime=0 7 | endif 8 | 9 | python << endpython 10 | import re 11 | 12 | # http://stackoverflow.com/questions/2695443/can-you-access-registers-from-python-functions-in-vim 13 | def set_register(reg, value): 14 | vim.command("let @%s='%s'" % (reg, value.replace("'","''"))) 15 | 16 | def send_to_tmux(lines): 17 | # Global variable can be used to switch between vimux and tslime 18 | if vim.eval("g:vimux_pyutils_use_tslime") == "1": 19 | vim.command(':call Send_to_Tmux("\%cpaste\n")') 20 | # Send by chunk of 20 lines 21 | lines_step = 20 22 | for i in xrange(0, len(lines), lines_step): 23 | lines_chunk = lines[i:i+lines_step] 24 | l = "\n".join(lines_chunk) 25 | l = l.replace('\\', '\\\\') 26 | l = l.replace('"', '\\"') 27 | 28 | vim.command("echo 'sending to tslime length : %i'"%len(l)) 29 | vim.command(':call Send_to_Tmux("%s\\n")' % l) 30 | # TODO: This is needed on some systems (OSX) to avoid getting scrambled 31 | # output. But this is a bit of an ugly fix 32 | 33 | # Sleep long enough to let the cpaste finish 34 | vim.command(':sleep 200m') 35 | 36 | vim.command(':call Send_to_Tmux("\n--\n")') 37 | else: 38 | l = "\n".join(lines) 39 | set_register('+', l) 40 | vim.command(':call VimuxRunCommand("%paste\n", 0)') 41 | 42 | 43 | def run_tmux_python_chunk(): 44 | """ 45 | Will copy/paste the currently selected block into the tmux split. 46 | The code is unindented so the first selected line has 0 indentation 47 | So you can select a statement from inside a function and it will run 48 | without python complaining about indentation. 49 | """ 50 | r = vim.current.range 51 | #vim.command("echo 'Range : %i %i'" % (r.start, r.end)) 52 | # Count indentation on first selected line 53 | firstline = vim.current.buffer[r.start] 54 | nindent = 0 55 | for i in xrange(0, len(firstline)): 56 | if firstline[i] == ' ': 57 | nindent += 1 58 | else: 59 | break 60 | # vim.command("echo '%i'" % nindent) 61 | 62 | # Shift the whole text by nindent spaces (so the first line has 0 indent) 63 | lines = vim.current.buffer[r.start:r.end+1] 64 | if nindent > 0: 65 | pat = '\s'*nindent 66 | lines = [re.sub('^%s'%pat, '', l) for l in lines] 67 | 68 | # Add empty newline at the end 69 | lines.append('\n\n') 70 | 71 | send_to_tmux(lines) 72 | # Now, there are multiple solutions to copy that to tmux 73 | 74 | # 1. With cpaste 75 | #vim.command(':call VimuxRunCommand("%cpaste\n", 0)') 76 | #vim.command(':call VimuxRunCommand("%s", 0)' % lines) 77 | #vim.command(':call VimuxRunCommand("\n--\n", 0)') 78 | 79 | # 2. With cpaste (better, only one command, but rely on system clipboard) 80 | 81 | # Move cursor to the end of the selection 82 | vim.current.window.cursor=(r.end+1, 0) 83 | 84 | def run_tmux_python_cell(restore_cursor=False): 85 | """ 86 | This is to emulate MATLAB's cell mode 87 | Cells are delimited by ##. Note that there should be a ## at the end of the 88 | file 89 | The :?##?;/##/ part creates a range with the following 90 | ?##? search backwards for ## 91 | Then ';' starts the range from the result of the previous search (##) 92 | /##/ End the range at the next ## 93 | See the doce on 'ex ranges' here : 94 | http://tnerual.eriogerg.free.fr/vimqrc.html 95 | Then, we simply call run_tmux_python_chunk that will run the range 96 | of the current buffer 97 | """ 98 | if restore_cursor: 99 | # Save cursor position 100 | (row, col) = vim.current.window.cursor 101 | 102 | # Run chunk on cell range 103 | vim.command(':?##?;/##/ :python run_tmux_python_chunk()') 104 | 105 | if restore_cursor: 106 | # Restore cursor position 107 | vim.current.window.cursor = (row, col) 108 | 109 | endpython 110 | 111 | vmap :python run_tmux_python_chunk() 112 | noremap :python run_tmux_python_cell(False) 113 | noremap :python run_tmux_python_cell(True) 114 | 115 | 116 | --------------------------------------------------------------------------------