2

In MATLAB, we can write to the editor the following

%% -- a example cell --

plot(rand(3));

%% -- another cell
A=rand(2^10);
t=linspace(-pi,pi,2^10);
compass(fft(A*sin(t))

and we can just hit Ctrl+Enter to run the cell being clicked by the mouse pointer.

Now I know in Vim, I can do

:'<,>'w !matlab to run a visually selected block of code.

But how do I implement the MATLAB-like cell mode in Vim/gVim?

For example some python code

import os
import subprocess
import random

## 1st cell
ps =["python", "-h"]
out = subprocess.Popen(ps).communicate()[0]
print out

## 2nd cell

# import random -sould not be needed if we concatenate the import section and the cell
print random.randint(1,100)

Can anyone offer some ideas?

Josh
  • 11,979
  • 17
  • 60
  • 96
Jerry Gao
  • 1,389
  • 3
  • 13
  • 17
  • [slime-vim](http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/) worths taking a look at. It uses `screen` sessions to "send" parts of your code to an open interpreter. – Eelvex Feb 24 '11 at 02:08
  • that's a good suggestion for display code output outside vim, thanks – Jerry Gao Feb 24 '11 at 18:13

2 Answers2

2

Here's my option for matlab, but it can be easily adapted for python. It switches from vim to a Matlab window and then you paste with the mouse or the keyboard shortcut. I described it in details there: Vim and matlab GUI - Emulate matlab Run (<F5>) with Vim

The following, ensures you are in the right directory before running the cell, and also goes back to Vim after evaluating the cell (if you have correctly configured the external editor in matlab. I use:gvim --servername MAT --remote-tab-silent).

function! MatRunCellAdvanced()
   execute "!echo \"cd(\'".expand("%:p:h")."\')\">/tmp/buff"  
   :?%%?;/%%/w>> /tmp/buff
   execute "!echo \"edit ".expand("%:f")."\">>/tmp/buff"
   !cat /tmp/buff|xclip -selection c
   !cat /tmp/buff|xclip
   !wmctrl -a MATLAB 
endfunction
map ,n :call MatRunCellAdvanced()  <cr><cr>
Community
  • 1
  • 1
e-malito
  • 878
  • 1
  • 7
  • 14
  • thanks for your answer, this is interesting, but why don't you just do something like ?%%?;/%%/w !matlab ? – Jerry Gao Apr 29 '12 at 20:57
  • I use this to avoid opening a new matlab instance and to benefit from matlab's GUI. If there is an error in my code, matlab will display a link in the command window, which by clicking on it will open in gvim the correct file at the correct line. This is not possible without the GUI. I consider this option worth a click! – e-malito May 15 '12 at 15:19
2

Not sure exactly what you're asking, but if what you want is to process a cell block upon double-clicking in the block with a mouse, then you can map mouse-double-click (the <2-LeftMouse> mapping) to call a function:

nnoremap <buffer> <2-LeftMouse> :call ProcessMouseDoubleClick()<CR>

ProcessMouseDoubleClick() would be a function that (1) visually selects the "cell" area and (2) issues '<,>'w !matlab to have matlab run the selected code.

When calling ProcessMouseDoubleClick the Vim cursor will be located at whatever point you clicked in the document. Other than that, there's nothing specific to the mouse. So you could also map any key to same function, e.g., a mnemonic command for 'evaluate cell':

map <buffer> <Leader>ec :call ProcessMouseDoubleClick()<CR>

So, there's not really any reason to have function name referencing mouse at all, you might want to call it something like EvaluateMatlabCell().

Herbert Sitz
  • 21,858
  • 9
  • 50
  • 54
  • thanks for the answer, but visually selects the "cell" area can only select a continuous block. if I want to select both import section and the 2nd cell, how do I do it? – Jerry Gao Feb 23 '11 at 16:29
  • @jerry: Ahhh, if that's the question you just have to build the logic into the function. If you make sure that that the import statements are in single block within buffer, you could (1) find import statements and yank to register, (2) move back to cell, paste import block at top of cell, (3) select cell and process in matlab, and (4) delete import statements that you copied into cell. There are probably simpler ways to do it, but I'm not quite sure what your main sticking point is. – Herbert Sitz Feb 23 '11 at 16:42
  • hi, herbert, I just got something to work now, :?##?;/##/w !python this command will search up to the ## an then down to another ##, then pass it to the w !python, it works :) – Jerry Gao Feb 23 '11 at 17:08
  • jerry -- yes, that's good way of selecting what you call the cell, but it won't get the import commands if you need those, too. You don't need to do the imports every time, though, do you, issuing them just once at start of edit session works if you're using same Python session throughout. Now you can just map your compound command to a key (mapping to works in gvim but not in many terminals) and you're good to go. – Herbert Sitz Feb 24 '11 at 06:06
  • herbert-- do you know how to concatenate 2 ranges? for example line 1,10 and 30,40, I think the w !python is from buffer to python, but if we can not use multiple ranges, then we need concatenate 2 ranges to a new buffer then write that buffer to python. – Jerry Gao Feb 24 '11 at 10:57
  • jerry -- Why not just (1) paste the import statements at beginning of desired cell, (2) select cell, (3) execute python, then (4) delete import statements you pasted? That would work. BUT, you should also check out compiling python support into your Vim. In that case there is no need to include import statements every time, since the Python session persists as long as Vim instance is open. Read `:h python`. – Herbert Sitz Feb 24 '11 at 15:57
  • :h python has a lot of good stuff, it maybe able to get a python terminal within vim as a separate window. :) – Jerry Gao Feb 24 '11 at 18:17
  • If you're using Python I have a barebones but useful little plugin that makes Vim into a very flexible scratchpad for Python. It would be trivial to add a feature to automatically select blocks of code, I think right now it does require visual selection. . . https://github.com/hsitz/PyScratch – Herbert Sitz Feb 25 '11 at 18:04