My first plugin
As I was working on various OCaml projects that were growing bigger and bigger, the various open
directives started accumulating in some files. And I missed the feature I had in visual studio that automatically sorts the names of the using
directives. This allowed a much quicker visual inspection of the various modules I needed for a piece of code to run.
As I could not find a solution to do it easily, I had a look at the different ways to implement vim plugins.
Python : import vim
It turned out that the plugins can be directly written using Python ! in a vim script (mine will be called librarySorter.vim
), you can simply write python code, import vim to read the buffer.
The buffer seems to be an array like structure on which you can get/set
the i-th element of the buffer (i.e. the i-th line of your file).
Unfortunately, the documentation to use the package vim is quite limited. As this Stack Overflow question stresses it.
A nice ressource though, is this presentation.
Coding the plugin
Making sure it is compiled with python3
if !has('python3')
echo "Error: Required vim compiled with +python3"
finish
endif
Declaring a function
function! LibrarySorter()
// your code
endfunction
Calling Python code
The part written in Python has to be between these two EOF
declarations.
python3 << EOF
# python code
EOF
In the case of my plugin, this looks like this:
python3 << EOF
import vim
#Reads the whole file, as a list
cb = list(vim.current.buffer)
#Filter the open directives
openLines = list(filter(lambda x: x.startswith("open "), cb))
#If all the open directives are not at the top of the file, stop immediatly
if not vim.current.buffer[len(openLines) - 1].startswith("open "):
raise Exception("Error, some open directives are not at the head of your file")
openLines = sorted(openLines)
#And rearrange the lines in the buffer
for i in range(len(openLines)):
vim.current.buffer[i] = openLines[i]
EOF
And now, in vim
, you can simply type: :call LibrarySorter()
anywhere in your OCaml source and look at the head of your file :)
The code
if !has('python3')
echo "Error: Required vim compiled with +python3"
finish
endif
function! LibrarySorter()
python3 << EOF
import vim
cb = list(vim.current.buffer)
openLines = list(filter(lambda x: x.startswith("open "), cb))
if not vim.current.buffer[len(openLines) - 1].startswith("open "):
raise Exception("Error, some open directives are not at the head of your file")
openLines = sorted(openLines)
for i in range(len(openLines)):
vim.current.buffer[i] = openLines[i]
EOF
endfunction
What’s next ?
I actually have the same issue when importing files in Python, TypeScript… Might be nice to generalize this to various languages :)
Learning more
Ocaml
Real World OCaml: Functional programming for the masses by Yaron Minsky, Anil Madhavapeddy and Jason Hickey is a good introduction to OCaml.
Purely Functional Data Structures by Chris Okasaki, which presents another way to look at data structures, from a functional point of view. As a prerequisite, a knowledge of common structures such as Heaps, Linked Lists is needed.
Vim
Practical Vim: Edit Text at the Speed of Thought
Modern Vim: Craft Your Development Environment with Vim 8 and Neovim