# Helix for Vim / Neovim Users

A migration guide for people who already know Vim. This skips the basics
(`hjkl`, insert mode, `:w`, `:q` — all the same) and focuses on where Helix
*thinks differently* than Vim, and how to do the everyday things you already
do in Vim without missing a beat.

---

## The one idea that changes everything: selection → action

This is the whole game. Internalize this and 80% of Helix falls into place.

- **Vim is `verb → object`.** You type the action first, then describe what it
  acts on. `dw` = "delete a word". `ci(` = "change inside parens". The object
  is invisible until the action fires.
- **Helix is `object → verb`.** You *select first*, see the selection
  highlighted, then apply the action. `wd` = "select to next word, then
  delete". `mi(c` = "select inside parens, then change".

Consequences:

- There is **always a selection**, even if it's just the single character under
  the cursor. Your cursor *is* a one-character selection.
- Actions like `d`, `c`, `y`, `r`, `~`, `>` operate on **whatever is currently
  selected** — no motion argument needed.
- You get **visual feedback before you commit**. You select, confirm it looks
  right, then act. Fewer "oops, that deleted the wrong thing, `u`" moments.
- Vim's operator-pending grammar (`d{motion}`, `c{motion}`, counts inside it)
  **does not exist**. There is no "operator waiting for a motion" state.

### Muscle-memory translation table

| You want to…                | Vim            | Helix           | Note |
|-----------------------------|----------------|-----------------|------|
| Delete a word forward       | `dw`           | `wd`            | select `w`, then `d` |
| Change a word               | `cw` / `ciw`   | `wc` / `miwc`   | |
| Delete to end of line       | `d$`           | `vg$d` or `Xd`  | select then delete |
| Change inside parens        | `ci(`          | `mi(c`          | match-mode select, then change |
| Delete around quotes        | `da"`          | `ma"d`          | |
| Delete a line               | `dd`           | `xd`            | `x` selects the line first |
| Change a line               | `cc`           | `xc`            | |
| Yank a line                 | `yy`           | `xy`            | |
| Delete char under cursor    | `x`            | `d`             | `x` is **line select** in Helix! |
| Replace one char            | `r{c}`         | `r{c}`          | same, but replaces *all* selected chars |
| Join lines                  | `J`            | `xJ` / `x J`    | select the lines first |
| Indent line                 | `>>`           | `>`             | acts on selected lines |
| Repeat last change          | `.`            | `.`             | repeats last **insert** only (see below) |
| Redo                        | `Ctrl-r`       | `U`             | capital U |
| Select whole file           | `ggVG`         | `%`             | `%` = "select all" in Helix |

> **The single most jarring gotcha:** in Vim `x` deletes a character. In Helix
> `x` **selects the whole line** (and again to extend downward). To delete a
> character in Helix, just press `d` (your cursor is already a selection).

---

## Deletion, change, and the clipboard

- `d` deletes the **selection**. `c` deletes the selection and enters insert
  mode. No motion suffix — select first.
- **Delete and change auto-yank.** Like Vim's default register, `d`/`c` copy the
  removed text. To delete/change *without* clobbering your yank (Vim's
  `"_dd` black-hole trick), use **`Alt-d`** and **`Alt-c`**.
- `r{char}` replaces **every selected character** with `{char}` (in Vim `r`
  replaces just one). Select 5 chars, `rx`, and you get five `x`s.
- `R` **replaces the selection with yanked text** (a paste-over). Not Vim's
  replace-*mode*.

### Clipboard

Helix does **not** touch the system clipboard by default — yanks go to Helix's
own registers, same as Vim without `clipboard=unnamedplus`.

| Action                        | Helix              |
|-------------------------------|--------------------|
| Yank to system clipboard      | `Space y`          |
| Paste from system clipboard   | `Space p` / `Space P` |
| Yank to Helix register        | `y`                |
| Paste from Helix register     | `p` / `P`          |

If you're used to `set clipboard=unnamedplus`, you can replicate it in
`config.toml`:

```toml
[editor]
default-yank-register = "+"   # not exactly the same, but see docs for clipboard providers
```

(Most people just learn `Space y` / `Space p`. It's two keys.)

---

## Text objects & surround — this is "match mode" (`m`)

Vim's text objects (`iw`, `i(`, `a"`) and the beloved `vim-surround` plugin are
**built in** under the `m` (match) prefix. No plugins needed.

| Vim / vim-surround        | Helix          | Meaning |
|---------------------------|----------------|---------|
| `%` (jump to match pair)  | `mm`           | jump between matching brackets |
| `ci(` (change inside)     | `mi(c`         | select inside pair, change |
| `di"` (delete inside)     | `mi"d`         | select inside quotes, delete |
| `da{` (delete around)     | `ma{d`         | select around pair, delete |
| `ysiw)` (surround add)    | `ms)`          | surround selection with `()` |
| `ds(` (surround delete)   | `md(`          | delete surrounding `()` |
| `cs([` (surround change)  | `mr([`         | replace surrounding `(` with `[` |

Because it's selection-first, the flow reads naturally:

- `mi(` → "select **i**nside `()`" → now do whatever (`c`, `d`, `y`, `>`…).
- `ma"` → "select **a**round the quotes" (delimiters included).
- `ms{` → with something selected, "surround with `{}`".
- `mr{[` → "replace surrounding `{` with `[`".

Word/paragraph text objects use the same idea — select the word with a motion
(`w`, `b`, `e`, or `miw`-style with `m`), then act.

---

## Multiple cursors: your new best friend (and macro replacement)

This is Helix's headline feature and it replaces a *huge* chunk of what you used
Vim macros, visual-block, and `:s` for.

| Task                                   | Key |
|----------------------------------------|-----|
| Add a cursor on the next line          | `C` |
| Add a cursor on the previous line      | `Alt-C` |
| Select all regex matches *in selection*| `s` then type a regex |
| Select next occurrence of selection    | `*` then `v` then `n` (adds cursors) |
| Split selection into one cursor per line | `Alt-s` |
| Collapse multi-cursor back to one      | `,` |
| Remove the primary cursor              | `Alt-,` |
| Rotate which cursor is primary         | `(` / `)` |
| Flip selection direction              | `Alt-;` |

**Vim's visual block (`Ctrl-v`) is gone** — you don't need it. To edit a column,
select the lines and use `C` / `Alt-s` to drop a cursor per line, then `I` / `A`
to insert at the same spot on each.

**Find-and-replace, the Helix way** — there is no `:%s/old/new/g` muscle habit;
you do it interactively and *see* it:

1. `%` — select the whole file (or select any region).
2. `s` — opens a prompt; type your regex (e.g. `old`), Enter. Every match is now
   a selection.
3. `c` — change them all at once, type `new`, `Esc`.

This is strictly more powerful than `:s` because you watch it select before you
change, and you can then keep editing with all cursors live.

> Vim's `:%s/old/new/gc` (confirm each) maps to: `%` `s` `old` Enter, then use
> `(` / `)` to walk the cursors and `Alt-,` to drop the ones you don't want.

---

## Search differences

- `/` forward, `?` backward — but **`?` does not flip search direction**. `n` is
  *always* forward, `N` is *always* backward. (In Vim, `n` after `?` reverses.)
- `f` / `t` / `F` / `T` **search the whole file, not just the current line.** So
  `fx` will happily jump to an `x` three lines down.
- `*` sets the search register to the current selection (like Vim's `*` but it
  uses whatever you've selected, not the word under cursor).
- `Alt-.` repeats the last `f`/`t` motion (Vim's `;`).
- Searching uses **Rust regex**, not Vim's regex dialect — no `\v` very-magic,
  no `\<` `\>` word boundaries (`\b` instead). Mostly PCRE-ish.

---

## Repeat, undo, macros

- **`.` repeats the last *insertion* only** — not the last full change like Vim.
  For "do this whole edit again", record a macro.
- Undo `u`, **redo `U`** (capital U, not `Ctrl-r`).
- **Macros use `Q` and `q`, swapped from Vim:**
  - `Q` — start recording (and `Q` again to stop). Vim used `q{reg}`.
  - `q` — replay the macro. Vim used `@{reg}`.
  - Record to a named register with `"a Q`… , replay with `"a q`.

---

## Leader / Space menu (the LSP + picker hub)

Helix has a `Space` leader menu that covers what you'd wire up with Telescope,
fzf, and LSP mappings in Neovim. It's discoverable — press `Space` and a popup
lists everything.

| Neovim (typical)              | Helix         |
|-------------------------------|---------------|
| `:Telescope find_files`       | `Space f`     |
| `:Telescope live_grep`        | `Space /`     |
| `:Telescope buffers`          | `Space b`     |
| Code action                   | `Space a`     |
| Rename symbol                 | `Space r`     |
| Hover / docs                  | `Space k`     |
| Symbol pickers                | `Space s` / `Space S` |
| Diagnostics picker            | `Space d` / `Space D` |
| File explorer                 | `Space e`     |

The `g` menu (goto) is also worth learning: `gd` definition, `gr` references,
`gi` implementation, `gy` type definition, `gg` top of file, `ge` end of file,
`gt`/`gc`/`gb` top/center/bottom of screen, `gn`/`gp` next/prev buffer.

LSP works out of the box for many languages — just install the language server
binary; no `nvim-lspconfig` equivalent to hand-wire.

---

## Everyday things that have a different key

| Task                          | Vim                  | Helix |
|-------------------------------|----------------------|-------|
| Comment / uncomment line      | `gcc` (plugin)       | `Ctrl-c` |
| Comment selection             | `gc` (plugin)        | select, `Ctrl-c` |
| Increment / decrement number  | `Ctrl-a` / `Ctrl-x`  | `Ctrl-a` / `Ctrl-x` (same) |
| Change case toggle            | `~`                  | `~` (on selection) |
| Lowercase / uppercase         | `gu` / `gU`          | `` ` `` / `` Alt-` `` |
| Align columns                 | (plugin, e.g. Tabular)| `&` |
| Jump to line label / EasyMotion| `<leader>` (plugin) | `gw` (2-char labels) |
| Save position to jumplist     | (implicit)           | `Ctrl-s` |
| Jumplist back / forward       | `Ctrl-o` / `Ctrl-i`  | `Ctrl-o` / `Ctrl-i` (same) |

---

## Windows & splits

Familiar `Ctrl-w`-based model, but it opens a **menu** (press `Ctrl-w` and see
options). Movement between splits is the same `Ctrl-w h/j/k/l`.

| Task                              | Helix |
|-----------------------------------|-------|
| New vertical / horizontal split (empty buffer) | `Ctrl-w nv` / `Ctrl-w ns` |
| Split current buffer vert / horiz | `Ctrl-w v` / `Ctrl-w s` |
| Move between splits               | `Ctrl-w h/j/k/l` |
| Close split / close others        | `Ctrl-w q` / `Ctrl-w o` |
| Swap split position               | `Ctrl-w` then `H/J/K/L` |
| Transpose split layout            | `Ctrl-w t` |
| Split via command                 | `:vs FILE` / `:hs FILE` |
| Open picked file in split         | `Ctrl-v` (vert) / `Ctrl-s` (horiz) from file picker |

---

## Things Vim has that Helix does *not* (and what to do instead)

- **No operator + motion grammar** (`d2j`, `y}`) → select first (`2xd`, `mi{y`).
- **No visual-block mode** → use multiple cursors (`C`, `Alt-s`, `s`).
- **No Ex `:s` habit** → use `%` `s` (select-then-change). `:s` exists but the
  selection workflow is the idiomatic path.
- **No Vimscript / init.vim** → config is `~/.config/helix/config.toml` (TOML),
  languages in `languages.toml`, keys under `[keys.normal]` etc. No scripting
  language; plugin system (Steel/Scheme) is still emerging.
- **No `set clipboard=unnamedplus`** as such → `Space y` / `Space p`, or set a
  default yank register.
- **`.` won't repeat a whole change** → macros (`Q` / `q`) for anything beyond a
  bare insertion.

---

## A 5-minute reflex cheat sheet

Just retrain these and you'll be productive immediately:

1. **Select, then act.** Word forward + delete is `wd`, not `dw`.
2. **`x` selects a line.** Delete a char is just `d`.
3. **`c` / `d` need no motion** — they hit the selection.
4. **Text objects & surround = `m`.** `mi(`, `ma"`, `ms)`, `md(`, `mr([`, `mm`.
5. **Find/replace = `%` `s` … then `c`.** Watch it select, then change.
6. **Redo is `U`. Macros are `Q` to record, `q` to play.**
7. **System clipboard = `Space y` / `Space p`.**
8. **Multiple cursors replace visual-block and most macros:** `C`, `s`, `Alt-s`.
9. **`Space` opens the everything-menu** (files, grep, LSP, actions).
10. **`Alt-d` / `Alt-c`** delete/change without touching your yank.

---

*Run `hx --tutor` inside Helix for the full interactive tutorial — this guide is
the "you already know Vim" express lane.*
