vmp: the most ambitious vim emulator

## I'm t9md

<p>
<img width="80" alt="t9md__t9md_.png" src="https://qiita-image-store.s3.amazonaws.com/0/30758/8658e72b-629d-7d1b-49dc-9950f59409cd.png">

<img width="400" alt="Presentation1.png" src="https://qiita-image-store.s3.amazonaws.com/0/30758/b2fdbbe1-425b-0d53-6d7b-015122067b87.png">
</p>


- My editor history: Vim > Emacs > Vim > Atom
- Emacs's limitless extensibility plant never give up sprit to me and it also made me editor addict.
- Vim plugins: choosewin, qickhl, smalls, textmanip, vim-chef, and more
- Atom packages: vim-mode-plus, narrow, quick-highlight, cursor-history, and more..(over 30 pkgs!).

**Are you familiar with this endless editor tuning loop?**.

- Frustration > Yes I can improve it > Ya I did it!! Oh, I found another frustration point > oh, I've spent too much hours!.

---

## What is the [vim-mode-plus](https://github.com/t9md/atom-vim-mode-plus)(VMP)?

- It's Atom editor package which provides vim keybinding and plus more.
- This is fork of [vim-mode](https://github.com/atom/vim-mode) created by GitHub :octocat:, they now *deprecated it in favor of vmp*.

| Version | Date       | Event                                          |
|---------|------------|------------------------------------------------|
| v0.0.0  | 2015-08-01 | fork GitHub's vim-mode                         |
| v0.1.1  | 2015-09-28 | 1st public                                     |
| v1.13.0 | 2017-10-27 | 185th release in 818 days (2 years + 3 months) |

**AVG. 1 release / 4.5 days !!**

I'm still keeping high pace release cycle as first year of vmp.

---

## Who use vmp?

- Jordan Walke(ReactJS, ReasonML)
  - https://twitter.com/jordwalke/status/911889758208499712
- Cheng Lou(ReactMotions, ReasonML)
  - https://twitter.com/_chenglou/status/903159866172235776
- Richard Feldman(Elm book author, evangelist)
- Kent C Todd(Author of lots of npm modules and more).
  - https://twitter.com/kentcdodds/status/898888597465477123
- Michael Jackson(React Router, React Training)
  - https://twitter.com/mjackson/status/913551031656636416
- Ryan Florence(React Router, React Training)
  - https://twitter.com/ryanflorence/status/918346908225085440

Some says vmp is the best vim emulator.
IMO, maybe it's because of precise cursor placement.(e.g. cursor placement after undo or redo operation).

---

## What I will talk today

### Part1. Understand editing in Vim

- What is editing in Vim
- How it's implemented and executed
- What is Motion, TextObject and Operator

### Part2. vmp's unique features

- UX improvement
- Cursor placement
- One key TextObject
- Occurrence

---

## Part1. Understand editing in Vim

---

## What is editing in Vim?

<img width="750" alt="slide-picture.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/30758/a561f971-012f-5fc5-e773-55f821cc1119.jpeg">

---

## Why can your `j` keystroke move-down cursors

<img width="700" alt="slide-picture.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/30758/9e5ae11b-c063-38b9-b076-b80d3bf88527.jpeg">

---

## Operation's life in stack on operationStack

<img width="650" alt="slide-picture.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/30758/72d83050-c2c4-2584-d5b1-eac196924c81.jpeg">

---

## Motion, TextObject, Operator

### Motion: `j`, `k`, `{`, `g g`...

- Move cursor from **here to there**.
- When used as **TARGET**, select **here-to-there**.

### TextObject: `i p`, `i w`, `a W`...

- Select text range, always used as **TARGET**.
- Select same range as long as cursor is within that range
  - `i w` select same word as long as cursor is within that word.

### Operator: `d`, `c`, `y`...

- Mutate **TARGET**
- Always require **TARGET**. "I will wait until I get target!".

---

## Summary

### Editing is to transform text by mutation.

### You build mutation instruction through keystroke.

### Each keystroke invoke one of Operator, Motion or TextObject.

### Formula: **Mutation = Operator + Target(= Motion or TextObject)**

---

## Part2. VMP's unique features

---

## :camera_with_flash: DEMO session

[demo file I used in talk](https://gist.github.com/t9md/bf6f1458de2794e214e5100f87b7fb7d#file-vmpdemo-js)

- Select operator
- TransformString operators
- Edge motion
- Occurrence
- Persistent selection
- Practical use of occurrence etc...

---

## Flash target :flashlight:

- :bulb: vmp flashes an operator's target and also flashes changes on `undo`, `redo`.
- When you type `y i p`, it flashes `i p` range with CSS keyframe animation.
- With flash, you can be more confident for your operation.

![flashOnOperate.gif](https://qiita-image-store.s3.amazonaws.com/0/30758/52ca3604-9ec3-d4fa-bcdf-493fad508df5.gif)

---

## UI feedback on surround

- :bulb: Surround is difficult for me.
- Because I have to type many keystrokes without mistake, without any UI feedback.
  - `y s i w (`: surround(`y s`) inner-word(`i w`) with `(`.
- vmp gives proper UI feedback to make surround easy to use, easy to understand
  - Select target immediately after target was provide(`i w`) and before you input final surround-char.
  - When `change-surround`, it shows char will be change at hover indicator.

- This GIF is after you type `c s "` and before you input final `'`
<img width="500" alt="main.js" src="https://qiita-image-store.s3.amazonaws.com/0/30758/66998de2-7bd1-b43d-03f7-6edc86834080.jpeg">

---

## Tunable `f` behavior and flash find-char.

- :bulb: `f` is difficult. Where to stop next?.
- With flashing finding-char, you can predict where to stop next.
- :bulb: I like all `vim-seek`, `clever-f` and `vim-sneak`, I want all of it's goodness.
  - Make it configurable to `find across lines`, `number of chars to find`, `auto confirm by timeout`, `reuse f as ;`...
  - You can tune vmp's `f` as you like.

![find.gif](https://qiita-image-store.s3.amazonaws.com/0/30758/4c008c34-656b-99a8-b88b-6f10bfa5e0dd.gif)

---

## Eliminate unwanted cursor move

- :bulb: What if cursor is not moved after `y i p`?
  - In pure-Vim, cursor is moved to start of paragraph.
- IMO, moving cursor after operator is unwanted side-effect.
- :gift: vmp introduces various **stayOnXXX** configuration and all have enabled by default.
  - In pure-Vim, `stayOnVerticalMotion` + `stayOnDelete` is doable by `:set startofline=false`

## stayOnXXX configurations

- Keep cursor positions after operator `y i p`, `d d`, `g U i p`..
  - `stayOnTransformString`, `stayOnYank`, `stayOnDelete`, `stayOnOccurrence`
- Keep column when selecting TextObject `v i p`, `v i i`..
  - `stayOnSelectTextObject`
- keep column on vertical motion `g g`, `G`...
  - `stayOnVerticalMotion`

---

## One-key for VIP(Very ImPortant) TextObject

- :gift: You can type `y p` instead of `y i p`. How many times have you ever typed `i p` in your life!?
- :tada: Why? Some keys are **freely available** in **operator-pending-mode**.
- :question: Since **Operator** is waiting for Target(**Motion** or **TextObject**) only. Remember `Operator + Target` rule?.
- :mag_right: So `Operator + Operator` keystroke(`y d`, `d p`...) makes no sense, OK to **re-map**.
  - :warning: One exception, same-operator-twice(`d d`, `y y`...) keystrokes have special meaning.

![shorthand.gif](https://qiita-image-store.s3.amazonaws.com/0/30758/9751a80a-4dae-3b66-8ec1-9353bab97a2f.gif)

---

## Occurrence

- :bulb: Noticed patterns in coding. I'm repeating same operation on same keyword again and again.
- :gift: With `occurrence`, you can **bulk apply operator to all occurrences of keyword within target**.
- You can edit more declaratively than imperatively, also can reduces need of `.` repeat.

![cof.gif](https://qiita-image-store.s3.amazonaws.com/0/30758/82137963-e000-16b7-0c29-fc0dd6a0b2e5.gif)

## Occurrence: How it works

<p>
<img width="350" alt="occurrence" src="https://qiita-image-store.s3.amazonaws.com/0/30758/947a35f3-4889-2a44-9878-8f7aef80ffe1.jpeg">
<img width="500" alt="slide-picture.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/30758/e01f71cf-e147-08d6-8002-edac1574634c.jpeg">
</p>

##### Occurrence is not difficult, technically it's marker edit

- **Mark keyword under cursor** then edit as in normal way.
- You can **mark** keyword by either of following way
  - operator-modifier: `o`(word) and `O`(subword).(e.g. `d o p`, `c O z`)
  - `preset-occurrence` command: `g o` and `g O`. *I'm remapping to `m` and `M` locally.*

1. Mark keyword by `g o` or `g O`(subword)
2. Select visually
3. `c` to change, `I` to insert at start `A` to append to end of occurrence.

---

## :beginner: Advice to improve vim-skill

- :mortar_board: Understand this formula. **Editing = Operator + Target(Motion or TextObject)**.
  - :loudspeaker: Install `Operator + Target` mental model into your brain by shouting loudly while typing.
  - `y`("Operator"!!) `i p`("Target!!")

- :chart_with_upwards_trend: Pick and master from high-return Motion, TextObject first.
  - Motion: `g g`, `G`, `[`, `]`(VMP only)
  - TextObjet: `i p`, `i w`, `i z`(VMP only), `i ,`(VMP only)

- :rice: Use it in daily editing.

- :musical_keyboard: Repeat, repeat, repeat! Till your finger moves without THINKING.
  - Vim: `y i p`, `y i p`, `y i p`... `c i p`, `c i p`... `d i p`...
  - Vim: `y i ,`, `y i ,`, `y i ,`... `c i ,`, `c i ,`... `d i ,`...
  - vmp shorthand: `y p`, `y p`, `y p`... `c p`, `c p`... `d p`...
  - vmp shorthand: `y ,`, `y ,`, `y ,`... `c ,`, `c ,`... `d ,`...

- :syringe: Gradually increase TextObject, Motion of daily use.

---

## :wave:: VMP is the most ambitious vim emulator in the world(IMO!).

- :gift: Bundled so many non-default Motion, TextObject, Operator.
- :gift: Introduces new editing concept: e.g. `occurrence`, `persistent-selection`.
- :heart: UX improvement to make Vim easy to use, easy to understand.
- :bomb: vmp is NOT aiming to become a perfect Vim emulator(no interest!).
- :ghost: My mental stance is just **borrowing** favorite Vim features.
- :bulb: Motivation is to experiment **what-if** ideas with hackable editor(Atom!).
- :skull: Ideas comes from frustration I encounter in daily vmp-dev. Endless feedback loop!
- I'm really SERIOUS for vmp, but vmp is NOT STRICT.

##### This GIF is now removed "show operator representing emoji" feature. You see how vmp is **NOT strict**?

![emoji.gif](https://qiita-image-store.s3.amazonaws.com/0/30758/e8de966a-6456-89b0-cbfe-f2e4a10c2e02.gif)

---

## :bow: Thank you!!! :bow: