## File: README.md

A [Kakoune](https://github.com/mawww/kakoune) / [Neovim](https://github.com/neovim/neovim) inspired editor, written in Rust.

The editing model is very heavily based on Kakoune; during development I found
myself agreeing with most of Kakoune's design decisions.

For more information, see the [website](https://helix-editor.com) or
[documentation](https://docs.helix-editor.com/).

All shortcuts/keymaps can be found [in the documentation on the website](https://docs.helix-editor.com/keymap.html).

[Troubleshooting](https://github.com/helix-editor/helix/wiki/Troubleshooting)

# Features

- Vim-like modal editing
- Multiple selections
- Built-in language server support
- Smart, incremental syntax highlighting and code editing via tree-sitter

Although it's primarily a terminal-based editor, I am interested in exploring
a custom renderer (similar to Emacs) using wgpu.

Note: Only certain languages have indentation definitions at the moment. Check
`runtime/queries/<lang>/` for `indents.scm`.

# Installation

[Installation documentation](https://docs.helix-editor.com/install.html).

[](https://repology.org/project/helix-editor/versions)

# Contributing

Contributing guidelines can be found [here](./docs/CONTRIBUTING.md).

# Getting help

Your question might already be answered on the [FAQ](https://github.com/helix-editor/helix/wiki/FAQ).

Discuss the project on the community [Matrix Space](https://matrix.to/#/#helix-community:matrix.org) (make sure to join `#helix-editor:matrix.org` if you're on a client that doesn't support Matrix Spaces yet).

# Credits

Thanks to [@jakenvac](https://github.com/jakenvac) for designing the logo!

---

## File: book/src/guides/README.md

# Guides

This section contains guides for adding new languages to Helix: language and
grammar configuration, and the tree-sitter query files that drive highlighting,
power indentation, textobjects, symbol tags, and other features.

---

## File: docs/architecture.md

| Crate           | Description                                                      |
| -----------     | -----------                                                      |
| helix-stdx      | Extensions to the standard library (similar to [`rust-analyzer`'s](https://github.com/rust-lang/rust-analyzer/blob/ea413f67a8f730b4211c09e103f8207c62e7dbc3/crates/stdx/Cargo.toml#L5)) |
| helix-core      | Core editing primitives, functional.                             |
| helix-lsp       | Language server client                                           |
| helix-lsp-types | Language Server Protocol type definitions                        |
| helix-dap       | Debug Adapter Protocol (DAP) client                              |
| helix-event     | Primitives for defining and handling events within the editor    |
| helix-loader    | Functions for building, fetching, and loading external resources |
| helix-view      | UI abstractions for use in backends, imperative shell.           |
| helix-term      | Terminal UI                                                      |
| helix-tui       | TUI primitives, forked from tui-rs, inspired by Cursive          |


This document contains a high-level overview of Helix internals.

> NOTE: Use `cargo doc --open` for API documentation as well as dependency
> documentation.

## Core

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.

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 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
highlighting 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. Views encapsulate the gutter, status line,
diagnostics, and the inner area where the code is displayed.

> 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`.

`Info` is the autoinfo box that shows hints when awaiting another key with bindings
like `g` and `m`. It is attached to the viewport as a whole.

`Surface` is like a buffer to which widgets draw themselves to, and the
surface is then rendered on the screen on each cycle.

`Rect`s are areas (simply an x and y coordinate with the origin at the
screen top left and then a height and width) which are part of a
`Surface`. They can be used to limit the area to which a `Component` can
render. For example if we wrap a `Markdown` component in a `Popup`
(think the documentation popup with space+k), Markdown's render method
will get a Rect that is the exact size of the popup.

Widgets are called `Component`s internally, and you can see most of them
in `helix-term/src/ui`. Some components like `Popup` and `Overlay` can take
other components as children.

`Layer`s are how multiple components are displayed, and is simply a
`Vec<Component>`. Layers are managed by the `Compositor`. On each top
level render call, the compositor renders each component in the order
they were pushed into the stack. This makes multiple components "layer"
on top of one another. Hence we get a file picker displayed over the
editor, etc.

The `Editor` holds the global state: all the open documents, a tree
representation of all the view splits, the configuration, 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

## Event

The `helix-event` crate defines primitives for defining and acting on events
within the editor. "Events" cover things like opening, changing and closing of
documents, starting and stopping of language servers and more.

`helix-event` has tools for defining events and registering _hooks_ which run
any time an event is emitted. `helix-event` also provides `AsyncHook` - a tool
for running cancellable tasks which run after events with _debouncing_.

See the `AsyncHook` type for more information. Events can be created within the
`events!` macro. Synchronous hooks can be created with `register_hook!`. And
editor-wide events can be sent to hooks with `helix_event::dispatch`.

---

## File: docs/CONTRIBUTING.md

# Contributing

Contributors are very welcome! **No contribution is too small and all contributions are valued.**

Some suggestions to get started:

- You can look at the [good first issue][good-first-issue] label on the issue tracker.
- Help with packaging on various distributions needed!
- To use print debugging to the [Helix log file][log-file], you must:
  * Print using `log::info!`, `warn!`, or `error!`. (`log::info!("helix!")`)
  * Pass the appropriate verbosity level option for the desired log level. (`hx -v <file>` for info, more `v`s for higher verbosity)
  * Want to display the logs in a separate file instead of using the `:log-open` command in your compiled Helix editor? Start your debug version with `cargo run -- --log foo.log` and in a new terminal use `tail -f foo.log`
- Instead of running a release version of Helix, while developing you may want to run in debug mode with `cargo run` which is way faster to compile
- Looking for even faster compile times? Give [mold](https://github.com/rui314/mold) a try
- If your preferred language is missing, integrating a tree-sitter grammar for
    it and defining syntax highlight queries for it is straightforward and
    doesn't require much knowledge of the internals.
- If you don't use the Nix development shell and are getting your rust-analyzer binary from rustup, you may need to run `rustup component add rust-analyzer`.
  This is because `rust-toolchain.toml` selects our MSRV for the development toolchain but doesn't download the matching rust-analyzer automatically.

We provide an [architecture.md][architecture.md] that should give you
a good overview of the internals.

# Auto generated documentation

Some parts of [the book][docs] are autogenerated from the code itself,
like the list of `:commands` and supported languages. To generate these
files, run

```shell
cargo xtask docgen
```

inside the project. We use [xtask][xtask] as an ad-hoc task runner.

To preview the book itself, install [mdbook][mdbook]. Then, run

```shell
mdbook serve book
```

and visit [http://localhost:3000](http://localhost:3000).

# Testing

## Unit tests/Documentation tests

Run `cargo test --workspace` to run unit tests and documentation tests in all packages.

## Integration tests

Integration tests for helix-term can be run with `cargo integration-test`. Code
contributors are strongly encouraged to write integration tests for their code.
Existing tests can be used as examples. Helpers can be found in
[helpers.rs][helpers.rs]. The log level can be set with the `HELIX_LOG_LEVEL`
environment variable, e.g. `HELIX_LOG_LEVEL=debug cargo integration-test`.

Contributors using MacOS might encounter `Too many open files (os error 24)`
failures while running integration tests. This can be resolved by increasing
the default value (e.g. to `10240` from `256`) by running `ulimit -n 10240`.

## Minimum Stable Rust Version (MSRV) Policy

Helix keeps an intentionally low MSRV for the sake of easy building and packaging
downstream. We follow [Firefox's MSRV policy]. Once Firefox's MSRV increases we
may bump ours as well, but be sure to check that popular distributions like Ubuntu
package the new MSRV version. When increasing the MSRV, update these three places:

* the `workspace.package.rust-version` key in `Cargo.toml` in the repository root
* the `env.MSRV` key at the top of `.github/workflows/build.yml`
* the `toolchain.channel` key in `rust-toolchain.toml`

[Firefox's MSRV policy]: https://firefox-source-docs.mozilla.org/writing-rust-code/update-policy.html
[good-first-issue]: https://github.com/helix-editor/helix/labels/E-easy
[log-file]: https://github.com/helix-editor/helix/wiki/FAQ#access-the-log-file
[architecture.md]: ./architecture.md
[docs]: https://docs.helix-editor.com/
[xtask]: https://github.com/matklad/cargo-xtask
[mdbook]: https://rust-lang.github.io/mdBook/guide/installation.html
[helpers.rs]: ../helix-term/tests/test/helpers.rs

---

## File: docs/releases.md

## Checklist

Helix releases are versioned in the Calendar Versioning scheme:
`YY.0M(.MICRO)`, for example, `22.05` for May of 2022, or in a patch release,
`22.05.1`. In these instructions we'll use `<tag>` as a placeholder for the tag
being published.

* Merge the PR with the release updates. That branch should:
    * Update the version:
        * Update the `workspace.package.version` key in `Cargo.toml`. Cargo only accepts
          SemVer versions so a CalVer version of `22.07` for example must be formatted
          as `22.7.0`. Patch/bugfix releases should increment the SemVer patch number. A
          patch release for 22.07 would be `22.7.1`.
        * Run `cargo check` and commit the resulting change to `Cargo.lock`
    * Add changelog notes to `CHANGELOG.md`
    * Add new `<release>` entry in `contrib/Helix.appdata.xml` with release information according to the [AppStream spec](https://www.freedesktop.org/software/appstream/docs/sect-Metadata-Releases.html)
* Tag and push
    * Switch to master and pull
    * `git tag -s -m "<tag>" -a <tag> && git push origin <tag>` (note the `-s` which signs the tag)
* Wait for the Release CI to finish
    * It will automatically turn the git tag into a GitHub release when it uploads artifacts
* Edit the new release
    * Use `<tag>` as the title
    * Link to the changelog and release notes
* Merge the release notes PR
* Download the macos and linux binaries and update the `sha256`s in the [homebrew formula]
    * Use `sha256sum` on the downloaded `.tar.xz` files to determine the hash
* Link to the release notes in this-week-in-rust
    * [Example PR](https://github.com/rust-lang/this-week-in-rust/pull/3300)
* Post to reddit
    * [Example post](https://www.reddit.com/r/rust/comments/uzp5ze/helix_editor_2205_released/)

[homebrew formula]: https://github.com/Homebrew/homebrew-core/blob/master/Formula/h/helix.rb

## Changelog Curation

The changelog is currently created manually by reading through commits in the
log since the last release. GitHub's compare view is a nice way to approach
this. For example, when creating the 22.07 release notes, this compare link
may be used

```
https://github.com/helix-editor/helix/compare/22.05...master
```

Either side of the triple-dot may be replaced with an exact revision, so if
you wish to incrementally compile the changelog, you can tackle a weeks worth
or so, record the revision where you stopped, and use that as a starting point
next week:

```
https://github.com/helix-editor/helix/compare/7706a4a0d8b67b943c31d0c5f7b00d357b5d838d...master
```

A work-in-progress commit for a changelog might look like
[this example](https://github.com/helix-editor/helix/commit/831adfd4c709ca16b248799bfef19698d5175e55).

Not every PR or commit needs a blurb in the changelog. Each release section
tends to have a blurb that links to a GitHub comparison between release
versions for convenience:

> As usual, the following is a summary of each of the changes since the last
> release. For the full log, check out the git log.

Typically, small changes like dependencies or documentation updates, refactors,
or meta changes like GitHub Actions work are left out.

---

## File: docs/vision.md

The Helix project still has a ways to go before reaching its goals.  This document outlines some of those goals and the overall vision for the project.

# Vision

An efficient, batteries-included editor you can take anywhere and be productive... if it's your kind of thing.

* **Cross-platform.**  Whether on Linux, Windows, or OSX, you should be able to take your editor with you.
* **Terminal first.**  Not all environments have a windowing system, and you shouldn't have to abandon your preferred editor in those cases.
* **Native.**  No Electron or HTML DOM here.  We want an efficient, native-compiled editor that can run with minimal resources when needed.  If you're working on a Raspberry Pi, your editor shouldn't consume half of your RAM.
* **Batteries included.**  Both the default configuration and bundled features should be enough to have a good editing experience and be productive.  You shouldn't need a massive custom config or external executables and plugins for basic features and functionality.
* **Don't try to be everything for everyone.**  There are many great editors out there to choose from.  Let's make Helix *one of* those great options, with its own take on things.

# Goals

Vision statements are all well and good, but are also vague and subjective.  Here is a (non-exhaustive) list of some of Helix's more concrete goals, to help give a clearer idea of the project's direction:

* **Modal.**  Vim is a great idea.
* **Selection -> Action**, not Verb -> Object.  Interaction models aren't linguistics, and "selection first" lets you see what you're doing (among other benefits).
* **We aren't playing code golf.**  It's more important for the keymap to be consistent and easy to memorize than it is to save a key stroke or two when editing.
* **Built-in tools** for working with code bases efficiently.  Most projects aren't a single file, and an editor should handle that as a first-class use case.  In Helix's case, this means (among other things) a fuzzy-search file navigator and LSP support.
* **Edit anything** that comes up when coding, within reason.  Whether it's a 200 MB XML file, a megabyte of minified javascript on a single line, or Japanese text encoded in ShiftJIS, you should be able to open it and edit it without problems.  (Note: this doesn't mean handle every esoteric use case.  Sometimes you do just need a specialized tool, and Helix isn't that.)
* **Configurable**, within reason.  Although the defaults should be good, not everyone will agree on what "good" is.  Within the bounds of Helix's core interaction models, it should be reasonably configurable so that it can be "good" for more people.  This means, for example, custom key maps among other things.
* **Extensible**, within reason.  Although we want Helix to be productive out-of-the-box, it's not practical or desirable to cram every useful feature and use case into the core editor.  The basics should be built-in, but you should be able to extend it with additional functionality as needed.
* **Clean code base.**  Sometimes other factors (e.g. significant performance gains, important features, correctness, etc.) will trump strict readability, but we nevertheless want to keep the code base straightforward and easy to understand to the extent we can.

---

## File: helix-lsp-types/README.md

# Helix's `lsp-types`

This is a fork of the [`lsp-types`](https://crates.io/crates/lsp-types) crate ([`gluon-lang/lsp-types`](https://github.com/gluon-lang/lsp-types)) taken at version v0.95.1 (commit [3e6daee](https://github.com/gluon-lang/lsp-types/commit/3e6daee771d14db4094a554b8d03e29c310dfcbe)). This fork focuses usability improvements that make the types easier to work with for the Helix codebase.

The URL type has been replaced with a newtype wrapper of a `String`. The `lsp-types` crate at the forked version used [`url::Url`](https://docs.rs/url/2.5.0/url/struct.Url.html) which provides conveniences for using URLs according to [the WHATWG URL spec](https://url.spec.whatwg.org). Helix supports a subset of valid URLs, namely the `file://` scheme, so a wrapper around a normal `String` is sufficient. Plus the LSP spec requires URLs to be in [RFC3986](https://tools.ietf.org/html/rfc3986) format instead.

---

## File: helix-tui/README.md

# helix-tui

This library is a fork of the great library
[tui-rs](https://github.com/fdehau/tui-rs/). We've mainly relied on the double
buffer implementation and render diffing, side-stepping its widget and
layouting.

---

## File: runtime/themes/README.md

# User submitted themes

If you submit a theme, please include a comment at the top with your name and email address:

```toml
# Author : Name 
```

If you are submitting a theme that is already published somewhere, then please
add the corresponding license file for it under `licenses/` with the following
name `theme_name.license` and add a comment at the top of the theme file:

```toml
# License: <License specification>
```

We have a preview page for themes on our [wiki](https://github.com/helix-editor/helix/wiki/Themes)!

---

## File: runtime/queries/ecma/README.md

# Inheritance model for ecma-based languages

Ecma-based languages share many traits. Because of this we want to share as many queries as possible while avoiding nested inheritance that can make query behaviour unpredictable due to unexpected precedence.

To achieve that, there are "public" and "private" versions for javascript, jsx, and typescript query files, that share the same name, but the "private" version name starts with an underscore (with the exception of ecma, that already exists as a sort of base "private" language). This allows the "private" versions to host the specific queries of the language excluding any `; inherits` statement, in order to make them safe to be inherited by the "public" version of the same language and other languages as well. The tsx language doesn't have a "private" version given that currently it doesn't need to be inherited by other languages.

| Language   | Inherits from           |
| ---------- | ----------------------- |
| javascript | _javascript, ecma       |
| jsx        | _jsx, _javascript, ecma |
| typescript | _typescript, ecma       |
| tsx        | _jsx, _typescript, ecma |

If you intend to add queries to any of the ecma-based languages above, make sure you add them to the correct private language they belong to, so that other languages down the line can benefit from them.