Ele: Extendable Lua Editor

Ele is an (In Development) Extendable Lua Editor written to be easy to understand, extend and modify. It is the primary editor and shell for the Civstack project, and also the core framework for the devleopment of Civstack's text-based learning games.

To install: follow civ.html#install, ele will be installed by default.

Architecture

Ele is architected using the MVI (model-view-intent) architecture, also known as the "React architecture" from the web library of the same name.

   ,_____________________________________________
   | intent(): keyboard, timer, executor, etc    |
   `~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
   /\                                    || Data + events
   || Data + scheduled                   \/
  ,__________________   Data + scheduled ,____________________________
  | view(): paint    | <================ | model(): keybind, actions  |
  `~~~~~~~~~~~~~~~~~~'                   `~~~~~~~~~~~~~~~~~~~~~~~~~~~~'

In practice, this is accomplished in four coroutines spawned by ele.lua's main function:

This roughly implements the MVI architecture because ALL actions are performed sequentially based on the ordering in the events channel.

Actions or plugins have the option to spawn their own coroutine. However, this behavior should be extremely rare, and reserved mostly for things that really can happen concurrently with no user feedback needed, such as saving a file, finding file lints, or updating syntax highlighting. Most real-world editor operations can block the user while they happen, and if they can't then they should consider not being included as an editor operation. Some exceptions such as searching for patterns in a recursive tree should be spawned as a coroutine but be cancelled if the user modifies the buffer that the results are being written to in any way.

Adding Bindings

Adding simple bindings is easy. Simply insert the space-separated chord of keys you want to go to your binding to one of ele's default modes, or create your own.

Mod ele.bindings

's command, insert and/or system entries are where you will find the default modes. For instance, the following will insert the expected text at the cursor position from command mode:

local B = require'ele.bindings'
B.command['y y'] = {action='insert', 'Why oh why did I bind this?\n'},

To write your own action you must:

Editor API

ele.Editor is the main object most custom actions or Ele scripts will interact with. It has several fields, but the fields and methods that most folks will care about are:

Most plugins will simply get edit and then insert/remove/search its buf data using its APIs and/or change its l,c (line,column) values. They are free to use any lua API to do so, but should avoid large amounts of work as much as possible.

Command ele

Usage: ele path/to/file.txt
The ele commandline editor.

Mod ele.types

Types: VSplit HSplit

Functions

Record VSplit

A container with windows split vertically (i.e. tall windows)

Fields:

Methods

Record HSplit

A container with windows split horizontally (i.e. wide windows)

Fields:

Methods

Mod ele.bindings

Types: KeySt KeyBindings

Functions

Record KeySt

The state of the keyboard input (chord). Some bindings are a simple action to perform, whereas callable bindings can update the KeySt to affect future ones, such as decimals causing later actions to be repeated a num of times.

Fields:

Methods

Record KeyBindings

A map of key -> binding. The name and doc can be provided for the user.

Other "fields" must be valid chords. They will be automatically split (by whitespace) to create sub-KeyBindings as-needed.

The value must be one of:

Fields:

Methods

Mod ele.edit

Types: Edit

Record Edit

Fields: Methods

Mod ele.actions

Types: nav

Functions

Mod ele.actions.nav

Functions

Record Editor

Fields: Methods

Record Session

Fields: Methods

Mod ele.testing

Functions