Skip to content
This repository has been archived by the owner on Apr 1, 2020. It is now read-only.

Development

Sam Vervaeck edited this page Dec 14, 2018 · 28 revisions

Setup

Install Dependencies

Windows
  • node v8 or higher
  • yarn
  • Run npm install --global --production windows-build-tools from an elevated PowerShell or cmd.exe (run as Administrator)
    • Amongst others, this will install Python2.7 in %USERPROFILE%\.windows-build-tools\python27. If you have no other versions of python installed on your machine, it is OK to add this directory to your %PATH% environment variables. If other versions are installed on your machine, make sure to use a v2.7 in the build steps below.

    • You can set the python used by npm with:

      npm config set python %USERPROFILE%\.windows-build-tools\python27\python.exe

Linux
  • node v8 or higher
  • yarn
  • Neovim 0.2.1+ (neovim binaries are only included for Windows and macOS)
  • python (v2.7 is required)
  • make
  • sudo apt install libxkbfile-dev (this is required for building the keyboard-layout module)
macOS
  • node v8 or higher
  • yarn
  • python (v2.7 is required)
  • XCode
    • You also need to install the Command Line Tools via Xcode. You can find this under the menu Xcode -> Preferences -> Downloads
    • This step will install GCC and the related toolchain containing make

Building

First build

  • Clone the repository: git clone --recursive https://github.com/onivim/oni.git
    • --recursive will also update submodules (which are required to build Oni)
  • cd oni to navigate to the root folder
  • yarn install to install the project dependencies
  • yarn run build to build the project
  • yarn launch to launch the locally-built Oni

Debug build

In order to build a source-map enabled build, you can do the following:

  • yarn run build-debug
  • yarn launch (only needed the first time)

Debugging in Visual Studio Code? Default launch configurations are provided for debugging both the Electron main process and Oni application from Visual Studio Code.

NOTE: You can also launch Oni via yarn run launch.

Production build

A production build removes source maps and applies minification, so it's worth testing in this configuration:

  • yarn run build
  • yarn launch (only needed the first time)
  • oni

NOTE: You can also launch Oni via yarn run launch.

Hot-reload build

The optimal way to debug Oni is to use:

yarn run start

This enables hot reloading of CSS styles, React components, and will automatically reload Oni when other JavaScript files have changed. Also, the hot-reload Webpack configuration has source maps enabled.

If you use the hot-reload build of Oni to make changes - you'll end up reloading your editor every time you make a JavaScript change. For that reason, I recommend keeping two instances open - one for development and one to see the changes.

Coding instance

  • yarn run build - build latest source
  • yarn launch - open the "coding" instance (optional: set a unique colorscheme to differentiate)

Test instance

  • yarn run start - start ONI against the webpack live-reload service - our "running" instance

Then, the flow is to make the code changes in the "coding" instance, and see them reflected immediately in the "running instance".

Here's an example of using hot reloading to edit the cursor (albeit in not very useful ways) in real time: cursor-hot-reload

Packaging

You might want to use a package to install oni on your system. Run

yarn run pack

after having run yarn install and yarn run build as usual.

⚠️ Make sure to run yarn run pack and not yarn pack as these are two entirely different commands!

This command generates packages in dist folder, namely, a .rpm, a .deb, and .tar.gz when run on linux. May be a .zip and an .exe on windows or an .app on macOS.

Currently packaging on macOS won't work because the signing certificate is private.

Debugging

Open DevTools

Note: some users may have issues with the react-devtools due to OS permissions. to resolve this follow these steps:

  1. Navigate to chrome://extensions in your browser, and find its extension ID, which is a hash string like fmkadmapgofadopljbjfkapdkoienihi.

  2. Find out filesystem location used by Chrome for storing extensions:

    • on Windows it is %LOCALAPPDATA%\Google\Chrome\User Data\Default\Extensions; on Linux it could be:
    • ~/.config/google-chrome/Default/Extensions/
    • ~/.config/google-chrome-beta/Default/Extensions/
    • ~/.config/google-chrome-canary/Default/Extensions/
    • ~/.config/chromium/Default/Extensions/
    • on macOS it is ~/Library/Application Support/Google/Chrome/Default/Extensions.
  3. Once you have found the extension location you will need to grant the current user R&W permissions using chmod 777 -R path/to/extension (N.B. the command recursively grants the current user access to the folder and all subfolders)

You can open up Chrome's developer tools at any time using the following steps:

  • Control+Shift+P - open command palette
  • Select Open DevTools

debug tools

Chrome's developer tools are great for profiling and debugging - you can read more here

Architecture

At a high-level, Oni is essentially a window manager hosting one or more 'window splits'. That sounds boring, but the stuff the window splits do - like host a NeovimEditor - starts to get more interesting!

An important consideration for Oni is to ensure that modules are as independent and orthogonal as possible. Most of the interesting work happens in our Services folder, which can be thought of as essentially plugins that are baked into Oni. In fact, many of these could simply be moved out to plugins with no ill effects.

In addition, one major difference between developing for Oni vs a traditional Web application is performance. Responsiveness and latency are incredibly important in an editor - we want to maintain 60 FPS at all times. As we build new features, we need to ensure that they are not regressing performance.

Prerequisites

There are a few pieces of technology that Oni relies on - getting familiar with these will help!

  • React
  • Redux
  • RxJS
  • TypeScript

In addition, Oni is heavily inspired by the flux architecture - unlike a traditional Redux app, we have several independent redux stores, with limited interaction. You can check out what these stores are up to by looking through the Redux devtools.

Running Tests

Oni has two types of tests:

  • CI tests - these are end-to-end integration tests, running in a live instance of Oni.
  • Unit tests - these are smaller tests run directly against a unit of code.

In general, unit tests should be preferred, as they are smaller, have less dependencies, and more stable. They help document the usage of code and also help act as a check in keeping our code modular and with a minimal set of dependencies.

Unit Tests

Unit tests can be run via yarn run test:unit. We also have an easy way to debug the browser unit tests - you can run yarn run debug:test:unit:browser, and the test results will show in the console, with the full test source available in the debugger.

Integration Tests

Integration tests can be found in test/ci, and can be run via yarn run test:integration.

NOTE: Make sure to close all running instance of Oni_ prior to running a CI test.

NOTE: Make sure you have run yarn run build prior to running the tests, so that your changes are reflected in the test run! yarn run test:integration only builds test files, and not the product build - so make sure to run yarn run build beforehand.

TIP: Instead of running all tests, use mocha's --grep option to run only the test you are interested in. Example: yarn run test:integration -- --grep QuickOpenTest.

You can also run the test by using the Oni.automation.runTest API from the console - you just need to pass in the built test path (ie, oni/lib_test/test/ci/<your test>.js) - this can be a faster way to iterate. However, some CiTests rely on specific configuration values.

Tips

  • You can use yarn run fix-lint to fix some lint issues automatically
  • From the developer console, you can access the Oni API directly (ie, Oni.windows.split(1, null))
  • Keep PRs small, scoped, and atomic - it's safer and easier to review. Prefer multiple incremental PRs to one giant PR.

We move fast and encourage experimentation! As opposed to maintaining a giant feature branch / PR, we encourage bringing in features that are off-by-default behind an experimental flag. In order to get your feature promoted from experimental to on-by-default, the following criteria must be met:

  • The feature and settings are documented
  • There are no blocking bugs
  • There is test coverage for the feature