Evaluate expressions within Vim
I put together my own solution using VimScript and the Mathematica script interface. This works for Linux; for other OSs modify as necessary.
First we create a file, say ~/bin/mathpipe.m
which takes a Mathematica expression from standard input and prints the result to standard output.
As far as I know, there's no built-in way to do this, please correct me if I'm wrong.
I'm using Mathematica 10;
consult the documentation to check the right hashbang line for you (it may have changed from MathematicaScript
to wolfram
).
#!/usr/local/bin/MathematicaScript -script
(* read standard input, one line at a time, evaluating each one.
print the InputForm of the evaluated last line. *)
val = Input[];
ret = val;
While[val = Input[]; val =!= EndOfFile, ret = val];
Print[ret];
Do chmod +x ~/bin/mathpipe.m
.
We can run
$ echo "2+2" | ~/bin/mathpipe.m
4
Now, in our .vimrc
we add one helper function:
function! s:get_visual_selection()
" from http://stackoverflow.com/a/6271254/371334
let [lnum1, col1] = getpos("'<")[1:2]
let [lnum2, col2] = getpos("'>")[1:2]
let lines = getline(lnum1, lnum2)
let lines[-1] = lines[-1][: col2 - (&selection == 'inclusive' ? 1 : 2)]
let lines[0] = lines[0][col1 - 1:]
"return join(lines, "\n")
return lines
endfunction
This gets the current (or most recent) visual selection and returns it as a list of string values.
With this we can define a command for echoing the evaluation of a selected expression (also goes in .vimrc
):
function! Mathpipe1()
let mathpipe = s:get_visual_selection()
call writefile(mathpipe, '/tmp/mathpipein')
silent !cat /tmp/mathpipein | ~/bin/mathpipe.m
endfunction
Add this line to map the function to the <leader>m
key sequence:
xnoremap <leader>m :<c-h><c-h><c-h><c-h><c-h>call Mathpipe1()<CR>
So now if we visually select some text in Vim that is a Mathematica expression and hit <leader>m
(usually \m
), the result is shown in the output area on the ex command line.
Multi-line selections work too.
If we want the result printed in the current Vim buffer right below what we selected, we can do that too:
function! Mathpipe2()
let mathpipe = s:get_visual_selection()
call writefile(mathpipe, '/tmp/mathpipein')
silent !cat /tmp/mathpipein | ~/bin/mathpipe.m > /tmp/mathpipeout
normal `>
r /tmp/mathpipeout
endfunction
xnoremap <leader>M :<c-h><c-h><c-h><c-h><c-h>call Mathpipe2()<CR>
With this, we can select text, hit <leader>M
and the evaluation is printed on the next line.
This package provides Vim-Mathematica integration:
- http://library.wolfram.com/infocenter/MathSource/2584/
Quoting from the package description:
This is a Mathematica front end built into Vim, which is a high-end programmer's editor, highly compatible to vi but with lots of additional features. The front end is just an add-on for the editor, which can still be used as a standard editor for all kinds of ASCII files.
The front end is a "text-mode' application which will run in any terminal (including, of course, xterms). The functionality is similar to the standard notebook interface, without graphics (there is, however, built-in support for external viewers like ghostview), but with greatly enhanced editing capabilities.
The package is from 1999. That's the era of Vim 5 and Mathematica 4. It very likely doesn't work out of the box today, but it should be a good starting point for implementing something similar with Vim 8 and Mathematica 11.