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
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 :)
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 :)
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.
Practical Vim: Edit Text at the Speed of Thought
Modern Vim: Craft Your Development Environment with Vim 8 and Neovim