• Stars
    star
    682
  • Rank 64,185 (Top 2 %)
  • Language
    Vim Script
  • License
    MIT License
  • Created about 5 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

libvim: The core Vim editing engine as a minimal C library

Build Status

What is libvim?

libvim is a fork of Vim, with the goal of providing a minimal 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 out neovim, or a GUI Vim, check out Onivim 2.

Why?

libvim is primarily intended for Onivim 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 is NOT 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 - leaving libvim to be focused on the job of fast buffer manipulation.

libvim builds cross-platform (since Onivim 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.

API

For an example of the API usage, check out the apitests like normal_mode_motion. The full API is available here: libvim.h

The heart of the API is vimInput 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 like vimSetBufferUpdateCallback.

This library is in active development and we currently make no guarantees about backwards compatibility. Use the API at your own risk.

Compiling

Install esy

esy is like npm for native code. If you don't have it already, install it by running:

npm install -g [email protected]

Get sources

  • git clone https://github.com/onivim/libvim
  • cd src

Installing dependencies

  • esy install
  • esy '@test' install

Building

  • esy build

Running tests

  • esy '@test' build

Development

The esy 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.

Building & running tests incrementally

  • cd src
  • make apitest/autoindent.test.exe
  • cd apitest
  • ./autoindent.test.exe

Testing changes against Onivim 2

You can test a locally-built libvim against a locally-built Onivim 2 by adding a resolution in the Onivim 2 package.json, like:

"resolutions": {
	...
	"libvim": "link:../libvim/src"
}

Just make sure it points to the libvim/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.

FAQ

Why is libvim based on Vim and not Neovim?

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 implemented libvim based on libnvim. In fact, the first time I tried to build this 'minimal abstraction' - I tried to base it off Neovim's libnvim. 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 of CMake 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 via esy cross-platform, with nvim - I'd be happy to use that :)

Supporting

If libvim is interesting to you, and you'd like to support development, consider the following:

Contributing

If you would like to help making libvim better, see the CONTRIBUTING.md file.

Some places for contribution:

License

libvim code is licensed under the MIT License.

It also depends on third-party code, notably Vim, but also others - see ThirdPartyLicenses.txt for license details.

More Repositories

1

oni

Oni: Modern Modal Editing - powered by Neovim
TypeScript
11,365
star
2

oni2

Native, lightweight modal code editor
Reason
7,759
star
3

reason-libvim

Reason API for libvim
Reason
21
star
4

reason-tree-sitter

ReasonML bindings for tree-sitter
C
21
star
5

reason-textmate

ReasonML native library for working with TextMate grammars
JavaScript
16
star
6

vscode-exthost

The backend of VSCode (the extension host), as a stand-alone NPM package
TypeScript
15
star
7

onivim.io

Website for onivim
TypeScript
14
star
8

markdown-language-server

Language server for Markdown
TypeScript
12
star
9

reason-vscode-exthost

Native ReasonML interface for VSCode extensions
Reason
11
star
10

css-language-server

Language server for CSS, LESS, and SASS.
TypeScript
8
star
11

reason-native-crash-utils

A set of reason-native utilities for reporting, troubleshooting, and testing native code
OCaml
7
star
12

vscode-snippet-parser

VSCode's snippet parsing logic, extracted in a standalone module
TypeScript
7
star
13

oni-api

Oni's extensibility model API
TypeScript
7
star
14

onivim.github.io

Onivim 2 Documentation
HTML
5
star
15

onivim-input

Input management and key bindings for native ReasonML
Reason
5
star
16

reason-jsonrpc

A jsonrpc implementation in Reason
Reason
5
star
17

editor-core-types

Core Editor Types for Onivim 2 and related projects
Reason
4
star
18

oni-neovim-binaries

NPM module for acquiring neovim binaries used by Oni
JavaScript
3
star
19

reason-oniguruma

ReasonML bindings for the Onigurama RegEx engine
Reason
3
star
20

oni-docs

Documentation for Oni
HTML
3
star
21

oni-plugin-starter-kit

πŸ”¨ Template for creating Oni plugins
TypeScript
2
star
22

oni-core-window-manager

Window split / dock management for Oni
TypeScript
2
star
23

esy-oniguruma

Esy-enabled build for the onigurama regex library
C
2
star
24

oni-bot

Bot used in Oni repository
JavaScript
2
star
25

oni-extensions-discovery

AP Client for discovering Oni extensions
2
star
26

oni-test

πŸ” Easily test plugins against Oni's API surface
TypeScript
1
star
27

oni-core-redux

Thin wrapper around Redux createStore, for oni
TypeScript
1
star
28

oni-types

Shared types and interfaces used across Oni
TypeScript
1
star
29

oni-core-logging

Simple logging utilities used across Oni
TypeScript
1
star
30

bot-test

bot-test
1
star
31

oni-release-downloader

Helper module to download release artifacts from github
JavaScript
1
star
32

oni-version-manager

CLI utility to help with managing Oni versions, for automation
TypeScript
1
star