How the analyser finds a shorter route
There are two checks, and neither searches all of Vim. On every exercise, par is the length of one reference route that was replayed in this site's editor before the site was published.
In a practice set, in challenges and on your own text, the analyser also takes each edit you made and tries c and d with fourteen text objects from where your cursor was. It names one only if it gives exactly the same text in at least three fewer keys.
How keys are counted
Every key you press in the editor counts once. Text you type in Insert mode counts one key per character, spaces included. Esc, Enter and a Ctrl combination count as one key each. Shift does not count on its own, so A is one key.
On your own text, pasted text is not counted and is left out of the comparison.
Par: one checked route per exercise
Every lesson exercise has a reference route, written with the lesson. Every practice task has one too, made by the task generator: the cheapest of a fixed set of ways to reach the place (j or k with a count, a line number and G, or a short / search, then f, t, F, w, e, b, 0, ^ or $), followed by the edit.
Before the site is built, each route is replayed in the editor the pages load: CodeMirror with its Vim mode. A route that does not produce the desired result stops the build. Par is the number of keys in the route that passed.
So par is a route that is known to work, not the shortest edit possible. The analyser can hold several routes for one exercise and take the shortest as par, but every exercise on the site has one route today. If you find a shorter way, you finish under par.
Example: par on a lesson exercise
This exercise is from the lesson “Edit a whole word”. The cursor starts on the t of waiting. The task: Change waiting to active. Preserve the parentheses and punctuation.
«const reminder = "Keep this line unchanged."; const label = "(waiting)";», cursor on «t», column 20
«const reminder = "Keep this line unchanged."; const label = "(active)";»
| Route | Keys | Count |
|---|---|---|
| Reference route (par) | ciwtype activeEsc | 10 |
| A longer way | F(ldt)itype activeEsc | 14 |
What the lesson's result card says after the longer way
Solved in 14 keys. Par 10.
Deleted, then entered Insert mode. For a replacement, c{motion} deletes the chosen range and enters Insert mode.
Both routes leave the same text. The longer one moves to the bracket and deletes up to the next one; ciw takes the whole word from where the cursor already is. On a lesson page the result card shows the par route as its tip when you typed more keys than par, unless the analyser has a note about a technique to show instead.
The shorter-route check
An exercise knows its reference route. Your own text has none: there is only what the text was, what it became and where the cursor stood. So after you edit, the analyser asks the engine a narrower question: from that exact position, does an operator with a text object produce that exact text in fewer keys?
First it splits what you typed into edits. An edit runs from the last change up to and including the key that changed the text, so the moves you made to get somewhere belong to the edit they were for. Insert mode stays part of one edit until you press Esc.
Then it looks at each edit, and at up to three edits in a row taken together, because a delete and the typing after it are often one change in your head and one c in Vim. For each, it tries c and d with these text objects, replaying every candidate in the editor from where the cursor was when the first edit began:
iwawi"a"i'a'i(a(i[a[i{a{itat
A c candidate retypes the text you typed. A candidate counts only if the replay gives the same text as your edit did and is at least three keys shorter. y is never tried, because copying does not change the text.
Example: a shorter route on your own text
Change not ready to ready now. The cursor starts at the beginning of the line.
«const state = "not ready";», cursor on «c», column 1
«const state = "ready now";»
| Edit | Keys | Count |
|---|---|---|
| Edit 1 | f"ldw | 5 |
| Edit 2 | dw | 2 |
| Edit 3 | itype ready nowEsc | 11 |
| Your 3 edits | f"ldwdwitype ready nowEsc | 18 |
| Same text, same cursor | ci"type ready nowEsc 5 keys fewer | 13 |
In this editor, ci" works from before the opening quote on the same line, so the check can start where the first edit did.
Example: a route the check does not find
Replace what is inside the brackets with final. The cursor starts at the beginning of the line.
«send(draft, true)», cursor on «s», column 1
«send(final)»
| Edit | Keys | Count |
|---|---|---|
| Edit 1 | f(ldt) | 6 |
| Edit 2 | itype finalEsc | 7 |
| Your 2 edits | f(ldt)itype finalEsc | 13 |
From inside the brackets, the 9-key route ci(type finalEsc would make the same change. Here is what the analyser's replay gives from each place:
«send(final)»
«finalsend(draft, true)»
With the cursor before the brackets, ci( does nothing in this site's editor (Vim 9.1 uses the next pair on the line, as the text objects guide notes), so the replay from where the edit began gives other text. The check does not try moving first, so a route that needs the cursor inside the brackets is never compared.
What the analyser cannot tell you
- On your own text it only suggests c or d with one of the fourteen text objects above. Counts, ., searches, macros, Visual mode and Ex commands are never suggested there.
- It looks at no more than three edits in a row, and it says nothing about savings of one or two keys.
- It starts from where your cursor was when the edit began. A route that only works after moving the cursor is not found.
- A match means the same text from the same starting point. It does not mean the route is the shortest possible, and the cursor and registers can end up in a different state from yours.
- Par is one route known to work, not a proof that nothing shorter exists.
- Everything is replayed in CodeMirror's Vim mode, not in Vim. It covers the commands the course teaches, not all of Vim. The guides' examples are also checked in Vim; the analyser's routes are not.
Try it
Edit any text of your own and press Analyse, or do a daily practice set and compare each edit with par.