I previously wrote a plugin called vim-notebook for using Maxima in a Vim buffer. But since Maxima is written in Lisp and intended to be usable from Lisp code, I finally figured out a very nice way to achieve a similar result by using the existing Slimv.
In this post, I explain how to:
- install a Lisp implementation (Clozure CL);
- install the Quicklisp library manager;
- install the Swank server;
- fetch the latest version of Maxima and compile the interpreter only;
- integrate Maxima to Vim with Slimv.
Assuming we work with some Linux distribution, we have to choose a directory for the whole installation described here; I choose ~/Documents/Thomas/lisp
; of course, any other location will be fine:
cd ~/Documents/Thomas
mkdir lisp
cd lisp
Now we have to download Clozure CL and uncompress it:
wget ftp://ftp.clozure.com/pub/release/1.11/ccl-1.11-linuxx86.tar.gz
tar -xzf ccl-1.11-linuxx86.tar.gz
rm ccl-1.11-linuxx86.tar.gz
We can check the Lisp interpreter works (the 64-bit version is chosen here):
ccl/lx86cl64
A simple operation can be tried:
(+ 1 1)
(quit)
Being in the same directory:
curl -O https://beta.quicklisp.org/quicklisp.lisp
ccl/lx86cl64 --load quicklisp.lisp
Now the two following commands have to be typed from the Lisp interpreter:
(quicklisp-quickstart:install)
(quit)
The installer puts the quicklisp
directory in the home directory; I don't like that, thus I move it in the same directory:
mv ~/quicklisp .
rm quicklisp.lisp
The new location has to be fixed in the init file of Clozure CL:
vim ~/.ccl-init.lisp
The following piece of code has to be written in the file (with the right path):
#-quicklisp
(defun load-quicklisp ()
(let ((quicklisp-init
(merge-pathnames
"Documents/Thomas/lisp/quicklisp/setup.lisp" (user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init))))
With Quicklisp, it is very easy to install the Swank server; a first Lisp image containing the server can also be dumped:
ccl/lx86cl64
The three following commands must be typed:
(load-quicklisp)
(ql:quickload "swank")
(swank-loader:dump-image "ccl-with-swank")
Now a new file, called ccl-with-swank
should be in the lisp/
working directory; let's try it:
ccl/lx86cl64 -I ccl-with-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)"
which should display a line ;; Swank started at port: 4005.
; furthermore, the following command (typed from another terminal window) should show the process lx86cl64
listening on prt 4005:
netstat -tulpn
I usually add the following line in my ~/.bashrc
in order to be able to launch the Swank server more easely:
alias swank='~/Documents/Thomas/lisp/ccl/lx86cl64 -I ~/Documents/Thomas/lisp/ccl-with-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)"'
Now, the slimv
plugin for Vim can be installed with some Plugin manager. In my ~/.vimrc
, I add the following lines:
let g:slimv_repl_split=4
let g:paredit_mode=0
let g:slimv_disable_scheme=1
let g:slimv_swank_cmd='! xfce4-terminal -T "Swank" -x ~/Documents/Thomas/lisp/ccl/lx86cl64 -I ~/Documents/Thomas/lisp/ccl-with-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)" &'
A first test can be performed:
vim test.lisp
Then, we can type ,c
(which should start the Swank server and connect to it); then a simple operation can be tried; type (+ 1 1)
in the Vim buffer, switch to normal mode, keep the cursor on this expression and type ,e
; the result should be displayed in the other buffer. Close Vim; and kill the Swank server (typing (quit)
in the other window is the best way for doing it).
We are still in the directory lisp/
; we have to install git
if it is not installed yet:
sudo apt-get install git
Then:
git clone git://git.code.sf.net/p/maxima/code maxima-code
cd maxima-code/
../ccl/lx86cl64
Type the three following commands:
(load "configure.lisp")
(configure :interactive nil)
(quit)
Then:
cd src
../../ccl/lx86cl64
Type the three following commands:
(load "maxima-build.lisp")
(maxima-compile)
(quit)
Finally we can dump another image containing both Maxima and the Swank server:
../../ccl/lx86cl64
with the following commands:
(load "maxima-build.lisp")
(maxima-load)
(load-quicklisp)
(ql:quickload "swank")
(save-application "../../ccl-with-maxima-and-swank")
The new image should be in the lisp/
directory:
cd ../..
ls
A low-level test with Vim can already be performed; in the same terminal, type:
ccl/lx86cl64 -I ccl-with-maxima-and-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)"
and in another window, type:
vim test.lisp
Then, type ,c
for connecting to this already running server; in the Vim buffer, type: #$1+1;$
and then (in normal mode, with the cursor being on this expression): "zyy
for yanking the line into the z
register; then "z,r
for sending the content of the z
register to the running Swank server; the result should appear in the second Vim buffer. After that, close Vim and kill the Swank server.
A second alias may be added in the ~/.bashrc
file for sending this special Swank server:
alias maxima-swank='~/Documents/Thomas/lisp/ccl/lx86cl64 -I ~/Documents/Thomas/lisp/ccl-with-maxima-and-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)"'
First, we have to find the right command for opening a new terminal emulator with this second Swank server running in it; I use:
xfce4-terminal -x ~/Documents/Thomas/lisp/ccl/lx86cl64 -I ~/Documents/Thomas/lisp/ccl-with-maxima-and-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)" &
or (with the right title for the window):
xfce4-terminal -T "Maxima/Swank" -x ~/Documents/Thomas/lisp/ccl/lx86cl64 -I ~/Documents/Thomas/lisp/ccl-with-maxima-and-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)" &
Now, I want to run Maxima from various documents type (even txt
or markdown md
files); thus, I add the following command in my ~/.vimrc
:
function! MaximaSwank()
let g:slimv_swank_cmd='!xfce4-terminal -T "Maxima/Swank" -x ~/Documents/Thomas/lisp/ccl/lx86cl64 -I ~/Documents/Thomas/lisp/ccl-with-maxima-and-swank -e "(swank:create-server :port 4005 :style :spawn :dont-close t)" &'
" Temporary change the filetype to 'lisp' in order to start slimv
let l:b=&filetype
set filetype=lisp
execute "normal ,c"
execute "set filetype=" . l:b
let @z="(cl-user::run)"
execute "normal \"z,r"
endfunc
map ,M :call MaximaSwank()<cr>
which will map the ,M
shortcut to a command starting the special Maxima/Swank Lisp image from any document.
The final step is write some macros for Vim allowing to evaluate Maxima expressions.
As a first attempt, the following macro (mapped to my µ
key) sends the selected block (in visual mode) to the Maxima interpreter:
map µ "zy"z,r
Another attempt defines the following function:
function! MaximaEvaluate() range
execute a:firstline . "," . a:lastline . "yank z"
execute "normal \"z,r"
endfunc
The functionMaximaEvaluate
takes a range of lines for evaluating them:
:1call MaximaEvaluate()
:3,7call MaximaEvaluate()
Of course, more convenient macros can embed MaximaEvaluate
.