We want to have a functional lean to our codebase... and ReasonML / OCaml are the perfect fit for that. OCaml is highly optimized - even down to its garbage collector implementation - for building functional applications in a performant way.
- Action: A payload of information to describe a state change. Just like an action in redux.
- State and Model: used interchangeably to describe the application state.
- Reducer: A function of (
action) that returns a new
- Updater: A function of (
action) that returns a tuple of (
effects). Similar to a reducer, but also handles side-effects. Inspired by the Elm Architecture
- Store Connector: Loosely akin to a middleware in Redux.
- Store: A State, Updater, and Store Connectors. Similar to a store in Redux.
One additional concept is the idea of our UI as a pure function of
state - this will be familiar for anyone coming from React.
The state management (actions, state, reducers, updaters, store) are facilitated by a reason-native library called `isolinear.
Source Code Overview
src- editor source code
src/editor- the source code for Onivim 2 (primarily Reason)
src/editor/Core- Core types used across the application
src/editor/Extensions- Modules relating to the extension host or syntax highlighting
src/editor/Model- description of the state of the application. The most important modules here are:
src/editor/Store- connects the state of the application with external effects.
- StoreThread.re is the entry point - creating a store and initializing all the store connectors.
src/editor/UI- the user interface for the application.
src/editor/bin_editor- The 'main' entry point of
Vim is at the heart of Onivim 2. There are a few moving parts:
- libvim - A fork of Vim that is platform and terminal agnostic. It is the core buffer editing engine exposed via a simple API.
- reason-libvim - Reason bindings for
libvim. Glance at the rei to get a feel for the API.
Onivim 2 integrates with
reason-libvim via a store connector:
Revery was built to support Onivim 2. It is a new UI framework that is intended to build fast, native, cross-platform applications with the ergonomics of React & Redux.
It manages the lifecycle of the application - it provides the
UI.start methods we use to kick-off the application:
For a cross-platform project built & maintained by a small team - test coverage is so important!
We have two classes of tests - unit tests and integration tests.
Unit tests live in the
test folder and be can be run via
esy '@test' run, but remember to run
esy '@test' install initially to install the test dependencies.
We organize our tests 1-to-1 with the
src code - for example, test cases for
src/editor/Core/LineNumber.re would live in
Unit tests verify a particular piece of code in isolation, and should have minimal dependencies.
Unit tests help us verify that individual modules work as expected - it's also important for an application like Onivim 2 to verify that things work when all these pieces come together.
We use integration tests to help us verify this - integration tests live in the
integration tests are each stand-alone executables that initialize an entire Store - just like the Onivim 2 app does! The only difference is that integration tests are headless (no UI).
integration tests can be run in one of two ways:
- They all can be run via
esy '@integrationtest' run
- Individual tests can be run via
esy '@integrationtest' x Test-Name.exe
If you're interested in learning about ReasonML, we recommend the following:
For learning more about the architectural ideas, we recommend: