on de0ef8a help sign in
helix/book/src/usage.md
192 lines 8.1 kB history raw
1# Using Helix
3<!--toc:start-->
4- [Registers](#registers)
5 - [User-defined registers](#user-defined-registers)
6 - [Special registers](#special-registers)
7- [Surround](#surround)
8- [Selecting and manipulating text with textobjects](#selecting-and-manipulating-text-with-textobjects)
9- [Navigating using tree-sitter textobjects](#navigating-using-tree-sitter-textobjects)
10- [Moving the selection with syntax-aware motions](#moving-the-selection-with-syntax-aware-motions)
11<!--toc:end-->
13For a full interactive introduction to Helix, refer to the
14[tutor](https://github.com/helix-editor/helix/blob/master/runtime/tutor) which
15can be accessed via the command `hx --tutor` or `:tutor`.
17> πŸ’‘ Currently, not all functionality is fully documented, please refer to the
18> [key mappings](./keymap.md) list.
20## Registers
22In Helix, registers are storage locations for text and other data, such as the
23result of a search. Registers can be used to cut, copy, and paste text, similar
24to the clipboard in other text editors. Usage is similar to Vim, with `"` being
25used to select a register.
27### User-defined registers
29Helix allows you to create your own named registers for storing text, for
30example:
32- `"ay` - Yank the current selection to register `a`.
33- `"op` - Paste the text in register `o` after the selection.
35If 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:
37- `"hc` - Store the selection in register `h` and then change it (delete and enter insert mode).
38- `"md` - Store the selection in register `m` and delete it.
40### Special registers
42| Register character | Contains |
43| --- | --- |
44| `/` | Last search |
45| `:` | Last executed command |
46| `"` | Last yanked text |
47| `_` | Black hole |
49The system clipboard is not directly supported by a special register. Instead, special commands and keybindings are provided. Refer to the
50[key map](keymap.md#space-mode) for more details.
52The black hole register is a no-op register, meaning that no data will be read or written to it.
54## Surround
56Helix includes built-in functionality similar to [vim-surround](https://github.com/tpope/vim-surround).
57The keymappings have been inspired from [vim-sandwich](https://github.com/machakann/vim-sandwich):
59![Surround demo](https://user-images.githubusercontent.com/23398472/122865801-97073180-d344-11eb-8142-8f43809982c6.gif)
61| Key Sequence | Action |
62| --------------------------------- | --------------------------------------- |
63| `ms<char>` (after selecting text) | Add surround characters to selection |
64| `mr<char_to_replace><new_char>` | Replace the closest surround characters |
65| `md<char_to_delete>` | Delete the closest surround characters |
67You can use counts to act on outer pairs.
69Surround can also act on multiple selections. For example, to change every occurrence of `(use)` to `[use]`:
711. `%` to select the whole file
722. `s` to split the selections on a search term
733. Input `use` and hit Enter
744. `mr([` to replace the parentheses with square brackets
76Multiple characters are currently not supported, but planned for future release.
78## Selecting and manipulating text with textobjects
80In Helix, textobjects are a way to select, manipulate and operate on a piece of
81text in a structured way. They allow you to refer to blocks of text based on
82their structure or purpose, such as a word, sentence, paragraph, or even a
83function or block of code.
85![Textobject demo](https://user-images.githubusercontent.com/23398472/124231131-81a4bb00-db2d-11eb-9d10-8e577ca7b177.gif)
86![Textobject tree-sitter demo](https://user-images.githubusercontent.com/23398472/132537398-2a2e0a54-582b-44ab-a77f-eb818942203d.gif)
88- `ma` - Select around the object (`va` in Vim, `<alt-a>` in Kakoune)
89- `mi` - Select inside the object (`vi` in Vim, `<alt-i>` in Kakoune)
91| Key after `mi` or `ma` | Textobject selected |
92| --- | --- |
93| `w` | Word |
94| `W` | WORD |
95| `p` | Paragraph |
96| `(`, `[`, `'`, etc. | Specified surround pairs |
97| `m` | The closest surround pair |
98| `f` | Function |
99| `c` | Class |
100| `a` | Argument/parameter |
101| `o` | Comment |
102| `t` | Test |
103| `g` | Change |
105> πŸ’‘ `f`, `c`, etc. need a tree-sitter grammar active for the current
106document and a special tree-sitter query file to work properly. [Only
107some grammars][lang-support] currently have the query file implemented.
108Contributions are welcome!
110## Navigating using tree-sitter textobjects
112Navigating between functions, classes, parameters, and other elements is
113possible using tree-sitter and textobject queries. For
114example to move to the next function use `]f`, to move to previous
115class use `[c`, and so on.
117![Tree-sitter-nav-demo][tree-sitter-nav-demo]
119For the full reference see the [unimpaired][unimpaired-keybinds] section of the key bind
120documentation.
122> πŸ’‘ This feature relies on tree-sitter textobjects
123> and requires the corresponding query file to work properly.
125## Moving the selection with syntax-aware motions
127`Alt-p`, `Alt-o`, `Alt-i`, and `Alt-n` (or `Alt` and arrow keys) allow you to move the
128selection according to its location in the syntax tree. For example, many languages have the
129following syntax for function calls:
131```js
132func(arg1, arg2, arg3);
133```
135A function call might be parsed by tree-sitter into a tree like the following.
137```tsq
138(call
139 function: (identifier) ; func
140 arguments:
141 (arguments ; (arg1, arg2, arg3)
142 (identifier) ; arg1
143 (identifier) ; arg2
144 (identifier))) ; arg3
145```
147Use `:tree-sitter-subtree` to view the syntax tree of the primary selection. In
148a more intuitive tree format:
150```
151 β”Œβ”€β”€β”€β”€β”
152 β”‚callβ”‚
153 β”Œβ”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”
154 β”‚ β”‚
155β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
156β”‚identifierβ”‚ β”‚argumentsβ”‚
157β”‚ "func" β”‚ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”
158β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚
159 β”‚ β”‚ β”‚
160 β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”
161 β”‚identifierβ”‚ β”‚identifierβ”‚ β”‚identifierβ”‚
162 β”‚ "arg1" β”‚ β”‚ "arg2" β”‚ β”‚ "arg3" β”‚
163 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
164```
166If you have a selection that wraps `arg1` (see the tree above), and you use
167`Alt-n`, it will select the next sibling in the syntax tree: `arg2`.
169```js
170// before
171func([arg1], arg2, arg3)
172// after
173func(arg1, [arg2], arg3);
174```
176Similarly, `Alt-o` will expand the selection to the parent node, in this case, the
177arguments node.
179```js
180func[(arg1, arg2, arg3)];
181```
183There is also some nuanced behavior that prevents you from getting stuck on a
184node with no sibling. When using `Alt-p` with a selection on `arg1`, the previous
185child node will be selected. In the event that `arg1` does not have a previous
186sibling, the selection will move up the syntax tree and select the previous
187element. As a result, using `Alt-p` with a selection on `arg1` will move the
188selection to the "func" `identifier`.
190[lang-support]: ./lang-support.md
191[unimpaired-keybinds]: ./keymap.md#unimpaired
192[tree-sitter-nav-demo]: https://user-images.githubusercontent.com/23398472/152332550-7dfff043-36a2-4aec-b8f2-77c13eb56d6f.gif