15
$\begingroup$

I want to be able to type a quick Mathematica expression, such as

  • 550/3. (e.g. common math),
  • Sum[i, {i, 0, n}]//TeXForm//ToString (e.g. writing LaTeX document), or
  • {55, 1, 10, 40, 9}//Total (e.g. do accounting calculations)

anywhere in any Vim buffer, visually select it, run a command, and see the result without leaving Vim. How could I do this?

$\endgroup$

2 Answers 2

14
$\begingroup$

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.

$\endgroup$
4
  • $\begingroup$ (+1) Slight problems when you have :set number. Then on screen stuff gets mixed up but after :wq and a fresh open the file is OK. $\endgroup$
    – user21
    Sep 17, 2016 at 19:19
  • $\begingroup$ @user21 yeah for me the screen loses a line and I have to hit j or something and it pops back $\endgroup$
    – Andrew
    Sep 17, 2016 at 19:39
  • 1
    $\begingroup$ @user21, @Andrew, you can fix this issue by putting redraw! just above endfunction in any of the Mathpipe functions above. This will tell vim to redraw the screen. $\endgroup$
    – Gert
    Jul 22, 2020 at 15:19
  • $\begingroup$ I also made a Python version here: github.com/amacfie/vim-run-python3 $\endgroup$
    – Andrew
    Sep 2, 2020 at 15:59
6
$\begingroup$

This package provides Vim-Mathematica integration:

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.