- Notifications
You must be signed in to change notification settings - Fork34
libvim: The core Vim editing engine as a minimal C library
License
onivim/libvim
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
libvim
is a fork ofVim, with the goal of providing aminimal C-based API, modelling Vim modal editing. It does not include any user interface at all (not even a terminal UI), and is primarily responsible for acting as a fast buffer manipulation engine, faithful to Vim keystrokes. It's still a work-in-progress and there is lots of work left to stabilize.
If you're looking for a terminal Vim, check outneovim, or a GUI Vim, check outOnivim 2.
libvim
is primarily intended forOnivim 2. After implementing several iterations of 'UI Vims' between v1, v2, and other projects, the abstraction I wished to have was a sort of a pure functional Vim, completely decoupled from terminal UI - where 'vim' is a function of(editor state, input) => (new editor state)
. As Onivim 2 completely handles the rendering layer, this Vim-modelled-as-a-pure-function could focus on just buffer manipulation.
To that end,libvim
exposes a simple C API for working with Vim, and supports listening to buffer changes, messages, etc.
It is responsible for:
- Managing and manipulating buffers
- Buffer manipulation in response to input
- Parsing and sourcing VimL
- Handling key remaps
It isNOT responsible for:
- Any sort of UI rendering (terminal, etc)
- Mouse support
- Syntax Highlighting
- Spell Checking
- Terminal Support
- Completion
- Input methods (IME)
All of these are intended to be handled by the consumer of the library - leavinglibvim
to be focused on the job of fast buffer manipulation.
libvim
builds cross-platform (sinceOnivim 2 requires it!), as well as for WebAssembly - we'd like to port our v1 tutorials to a browser-based experience.
There are other interesting applications of such an 'abstracted Vim':
- WebAssembly builds could be useful for implementing Vim modes in browsers / websites
- Native builds could be useful for applications that want Vim-native bindings - it'd be a nice foundation for implementing
readline
, for example.
For an example of the API usage, check out theapitests likenormal_mode_motion. The full API is available here:libvim.h
The heart of the API isvimInput
which takes a single key, and is synchronously processed by the state machine. 'Side-effects' like buffer updates, messages, etc can be subscribed to via callbacks likevimSetBufferUpdateCallback
.
This library is in active development and we currently make no guarantees about backwards compatibility. Use the API at your own risk.
Installesy
esy
is likenpm
for native code. If you don't have it already, install it by running:
npm install -g esy@0.5.7
git clone https://github.com/onivim/libvim
cd src
esy install
esy '@test' install
esy build
esy '@test' build
Theesy
workflow works great for one-off builds, but will rebuild the world every time, so during development it's better to have an incremental workflow.
cd src
make apitest/autoindent.test.exe
cd apitest
./autoindent.test.exe
You can test a locally-builtlibvim
against a locally-built Onivim 2 by adding a resolution in the Onivim 2package.json
, like:
"resolutions": {..."libvim":"link:../libvim/src"}
Just make sure it points to thelibvim/src
folder.
NOTE: We've seen issues with this workflow where the binaries can be out-of-date in Onivim 2, so we recommend running
rm -rf _esy && esy i
after each change to rebuild the dependency.
I'm a huge fan of the work the Neovim team is doing (and the team has been incredibly supportive of the Onivim project). Ideally, we would've stuck with Neovim or implementedlibvim
based onlibnvim
. In fact, the first time I tried to build this 'minimal abstraction' - I tried to base it off Neovim'slibnvim
. I timeboxed the investigation to 2 days, and ran into some serious hurdles - our build environment is a bit challenging on Windows (it's based on Cygwin + MingW cross-compiler toolchain) - I encountered several issues getting Neovim + deps to build in that environment. Based off that spike, I estimated it would take ~3-4 weeks to get it working in that toolchain.
Note that this is not a Neovim issue - the dependency usage and leveraging ofCMake
are good decisions - it's a consequence of our OCaml build system. The Cygwin + MingW cross-compiler toolchain isn't well handled by all dependencies (being a weird hybrid of Win32 and Unix, it's often the case where #ifdefs are wrong, incorrect dependencies are pulled in, and it can be a huge time sink working through these issues).
Vim, in contrast, was able to compile in that environment easily (NOTE: If anyone is interested in building a cross-platform,esy
-enabled Neovim package - we can revisit this!). I'm also interested in WebAssembly builds, for porting the Onivim v1 tutorials to the web, in which this C-abstracted library compiled to WebAssembly would be a perfect fit.
Beyond the build issues, both Neovim and Vim would need refactoring to provide that synchronous, functional API:
- Neovim uses an event loop at its core, which would need to be short-circuited or removed to provide that API
- Vim uses blocking input, which would need to be inverted to support the functional API
The motivation of all this work was to remove the RPC layer from Onivim v2 to reduce complexity and failure modes - at the end, this was purely a constraint-based technical decision. If we can get a similar API, buildable viaesy
cross-platform, withnvim
- I'd be happy to use that :)
Iflibvim
is interesting to you, and you'd like to support development, consider the following:
If you would like to help makinglibvim
better, see theCONTRIBUTING.md file.
Some places for contribution:
- Help usadd test cases
- Help us removecode orfeatures that aren't required for
libvim
- Help us portpatches from Vim
libvim
code is licensed under theMIT License.
It also depends on third-party code, notably Vim, but also others - seeThirdPartyLicenses.txt for license details.