Rewrite and refactor all documentation

pull/5534/head
David-Else 1 year ago
parent b6331394a3
commit 421b5ebace

@ -1,5 +1,6 @@
# Commands # Commands
Command mode can be activated by pressing `:`, similar to Vim. Built-in commands: Command mode, similar to Vim, can be activated by pressing `:`. The built-in
commands are:
{{#include ./generated/typable-cmd.md}} {{#include ./generated/typable-cmd.md}}

@ -1,11 +1,13 @@
# Configuration # Configuration
To override global configuration parameters, create a `config.toml` file located in your config directory: To override global configuration parameters, create a `config.toml` file located
in your config directory:
* Linux and Mac: `~/.config/helix/config.toml` - Linux and Mac: `~/.config/helix/config.toml`
* Windows: `%AppData%\helix\config.toml` - Windows: `%AppData%\helix\config.toml`
> Hint: You can easily open the config file by typing `:config-open` within Helix normal mode. > 💡 You can easily open the config file by typing `:config-open` within Helix
> normal mode.
Example config: Example config:
@ -25,38 +27,37 @@ select = "underline"
hidden = false hidden = false
``` ```
You may also specify a file to use for configuration with the `-c` or You can use a custom configuration file by specifying it with the `-c` or
`--config` CLI argument: `hx -c path/to/custom-config.toml`. `--config` command line argument, for example
`hx -c path/to/custom-config.toml`. Additionally, you can reload the
It is also possible to trigger configuration file reloading by sending the `USR1` configuration file by sending the USR1 signal to the Helix process on Unix
signal to the helix process, e.g. via `pkill -USR1 hx`. This is only supported operating systems, such as by using the command `pkill -USR1 hx`.
on unix operating systems.
## Editor ## Editor
### `[editor]` Section ### `[editor]` Section
| Key | Description | Default | | Key | Description | Default |
|--|--|---------| | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| `scrolloff` | Number of lines of padding around the edge of the screen when scrolling. | `5` | | `scrolloff` | Number of lines of padding around the edge of the screen when scrolling. | `5` |
| `mouse` | Enable mouse mode. | `true` | | `mouse` | Enable mouse mode. | `true` |
| `middle-click-paste` | Middle click paste support. | `true` | | `middle-click-paste` | Middle click paste support. | `true` |
| `scroll-lines` | Number of lines to scroll per scroll wheel step. | `3` | | `scroll-lines` | Number of lines to scroll per scroll wheel step. | `3` |
| `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` | | `shell` | Shell to use when running external commands. | Unix: `["sh", "-c"]`<br/>Windows: `["cmd", "/C"]` |
| `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers. | `absolute` | | `line-number` | Line number display: `absolute` simply shows each line's number, while `relative` shows the distance from the current line. When unfocused or in insert mode, `relative` will still show absolute line numbers. | `absolute` |
| `cursorline` | Highlight all lines with a cursor. | `false` | | `cursorline` | Highlight all lines with a cursor. | `false` |
| `cursorcolumn` | Highlight all columns with a cursor. | `false` | | `cursorcolumn` | Highlight all columns with a cursor. | `false` |
| `gutters` | Gutters to display: Available are `diagnostics` and `diff` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` | | `gutters` | Gutters to display: Available are `diagnostics` and `diff` and `line-numbers` and `spacer`, note that `diagnostics` also includes other features like breakpoints, 1-width padding will be inserted if gutters is non-empty | `["diagnostics", "spacer", "line-numbers", "spacer", "diff"]` |
| `auto-completion` | Enable automatic pop up of auto-completion. | `true` | | `auto-completion` | Enable automatic pop up of auto-completion. | `true` |
| `auto-format` | Enable automatic formatting on save. | `true` | | `auto-format` | Enable automatic formatting on save. | `true` |
| `auto-save` | Enable automatic saving on focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal. | `false` | | `auto-save` | Enable automatic saving on the focus moving away from Helix. Requires [focus event support](https://github.com/helix-editor/helix/wiki/Terminal-Support) from your terminal. | `false` |
| `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` | | `idle-timeout` | Time in milliseconds since last keypress before idle timers trigger. Used for autocompletion, set to 0 for instant. | `400` |
| `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` | | `completion-trigger-len` | The min-length of word under cursor to trigger autocompletion | `2` |
| `auto-info` | Whether to display infoboxes | `true` | | `auto-info` | Whether to display infoboxes | `true` |
| `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` | | `true-color` | Set to `true` to override automatic detection of terminal truecolor support in the event of a false negative. | `false` |
| `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file. | `[]` | | `rulers` | List of column positions at which to display the rulers. Can be overridden by language specific `rulers` in `languages.toml` file. | `[]` |
| `bufferline` | Renders a line at the top of the editor displaying open buffers. Can be `always`, `never` or `multiple` (only shown if more than one buffer is in use) | `never` | | `bufferline` | Renders a line at the top of the editor displaying open buffers. Can be `always`, `never` or `multiple` (only shown if more than one buffer is in use) | `never` |
| `color-modes` | Whether to color the mode indicator with different colors depending on the mode itself | `false` | | `color-modes` | Whether to color the mode indicator with different colors depending on the mode itself | `false` |
### `[editor.statusline]` Section ### `[editor.statusline]` Section
@ -78,57 +79,62 @@ mode.normal = "NORMAL"
mode.insert = "INSERT" mode.insert = "INSERT"
mode.select = "SELECT" mode.select = "SELECT"
``` ```
The `[editor.statusline]` key takes the following sub-keys: The `[editor.statusline]` key takes the following sub-keys:
| Key | Description | Default | | Key | Description | Default |
| --- | --- | --- | | ------------- | ---------------------------------------------------------- | ------------------------------------------------------------ |
| `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name"]` | | `left` | A list of elements aligned to the left of the statusline | `["mode", "spinner", "file-name"]` |
| `center` | A list of elements aligned to the middle of the statusline | `[]` | | `center` | A list of elements aligned to the middle of the statusline | `[]` |
| `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "position", "file-encoding"]` | | `right` | A list of elements aligned to the right of the statusline | `["diagnostics", "selections", "position", "file-encoding"]` |
| `separator` | The character used to separate elements in the statusline | `"│"` | | `separator` | The character used to separate elements in the statusline | `"│"` |
| `mode.normal` | The text shown in the `mode` element for normal mode | `"NOR"` | | `mode.normal` | The text shown in the `mode` element for normal mode | `"NOR"` |
| `mode.insert` | The text shown in the `mode` element for insert mode | `"INS"` | | `mode.insert` | The text shown in the `mode` element for insert mode | `"INS"` |
| `mode.select` | The text shown in the `mode` element for select mode | `"SEL"` | | `mode.select` | The text shown in the `mode` element for select mode | `"SEL"` |
The following statusline elements can be configured: The following statusline elements can be configured:
| Key | Description | | Key | Description |
| ------ | ----------- | | -------------------------- | ------------------------------------------------------------------------------- |
| `mode` | The current editor mode (`mode.normal`/`mode.insert`/`mode.select`) | | `mode` | The current editor mode (`mode.normal`/`mode.insert`/`mode.select`) |
| `spinner` | A progress spinner indicating LSP activity | | `spinner` | A progress spinner indicating LSP activity |
| `file-name` | The path/name of the opened file | | `file-name` | The path/name of the opened file |
| `file-base-name` | The basename of the opened file | | `file-base-name` | The basename of the opened file |
| `file-encoding` | The encoding of the opened file if it differs from UTF-8 | | `file-encoding` | The encoding of the opened file if it differs from UTF-8 |
| `file-line-ending` | The file line endings (CRLF or LF) | | `file-line-ending` | The file line endings (CRLF or LF) |
| `total-line-numbers` | The total line numbers of the opened file | | `total-line-numbers` | The total line numbers of the opened file |
| `file-type` | The type of the opened file | | `file-type` | The type of the opened file |
| `diagnostics` | The number of warnings and/or errors | | `diagnostics` | The number of warnings and/or errors |
| `workspace-diagnostics` | The number of warnings and/or errors on workspace | | `workspace-diagnostics` | The number of warnings and/or errors on workspace |
| `selections` | The number of active selections | | `selections` | The number of active selections |
| `primary-selection-length` | The number of characters currently in primary selection | | `primary-selection-length` | The number of characters currently in primary selection |
| `position` | The cursor position | | `position` | The cursor position |
| `position-percentage` | The cursor position as a percentage of the total number of lines | | `position-percentage` | The cursor position as a percentage of the total number of lines |
| `separator` | The string defined in `editor.statusline.separator` (defaults to `"│"`) | | `separator` | The string defined in `editor.statusline.separator` (defaults to `"│"`) |
| `spacer` | Inserts a space between elements (multiple/contiguous spacers may be specified) | | `spacer` | Inserts a space between elements (multiple/contiguous spacers may be specified) |
### `[editor.lsp]` Section ### `[editor.lsp]` Section
| Key | Description | Default | | Key | Description | Default |
| --- | ----------- | ------- | | ----------------------------- | ---------------------------------------------------------- | ------- |
| `display-messages` | Display LSP progress messages below statusline[^1] | `false` | | `display-messages` | Display LSP progress messages below statusline[^1] | `false` |
| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` | | `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
| `display-signature-help-docs` | Display docs under signature help popup | `true` | | `display-signature-help-docs` | Display docs under signature help popup | `true` |
[^1]: By default, a progress spinner is shown in the statusline beside the file path. [^1]:
By default, a progress spinner is shown in the statusline beside the file
path.
### `[editor.cursor-shape]` Section ### `[editor.cursor-shape]` Section
Defines the shape of cursor in each mode. Note that due to limitations Defines the shape of cursor in each mode. Valid values for these options are
of the terminal environment, only the primary cursor can change shape. `block`, `bar`, `underline`,or `hidden`.
Valid values for these options are `block`, `bar`, `underline`, or `hidden`.
> 💡Due to limitations of the terminal environment, only the primary cursor can
> change shape.
| Key | Description | Default | | Key | Description | Default |
| --- | ----------- | ------- | | -------- | ------------------------------------------ | ------- |
| `normal` | Cursor shape in [normal mode][normal mode] | `block` | | `normal` | Cursor shape in [normal mode][normal mode] | `block` |
| `insert` | Cursor shape in [insert mode][insert mode] | `block` | | `insert` | Cursor shape in [insert mode][insert mode] | `block` |
| `select` | Cursor shape in [select mode][select mode] | `block` | | `select` | Cursor shape in [select mode][select mode] | `block` |
@ -139,23 +145,20 @@ Valid values for these options are `block`, `bar`, `underline`, or `hidden`.
### `[editor.file-picker]` Section ### `[editor.file-picker]` Section
Sets options for file picker and global search. All but the last key listed in Set options for file picker and global search. Ignoring a file means it is not
the default file-picker configuration below are IgnoreOptions: whether hidden visible in the Helix file picker and global search.
files and files listed within ignore files are ignored by (not visible in) the
helix file picker and global search. There is also one other key, `max-depth`
available, which is not defined by default.
All git related options are only enabled in a git repository. All git related options are only enabled in a git repository.
| Key | Description | Default | | Key | Description | Default |
|--|--|---------| | ------------- | -------------------------------------------------------------------------------------------------------- | ------------------- |
|`hidden` | Enables ignoring hidden files. | true | `hidden` | Enables ignoring hidden files. | true |
|`parents` | Enables reading ignore files from parent directories. | true | `parents` | Enables reading ignore files from parent directories. | true |
|`ignore` | Enables reading `.ignore` files. | true | `ignore` | Enables reading `.ignore` files. | true |
|`git-ignore` | Enables reading `.gitignore` files. | true | `git-ignore` | Enables reading `.gitignore` files. | true |
|`git-global` | Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option. | true | `git-global` | Enables reading global `.gitignore`, whose path is specified in git's config: `core.excludefile` option. | true |
|`git-exclude` | Enables reading `.git/info/exclude` files. | true | `git-exclude` | Enables reading `.git/info/exclude` files. | true |
|`max-depth` | Set with an integer value for maximum depth to recurse. | Defaults to `None`. | `max-depth` | Set with an integer value for maximum depth to recurse. | Defaults to `None`. |
### `[editor.auto-pairs]` Section ### `[editor.auto-pairs]` Section
@ -169,8 +172,9 @@ To disable auto-pairs altogether, set `auto-pairs` to `false`:
auto-pairs = false # defaults to `true` auto-pairs = false # defaults to `true`
``` ```
The default pairs are <code>(){}[]''""``</code>, but these can be customized by The default pairs are
setting `auto-pairs` to a TOML table: <code>(){}[]''""``</code>, but these can be customized by setting `auto-pairs`
to a TOML table:
```toml ```toml
[editor.auto-pairs] [editor.auto-pairs]
@ -182,9 +186,9 @@ setting `auto-pairs` to a TOML table:
'<' = '>' '<' = '>'
``` ```
Additionally, this setting can be used in a language config. Unless Additionally, this setting can be used in a language config. Unless the editor
the editor setting is `false`, this will override the editor config in setting is `false`, this will override the editor config in documents with this
documents with this language. language.
Example `languages.toml` that adds <> and removes '' Example `languages.toml` that adds <> and removes ''
@ -205,18 +209,19 @@ name = "rust"
Search specific options. Search specific options.
| Key | Description | Default | | Key | Description | Default |
|--|--|---------| | ------------- | -------------------------------------------------------------------------------------------------- | ------- |
| `smart-case` | Enable smart case regex searching (case insensitive unless pattern contains upper case characters) | `true` | | `smart-case` | Enable smart case regex searching (case-insensitive unless pattern contains upper case characters) | `true` |
| `wrap-around`| Whether the search should wrap after depleting the matches | `true` | | `wrap-around` | Whether the search should wrap after depleting the matches | `true` |
### `[editor.whitespace]` Section ### `[editor.whitespace]` Section
Options for rendering whitespace with visible characters. Use `:set whitespace.render all` to temporarily enable visible whitespace. Options for rendering whitespace with visible characters. Use
`:set whitespace.render all` to temporarily enable visible whitespace.
| Key | Description | Default | | Key | Description | Default |
|-----|-------------|---------| | ------------ | ------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| `render` | Whether to render whitespace. May either be `"all"` or `"none"`, or a table with sub-keys `space`, `tab`, and `newline`. | `"none"` | | `render` | Whether to render whitespace. May either be `"all"` or `"none"`, or a table with sub-keys `space`, `tab`, and `newline`. | `"none"` |
| `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `newline` or `tabpad` | See example below | | `characters` | Literal characters to use when rendering whitespace. Sub-keys may be any of `tab`, `space`, `nbsp`, `newline` or `tabpad` | See example below |
Example Example
@ -243,7 +248,7 @@ tabpad = "·" # Tabs will look like "→···" (depending on tab width)
Options for rendering vertical indent guides. Options for rendering vertical indent guides.
| Key | Description | Default | | Key | Description | Default |
| --- | --- | --- | | ------------- | ------------------------------------------------------- | ------- |
| `render` | Whether to render indent guides. | `false` | | `render` | Whether to render indent guides. | `false` |
| `character` | Literal character to use for rendering the indent guide | `│` | | `character` | Literal character to use for rendering the indent guide | `│` |
| `skip-levels` | Number of indent levels to skip | `0` | | `skip-levels` | Number of indent levels to skip | `0` |

@ -1,171 +1,222 @@
# Installation # Installing Helix
We provide pre-built binaries on the [GitHub Releases page](https://github.com/helix-editor/helix/releases). <!--toc:start-->
[![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg)](https://repology.org/project/helix/versions) - [Installing Helix](#installing-helix)
- [Using the Pre-built Binaries](#using-the-pre-built-binaries)
## OSX - [Installing Helix on Linux through the Official Package Manager](#installing-helix-on-linux-through-the-official-package-manager)
- [Installing Helix on Linux via Third-Party Repositories](#installing-helix-on-linux-via-third-party-repositories)
- [Installing Helix on macOS via Homebrew](#installing-helix-on-macos-via-homebrew)
- [Installing Helix on Windows](#installing-helix-on-windows)
- [Building from Source](#building-from-source)
- [Validating the Installation](#validating-the-installation)
<!--toc:end-->
Helix is available in homebrew-core: To install Helix, follow the instructions specific to your operating system.
Additionally:
``` - To get the latest pre-release version of Helix, you will need to
brew install helix [build from source](#building-from-source).
```
## Linux - To take full advantage of Helix, install the language servers for your
preferred programming languages. Refer to the
[Helix Wiki](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers)
for detailed instructions.
### NixOS ## Using the Pre-built Binaries
A [flake](https://nixos.wiki/wiki/Flakes) containing the package is available in Download pre-built binaries from the
the project root. The flake can also be used to spin up a reproducible development [GitHub Releases page](https://github.com/helix-editor/helix/releases). You will
shell for working on Helix with `nix develop`. need to add the binary to your system's `$PATH` to access it from the command
line.
Flake outputs are cached for each push to master using ## Installing Helix on Linux through the Official Package Manager
[Cachix](https://www.cachix.org/). The flake is configured to
automatically make use of this cache assuming the user accepts
the new settings on first use.
If you are using a version of Nix without flakes enabled you can If your Linux distribution has Helix available through its official package
[install Cachix cli](https://docs.cachix.org/installation); `cachix use helix` will manager, install it through that. The following list shows availability
configure Nix to use cached outputs when possible. throughout the Linux ecosystem:
### Arch Linux [![Packaging status](https://repology.org/badge/vertical-allrepos/helix.svg)](https://repology.org/project/helix/versions)
Releases are available in the `community` repository. ## Installing Helix on Linux via Third-Party Repositories
A [helix-git](https://aur.archlinux.org/packages/helix-git/) package is also available on the AUR, which builds the master branch. If Helix is not available through your distribution's official repository, use a
third-party repository.
### Fedora Linux - Ubuntu
You can install the COPR package for Helix via Helix is available for 20.04 LTS (Focal Fossa) and 22.04 Ubuntu 22.04 LTS (Jammy
Jellyfish) via
[Maveonair's PPA](https://launchpad.net/~maveonair/+archive/ubuntu/helix-editor):
```sh
sudo add-apt-repository ppa:maveonair/helix-editor
sudo apt update
sudo apt install helix
``` ```
- Fedora/RHEL Linux
Helix is available via `copr`:
```sh
sudo dnf copr enable varlad/helix sudo dnf copr enable varlad/helix
sudo dnf install helix sudo dnf install helix
``` ```
### Void Linux - Arch Linux Community
``` Releases are available in the community repository. Additionally, a
sudo xbps-install helix [helix-git](https://aur.archlinux.org/packages/helix-git/) package is available
in the AUR, which builds the master branch.
- NixOS
Helix is available as a [flake](https://nixos.wiki/wiki/Flakes) in the project
root. Use `nix develop` to spin up a reproducible development shell. Outputs are
cached for each push to master using [Cachix](https://www.cachix.org/). The
flake is configured to automatically make use of this cache assuming the user
accepts the new settings on first use.
If you are using a version of Nix without flakes enabled,
[install Cachix CLI](https://docs.cachix.org/installation) and use
`cachix use helix` to configure Nix to use cached outputs when possible.
## Installing Helix on macOS via Homebrew
Helix is available in Homebrew Core:
```sh
brew install helix
``` ```
## Windows ## Installing Helix on Windows
Helix can be installed using [Scoop](https://scoop.sh/), [Chocolatey](https://chocolatey.org/) Install on Windows using [Scoop](https://scoop.sh/),
or [MSYS2](https://msys2.org/). [Chocolatey](https://chocolatey.org/) or [MSYS2](https://msys2.org/).
**Scoop:** **Scoop:**
``` ```sh
scoop install helix scoop install helix
``` ```
**Chocolatey:** **Chocolatey:**
``` ```sh
choco install helix choco install helix
``` ```
**MSYS2:** **MSYS2:**
Choose the proper command for your system from below: For 64-bit Windows 8.1 or above:
- For 32 bit Windows 7 or above:
``` ```sh
pacman -S mingw-w64-i686-helix pacman -S mingw-w64-ucrt-x86_64-helix
``` ```
- For 64 bit Windows 7 or above: ## Building from Source
``` 1. Clone the repository:
pacman -S mingw-w64-x86_64-helix
```
- For 64 bit Windows 8.1 or above:
``` ```sh
pacman -S mingw-w64-ucrt-x86_64-helix git clone https://github.com/helix-editor/helix
cd helix
``` ```
## Build from source 2. Compile Helix:
``` ```sh
git clone https://github.com/helix-editor/helix
cd helix
cargo install --path helix-term --locked cargo install --path helix-term --locked
``` ```
This will install the `hx` binary to `$HOME/.cargo/bin` and build tree-sitter grammars in `./runtime/grammars`. This command will create the `hx` executable and construct the tree-sitter
grammars in the `runtime` folder, or in the folder specified in `HELIX_RUNTIME`
(as described below).
Helix also needs its runtime files so make sure to copy/symlink the `runtime/` directory into the 3. Configure Helix's runtime files
config directory (for example `~/.config/helix/runtime` on Linux/macOS). This location can be overridden
via the `HELIX_RUNTIME` environment variable.
| OS | Command | **IMPORTANT**: The runtime files must be accessible to the newly created binary.
| -------------------- | ------------------------------------------------ | They are currently located in the source code `runtime` directory. To make them
| Windows (Cmd) | `xcopy /e /i runtime %AppData%\helix\runtime` | accessible, you must follow the instructions for your operating system:
| Windows (PowerShell) | `xcopy /e /i runtime $Env:AppData\helix\runtime` |
| Linux / macOS | `ln -s $PWD/runtime ~/.config/helix/runtime` |
Starting with Windows Vista you can also create symbolic links on Windows. Note that this requires > 💡 Tree-sitter grammars can be fetched and compiled if not pre-packaged. Fetch
elevated privileges - i.e. PowerShell or Cmd must be run as administrator. > grammars with `hx --grammar fetch` (requires `git`) and compile them with
> `hx --grammar build` (requires a C++ compiler).
**PowerShell:** - Linux and macOS
```powershell Either,
New-Item -ItemType SymbolicLink -Target "runtime" -Path "$Env:AppData\helix\runtime"
```
**Cmd:** 1. Set the `HELIX_RUNTIME` environmental variable on your system to tell Helix
where to find the runtime files.
```cmd Use the `HELIX_RUNTIME=/path/to/helix/runtime` format, for example:
cd %appdata%\helix `HELIX_RUNTIME=/home/user-name/src/helix/runtime`. Add this variable to your
mklink /D runtime "<helix-repo>\runtime" `~/.bashrc` file or equivalent to persist it.
```
The runtime location can be overridden via the `HELIX_RUNTIME` environment variable. Or,
> NOTE: if `HELIX_RUNTIME` is set prior to calling `cargo install --path helix-term --locked`, 2. Create a symlink in `~/.config/helix/` that links to the source code
> tree-sitter grammars will be built in `$HELIX_RUNTIME/grammars`. directory.
If you plan on keeping the repo locally, an alternative to copying/symlinking `ln -s $PWD/runtime ~/.config/helix/runtime`
runtime files is to set `HELIX_RUNTIME=/path/to/helix/runtime`
(`HELIX_RUNTIME=$PWD/runtime` if you're in the helix repo directory).
To use Helix in desktop environments that supports [XDG desktop menu](https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html), including Gnome and KDE, copy the provided `.desktop` file to the correct folder: And optionally:
```bash 3. Configure the Desktop Shortcut
If your desktop environment supports the
[XDG desktop menu](https://specifications.freedesktop.org/menu-spec/menu-spec-latest.html),
you can configure Helix to show up in the application menu by copying the
provided `.desktop` and icon files to their correct folders:
```sh
cp contrib/Helix.desktop ~/.local/share/applications cp contrib/Helix.desktop ~/.local/share/applications
cp contrib/helix.png ~/.local/share/icons
``` ```
To use another terminal than the default, you will need to modify the `.desktop` file. For example, to use `kitty`: To use another terminal than the system default, you can modify the `.desktop`
file. For example, to use `kitty`:
```bash ```sh
sed -i "s|Exec=hx %F|Exec=kitty hx %F|g" ~/.local/share/applications/Helix.desktop sed -i "s|Exec=hx %F|Exec=kitty hx %F|g" ~/.local/share/applications/Helix.desktop
sed -i "s|Terminal=true|Terminal=false|g" ~/.local/share/applications/Helix.desktop sed -i "s|Terminal=true|Terminal=false|g" ~/.local/share/applications/Helix.desktop
``` ```
Please note: there is no icon for Helix yet, so the system default will be used. - Windows
## Finishing up the installation > TODO Add correct file paths after feedback
To make sure everything is set up as expected you should finally run the helix healthcheck via Either,
``` 1. Set the `HELIX_RUNTIME` environmental variable on your system to tell Helix
hx --health where to find the runtime files.
```
Use the `???` format, for example: `???`. Add this variable to your `???`
file or equivalent to persist it.
For more information on the information displayed in the health check results refer to [Healthcheck](https://github.com/helix-editor/helix/wiki/Healthcheck). Or,
### Building tree-sitter grammars 2. Create a symlink in `???` that links to the source code directory.
Tree-sitter grammars must be fetched and compiled if not pre-packaged. | Method | Command |
Fetch grammars with `hx --grammar fetch` (requires `git`) and compile them | ---------- | -------------------------------------------------------------------------------------- |
with `hx --grammar build` (requires a C++ compiler). | PowerShell | `New-Item -ItemType SymbolicLink -Target "runtime" -Path "$Env:AppData\helix\runtime"` |
| Cmd | `cd %appdata%\helix` |
| | `mklink /D runtime "<helix-repo>\runtime"` |
### Installing language servers > 💡 On Windows, creating a symbolic link may require running PowerShell or Cmd
> as an administrator.
## Validating the Installation
To make sure everything is set up as expected you should run the Helix health
check:
```sh
hx --health
```
Language servers can optionally be installed if you want their features (auto-complete, diagnostics etc.). For more information on the health check results refer to
Follow the [instructions on the wiki page](https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers) to add your language servers of choice. [Health check](https://github.com/helix-editor/helix/wiki/Healthcheck).

@ -21,46 +21,46 @@
> 💡 Mappings marked (**LSP**) require an active language server for the file. > 💡 Mappings marked (**LSP**) require an active language server for the file.
> 💡 Mappings marked (**TS**) require a tree-sitter grammar for the filetype. > 💡 Mappings marked (**TS**) require a tree-sitter grammar for the file type.
## Normal mode ## Normal mode
### Movement ### Movement
> NOTE: Unlike Vim, `f`, `F`, `t` and `T` are not confined to the current line. > 💡 Unlike Vim, `f`, `F`, `t` and `T` are not confined to the current line.
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | -------------------- | ------------------------------------------- | --------------------------- |
| `h`, `Left` | Move left | `move_char_left` | | `h`, `Left` | Move left | `move_char_left` |
| `j`, `Down` | Move down | `move_line_down` | | `j`, `Down` | Move down | `move_line_down` |
| `k`, `Up` | Move up | `move_line_up` | | `k`, `Up` | Move up | `move_line_up` |
| `l`, `Right` | Move right | `move_char_right` | | `l`, `Right` | Move right | `move_char_right` |
| `w` | Move next word start | `move_next_word_start` | | `w` | Move next word start | `move_next_word_start` |
| `b` | Move previous word start | `move_prev_word_start` | | `b` | Move previous word start | `move_prev_word_start` |
| `e` | Move next word end | `move_next_word_end` | | `e` | Move next word end | `move_next_word_end` |
| `W` | Move next WORD start | `move_next_long_word_start` | | `W` | Move next WORD start | `move_next_long_word_start` |
| `B` | Move previous WORD start | `move_prev_long_word_start` | | `B` | Move previous WORD start | `move_prev_long_word_start` |
| `E` | Move next WORD end | `move_next_long_word_end` | | `E` | Move next WORD end | `move_next_long_word_end` |
| `t` | Find 'till next char | `find_till_char` | | `t` | Find 'till next char | `find_till_char` |
| `f` | Find next char | `find_next_char` | | `f` | Find next char | `find_next_char` |
| `T` | Find 'till previous char | `till_prev_char` | | `T` | Find 'till previous char | `till_prev_char` |
| `F` | Find previous char | `find_prev_char` | | `F` | Find previous char | `find_prev_char` |
| `G` | Go to line number `<n>` | `goto_line` | | `G` | Go to line number `<n>` | `goto_line` |
| `Alt-.` | Repeat last motion (`f`, `t` or `m`) | `repeat_last_motion` | | `Alt-.` | Repeat last motion (`f`, `t` or `m`) | `repeat_last_motion` |
| `Home` | Move to the start of the line | `goto_line_start` | | `Home` | Move to the start of the line | `goto_line_start` |
| `End` | Move to the end of the line | `goto_line_end` | | `End` | Move to the end of the line | `goto_line_end` |
| `Ctrl-b`, `PageUp` | Move page up | `page_up` | | `Ctrl-b`, `PageUp` | Move page up | `page_up` |
| `Ctrl-f`, `PageDown` | Move page down | `page_down` | | `Ctrl-f`, `PageDown` | Move page down | `page_down` |
| `Ctrl-u` | Move half page up | `half_page_up` | | `Ctrl-u` | Move half page up | `half_page_up` |
| `Ctrl-d` | Move half page down | `half_page_down` | | `Ctrl-d` | Move half page down | `half_page_down` |
| `Ctrl-i` | Jump forward on the jumplist | `jump_forward` | | `Ctrl-i` | Jump forward on the jump list | `jump_forward` |
| `Ctrl-o` | Jump backward on the jumplist | `jump_backward` | | `Ctrl-o` | Jump backward on the jump list | `jump_backward` |
| `Ctrl-s` | Save the current selection to the jumplist | `save_selection` | | `Ctrl-s` | Save the current selection to the jump list | `save_selection` |
### Changes ### Changes
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | ----------- | -------------------------------------------------------------------- | ------------------------- |
| `r` | Replace with a character | `replace` | | `r` | Replace with a character | `replace` |
| `R` | Replace with yanked text | `replace_with_yanked` | | `R` | Replace with yanked text | `replace_with_yanked` |
| `~` | Switch case of the selected text | `switch_case` | | `~` | Switch case of the selected text | `switch_case` |
@ -82,7 +82,7 @@
| `P` | Paste before selection | `paste_before` | | `P` | Paste before selection | `paste_before` |
| `"` `<reg>` | Select a register to yank to or paste from | `select_register` | | `"` `<reg>` | Select a register to yank to or paste from | `select_register` |
| `>` | Indent selection | `indent` | | `>` | Indent selection | `indent` |
| `<` | Unindent selection | `unindent` | | `<` | Remove indentation from the selection | `unindent` |
| `=` | Format selection (currently nonfunctional/disabled) (**LSP**) | `format_selections` | | `=` | Format selection (currently nonfunctional/disabled) (**LSP**) | `format_selections` |
| `d` | Delete selection | `delete_selection` | | `d` | Delete selection | `delete_selection` |
| `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` | | `Alt-d` | Delete selection, without yanking | `delete_selection_noyank` |
@ -95,68 +95,69 @@
#### Shell #### Shell
| Key | Description | Command | | Key | Description | Command |
| ------ | ----------- | ------- | | ----------------------- | -------------------------------------------------------------------------------- | --------------------- |
| <code>&#124;</code> | Pipe each selection through shell command, replacing with output | `shell_pipe` | | <code>&#124;</code> | Pipe each selection through shell command, replacing with output | `shell_pipe` |
| <code>Alt-&#124;</code> | Pipe each selection into shell command, ignoring output | `shell_pipe_to` | | <code>Alt-&#124;</code> | Pipe each selection into shell command, ignoring output | `shell_pipe_to` |
| `!` | Run shell command, inserting output before each selection | `shell_insert_output` | | `!` | Run shell command, inserting output before each selection | `shell_insert_output` |
| `Alt-!` | Run shell command, appending output after each selection | `shell_append_output` | | `Alt-!` | Run shell command, appending output after each selection | `shell_append_output` |
| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` | | `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` |
### Selection manipulation ### Selection manipulation
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | -------------------- | ------------------------------------------------------------- | ------------------------------------ |
| `s` | Select all regex matches inside selections | `select_regex` | | `s` | Select all regex matches inside selections | `select_regex` |
| `S` | Split selection into subselections on regex matches | `split_selection` | | `S` | Split selection into sub selections on regex matches | `split_selection` |
| `Alt-s` | Split selection on newlines | `split_selection_on_newline` | | `Alt-s` | Split selection on newlines | `split_selection_on_newline` |
| `Alt-_ ` | Merge consecutive selections | `merge_consecutive_selections` | | `Alt-_ ` | Merge consecutive selections | `merge_consecutive_selections` |
| `&` | Align selection in columns | `align_selections` | | `&` | Align selection in columns | `align_selections` |
| `_` | Trim whitespace from the selection | `trim_selections` | | `_` | Trim whitespace from the selection | `trim_selections` |
| `;` | Collapse selection onto a single cursor | `collapse_selection` | | `;` | Collapse selection onto a single cursor | `collapse_selection` |
| `Alt-;` | Flip selection cursor and anchor | `flip_selections` | | `Alt-;` | Flip selection cursor and anchor | `flip_selections` |
| `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` | | `Alt-:` | Ensures the selection is in forward direction | `ensure_selections_forward` |
| `,` | Keep only the primary selection | `keep_primary_selection` | | `,` | Keep only the primary selection | `keep_primary_selection` |
| `Alt-,` | Remove the primary selection | `remove_primary_selection` | | `Alt-,` | Remove the primary selection | `remove_primary_selection` |
| `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` | | `C` | Copy selection onto the next line (Add cursor below) | `copy_selection_on_next_line` |
| `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` | | `Alt-C` | Copy selection onto the previous line (Add cursor above) | `copy_selection_on_prev_line` |
| `(` | Rotate main selection backward | `rotate_selections_backward` | | `(` | Rotate main selection backward | `rotate_selections_backward` |
| `)` | Rotate main selection forward | `rotate_selections_forward` | | `)` | Rotate main selection forward | `rotate_selections_forward` |
| `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` | | `Alt-(` | Rotate selection contents backward | `rotate_selection_contents_backward` |
| `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` | | `Alt-)` | Rotate selection contents forward | `rotate_selection_contents_forward` |
| `%` | Select entire file | `select_all` | | `%` | Select entire file | `select_all` |
| `x` | Select current line, if already selected, extend to next line | `extend_line_below` | | `x` | Select current line, if already selected, extend to next line | `extend_line_below` |
| `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` | | `X` | Extend selection to line bounds (line-wise selection) | `extend_to_line_bounds` |
| `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` | | `Alt-x` | Shrink selection to line bounds (line-wise selection) | `shrink_to_line_bounds` |
| `J` | Join lines inside selection | `join_selections` | | `J` | Join lines inside selection | `join_selections` |
| `Alt-J` | Join lines inside selection and select space | `join_selections_space` | | `Alt-J` | Join lines inside selection and select space | `join_selections_space` |
| `K` | Keep selections matching the regex | `keep_selections` | | `K` | Keep selections matching the regex | `keep_selections` |
| `Alt-K` | Remove selections matching the regex | `remove_selections` | | `Alt-K` | Remove selections matching the regex | `remove_selections` |
| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` | | `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` |
| `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` | | `Alt-o`, `Alt-up` | Expand selection to parent syntax node (**TS**) | `expand_selection` |
| `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` | | `Alt-i`, `Alt-down` | Shrink syntax tree object selection (**TS**) | `shrink_selection` |
| `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` | | `Alt-p`, `Alt-left` | Select previous sibling node in syntax tree (**TS**) | `select_prev_sibling` |
| `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` | | `Alt-n`, `Alt-right` | Select next sibling node in syntax tree (**TS**) | `select_next_sibling` |
### Search ### Search
Search commands all operate on the `/` register by default. Use `"<char>` to operate on a different one. Search commands operate on the `/` register by default. To use a different
register, use `"<char>.`
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | --- | ------------------------------------------- | ------------------ |
| `/` | Search for regex pattern | `search` | | `/` | Search for regex pattern | `search` |
| `?` | Search for previous pattern | `rsearch` | | `?` | Search for previous pattern | `rsearch` |
| `n` | Select next search match | `search_next` | | `n` | Select next search match | `search_next` |
| `N` | Select previous search match | `search_prev` | | `N` | Select previous search match | `search_prev` |
| `*` | Use current selection as the search pattern | `search_selection` | | `*` | Use current selection as the search pattern | `search_selection` |
### Minor modes ### Minor modes
These sub-modes are accessible from normal mode and typically switch back to normal mode after a command. Minor modes are accessible from normal mode and typically switch back to normal
mode after a command.
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | -------- | -------------------------------------------------- | -------------- |
| `v` | Enter [select (extend) mode](#select--extend-mode) | `select_mode` | | `v` | Enter [select (extend) mode](#select--extend-mode) | `select_mode` |
| `g` | Enter [goto mode](#goto-mode) | N/A | | `g` | Enter [goto mode](#goto-mode) | N/A |
| `m` | Enter [match mode](#match-mode) | N/A | | `m` | Enter [match mode](#match-mode) | N/A |
@ -168,17 +169,14 @@ These sub-modes are accessible from normal mode and typically switch back to nor
#### View mode #### View mode
Accessed by typing `z` in [normal mode](#normal-mode). View mode is accessed by typing `z` in [normal mode](#normal-mode) and is
intended for scrolling and manipulating the view without changing the selection.
View mode is intended for scrolling and manipulating the view without changing The "sticky" variant of this mode (accessed by typing `Z` in normal mode) is
the selection. The "sticky" variant of this mode (accessed by typing `Z` in persistent and can be exited using the escape key. This is useful when you're
normal mode) is persistent; use the Escape key to return to normal mode after simply looking over text and not actively editing it.
usage (useful when you're simply looking over text and not actively editing
it).
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | -------------------- | --------------------------------------------------------- | ------------------- |
| `z`, `c` | Vertically center the line | `align_view_center` | | `z`, `c` | Vertically center the line | `align_view_center` |
| `t` | Align the line to the top of the screen | `align_view_top` | | `t` | Align the line to the top of the screen | `align_view_top` |
| `b` | Align the line to the bottom of the screen | `align_view_bottom` | | `b` | Align the line to the bottom of the screen | `align_view_bottom` |
@ -192,57 +190,55 @@ it).
#### Goto mode #### Goto mode
Accessed by typing `g` in [normal mode](#normal-mode). Goto mode is accessed by typing `g` in [normal mode](#normal-mode), it jumps to
various locations.
Jumps to various locations.
| Key | Description | Command |
| Key | Description | Command | | --- | ------------------------------------------------ | -------------------------- |
| ----- | ----------- | ------- | | `g` | Go to line number `<n>` else start of file | `goto_file_start` |
| `g` | Go to line number `<n>` else start of file | `goto_file_start` | | `e` | Go to the end of the file | `goto_last_line` |
| `e` | Go to the end of the file | `goto_last_line` | | `f` | Go to files in the selection | `goto_file` |
| `f` | Go to files in the selection | `goto_file` | | `h` | Go to the start of the line | `goto_line_start` |
| `h` | Go to the start of the line | `goto_line_start` | | `l` | Go to the end of the line | `goto_line_end` |
| `l` | Go to the end of the line | `goto_line_end` | | `s` | Go to first non-whitespace character of the line | `goto_first_nonwhitespace` |
| `s` | Go to first non-whitespace character of the line | `goto_first_nonwhitespace` | | `t` | Go to the top of the screen | `goto_window_top` |
| `t` | Go to the top of the screen | `goto_window_top` | | `c` | Go to the middle of the screen | `goto_window_center` |
| `c` | Go to the middle of the screen | `goto_window_center` | | `b` | Go to the bottom of the screen | `goto_window_bottom` |
| `b` | Go to the bottom of the screen | `goto_window_bottom` | | `d` | Go to definition (**LSP**) | `goto_definition` |
| `d` | Go to definition (**LSP**) | `goto_definition` | | `y` | Go to type definition (**LSP**) | `goto_type_definition` |
| `y` | Go to type definition (**LSP**) | `goto_type_definition` | | `r` | Go to references (**LSP**) | `goto_reference` |
| `r` | Go to references (**LSP**) | `goto_reference` | | `i` | Go to implementation (**LSP**) | `goto_implementation` |
| `i` | Go to implementation (**LSP**) | `goto_implementation` | | `a` | Go to the last accessed/alternate file | `goto_last_accessed_file` |
| `a` | Go to the last accessed/alternate file | `goto_last_accessed_file` | | `m` | Go to the last modified/alternate file | `goto_last_modified_file` |
| `m` | Go to the last modified/alternate file | `goto_last_modified_file` | | `n` | Go to next buffer | `goto_next_buffer` |
| `n` | Go to next buffer | `goto_next_buffer` | | `p` | Go to previous buffer | `goto_previous_buffer` |
| `p` | Go to previous buffer | `goto_previous_buffer` | | `.` | Go to last modification in current file | `goto_last_modification` |
| `.` | Go to last modification in current file | `goto_last_modification` |
#### Match mode #### Match mode
Accessed by typing `m` in [normal mode](#normal-mode). Match mode is accessed by typing `m` in [normal mode](#normal-mode).
See the relevant section in [Usage](./usage.md) for an explanation about See the relevant section in [Usage](./usage.md) for an explanation about
[surround](./usage.md#surround) and [textobject](./usage.md#textobjects) usage. [surround](./usage.md#surround) and [text object](./usage.md#textobjects) usage.
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | ---------------- | ----------------------------------------------- | -------------------------- |
| `m` | Goto matching bracket (**TS**) | `match_brackets` | | `m` | Goto matching bracket (**TS**) | `match_brackets` |
| `s` `<char>` | Surround current selection with `<char>` | `surround_add` | | `s` `<char>` | Surround current selection with `<char>` | `surround_add` |
| `r` `<from><to>` | Replace surround character `<from>` with `<to>` | `surround_replace` | | `r` `<from><to>` | Replace surround character `<from>` with `<to>` | `surround_replace` |
| `d` `<char>` | Delete surround character `<char>` | `surround_delete` | | `d` `<char>` | Delete surround character `<char>` | `surround_delete` |
| `a` `<object>` | Select around textobject | `select_textobject_around` | | `a` `<object>` | Select around text object | `select_textobject_around` |
| `i` `<object>` | Select inside textobject | `select_textobject_inner` | | `i` `<object>` | Select inside text object | `select_textobject_inner` |
TODO: Mappings for selecting syntax nodes (a superset of `[`). TODO: Mappings for selecting syntax nodes (a superset of `[`).
#### Window mode #### Window mode
Accessed by typing `Ctrl-w` in [normal mode](#normal-mode). Window mode is accessed by typing `Ctrl-w` in [normal mode](#normal-mode), this
layer is similar to Vim keybindings as Kakoune does not support window.
This layer is similar to Vim keybindings as Kakoune does not support window.
| Key | Description | Command | | Key | Description | Command |
| ----- | ------------- | ------- | | ---------------------- | ---------------------------------------------------- | ----------------- |
| `w`, `Ctrl-w` | Switch to next window | `rotate_view` | | `w`, `Ctrl-w` | Switch to next window | `rotate_view` |
| `v`, `Ctrl-v` | Vertical right split | `vsplit` | | `v`, `Ctrl-v` | Vertical right split | `vsplit` |
| `s`, `Ctrl-s` | Horizontal bottom split | `hsplit` | | `s`, `Ctrl-s` | Horizontal bottom split | `hsplit` |
@ -261,50 +257,53 @@ This layer is similar to Vim keybindings as Kakoune does not support window.
#### Space mode #### Space mode
Accessed by typing `Space` in [normal mode](#normal-mode). Space mode is accessed by typing `Space` in [normal mode](#normal-mode).
This layer is a kludge of mappings, mostly pickers. This layer is a kludge of mappings, mostly pickers.
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | --- | ----------------------------------------------------------------------- | ----------------------------------- |
| `f` | Open file picker | `file_picker` | | `f` | Open file picker | `file_picker` |
| `F` | Open file picker at current working directory | `file_picker_in_current_directory` | | `F` | Open file picker at current working directory | `file_picker_in_current_directory` |
| `b` | Open buffer picker | `buffer_picker` | | `b` | Open buffer picker | `buffer_picker` |
| `j` | Open jumplist picker | `jumplist_picker` | | `j` | Open jump list picker | `jumplist_picker` |
| `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` | | `k` | Show documentation for item under cursor in a [popup](#popup) (**LSP**) | `hover` |
| `s` | Open document symbol picker (**LSP**) | `symbol_picker` | | `s` | Open document symbol picker (**LSP**) | `symbol_picker` |
| `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` | | `S` | Open workspace symbol picker (**LSP**) | `workspace_symbol_picker` |
| `d` | Open document diagnostics picker (**LSP**) | `diagnostics_picker` | | `d` | Open document diagnostics picker (**LSP**) | `diagnostics_picker` |
| `D` | Open workspace diagnostics picker (**LSP**) | `workspace_diagnostics_picker` | | `D` | Open workspace diagnostics picker (**LSP**) | `workspace_diagnostics_picker` |
| `r` | Rename symbol (**LSP**) | `rename_symbol` | | `r` | Rename symbol (**LSP**) | `rename_symbol` |
| `a` | Apply code action (**LSP**) | `code_action` | | `a` | Apply code action (**LSP**) | `code_action` |
| `'` | Open last fuzzy picker | `last_picker` | | `'` | Open last fuzzy picker | `last_picker` |
| `w` | Enter [window mode](#window-mode) | N/A | | `w` | Enter [window mode](#window-mode) | N/A |
| `p` | Paste system clipboard after selections | `paste_clipboard_after` | | `p` | Paste system clipboard after selections | `paste_clipboard_after` |
| `P` | Paste system clipboard before selections | `paste_clipboard_before` | | `P` | Paste system clipboard before selections | `paste_clipboard_before` |
| `y` | Join and yank selections to clipboard | `yank_joined_to_clipboard` | | `y` | Join and yank selections to clipboard | `yank_joined_to_clipboard` |
| `Y` | Yank main selection to clipboard | `yank_main_selection_to_clipboard` | | `Y` | Yank main selection to clipboard | `yank_main_selection_to_clipboard` |
| `R` | Replace selections by clipboard contents | `replace_selections_with_clipboard` | | `R` | Replace selections by clipboard contents | `replace_selections_with_clipboard` |
| `/` | Global search in workspace folder | `global_search` | | `/` | Global search in workspace folder | `global_search` |
| `?` | Open command palette | `command_palette` | | `?` | Open command palette | `command_palette` |
> TIP: Global search displays results in a fuzzy picker, use `Space + '` to bring it back up after opening a file. > 💡 Global search displays results in a fuzzy picker, use `Space + '` to bring
> it back up after opening a file.
##### Popup ##### Popup
Displays documentation for item under cursor. Popups display documentation for items under the cursor. If there is more
content than fits on the screen, you can use scroll:
| Key | Description | | Key | Description |
| ---- | ----------- | | -------- | ----------- |
| `Ctrl-u` | Scroll up | | `Ctrl-u` | Scroll up |
| `Ctrl-d` | Scroll down | | `Ctrl-d` | Scroll down |
#### Unimpaired #### Unimpaired
Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaired). These mappings are in the style of
[vim-unimpaired](https://github.com/tpope/vim-unimpaired).
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | -------- | -------------------------------------------- | --------------------- |
| `[d` | Go to previous diagnostic (**LSP**) | `goto_prev_diag` | | `[d` | Go to previous diagnostic (**LSP**) | `goto_prev_diag` |
| `]d` | Go to next diagnostic (**LSP**) | `goto_next_diag` | | `]d` | Go to next diagnostic (**LSP**) | `goto_next_diag` |
| `[D` | Go to first diagnostic in document (**LSP**) | `goto_first_diag` | | `[D` | Go to first diagnostic in document (**LSP**) | `goto_first_diag` |
@ -330,43 +329,44 @@ Mappings in the style of [vim-unimpaired](https://github.com/tpope/vim-unimpaire
## Insert mode ## Insert mode
Insert mode bindings are somewhat minimal by default. Helix is designed to Insert mode bindings are minimal by default. Helix is designed to be a modal
be a modal editor, and this is reflected in the user experience and internal editor, and this is reflected in the user experience and internal mechanics.
mechanics. For example, changes to the text are only saved for undos when Changes to the text are only saved for undos when escaping from insert mode to
escaping from insert mode to normal mode. For this reason, new users are normal mode.
strongly encouraged to learn the modal editing paradigm to get the smoothest
experience. > 💡 New users are strongly encouraged to learn the modal editing paradigm to
> get the smoothest experience.
| Key | Description | Command |
| ----- | ----------- | ------- | | Key | Description | Command |
| `Escape` | Switch to normal mode | `normal_mode` | | ------------------------- | ------------------------- | ------------------------ |
| `Ctrl-s` | Commit undo checkpoint | `commit_undo_checkpoint` | | `Escape` | Switch to normal mode | `normal_mode` |
| `Ctrl-x` | Autocomplete | `completion` | | `Ctrl-s` | Commit undo checkpoint | `commit_undo_checkpoint` |
| `Ctrl-r` | Insert a register content | `insert_register` | | `Ctrl-x` | Autocomplete | `completion` |
| `Ctrl-w`, `Alt-Backspace` | Delete previous word | `delete_word_backward` | | `Ctrl-r` | Insert a register content | `insert_register` |
| `Alt-d`, `Alt-Delete` | Delete next word | `delete_word_forward` | | `Ctrl-w`, `Alt-Backspace` | Delete previous word | `delete_word_backward` |
| `Ctrl-u` | Delete to start of line | `kill_to_line_start` | | `Alt-d`, `Alt-Delete` | Delete next word | `delete_word_forward` |
| `Ctrl-k` | Delete to end of line | `kill_to_line_end` | | `Ctrl-u` | Delete to start of line | `kill_to_line_start` |
| `Ctrl-h`, `Backspace` | Delete previous char | `delete_char_backward` | | `Ctrl-k` | Delete to end of line | `kill_to_line_end` |
| `Ctrl-d`, `Delete` | Delete next char | `delete_char_forward` | | `Ctrl-h`, `Backspace` | Delete previous char | `delete_char_backward` |
| `Ctrl-j`, `Enter` | Insert new line | `insert_newline` | | `Ctrl-d`, `Delete` | Delete next char | `delete_char_forward` |
| `Ctrl-j`, `Enter` | Insert new line | `insert_newline` |
These keys are not recommended, but are included for new users less familiar These keys are not recommended, but are included for new users less familiar
with modal editors. with modal editors.
| Key | Description | Command | | Key | Description | Command |
| ----- | ----------- | ------- | | ---------- | --------------------- | ----------------------- |
| `Up` | Move to previous line | `move_line_up` | | `Up` | Move to previous line | `move_line_up` |
| `Down` | Move to next line | `move_line_down` | | `Down` | Move to next line | `move_line_down` |
| `Left` | Backward a char | `move_char_left` | | `Left` | Backward a char | `move_char_left` |
| `Right` | Forward a char | `move_char_right` | | `Right` | Forward a char | `move_char_right` |
| `PageUp` | Move one page up | `page_up` | | `PageUp` | Move one page up | `page_up` |
| `PageDown` | Move one page down | `page_down` | | `PageDown` | Move one page down | `page_down` |
| `Home` | Move to line start | `goto_line_start` | | `Home` | Move to line start | `goto_line_start` |
| `End` | Move to line end | `goto_line_end_newline` | | `End` | Move to line end | `goto_line_end_newline` |
If you want to disable them in insert mode as you become more comfortable with modal editing, you can use As you become more comfortable with modal editing, you may want to disable some
the following in your `config.toml`: insert mode bindings. You can do this by editing your `config.toml` file.
```toml ```toml
[keys.insert] [keys.insert]
@ -382,58 +382,57 @@ end = "no_op"
## Select / extend mode ## Select / extend mode
This mode echoes Normal mode, but changes any movements to extend Select mode echoes Normal mode, but changes any movements to extend selections
selections rather than replace them. Goto motions are also changed to rather than replace them. Goto motions are also changed to extend, so that `vgl`
extend, so that `vgl` for example extends the selection to the end of for example extends the selection to the end of the line.
the line.
Search is also affected. By default, `n` and `N` will remove the current Search is also affected. By default, `n` and `N` will remove the current
selection and select the next instance of the search term. Toggling this selection and select the next instance of the search term. Toggling this mode
mode before pressing `n` or `N` makes it possible to keep the current before pressing `n` or `N` makes it possible to keep the current selection.
selection. Toggling it on and off during your iterative searching allows Toggling it on and off during your iterative searching allows you to selectively
you to selectively add search terms to your selections. add search terms to your selections.
## Picker ## Picker
Keys to use within picker. Remapping currently not supported. Keys to use within picker. Remapping currently not supported.
| Key | Description | | Key | Description |
| ----- | ------------- | | --------------------------- | ----------------- |
| `Shift-Tab`, `Up`, `Ctrl-p` | Previous entry | | `Shift-Tab`, `Up`, `Ctrl-p` | Previous entry |
| `Tab`, `Down`, `Ctrl-n` | Next entry | | `Tab`, `Down`, `Ctrl-n` | Next entry |
| `PageUp`, `Ctrl-u` | Page up | | `PageUp`, `Ctrl-u` | Page up |
| `PageDown`, `Ctrl-d` | Page down | | `PageDown`, `Ctrl-d` | Page down |
| `Home` | Go to first entry | | `Home` | Go to first entry |
| `End` | Go to last entry | | `End` | Go to last entry |
| `Enter` | Open selected | | `Enter` | Open selected |
| `Ctrl-s` | Open horizontally | | `Ctrl-s` | Open horizontally |
| `Ctrl-v` | Open vertically | | `Ctrl-v` | Open vertically |
| `Ctrl-t` | Toggle preview | | `Ctrl-t` | Toggle preview |
| `Escape`, `Ctrl-c` | Close picker | | `Escape`, `Ctrl-c` | Close picker |
## Prompt ## Prompt
Keys to use within prompt, Remapping currently not supported. Keys to use within prompt, Remapping currently not supported.
| Key | Description | | Key | Description |
| ----- | ------------- | | ------------------------------------------- | --------------------------------------------------------------------- |
| `Escape`, `Ctrl-c` | Close prompt | | `Escape`, `Ctrl-c` | Close prompt |
| `Alt-b`, `Ctrl-Left` | Backward a word | | `Alt-b`, `Ctrl-Left` | Backward a word |
| `Ctrl-b`, `Left` | Backward a char | | `Ctrl-b`, `Left` | Backward a char |
| `Alt-f`, `Ctrl-Right` | Forward a word | | `Alt-f`, `Ctrl-Right` | Forward a word |
| `Ctrl-f`, `Right` | Forward a char | | `Ctrl-f`, `Right` | Forward a char |
| `Ctrl-e`, `End` | Move prompt end | | `Ctrl-e`, `End` | Move prompt end |
| `Ctrl-a`, `Home` | Move prompt start | | `Ctrl-a`, `Home` | Move prompt start |
| `Ctrl-w`, `Alt-Backspace`, `Ctrl-Backspace` | Delete previous word | | `Ctrl-w`, `Alt-Backspace`, `Ctrl-Backspace` | Delete previous word |
| `Alt-d`, `Alt-Delete`, `Ctrl-Delete` | Delete next word | | `Alt-d`, `Alt-Delete`, `Ctrl-Delete` | Delete next word |
| `Ctrl-u` | Delete to start of line | | `Ctrl-u` | Delete to start of line |
| `Ctrl-k` | Delete to end of line | | `Ctrl-k` | Delete to end of line |
| `Backspace`, `Ctrl-h` | Delete previous char | | `Backspace`, `Ctrl-h` | Delete previous char |
| `Delete`, `Ctrl-d` | Delete next char | | `Delete`, `Ctrl-d` | Delete next char |
| `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later | | `Ctrl-s` | Insert a word under doc cursor, may be changed to Ctrl-r Ctrl-w later |
| `Ctrl-p`, `Up` | Select previous history | | `Ctrl-p`, `Up` | Select previous history |
| `Ctrl-n`, `Down` | Select next history | | `Ctrl-n`, `Down` | Select next history |
| `Ctrl-r` | Insert the content of the register selected by following input char | | `Ctrl-r` | Insert the content of the register selected by following input char |
| `Tab` | Select next completion item | | `Tab` | Select next completion item |
| `BackTab` | Select previous completion item | | `BackTab` | Select previous completion item |
| `Enter` | Open selected | | `Enter` | Open selected |

@ -1,16 +1,18 @@
# Language Support # Language Support
The following languages and Language Servers are supported. In order to use The following languages and Language Servers are supported. To use Language
Language Server features, you must first [install][lsp-install-wiki] the Server features, you must first [install][lsp-install-wiki] the appropriate
appropriate Language Server. Language Server.
Check the language support in your installed helix version with `hx --health`. You can check the language support in your installed Helix version with
`hx --health`.
Also see the [Language Configuration][lang-config] docs and the [Adding Also see the [Language Configuration][lang-config] docs and the [Adding
Languages][adding-languages] guide for more language configuration information. Languages][adding-languages] guide for more language configuration information.
{{#include ./generated/lang-support.md}} {{#include ./generated/lang-support.md}}
[lsp-install-wiki]: https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers [lsp-install-wiki]:
https://github.com/helix-editor/helix/wiki/How-to-install-the-default-language-servers
[lang-config]: ./languages.md [lang-config]: ./languages.md
[adding-languages]: ./guides/adding_languages.md [adding-languages]: ./guides/adding_languages.md

@ -1,17 +1,19 @@
# Languages # Languages
Language-specific settings and settings for language servers are configured Language-specific settings and settings for language servers are configured in
in `languages.toml` files. `languages.toml` files.
## `languages.toml` files ## `languages.toml` files
There are three possible `languages.toml` files. The first is compiled into There are three possible locations for a `languages.toml` file:
Helix and lives in the [Helix repository](https://github.com/helix-editor/helix/blob/master/languages.toml).
This provides the default configurations for languages and language servers.
You may define a `languages.toml` in your [configuration directory](./configuration.md) 1. In the Helix source code, this lives in the
which overrides values from the built-in language configuration. For example [Helix repository](https://github.com/helix-editor/helix/blob/master/languages.toml).
to disable auto-LSP-formatting in Rust: It provides the default configurations for languages and language servers.
2. In your [configuration directory](./configuration.md). This overrides values
from the built-in language configuration. For example to disable
auto-LSP-formatting in Rust:
```toml ```toml
# in <config_dir>/helix/languages.toml # in <config_dir>/helix/languages.toml
@ -21,10 +23,10 @@ name = "rust"
auto-format = false auto-format = false
``` ```
Language configuration may also be overridden local to a project by creating 3. In a `.helix` folder in your project. Language configuration may also be
a `languages.toml` file under a `.helix` directory. Its settings will be merged overridden local to a project by creating a `languages.toml` file in a
with the language configuration in the configuration directory and the built-in `.helix` folder. Its settings will be merged with the language configuration
configuration. in the configuration directory and the built-in configuration.
## Language configuration ## Language configuration
@ -45,28 +47,28 @@ formatter = { command = "mylang-formatter" , args = ["--stdin"] }
These configuration keys are available: These configuration keys are available:
| Key | Description | | Key | Description |
| ---- | ----------- | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | The name of the language | | `name` | The name of the language |
| `scope` | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.<name>` or `text.<name>` in case of markup languages | | `scope` | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.<name>` or `text.<name>` in case of markup languages |
| `injection-regex` | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. | | `injection-regex` | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. |
| `file-types` | The filetypes of the language, for example `["yml", "yaml"]`. See the file-type detection section below. | | `file-types` | The filetypes of the language, for example `["yml", "yaml"]`. See the file-type detection section below. |
| `shebangs` | The interpreters from the shebang line, for example `["sh", "bash"]` | | `shebangs` | The interpreters from the shebang line, for example `["sh", "bash"]` |
| `roots` | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` | | `roots` | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` |
| `auto-format` | Whether to autoformat this language when saving | | `auto-format` | Whether to autoformat this language when saving |
| `diagnostic-severity` | Minimal severity of diagnostic for it to be displayed. (Allowed values: `Error`, `Warning`, `Info`, `Hint`) | | `diagnostic-severity` | Minimal severity of diagnostic for it to be displayed. (Allowed values: `Error`, `Warning`, `Info`, `Hint`) |
| `comment-token` | The token to use as a comment-token | | `comment-token` | The token to use as a comment-token |
| `indent` | The indent to use. Has sub keys `tab-width` and `unit` | | `indent` | The indent to use. Has sub keys `tab-width` and `unit` |
| `language-server` | The Language Server to run. See the Language Server configuration section below. | | `language-server` | The Language Server to run. See the Language Server configuration section below. |
| `config` | Language Server configuration | | `config` | Language Server configuration |
| `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) | | `grammar` | The tree-sitter grammar to use (defaults to the value of `name`) |
| `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout | | `formatter` | The formatter for the language, it will take precedence over the lsp when defined. The formatter must be able to take the original file as input from stdin and write the formatted file to stdout |
| `max-line-length` | Maximum line length. Used for the `:reflow` command | | `max-line-length` | Maximum line length. Used for the `:reflow` command |
### File-type detection and the `file-types` key ### File-type detection and the `file-types` key
Helix determines which language configuration to use with the `file-types` key Helix determines which language configuration to use based on the `file-types`
from the above section. `file-types` is a list of strings or tables, for key from the above section. `file-types` is a list of strings or tables, for
example: example:
```toml ```toml
@ -82,27 +84,28 @@ with the following priorities:
2. Extension: if there are no exact matches, any `file-types` string that 2. Extension: if there are no exact matches, any `file-types` string that
matches the file extension of a given file wins. In the example above, the matches the file extension of a given file wins. In the example above, the
`"toml"` matches files like `Cargo.toml` or `languages.toml`. `"toml"` matches files like `Cargo.toml` or `languages.toml`.
3. Suffix: if there are still no matches, any values in `suffix` tables 3. Suffix: if there are still no matches, any values in `suffix` tables are
are checked against the full path of the given file. In the example above, checked against the full path of the given file. In the example above, the
the `{ suffix = ".git/config" }` would match against any `config` files `{ suffix = ".git/config" }` would match against any `config` files in `.git`
in `.git` directories. Note: `/` is used as the directory separator but is directories. Note: `/` is used as the directory separator but is replaced at
replaced at runtime with the appropriate path separator for the operating runtime with the appropriate path separator for the operating system, so this
system, so this rule would match against `.git\config` files on Windows. rule would match against `.git\config` files on Windows.
### Language Server configuration ### Language Server configuration
The `language-server` field takes the following keys: The `language-server` field takes the following keys:
| Key | Description | | Key | Description |
| --- | ----------- | | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `command` | The name of the language server binary to execute. Binaries must be in `$PATH` | | `command` | The name of the language server binary to execute. Binaries must be in `$PATH` |
| `args` | A list of arguments to pass to the language server binary | | `args` | A list of arguments to pass to the language server binary |
| `timeout` | The maximum time a request to the language server may take, in seconds. Defaults to `20` | | `timeout` | The maximum time a request to the language server may take, in seconds. Defaults to `20` |
| `language-id` | The language name to pass to the language server. Some language servers support multiple languages and use this field to determine which one is being served in a buffer | | `language-id` | The language name to pass to the language server. Some language servers support multiple languages and use this field to determine which one is being served in a buffer |
| `environment` | Any environment variables that will be used when starting the language server `{ "KEY1" = "Value1", "KEY2" = "Value2" }` | | `environment` | Any environment variables that will be used when starting the language server `{ "KEY1" = "Value1", "KEY2" = "Value2" }` |
The top-level `config` field is used to configure the LSP initialization options. A `format` The top-level `config` field is used to configure the LSP initialization
sub-table within `config` can be used to pass extra formatting options to options. A `format` sub-table within `config` can be used to pass extra
formatting options to
[Document Formatting Requests](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md#document-formatting-request--leftwards_arrow_with_hook). [Document Formatting Requests](https://github.com/microsoft/language-server-protocol/blob/gh-pages/_specifications/specification-3-16.md#document-formatting-request--leftwards_arrow_with_hook).
For example with typescript: For example with typescript:
@ -128,23 +131,23 @@ source = { git = "https://github.com/example/mylang", rev = "a250c4582510ff34767
Grammar configuration takes these keys: Grammar configuration takes these keys:
| Key | Description | | Key | Description |
| --- | ----------- | | -------- | ------------------------------------------------------------------------ |
| `name` | The name of the tree-sitter grammar | | `name` | The name of the tree-sitter grammar |
| `source` | The method of fetching the grammar - a table with a schema defined below | | `source` | The method of fetching the grammar - a table with a schema defined below |
Where `source` is a table with either these keys when using a grammar from a Where `source` is a table with either these keys when using a grammar from a git
git repository: repository:
| Key | Description | | Key | Description |
| --- | ----------- | | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `git` | A git remote URL from which the grammar should be cloned | | `git` | A git remote URL from which the grammar should be cloned |
| `rev` | The revision (commit hash or tag) which should be fetched | | `rev` | The revision (commit hash or tag) which should be fetched |
| `subpath` | A path within the grammar directory which should be built. Some grammar repositories host multiple grammars (for example `tree-sitter-typescript` and `tree-sitter-ocaml`) in subdirectories. This key is used to point `hx --grammar build` to the correct path for compilation. When omitted, the root of repository is used | | `subpath` | A path within the grammar directory which should be built. Some grammar repositories host multiple grammars (for example `tree-sitter-typescript` and `tree-sitter-ocaml`) in subdirectories. This key is used to point `hx --grammar build` to the correct path for compilation. When omitted, the root of repository is used |
### Choosing grammars ### Choosing grammars
You may use a top-level `use-grammars` key to control which grammars are You may use a top-level `use-grammars` key to control which grammars are fetched
fetched and built when using `hx --grammar fetch` and `hx --grammar build`. and built when using `hx --grammar fetch` and `hx --grammar build`.
```toml ```toml
# Note: this key must come **before** the [[language]] and [[grammar]] sections # Note: this key must come **before** the [[language]] and [[grammar]] sections
@ -155,4 +158,5 @@ use-grammars = { except = [ "yaml", "json" ] }
When omitted, all grammars are fetched and built. When omitted, all grammars are fetched and built.
[treesitter-language-injection]: https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection [treesitter-language-injection]:
https://tree-sitter.github.io/tree-sitter/syntax-highlighting#language-injection

@ -1,35 +1,43 @@
# Key Remapping # Key Remapping
One-way key remapping is temporarily supported via a simple TOML configuration Helix currently supports one-way key remapping through a simple TOML
file. (More powerful solutions such as rebinding via commands will be configuration file. (More powerful solutions such as rebinding via commands will
available in the future). be available in the future).
To remap keys, write a `config.toml` file in your `helix` configuration To remap keys, create a `config.toml` file in your `Helix` configuration
directory (default `~/.config/helix` in Linux systems) with a structure like directory (default `~/.config/helix` on Linux systems) with a structure like
this: this:
```toml ```toml
# At most one section each of 'keys.normal', 'keys.insert' and 'keys.select' # At most one section each of 'keys.normal', 'keys.insert' and 'keys.select'
[keys.normal] [keys.normal]
C-s = ":w" # Maps the Ctrl-s to the typable command :w which is an alias for :write (save file) C-s = ":w" # Maps Ctrl-s to the typable command :w which is an alias for :write (save file)
C-o = ":open ~/.config/helix/config.toml" # Maps the Ctrl-o to opening of the helix config file C-o = ":open ~/.config/helix/config.toml" # Maps Ctrl-o to opening of the helix config file
a = "move_char_left" # Maps the 'a' key to the move_char_left command a = "move_char_left" # Maps the 'a' key to the move_char_left command
w = "move_line_up" # Maps the 'w' key move_line_up w = "move_line_up" # Maps the 'w' key move_line_up
"C-S-esc" = "extend_line" # Maps Ctrl-Shift-Escape to extend_line "C-S-esc" = "extend_line" # Maps Ctrl-Shift-Escape to extend_line
g = { a = "code_action" } # Maps `ga` to show possible code actions g = { a = "code_action" } # Maps `ga` to show possible code actions
"ret" = ["open_below", "normal_mode"] # Maps the enter key to open_below then re-enter normal mode "ret" = [
"open_below",
"normal_mode",
] # Maps the enter key to open_below then re-enter normal mode
[keys.insert] [keys.insert]
"A-x" = "normal_mode" # Maps Alt-X to enter normal mode "A-x" = "normal_mode" # Maps Alt-X to enter normal mode
j = { k = "normal_mode" } # Maps `jk` to exit insert mode j = { k = "normal_mode" } # Maps `jk` to exit insert mode
``` ```
> NOTE: Typable commands can also be remapped, remember to keep the `:` prefix to indicate it's a typable command.
Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes > NOTE: Typable commands can also be remapped, remember to keep the `:` prefix
`C-`, `S-` and `A-`. Special keys are encoded as follows: > to indicate it's a typable command.
Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes `C-`,
`S-` and `A-`. Special keys are encoded as follows:
| Key name | Representation | | Key name | Representation |
| --- | --- | | ------------ | -------------- |
| Backspace | `"backspace"` | | Backspace | `"backspace"` |
| Space | `"space"` | | Space | `"space"` |
| Return/Enter | `"ret"` | | Return/Enter | `"ret"` |
@ -50,5 +58,9 @@ Ctrl, Shift and Alt modifiers are encoded respectively with the prefixes
Keys can be disabled by binding them to the `no_op` command. Keys can be disabled by binding them to the `no_op` command.
Commands can be found at [Keymap](https://docs.helix-editor.com/keymap.html) Commands. You can find a list of available commands at
> Commands can also be found in the source code at [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs) at the invocation of `static_commands!` macro and the `TypableCommandList`. [Keymap](https://docs.helix-editor.com/keymap.html)
> Commands can also be found in the source code at
> [`helix-term/src/commands.rs`](https://github.com/helix-editor/helix/blob/master/helix-term/src/commands.rs)
> at the invocation of `static_commands!` macro and the `TypableCommandList`.

@ -1,22 +1,35 @@
# Themes # Themes
To use a theme add `theme = "<name>"` to your [`config.toml`](./configuration.md) at the very top of the file before the first section or select it during runtime using `:theme <name>`. To use a theme, add `theme = "<name>"` to the top of your
[`config.toml`](./configuration.md) file, or select it during runtime using
`:theme <name>`.
## Creating a theme ## Creating a Theme
Create a file with the name of your theme as file name (i.e `mytheme.toml`) and place it in your `themes` directory (i.e `~/.config/helix/themes`). The directory might have to be created beforehand. ### Creating Your Theme File
The names "default" and "base16_default" are reserved for the builtin themes and cannot be overridden by user defined themes. To create a theme file:
The default theme.toml can be found [here](https://github.com/helix-editor/helix/blob/master/theme.toml), and user submitted themes [here](https://github.com/helix-editor/helix/blob/master/runtime/themes). 1. Create a 'themes' folder in your user configuration folder (e.g.
`~/.config/helix/themes`)
2. Create a file with the name of your theme as the file name (e.g.
`mytheme.toml`) and place it in your `themes` folder.
Each line in the theme file is specified as below: > 💡 The names "default" and "base16_default" are reserved for built-in themes
> and cannot be overridden by user-defined themes.
### An Overview of the Theme File Format
Each line in the theme file is specified as follows:
```toml ```toml
key = { fg = "#ffffff", bg = "#000000", underline = { color = "#ff0000", style = "curl"}, modifiers = ["bold", "italic"] } key = { fg = "#ffffff", bg = "#000000", underline = { color = "#ff0000", style = "curl"}, modifiers = ["bold", "italic"] }
``` ```
where `key` represents what you want to style, `fg` specifies the foreground color, `bg` the background color, `underline` the underline `style`/`color`, and `modifiers` is a list of style modifiers. `bg`, `underline` and `modifiers` can be omitted to defer to the defaults. Where `key` represents what you want to style, `fg` specifies the foreground
color, `bg` the background color, `underline` the underline `style`/`color`, and
`modifiers` is a list of style modifiers. `bg`, `underline` and `modifiers` can
be omitted to defer to the defaults.
To specify only the foreground color: To specify only the foreground color:
@ -24,17 +37,34 @@ To specify only the foreground color:
key = "#ffffff" key = "#ffffff"
``` ```
if the key contains a dot `'.'`, it must be quoted to prevent it being parsed as a [dotted key](https://toml.io/en/v1.0.0#keys). If the key contains a dot `'.'`, it must be quoted to prevent it being parsed as
a [dotted key](https://toml.io/en/v1.0.0#keys).
```toml ```toml
"key.key" = "#ffffff" "key.key" = "#ffffff"
``` ```
For inspiration, you can find the default `theme.toml`
[here](https://github.com/helix-editor/helix/blob/master/theme.toml) and
user-submitted themes
[here](https://github.com/helix-editor/helix/blob/master/runtime/themes).
### Using the Linter
If you plan to submit your theme for inclusion in Helix, it is recommended to
use the supplied linting tool to ensure compliance with the specifications:
```sh
cargo xtask themelint onedark # replace onedark with <name>
```
## The Details of Theme Creation
### Color palettes ### Color palettes
It's recommended define a palette of named colors, and refer to them from the It's recommended to define a palette of named colors and refer to them in the
configuration values in your theme. To do this, add a table called configuration values in your theme. To do this, add a table called `palette` to
`palette` to your theme file: your theme file:
```toml ```toml
"ui.background" = "white" "ui.background" = "white"
@ -45,15 +75,15 @@ white = "#ffffff"
black = "#000000" black = "#000000"
``` ```
Remember that the `[palette]` table includes all keys after its header, Keep in mind that the [palette] table includes all keys after its header, so it
so you should define the palette after normal theme options. should be defined after the normal theme options.
The default palette uses the terminal's default 16 colors, and the colors names The default palette uses the terminal's default 16 colors, and the colors names
are listed below. The `[palette]` section in the config file takes precedence are listed below. The `[palette]` section in the config file takes precedence
over it and is merged into the default palette. over it and is merged into the default palette.
| Color Name | | Color Name |
| --- | | --------------- |
| `black` | | `black` |
| `red` | | `red` |
| `green` | | `green` |
@ -73,43 +103,40 @@ over it and is merged into the default palette.
### Modifiers ### Modifiers
The following values may be used as modifiers. The following values can be used as modifiers, providing they are supported by
your terminal emulator.
Less common modifiers might not be supported by your terminal emulator. | Modifier |
| ------------- |
| `bold` |
| `dim` |
| `italic` |
| `underlined` |
| `slow_blink` |
| `rapid_blink` |
| `reversed` |
| `hidden` |
| `crossed_out` |
| Modifier | > 💡 The `underlined` modifier is deprecated and only available for backwards
| --- | > compatibility. Its behavior is equivalent to setting `underline.style="line"`.
| `bold` |
| `dim` |
| `italic` |
| `underlined` |
| `slow_blink` |
| `rapid_blink` |
| `reversed` |
| `hidden` |
| `crossed_out` |
> Note: The `underlined` modifier is deprecated and only available for backwards compatibility.
> Its behavior is equivalent to setting `underline.style="line"`.
### Underline Style ### Underline Style
One of the following values may be used as a value for `underline.style`. One of the following values can be used for `underline.style`, providing it is
supported by your terminal emulator.
Some styles might not be supported by your terminal emulator.
| Modifier |
| --- |
| `line` |
| `curl` |
| `dashed` |
| `dotted` |
| `double_line` |
| Modifier |
| ------------- |
| `line` |
| `curl` |
| `dashed` |
| `dotted` |
| `double_line` |
### Inheritance ### Inheritance
Extend upon other themes by setting the `inherits` property to an existing theme. Extends other themes by setting the `inherits` property to an existing theme.
```toml ```toml
inherits = "boo_berry" inherits = "boo_berry"
@ -124,19 +151,22 @@ berry = "#2A2A4D"
### Scopes ### Scopes
The following is a list of scopes available to use for styling. The following is a list of scopes available to use for styling:
#### Syntax highlighting #### Syntax highlighting
These keys match [tree-sitter scopes](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#theme). These keys match
[tree-sitter scopes](https://tree-sitter.github.io/tree-sitter/syntax-highlighting#theme).
For a given highlight produced, styling will be determined based on the longest matching theme key. For example, the highlight `function.builtin.static` would match the key `function.builtin` rather than `function`. When determining styling for a highlight, the longest matching theme key will be
used. For example, if the highlight is `function.builtin.static,` the key
`function.builtin` will be used instead of function.
We use a similar set of scopes as We use a similar set of scopes as
[SublimeText](https://www.sublimetext.com/docs/scope_naming.html). See also [Sublime Text](https://www.sublimetext.com/docs/scope_naming.html). See also
[TextMate](https://macromates.com/manual/en/language_grammars) scopes. [TextMate](https://macromates.com/manual/en/language_grammars) scopes.
- `attribute` - Class attributes, html tag attributes - `attribute` - Class attributes, HTML tag attributes
- `type` - Types - `type` - Types
- `builtin` - Primitive types provided by the language (`int`, `usize`) - `builtin` - Primitive types provided by the language (`int`, `usize`)
@ -144,8 +174,10 @@ We use a similar set of scopes as
- `variant` - `variant`
- `constructor` - `constructor`
- `constant` (TODO: constant.other.placeholder for %v) - `constant` (TODO: constant.other.placeholder for `%v)`
- `builtin` Special constants provided by the language (`true`, `false`, `nil` etc)
- `builtin` Special constants provided by the language (`true`, `false`, `nil`
etc.)
- `boolean` - `boolean`
- `character` - `character`
- `escape` - `escape`
@ -154,6 +186,7 @@ We use a similar set of scopes as
- `float` - `float`
- `string` (TODO: string.quoted.{single, double}, string.raw/.unquoted)? - `string` (TODO: string.quoted.{single, double}, string.raw/.unquoted)?
- `regexp` - Regular expressions - `regexp` - Regular expressions
- `special` - `special`
- `path` - `path`
@ -161,12 +194,14 @@ We use a similar set of scopes as
- `symbol` - Erlang/Elixir atoms, Ruby symbols, Clojure keywords - `symbol` - Erlang/Elixir atoms, Ruby symbols, Clojure keywords
- `comment` - Code comments - `comment` - Code comments
- `line` - Single line comments (`//`) - `line` - Single line comments (`//`)
- `block` - Block comments (e.g. (`/* */`) - `block` - Block comments (e.g. (`/* */`)
- `documentation` - Documentation comments (e.g. `///` in Rust) - `documentation` - Documentation comments (e.g. `///` in Rust)
- `variable` - Variables - `variable` - Variables
- `builtin` - Reserved language variables (`self`, `this`, `super`, etc)
- `builtin` - Reserved language variables (`self`, `this`, `super`, etc.)
- `parameter` - Function parameters - `parameter` - Function parameters
- `other` - `other`
- `member` - Fields of composite data types (e.g. structs, unions) - `member` - Fields of composite data types (e.g. structs, unions)
@ -174,11 +209,13 @@ We use a similar set of scopes as
- `label` - `label`
- `punctuation` - `punctuation`
- `delimiter` - Commas, colons - `delimiter` - Commas, colons
- `bracket` - Parentheses, angle brackets, etc. - `bracket` - Parentheses, angle brackets, etc.
- `special` - String interpolation brackets. - `special` - String interpolation brackets.
- `keyword` - `keyword`
- `control` - `control`
- `conditional` - `if`, `else` - `conditional` - `if`, `else`
- `repeat` - `for`, `while`, `loop` - `repeat` - `for`, `while`, `loop`
@ -186,15 +223,16 @@ We use a similar set of scopes as
- `return` - `return`
- `exception` - `exception`
- `operator` - `or`, `in` - `operator` - `or`, `in`
- `directive` - Preprocessor directives (`#if` in C) - `directive` - Preprocessor directives (`#if` in C)
- `function` - `fn`, `func` - `function` - `fn`, `func`
- `storage` - Keywords describing how things are stored - `storage` - Keywords describing how things are stored
- `type` - The type of something, `class`, `function`, `var`, `let`, etc. - `type` - The type of something, `class`, `function`, `var`, `let`, etc.
- `modifier` - Storage modifiers like `static`, `mut`, `const`, `ref`, etc. - `modifier` - Storage modifiers like `static`, `mut`, `const`, `ref`, etc.
- `operator` - `||`, `+=`, `>` - `operator` - `||`, `+=`, `>`
- `function` - `function`
- `builtin` - `builtin`
- `method` - `method`
- `macro` - `macro`
@ -207,6 +245,7 @@ We use a similar set of scopes as
- `special` - `special`
- `markup` - `markup`
- `heading` - `heading`
- `marker` - `marker`
- `1`, `2`, `3`, `4`, `5`, `6` - heading text for h1 through h6 - `1`, `2`, `3`, `4`, `5`, `6` - heading text for h1 through h6
@ -216,9 +255,9 @@ We use a similar set of scopes as
- `bold` - `bold`
- `italic` - `italic`
- `link` - `link`
- `url` - urls pointed to by links - `url` - URLs pointed to by links
- `label` - non-url link references - `label` - non-URL link references
- `text` - url and image descriptions in links - `text` - URL and image descriptions in links
- `quote` - `quote`
- `raw` - `raw`
- `inline` - `inline`
@ -232,74 +271,67 @@ We use a similar set of scopes as
#### Interface #### Interface
These scopes are used for theming the editor interface. These scopes are used for theming the editor interface:
- `markup` - `markup`
- `normal` - `normal`
- `completion` - for completion doc popup ui - `completion` - for completion doc popup UI
- `hover` - for hover popup ui - `hover` - for hover popup UI
- `heading` - `heading`
- `completion` - for completion doc popup ui - `completion` - for completion doc popup UI
- `hover` - for hover popup ui - `hover` - for hover popup UI
- `raw` - `raw`
- `inline` - `inline`
- `completion` - for completion doc popup ui - `completion` - for completion doc popup UI
- `hover` - for hover popup ui - `hover` - for hover popup UI
| Key | Notes |
| Key | Notes | | --------------------------- | ------------------------------------------------------------------------------------------------ |
| --- | --- | | `ui.background` | |
| `ui.background` | | | `ui.background.separator` | Picker separator below input line |
| `ui.background.separator` | Picker separator below input line | | `ui.cursor` | |
| `ui.cursor` | | | `ui.cursor.insert` | |
| `ui.cursor.insert` | | | `ui.cursor.select` | |
| `ui.cursor.select` | | | `ui.cursor.match` | Matching bracket etc. |
| `ui.cursor.match` | Matching bracket etc. | | `ui.cursor.primary` | Cursor with primary selection |
| `ui.cursor.primary` | Cursor with primary selection | | `ui.gutter` | Gutter |
| `ui.gutter` | Gutter | | `ui.gutter.selected` | Gutter for the line the cursor is on |
| `ui.gutter.selected` | Gutter for the line the cursor is on | | `ui.linenr` | Line numbers |
| `ui.linenr` | Line numbers | | `ui.linenr.selected` | Line number for the line the cursor is on |
| `ui.linenr.selected` | Line number for the line the cursor is on | | `ui.statusline` | `statusline` |
| `ui.statusline` | Statusline | | `ui.statusline.inactive` | `statusline` (unfocused document) |
| `ui.statusline.inactive` | Statusline (unfocused document) | | `ui.statusline.normal` | `statusline` mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) |
| `ui.statusline.normal` | Statusline mode during normal mode ([only if `editor.color-modes` is enabled][editor-section]) | | `ui.statusline.insert` | `statusline` mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) |
| `ui.statusline.insert` | Statusline mode during insert mode ([only if `editor.color-modes` is enabled][editor-section]) | | `ui.statusline.select` | `statusline` mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) |
| `ui.statusline.select` | Statusline mode during select mode ([only if `editor.color-modes` is enabled][editor-section]) | | `ui.statusline.separator` | Separator character in `statusline` |
| `ui.statusline.separator` | Separator character in statusline | | `ui.popup` | Documentation popups (e.g. Space + k) |
| `ui.popup` | Documentation popups (e.g Space + k) | | `ui.popup.info` | Prompt for multiple key options |
| `ui.popup.info` | Prompt for multiple key options | | `ui.window` | Borderlines separating splits |
| `ui.window` | Border lines separating splits | | `ui.help` | Description box for commands |
| `ui.help` | Description box for commands | | `ui.text` | Command prompts, popup text, etc. |
| `ui.text` | Command prompts, popup text, etc. | | `ui.text.focus` | |
| `ui.text.focus` | | | `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) |
| `ui.text.inactive` | Same as `ui.text` but when the text is inactive (e.g. suggestions) | | `ui.text.info` | The key: command text in `ui.popup.info` boxes |
| `ui.text.info` | The key: command text in `ui.popup.info` boxes | | `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) |
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) | | `ui.virtual.whitespace` | Visible whitespace characters |
| `ui.virtual.whitespace` | Visible whitespace characters | | `ui.virtual.indent-guide` | Vertical indent width guides |
| `ui.virtual.indent-guide` | Vertical indent width guides | | `ui.menu` | Code and command completion menus |
| `ui.menu` | Code and command completion menus | | `ui.menu.selected` | Selected autocomplete item |
| `ui.menu.selected` | Selected autocomplete item | | `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar |
| `ui.menu.scroll` | `fg` sets thumb color, `bg` sets track color of scrollbar | | `ui.selection` | For selections in the editing area |
| `ui.selection` | For selections in the editing area | | `ui.selection.primary` | |
| `ui.selection.primary` | | | `ui.cursorline.primary` | The line of the primary cursor ([if `cursorline` is enabled][editor-section]) |
| `ui.cursorline.primary` | The line of the primary cursor ([if cursorline is enabled][editor-section]) | | `ui.cursorline.secondary` | The lines of any other cursors ([if `cursorline` is enabled][editor-section]) |
| `ui.cursorline.secondary` | The lines of any other cursors ([if cursorline is enabled][editor-section]) | | `ui.cursorcolumn.primary` | The column of the primary cursor ([if `cursorcolumn` is enabled][editor-section]) |
| `ui.cursorcolumn.primary` | The column of the primary cursor ([if cursorcolumn is enabled][editor-section]) | | `ui.cursorcolumn.secondary` | The columns of any other cursors ([if `cursorcolumn` is enabled][editor-section]) |
| `ui.cursorcolumn.secondary` | The columns of any other cursors ([if cursorcolumn is enabled][editor-section]) | | `warning` | Diagnostics warning (gutter) |
| `warning` | Diagnostics warning (gutter) | | `error` | Diagnostics error (gutter) |
| `error` | Diagnostics error (gutter) | | `info` | Diagnostics info (gutter) |
| `info` | Diagnostics info (gutter) | | `hint` | Diagnostics hint (gutter) |
| `hint` | Diagnostics hint (gutter) | | `diagnostic` | Diagnostics fallback style (editing area) |
| `diagnostic` | Diagnostics fallback style (editing area) | | `diagnostic.hint` | Diagnostics hint (editing area) |
| `diagnostic.hint` | Diagnostics hint (editing area) | | `diagnostic.info` | Diagnostics info (editing area) |
| `diagnostic.info` | Diagnostics info (editing area) | | `diagnostic.warning` | Diagnostics warning (editing area) |
| `diagnostic.warning` | Diagnostics warning (editing area) | | `diagnostic.error` | Diagnostics error (editing area) |
| `diagnostic.error` | Diagnostics error (editing area) |
You can check compliance to spec with
```shell
cargo xtask themelint onedark # replace onedark with <name>
```
[editor-section]: ./configuration.md#editor-section [editor-section]: ./configuration.md#editor-section

@ -1,68 +1,100 @@
# Usage # Using Helix
(Currently not fully documented, see the [keymappings](./keymap.md) list for more.) <!--toc:start-->
See [tutor](https://github.com/helix-editor/helix/blob/master/runtime/tutor) (accessible via `hx --tutor` or `:tutor`) for a vimtutor-like introduction. - [Using Helix](#using-helix)
- [Registers](#registers)
- [User-defined Registers](#user-defined-registers)
- [Built-in Registers](#built-in-registers)
- [Surround](#surround)
- [Moving the Primary Selection with Syntax-tree Motions](#moving-the-primary-selection-with-syntax-tree-motions)
- [Selecting and Manipulating Text with Textobjects](#selecting-and-manipulating-text-with-textobjects)
- [Navigating Using Tree-sitter Textobjects](#navigating-using-tree-sitter-textobjects)
<!--toc:end-->
For a full interactive introduction to Helix, refer to the
[tutor](https://github.com/helix-editor/helix/blob/master/runtime/tutor) which
can be accessed via the command `hx --tutor` or `:tutor`.
> 💡 Currently, not all functionality is fully documented, please refer to the
> [key mappings](./keymap.md) list.
## Registers ## Registers
Vim-like registers can be used to yank and store text to be pasted later. Usage is similar, with `"` being used to select a register: In Helix, registers are storage locations for text and other data, such as the
result of a search. Registers can be used to cut, copy, and paste text, similar
to the clipboard in other text editors. Usage is similar to Vim, with `"` being
used to select a register.
### User-defined Registers
Helix allows you to create your own named registers for storing text, for
example:
- `"ay` - Yank the current selection to register `a`. - `"ay` - Yank the current selection to register `a`.
- `"op` - Paste the text in register `o` after the selection. - `"op` - Paste the text in register `o` after the selection.
If there is a selected register before invoking a change or delete command, the selection will be stored in the register and the action will be carried out: If a register is selected before invoking a change or delete command, the
selection will be stored in the register and the action will be carried out:
- `"hc` - Store the selection in register `h` and then change it (delete and enter insert mode). - `"hc` - Store the selection in register `h` and then change it (delete and
enter insert mode).
- `"md` - Store the selection in register `m` and delete it. - `"md` - Store the selection in register `m` and delete it.
### Special Registers ### Built-in Registers
| Register character | Contains | | Register character | Contains |
| --- | --- | | ------------------ | --------------------- |
| `/` | Last search | | `/` | Last search |
| `:` | Last executed command | | `:` | Last executed command |
| `"` | Last yanked text | | `"` | Last yanked text |
| `_` | Black hole | | `_` | Black hole |
> There is no special register for copying to system clipboard, instead special commands and keybindings are provided. See the [keymap](keymap.md#space-mode) for the specifics. The system clipboard is not directly supported by a built-in register. Instead,
> The black hole register works as a no-op register, meaning no data will be written to / read from it. special commands and keybindings are provided. Refer to the
[key map](keymap.md#space-mode) for more details.
The black hole register is a no-op register, meaning that no data will be read
or written to it.
## Surround ## Surround
Functionality similar to [vim-surround](https://github.com/tpope/vim-surround) is built into Helix includes built-in functionality similar to
helix. The keymappings have been inspired from [vim-sandwich](https://github.com/machakann/vim-sandwich): [vim-surround](https://github.com/tpope/vim-surround). The key mappings for this
functionality have been inspired by
[vim-sandwich](https://github.com/machakann/vim-sandwich).
![surround demo](https://user-images.githubusercontent.com/23398472/122865801-97073180-d344-11eb-8142-8f43809982c6.gif) ![Surround demo](https://user-images.githubusercontent.com/23398472/122865801-97073180-d344-11eb-8142-8f43809982c6.gif)
- `ms` - Add surround characters | Key Sequence | Action |
- `mr` - Replace surround characters | --------------------------------- | --------------------------------------- |
- `md` - Delete surround characters | `ms<char>` (after selecting text) | Add surround characters to selection |
| `mr<char_to_replace><new_char>` | Replace the closest surround characters |
| `md<char_to_delete>` | Delete the closest surround characters |
`ms` acts on a selection, so select the text first and use `ms<char>`. `mr` and `md` work You can use counts to act on outer pairs.
on the closest pairs found and selections are not required; use counts to act in outer pairs.
It can also act on multiple selections (yay!). For example, to change every occurrence of `(use)` to `[use]`: Surround can also act on multiple selections. For example, to change every
occurrence of `(use)` to `[use]`:
- `%` to select the whole file 1. `%` to select the whole file
- `s` to split the selections on a search term 2. `s` to split the selections on a search term
- Input `use` and hit Enter 3. Input `use` and hit Enter
- `mr([` to replace the parens with square brackets 4. `mr([` to replace the parentheses with square brackets
Multiple characters are currently not supported, but planned. Multiple characters are currently not supported, but planned for future release.
## Syntax-tree Motions ## Moving the Primary Selection with Syntax-tree Motions
`Alt-p`, `Alt-o`, `Alt-i`, and `Alt-n` (or `Alt` and arrow keys) move the primary `Alt-p`, `Alt-o`, `Alt-i`, and `Alt-n` (or `Alt` and arrow keys) allow you to
selection according to the selection's place in the syntax tree. Let's walk move the primary selection according to its location in the syntax tree. For
through an example to get familiar with them. Many languages have a syntax like example, many languages have the following syntax for function calls:
so for function calls:
``` ```js
func(arg1, arg2, arg3) func(arg1, arg2, arg3);
``` ```
A function call might be parsed by tree-sitter into a tree like the following. A function call parsed by tree-sitter might look like:
```tsq ```tsq
(call (call
@ -93,50 +125,46 @@ a more intuitive tree format:
└──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
``` ```
Say we have a selection that wraps `arg1`. The selection is on the `arg1` leaf If you have a selection that wraps `arg1` (see the tree above), and you use
in the tree above. Alt-n, it will select the next sibling in the syntax tree: `arg2`.
```
func([arg1], arg2, arg3)
```
Using `Alt-n` would select the next sibling in the syntax tree: `arg2`.
``` ```js
func(arg1, [arg2], arg3) func([arg1], arg2, arg3) > func(arg1, [arg2], arg3);
``` ```
While `Alt-o` would expand the selection to the parent node. In the tree above we Similarly, Alt-o will expand the selection to the parent node, in this case, the
can see that we would select the `arguments` node. arguments node.
``` ```js
func[(arg1, arg2, arg3)] func[(arg1, arg2, arg3)];
``` ```
There is also some nuanced behavior that prevents you from getting stuck on a There is also some nuanced behavior that prevents you from getting stuck on a
node with no sibling. If we have a selection on `arg1`, `Alt-p` would bring us node with no sibling. When using Alt-p with a selection on `arg1`, the previous
to the previous child node. Since `arg1` doesn't have a sibling to its left, child node will be selected. In the event that `arg1` does not have a previous
though, we climb the syntax tree and then take the previous selection. So sibling, the selection will move up the syntax tree and select the previous
`Alt-p` will move the selection over to the "func" `identifier`. element. As a result, using Alt-p with a selection on `arg1` will move the
selection to the "func" `identifier`.
``` ## Selecting and Manipulating Text with Textobjects
[func](arg1, arg2, arg3)
```
## Textobjects In Helix, Textobjects are a way to select, manipulate and operate on a piece of
text in a structured way. They allow you to refer to blocks of text based on
their structure or purpose, such as a word, sentence, paragraph, or even a
function or block of code.
![textobject-demo](https://user-images.githubusercontent.com/23398472/124231131-81a4bb00-db2d-11eb-9d10-8e577ca7b177.gif) ![Textobject demo](https://user-images.githubusercontent.com/23398472/124231131-81a4bb00-db2d-11eb-9d10-8e577ca7b177.gif)
![textobject-treesitter-demo](https://user-images.githubusercontent.com/23398472/132537398-2a2e0a54-582b-44ab-a77f-eb818942203d.gif) ![Textobject tree-sitter demo](https://user-images.githubusercontent.com/23398472/132537398-2a2e0a54-582b-44ab-a77f-eb818942203d.gif)
- `ma` - Select around the object (`va` in Vim, `<alt-a>` in Kakoune) - `ma` - Select around the object (`va` in Vim, `<alt-a>` in Kakoune)
- `mi` - Select inside the object (`vi` in Vim, `<alt-i>` in Kakoune) - `mi` - Select inside the object (`vi` in Vim, `<alt-i>` in Kakoune)
| Key after `mi` or `ma` | Textobject selected | | Key after `mi` or `ma` | Textobject selected |
| --- | --- | | ---------------------- | ------------------------ |
| `w` | Word | | `w` | Word |
| `W` | WORD | | `W` | WORD |
| `p` | Paragraph | | `p` | Paragraph |
| `(`, `[`, `'`, etc | Specified surround pairs | | `(`, `[`, `'`, etc. | Specified surround pairs |
| `m` | Closest surround pair | | `m` | Closest surround pair |
| `f` | Function | | `f` | Function |
| `c` | Class | | `c` | Class |
@ -145,26 +173,26 @@ though, we climb the syntax tree and then take the previous selection. So
| `t` | Test | | `t` | Test |
| `g` | Change | | `g` | Change |
> NOTE: `f`, `c`, etc need a tree-sitter grammar active for the current > 💡`f`, `c`, etc. need a tree-sitter grammar active for the current document
document and a special tree-sitter query file to work properly. [Only > and a special tree-sitter query file to work properly. [Only some
some grammars][lang-support] currently have the query file implemented. > grammars][lang-support] currently have the query file implemented.
Contributions are welcome! > Contributions are welcome!
## Tree-sitter Textobject Based Navigation ## Navigating Using Tree-sitter Textobjects
Navigating between functions, classes, parameters, etc is made Navigating between functions, classes, parameters, and other elements is
possible by leveraging tree-sitter and textobjects queries. For possible using tree-sitter and Textobject queries. For example, to move to the
example to move to the next function use `]f`, to move to previous next function use `]f`, to move to previous class use `[c`, and so on.
class use `[c`, and so on.
![tree-sitter-nav-demo][tree-sitter-nav-demo] ![tree-sitter-nav-demo][tree-sitter-nav-demo]
See the [unimpaired][unimpaired-keybinds] section of the keybind For the full reference see the [unimpaired][unimpaired-keybinds] section of the
documentation for the full reference. key bind documentation.
> NOTE: This feature is dependent on tree-sitter based textobjects > 💡 This feature relies on tree-sitter Textobjects and requires the
and therefore requires the corresponding query file to work properly. > corresponding query file to work properly.
[lang-support]: ./lang-support.md [lang-support]: ./lang-support.md
[unimpaired-keybinds]: ./keymap.md#unimpaired [unimpaired-keybinds]: ./keymap.md#unimpaired
[tree-sitter-nav-demo]: https://user-images.githubusercontent.com/23398472/152332550-7dfff043-36a2-4aec-b8f2-77c13eb56d6f.gif [tree-sitter-nav-demo]:
https://user-images.githubusercontent.com/23398472/152332550-7dfff043-36a2-4aec-b8f2-77c13eb56d6f.gif

Loading…
Cancel
Save