From 6460501a446ae52e15fba0e8368c1a7d22fc288e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sun, 30 May 2021 17:52:46 +0900 Subject: [PATCH] Update architecture.md --- docs/architecture.md | 130 +++++++++++++++++++++++------------------- helix-core/src/lib.rs | 2 +- 2 files changed, 71 insertions(+), 61 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 13cdab5e6..17ef296dc 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -8,68 +8,78 @@ | helix-term | Terminal UI | | helix-tui | TUI primitives, forked from tui-rs, inspired by Cursive | -# Notes -- server-client architecture via gRPC, UI separate from core -- multi cursor based editing and slicing -- WASM based plugins (builtin LSP & fuzzy file finder) +This document contains a high-level overview of Helix internals. -Structure similar to codemirror: +> NOTE: Use `cargo doc --open` for API documentation as well as dependency +> documentation. -- text (ropes) -- transactions - - changes - - invert changes (generates a revert) - - annotations (time changed etc) - - state effects - - additional editor state as facets -- snapshots as an async view into current state -- selections { anchor (nonmoving), head (moving) from/to } -> SelectionSet with a primary - - cursor is just a single range selection -- markers - track a position inside text that synchronizes with edits -- { doc, selection, update(), splice, changes(), facets, tabSize, identUnit, lineSeparator, changeFilter/transactionFilter to modify stuff before } -- view (actual UI) -- viewport(Lines) -> what's actually visible -- extend the view via Decorations (inline styling) or Components (UI) - - mark / wieget / line / replace decoration -- commands (transform state) -- movement -- selection extension -- deletion -- indentation -- keymap (maps keys to commands) -- history (undo tree via immutable ropes) - - undoes transactions via reverts -- (collab mode) -- gutter (line numbers, diagnostic marker, etc) -> ties into UI components -- rangeset/span -> mappable over changes (can be a marker primitive?) -- syntax (treesitter) -- fold -- selections (select mode/multiselect) -- matchbrackets -- closebrackets -- special-chars (shows dots etc for specials) -- panel (for UI: file pickers, search dialogs, etc) -- tooltip (for UI) -- search (regex) -- lint (async linters) -- lsp -- highlight -- stream-syntax -- autocomplete -- comment (gc, etc for auto commenting) -- snippets -- terminal mode? +## Core -- plugins can contain more commands/ui abstractions to use elsewhere -- languageData as presets for each language (syntax, indent, comment, etc) +The core contains basic building blocks used to construct the editor. It is +heavily based on [CodeMirror 6](https://codemirror.net/6/docs/). The primitives +are functional: most operations won't modify data in place but instead return +a new copy. -Vim stuff: -- motions/operators/text objects -- full visual mode -- macros -- jump lists -- marks -- yank/paste -- conceal for markdown markers, etc +The main data structure used for representing buffers is a `Rope`. We re-export +the excellent [ropey](https://github.com/cessen/ropey) library. Ropes are cheap +to clone, and allow us to easily make snapshots of a text state. + +Multiple selections are a core editing primitive. Document selections are +represented by a `Selection`. Each `Range` in the selection consists of a moving +`head` and an immovable `anchor`. A single cursor in the editor is simply +a selection with a single range, with the head and the anchor in the same +position. + +Ropes are modified by constructing an OT-like `Transaction`. It's represents +a single coherent change to the document and can be applied to the rope. +A transaction can be inverted to produce an undo. Selections and marks can be +mapped over a transaction to translate to a position in the new text state after +applying the transaction. + +> NOTE: `Transaction::change`/`Transaction::change_by_selection` is the main +> interface used to generate text edits. + +`Syntax` is the interface used to interact with tree-sitter ASTs for syntax +highling and other features. + +## View + +The `view` layer was supposed to be a frontend-agnostic imperative library that +would build on top of `core` to provide the common editor logic. Currently it's +tied to the terminal UI. + +A `Document` ties together the `Rope`, `Selection`(s), `Syntax`, document +`History`, language server (etc.) into a comprehensive representation of an open +file. + +A `View` represents an open split in the UI. It holds the currently open +document ID and other related state. + +> NOTE: Multiple views are able to display the same document, so the document +> contains selections for each view. To retrieve, `document.selection()` takes +> a `ViewId`. + +The `Editor` holds the global state: all the open documents, a tree +representation of all the view splits, and a registry of language servers. To +open or close files, interact with the editor. + +## LSP + +A language server protocol client. + +## Term + +The terminal frontend. + +The `main` function sets up a new `Application` that runs the event loop. + +`commands.rs` is probably the most interesting file. It contains all commands +(actions tied to keybindings). + +`keymap.rs` links commands to key combinations. + + +## TUI / Term + +TODO: document Component and rendering related stuff diff --git a/helix-core/src/lib.rs b/helix-core/src/lib.rs index 5ce6a63f7..d5b0cd156 100644 --- a/helix-core/src/lib.rs +++ b/helix-core/src/lib.rs @@ -13,7 +13,7 @@ pub mod register; pub mod search; pub mod selection; -pub mod state; +mod state; pub mod syntax; mod transaction;