kneasle / sapling

A highly experimental vi-inspired editor where you edit code, not text.
MIT License
727 stars 19 forks source link
code-editor editor experimental rust structured-editing text-editor vim
Sapling Logo

Sapling

A highly experimental code editor where you edit code, not text.

I (@kneasle) don't currently have time to work on Sapling (I have exams coming up and other projects are requiring my time). This doesn't mean the project is dead or that I've forgotten about it - I still think it's cool and the community support has been crazy. I'm also not currently streaming development, but all vods are still on my YouTube channel for anyone interested. There's also a discord server for discussions about Sapling and structured editing in general (invite link). OK enough from me, onto the real README!

Most of the ideas for this project come from my friend Shtanton's blog post. The concept of directly editing syntax trees is called 'structured editing' and is not new; the purpose of Sapling is to use ideas from structured editing to speed up moment-to-moment code editing, much how editors like Vim and Emacs speed up editing. Sapling's editing model will be largely inspired by Vim/NeoVim and kakoune. Sapling also aims to be general purpose - Sapling should be able to edit any language, given that a suitable grammar is provided.

Contributions of all kinds are very welcome!

It is worth noting that Sapling is primarily an experiment to determine whether or not such an editor could work. Therefore, for the time being, Sapling can be expected to change at any time. Hopefully the design of Sapling will converge over time - its current state is similar to how pre-1.0 Rust was continually evolving and making potentially-breaking changes so that post-1.0 Rust could be as useful as possible.

Contents


But why?

When writing code with any text editor, you are usually only interested in a tiny subset of all the possible strings of text - those that correspond to valid programs in whatever language you're writing. In a text editor, you will spend the overwhelming majority of your time with the text in your editor being invalid as you make edits to move between valid programs. This is inefficient for the programmer, and causes lots of issues for software like Language Servers which have to cope as best they can with these invalid states.

To be fair, editors like Vim, Emacs and Kakoune do better than most by providing shortcuts to do common text manipulations, which is a step in the right direction. Interestingly, though, the most useful of these shortcuts are those correspond to modifications of the syntax tree (e.g. ci) to remove the replace the contents of () in Vim), and so it seems logical to apply modal editing to directly modifying the syntax trees of programs.

Sapling takes the idea of keystrokes primarily modifying text, but instead applies those keystrokes as actions to the syntax tree of your program. I have no idea if this will be useful, but it seems worth a try.

Goals of Sapling

These goals are roughly in order of importance, with the most important first:

Inspirations:

Quick Start/Play with Sapling

Installation

Sapling is not yet on crates.io and is very much still in early development, but if you want to play around with Sapling as it currently stands, the best way is to clone the repository and build from source (you'll need Rust installed in order to do this):

git clone https://github.com/kneasle/sapling.git
cargo run 2> log

Demo

Demo GIF

Current Keybindings

Misc

Cursor Movement

Modify the tree

As with Vim, all commands can be repeated by inserting a count before them. For example, 3u will undo 3 steps in one go.

Sapling can currently only edit JSON with the following keys: [a]rray, [o]bject, [t]rue, [f]alse, [n]ull, [s]tring. There is currently no way to insert text into a string or to open and close files (yet!).

Sapling handle multiple nodes in one go by adding a count before the node name, for example i3t will insert 3 trues before the cursor.

Pros of AST-based editing

Cons of AST-based editing (otherwise known as 'Extra Fun Challenges')

Because the editor has to hold a valid program, the following things that other editors take for granted are hard to implement:

What's an AST?

AST stands for 'Abstract Syntax Tree', and in essence it is a tree-like representation of only the structure of a program, without any details about formatting.

For example, the following Rust code:

fn foo(y: u64, z: u32) {
    let x = y * 3 + z as u64;
    combine(x, y);
}

would correspond to a syntax tree something like the following (simplified for demonstration purposes). Notice how each 'element' of the code corresponds to one 'node' in the syntax tree:

Example tree