vimniscient 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vimniscient-0.2.0 → vimniscient-0.2.1}/PKG-INFO +1 -1
- {vimniscient-0.2.0 → vimniscient-0.2.1}/pyproject.toml +1 -1
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/answer.py +2 -2
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cards/lazyvim.yaml +1 -1
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cards/shell.yaml +3 -3
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cards/vim.yaml +2 -2
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cards.py +1 -1
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/generate.py +3 -23
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/habits.py +2 -1
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/sources.md +3 -3
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w1d1-words.yaml +0 -39
- vimniscient-0.2.1/src/vimniscient/lessons/w1d2-pairs.yaml +101 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w1d3-sentences.yaml +115 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w1d4-find.yaml +90 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w1d5-lines.yaml +132 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w1d6-counts.yaml +171 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w1d7-review.yaml +15 -103
- vimniscient-0.2.1/src/vimniscient/lessons/w2d1-dot.yaml +93 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w2d2-search.yaml +0 -91
- vimniscient-0.2.1/src/vimniscient/lessons/w2d3-cgn.yaml +92 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w2d4-case-numbers.yaml +100 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w2d5-insert.yaml +106 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w2d6-visual.yaml +102 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w2d7-review.yaml +98 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w3d1-macros.yaml +18 -125
- vimniscient-0.2.1/src/vimniscient/lessons/w3d2-macros-more.yaml +96 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w3d3-registers.yaml +3 -104
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w3d4-marks.yaml +5 -89
- vimniscient-0.2.1/src/vimniscient/lessons/w3d5-visual-block.yaml +113 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w3d6-substitute.yaml +162 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w3d7-review.yaml +114 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w4d1-ranges.yaml +122 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w4d2-sort-filter.yaml +137 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w4d3-regex.yaml +23 -92
- vimniscient-0.2.1/src/vimniscient/lessons/w4d4-norm.yaml +90 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w4d5-motions.yaml +6 -67
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w4d6-indent.yaml +18 -77
- vimniscient-0.2.1/src/vimniscient/lessons/w4d7-review.yaml +100 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w5d1-arguments.yaml +82 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w5d2-any-quote-bracket.yaml +4 -58
- vimniscient-0.2.1/src/vimniscient/lessons/w5d3-functions.yaml +110 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w5d4-small-objects.yaml +107 -0
- vimniscient-0.2.1/src/vimniscient/lessons/w5d5-comments.yaml +96 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w5d6-review.yaml +0 -18
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/nvim/runner.lua +34 -24
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/main.py +11 -1
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_answers.py +2 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_app.py +10 -0
- vimniscient-0.2.0/src/vimniscient/lessons/w1d2-pairs.yaml +0 -188
- vimniscient-0.2.0/src/vimniscient/lessons/w1d3-sentences.yaml +0 -247
- vimniscient-0.2.0/src/vimniscient/lessons/w1d4-find.yaml +0 -184
- vimniscient-0.2.0/src/vimniscient/lessons/w1d5-lines.yaml +0 -249
- vimniscient-0.2.0/src/vimniscient/lessons/w1d6-counts.yaml +0 -351
- vimniscient-0.2.0/src/vimniscient/lessons/w2d1-dot.yaml +0 -195
- vimniscient-0.2.0/src/vimniscient/lessons/w2d3-cgn.yaml +0 -196
- vimniscient-0.2.0/src/vimniscient/lessons/w2d4-case-numbers.yaml +0 -201
- vimniscient-0.2.0/src/vimniscient/lessons/w2d5-insert.yaml +0 -229
- vimniscient-0.2.0/src/vimniscient/lessons/w2d6-visual.yaml +0 -206
- vimniscient-0.2.0/src/vimniscient/lessons/w2d7-review.yaml +0 -197
- vimniscient-0.2.0/src/vimniscient/lessons/w3d2-macros-more.yaml +0 -170
- vimniscient-0.2.0/src/vimniscient/lessons/w3d5-visual-block.yaml +0 -201
- vimniscient-0.2.0/src/vimniscient/lessons/w3d6-substitute.yaml +0 -290
- vimniscient-0.2.0/src/vimniscient/lessons/w3d7-review.yaml +0 -204
- vimniscient-0.2.0/src/vimniscient/lessons/w4d1-ranges.yaml +0 -214
- vimniscient-0.2.0/src/vimniscient/lessons/w4d2-sort-filter.yaml +0 -243
- vimniscient-0.2.0/src/vimniscient/lessons/w4d4-norm.yaml +0 -158
- vimniscient-0.2.0/src/vimniscient/lessons/w4d7-review.yaml +0 -175
- vimniscient-0.2.0/src/vimniscient/lessons/w5d1-arguments.yaml +0 -133
- vimniscient-0.2.0/src/vimniscient/lessons/w5d3-functions.yaml +0 -193
- vimniscient-0.2.0/src/vimniscient/lessons/w5d4-small-objects.yaml +0 -185
- vimniscient-0.2.0/src/vimniscient/lessons/w5d5-comments.yaml +0 -161
- {vimniscient-0.2.0 → vimniscient-0.2.1}/.gitignore +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/LICENSE +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/README.md +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/extras/nvim/vimniscient.lua +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/__init__.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/__main__.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/app.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cards/foot.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cards/zathura.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/cli.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/drills/omarchy.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/drills.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/endless.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/keys.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w6d1-code.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w6d2-notes.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons/w6d3-data.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/lessons.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/mnemonics.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/mnemonics.yaml +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/nvim/keymaps.lua +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/progress.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/reminders.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/session.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/settings.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/srs.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/today.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/__init__.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/builtin_lessons.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/cards.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/common.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/drills.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/lesson.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/ui/stats.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/src/vimniscient/vimgolf.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_drills.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_generate.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_lessons.lua +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_lessons.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_timing.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/check_today.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/live_drills.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/live_endless.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/live_lessons.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/live_retry.py +0 -0
- {vimniscient-0.2.0 → vimniscient-0.2.1}/tests/live_review.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vimniscient
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Get fluent in Vim in fifteen minutes a day, in your own Neovim.
|
|
5
5
|
Project-URL: Homepage, https://vimniscient.com
|
|
6
6
|
Project-URL: Source, https://github.com/dialectmaterial/Vimniscient
|
|
@@ -40,7 +40,7 @@ def _norm_token(match: re.Match) -> str:
|
|
|
40
40
|
|
|
41
41
|
def norm_keys(text: str, case_sensitive: bool = True) -> str:
|
|
42
42
|
s = text.strip()
|
|
43
|
-
s = re.sub(r"(?i)^(leader|space|spc)(\s+|$)", "<leader>", s)
|
|
43
|
+
s = re.sub(r"(?i)^(leader|space|spc)(\s*\+\s*|\s+|$)", "<leader>", s)
|
|
44
44
|
s = re.sub(r"(?i)(?<![<\w])space(?![>\w])", "<Space>", s)
|
|
45
45
|
s = re.sub(r"(?i)\b(?:ctrl|control)[-+ ]+(\S)", lambda m: f"<C-{m.group(1)}>", s)
|
|
46
46
|
s = re.sub(r"(?i)\b(?:alt|meta)[-+ ]+(\S)", lambda m: f"<M-{m.group(1)}>", s)
|
|
@@ -55,7 +55,7 @@ _MOD_ALIASES = {
|
|
|
55
55
|
"SUPER": "SUPER", "WIN": "SUPER", "CMD": "SUPER", "MOD": "SUPER", "LOGO": "SUPER",
|
|
56
56
|
"CTRL": "CTRL", "CONTROL": "CTRL", "CTL": "CTRL",
|
|
57
57
|
"ALT": "ALT", "OPT": "ALT", "OPTION": "ALT", "MOD1": "ALT", "META": "ALT",
|
|
58
|
-
"SHIFT": "SHIFT", "PREFIX": "PREFIX", "COPYMODE": "COPYMODE",
|
|
58
|
+
"SHIFT": "SHIFT", "PREFIX": "PREFIX", "LEADER": "PREFIX", "COPYMODE": "COPYMODE",
|
|
59
59
|
}
|
|
60
60
|
_KEY_ALIASES = {
|
|
61
61
|
"ENTER": "RETURN", "CR": "RETURN", "ESC": "ESCAPE", "DEL": "DELETE", "INS": "INSERT",
|
|
@@ -12,7 +12,7 @@ cards:
|
|
|
12
12
|
- {prompt: Grep the project (root dir), answer: [<leader>/, <leader>sg]}
|
|
13
13
|
- {prompt: Switch buffer, answer: ['<leader>,', '<leader>fb']}
|
|
14
14
|
- {prompt: Recent files, answer: [<leader>fr]}
|
|
15
|
-
- {prompt: File explorer (neo-tree), answer: [<leader>e]}
|
|
15
|
+
- {prompt: File explorer (neo-tree), answer: [<leader>e], note: 'e is explorer.'}
|
|
16
16
|
- {prompt: Next buffer, answer: [<S-l>, ']b']}
|
|
17
17
|
- {prompt: Previous buffer, answer: [<S-h>, '[b']}
|
|
18
18
|
- {prompt: Delete the buffer, answer: [<leader>bd]}
|
|
@@ -5,9 +5,9 @@ case_sensitive: false
|
|
|
5
5
|
note: Readline keys work in bash and in most terminal prompts.
|
|
6
6
|
cards:
|
|
7
7
|
- {prompt: Search back through your command history, answer: [<C-r>]}
|
|
8
|
-
- {prompt: Jump to the start of the line, answer: [<C-a>, <Home>]}
|
|
9
|
-
- {prompt: Jump to the end of the line, answer: [<C-e>, <End>]}
|
|
10
|
-
- {prompt: Delete the word before the cursor, answer: [<C-w>]}
|
|
8
|
+
- {prompt: Jump to the start of the line, answer: [<C-a>, <Home>], note: 'a is the start of the alphabet. The shell isn’t Vim: 0 and $ just type themselves.'}
|
|
9
|
+
- {prompt: Jump to the end of the line, answer: [<C-e>, <End>], note: 'e is end. The shell isn’t Vim: $ just types itself.'}
|
|
10
|
+
- {prompt: Delete the word before the cursor, answer: [<C-w>], note: 'w is word.'}
|
|
11
11
|
- {prompt: Delete from the cursor to the start of the line, answer: [<C-u>]}
|
|
12
12
|
- {prompt: Delete from the cursor to the end of the line, answer: [<C-k>]}
|
|
13
13
|
- {prompt: Paste what you just deleted with Ctrl-w/u/k, answer: [<C-y>]}
|
|
@@ -7,8 +7,8 @@ case_sensitive: true
|
|
|
7
7
|
cards:
|
|
8
8
|
# week 1: text objects, find/till, lines, counts
|
|
9
9
|
- {week: 1, day: 1, prompt: 'Change the whole word under the cursor, wherever in it the cursor is', answer: [ciw], note: 'cw only changes from the cursor to the end of the word.'}
|
|
10
|
-
- {week: 1, day: 1,
|
|
11
|
-
- {week: 1, day: 1,
|
|
10
|
+
- {week: 1, day: 1, id: 'vim:Delete a word and the space after it', prompt: 'Delete the whole word under the cursor, wherever in it the cursor is, and the space after it', answer: [daw], note: 'dw only deletes from the cursor on.'}
|
|
11
|
+
- {week: 1, day: 1, id: 'vim:Change a WORD (space to space, punctuation included)', prompt: 'Change the whole WORD under the cursor (space to space, punctuation included), keeping the space after it', answer: [ciW]}
|
|
12
12
|
- {week: 1, day: 1, prompt: Yank the word under the cursor, answer: [yiw]}
|
|
13
13
|
- {week: 1, day: 2, prompt: Change everything inside the double quotes, answer: ['ci"']}
|
|
14
14
|
- {week: 1, day: 2, prompt: Delete the quotes and what is inside them, answer: ['da"']}
|
|
@@ -77,7 +77,7 @@ def _static_decks() -> dict[str, Deck]:
|
|
|
77
77
|
deck.cards.append(
|
|
78
78
|
Card(
|
|
79
79
|
deck=deck.id,
|
|
80
|
-
id=f"{deck.id}:{c['prompt']}",
|
|
80
|
+
id=c.get("id", f"{deck.id}:{c['prompt']}"), # `id` keeps a reworded card's history
|
|
81
81
|
prompt=c["prompt"],
|
|
82
82
|
answers=[str(a) for a in c["answer"]],
|
|
83
83
|
style=data.get("style", "keys"),
|
|
@@ -6,8 +6,8 @@ practised on sentences you haven't seen. The same seed always gives the same
|
|
|
6
6
|
task, so a run can be replayed and every kind can be checked in Neovim
|
|
7
7
|
(tests/check_generate.py).
|
|
8
8
|
|
|
9
|
-
The sentences stay mnemonic: they're the hooks from mnemonics.yaml
|
|
10
|
-
stand for
|
|
9
|
+
The sentences stay mnemonic: they're the hooks from mnemonics.yaml, what keys
|
|
10
|
+
stand for.
|
|
11
11
|
|
|
12
12
|
Kinds, all word text objects (w1d1):
|
|
13
13
|
ciw-typo two letters of a word swapped; ciw and type it right
|
|
@@ -25,31 +25,11 @@ from vimniscient.mnemonics import _tables
|
|
|
25
25
|
|
|
26
26
|
KINDS = ("ciw-typo", "daw-double", "ciW-dotted")
|
|
27
27
|
|
|
28
|
-
# Facts from lessons/sources.md, one sentence each.
|
|
29
|
-
FACTS = [
|
|
30
|
-
"Ebbinghaus tested himself on nonsense syllables and published his results in 1885.",
|
|
31
|
-
"Forgetting is steepest right after learning, then the curve levels off.",
|
|
32
|
-
"Miller wrote about the magical number seven, plus or minus two.",
|
|
33
|
-
"Cowan later argued that short-term memory holds about four chunks.",
|
|
34
|
-
"Retrieval practice beat restudying on a test a week later.",
|
|
35
|
-
"Restudying looked better after five minutes, which is why it feels like it works.",
|
|
36
|
-
"Spacing reviews out is among the best replicated findings about memory.",
|
|
37
|
-
"Sleep after learning helps new memories stabilise.",
|
|
38
|
-
"Rereading makes text feel familiar, and people mistake that for knowing it.",
|
|
39
|
-
"Words read aloud are remembered better than words read silently.",
|
|
40
|
-
"Mixed practice feels harder than blocked practice but tests better later.",
|
|
41
|
-
"Practising with variation helps a skill carry over to new conditions.",
|
|
42
|
-
"Trying to recall an answer before seeing it helps you remember it later.",
|
|
43
|
-
"Fitts and Posner described three stages of skill: cognitive, associative and autonomous.",
|
|
44
|
-
"Desirable difficulties make learning feel harder but make it last.",
|
|
45
|
-
]
|
|
46
|
-
|
|
47
|
-
|
|
48
28
|
@cache
|
|
49
29
|
def sentences() -> list[str]:
|
|
50
30
|
hooks = list(dict.fromkeys(hook for table in _tables()[:2] for hook in table.values()))
|
|
51
31
|
# as written: a capital would change the key ("u is down" is not "U is down")
|
|
52
|
-
return [h + ("" if h.endswith(".") else ".") for h in hooks]
|
|
32
|
+
return [h + ("" if h.endswith(".") else ".") for h in hooks]
|
|
53
33
|
|
|
54
34
|
|
|
55
35
|
_WORD = re.compile(r"(?<![\w'.-])[A-Za-z]{4,}(?![\w'-])")
|
|
@@ -15,6 +15,7 @@ from pathlib import Path
|
|
|
15
15
|
|
|
16
16
|
from vimniscient.cards import Card, Deck
|
|
17
17
|
from vimniscient.keys import split_keys
|
|
18
|
+
from vimniscient.mnemonics import OPERATORS
|
|
18
19
|
|
|
19
20
|
LOG = Path(os.environ.get("XDG_STATE_HOME", Path.home() / ".local/state")) / "nvim" / "hardtime.nvim.log"
|
|
20
21
|
|
|
@@ -91,7 +92,7 @@ def habit_deck() -> Deck:
|
|
|
91
92
|
answers=[better],
|
|
92
93
|
style="keys",
|
|
93
94
|
case_sensitive=True,
|
|
94
|
-
note=f"hardtime caught this {habit.total}×.",
|
|
95
|
+
note=f"{'Verb first, then the motion. ' if better[0] in OPERATORS else ''}hardtime caught this {habit.total}×.",
|
|
95
96
|
order=i,
|
|
96
97
|
)
|
|
97
98
|
)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Sources for the facts in the lesson texts
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
`../mnemonics.yaml`)
|
|
5
|
-
Every factual claim
|
|
3
|
+
Lesson practice texts are mnemonic: each one is about the keys it practises (see
|
|
4
|
+
`../mnemonics.yaml`). Memory science belongs in lesson intros, where it explains
|
|
5
|
+
why the training works. Every factual claim there should trace back to one of these.
|
|
6
6
|
|
|
7
7
|
- **Atkinson & Raugh (1975).** An application of the mnemonic keyword method to
|
|
8
8
|
the acquisition of a Russian vocabulary. *JEP: Human Learning and Memory*
|
|
@@ -32,12 +32,6 @@ tasks:
|
|
|
32
32
|
target: |-
|
|
33
33
|
Change inner word: c is the verb, iw the noun, and the cursor sits anywhere in it.
|
|
34
34
|
solution: 'ciwanywhere<Esc>'
|
|
35
|
-
- goal: 'Fix "memroy" to "memory" (the cursor is in the middle of the word).'
|
|
36
|
-
start: |-
|
|
37
|
-
Testing yourself beats rereading: type ciw from mem▮roy, not from the page.
|
|
38
|
-
target: |-
|
|
39
|
-
Testing yourself beats rereading: type ciw from memory, not from the page.
|
|
40
|
-
solution: 'ciwmemory<Esc>'
|
|
41
35
|
- goal: 'Fix "undersocres" to "underscores" (the cursor is in the middle of the word).'
|
|
42
36
|
start: |-
|
|
43
37
|
In ciw, the w is a word: letters, digits and under▮socres, nothing else.
|
|
@@ -64,11 +58,6 @@ tasks:
|
|
|
64
58
|
daw takes a word and what is around it, its ▮its trailing space.
|
|
65
59
|
target: |-
|
|
66
60
|
daw takes a word and what is around it, its trailing space.
|
|
67
|
-
- goal: 'Delete one "himself".'
|
|
68
|
-
start: |-
|
|
69
|
-
Ebbinghaus tested ▮himself himself on nonsense syllables; daw cuts the echo.
|
|
70
|
-
target: |-
|
|
71
|
-
Ebbinghaus tested himself on nonsense syllables; daw cuts the echo.
|
|
72
61
|
- goal: 'Delete one "so".'
|
|
73
62
|
start: |-
|
|
74
63
|
With daw, a means around: the word goes, and ▮so so does one space.
|
|
@@ -101,12 +90,6 @@ tasks:
|
|
|
101
90
|
target: |-
|
|
102
91
|
ciW sees a path as one WORD, slashes and all.
|
|
103
92
|
solution: 'ciWa path<Esc>'
|
|
104
|
-
- goal: 'Replace "Fitts&Posner(1967)" with "Fitts-and-Posner".'
|
|
105
|
-
start: |-
|
|
106
|
-
ciW: from space to space, Fitts&Pos▮ner(1967) counts as one WORD.
|
|
107
|
-
target: |-
|
|
108
|
-
ciW: from space to space, Fitts-and-Posner counts as one WORD.
|
|
109
|
-
solution: 'ciWFitts-and-Posner<Esc>'
|
|
110
93
|
- goal: 'Spell the function name out as change_inner_word.'
|
|
111
94
|
ft: python
|
|
112
95
|
start: |-
|
|
@@ -180,18 +163,6 @@ tasks:
|
|
|
180
163
|
target: |-
|
|
181
164
|
viwp swaps a selection for the yank, so select, then put the yank
|
|
182
165
|
solution: 'yiw$viwp'
|
|
183
|
-
- goal: 'Copy "spaced" over "massed".'
|
|
184
|
-
start: |-
|
|
185
|
-
▮spaced reviews beat massed ones, so keep them massed
|
|
186
|
-
target: |-
|
|
187
|
-
spaced reviews beat massed ones, so keep them spaced
|
|
188
|
-
solution: 'yiw$viwp'
|
|
189
|
-
- goal: 'Copy "mixed" over the last "blocked".'
|
|
190
|
-
start: |-
|
|
191
|
-
Rohrer and Taylor: blocked practice feels better than ▮mixed, yet scores below blocked
|
|
192
|
-
target: |-
|
|
193
|
-
Rohrer and Taylor: blocked practice feels better than mixed, yet scores below mixed
|
|
194
|
-
solution: 'yiw$viwp'
|
|
195
166
|
- goal: 'Delete the doubled "the".'
|
|
196
167
|
start: |-
|
|
197
168
|
daw: delete a word, and ▮the the space after it.
|
|
@@ -206,16 +177,6 @@ tasks:
|
|
|
206
177
|
Doubled words ▮like like this one are what daw is for.
|
|
207
178
|
target: |-
|
|
208
179
|
Doubled words like this one are what daw is for.
|
|
209
|
-
- goal: 'Delete the doubled "four".'
|
|
210
|
-
start: |-
|
|
211
|
-
Cowan put short-term memory at about ▮four four chunks.
|
|
212
|
-
target: |-
|
|
213
|
-
Cowan put short-term memory at about four chunks.
|
|
214
|
-
- goal: 'Delete the doubled "familiar".'
|
|
215
|
-
start: |-
|
|
216
|
-
Rereading builds a fluency illusion: the text feels ▮familiar familiar, not known.
|
|
217
|
-
target: |-
|
|
218
|
-
Rereading builds a fluency illusion: the text feels familiar, not known.
|
|
219
180
|
- goal: 'Delete the doubled "and".'
|
|
220
181
|
start: |-
|
|
221
182
|
daw: d for delete, a for a word ▮and and its space.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
week: 1
|
|
2
|
+
day: 2
|
|
3
|
+
title: Quotes, brackets and tags
|
|
4
|
+
intro: |
|
|
5
|
+
The same `i`/`a` trick works on pairs, and the noun is simply the pair's own
|
|
6
|
+
sign: `i"` is inside the quotes, `a"` takes the quotes too. Brackets name
|
|
7
|
+
themselves the same way: `i(` `i[` `i{` `i<`. `t` is for *tag*: `it` is
|
|
8
|
+
inside an HTML tag. For quotes the cursor doesn't even have to be inside:
|
|
9
|
+
`ci"` jumps to the next quoted string on the line.
|
|
10
|
+
keys: ['ci"', 'da"', 'di(', 'da(', 'di[', 'cit']
|
|
11
|
+
tasks:
|
|
12
|
+
- goal: 'Set the string to "change inside".'
|
|
13
|
+
ft: python
|
|
14
|
+
start: |-
|
|
15
|
+
ci_quote = "▮delete outside"
|
|
16
|
+
target: |-
|
|
17
|
+
ci_quote = "change inside"
|
|
18
|
+
solution: 'ci"change inside<Esc>'
|
|
19
|
+
hint: 'c changes, i keeps it inside, " names the pair: ci".'
|
|
20
|
+
variants:
|
|
21
|
+
- goal: 'Set the string to "the quote names the pair".'
|
|
22
|
+
start: |-
|
|
23
|
+
quote_object = "▮brackets name it"
|
|
24
|
+
target: |-
|
|
25
|
+
quote_object = "the quote names the pair"
|
|
26
|
+
solution: 'ci"the quote names the pair<Esc>'
|
|
27
|
+
- goal: 'Set the string to "without the quotes".'
|
|
28
|
+
start: |-
|
|
29
|
+
inner_quote = "▮with the quotes"
|
|
30
|
+
target: |-
|
|
31
|
+
inner_quote = "without the quotes"
|
|
32
|
+
solution: 'ci"without the quotes<Esc>'
|
|
33
|
+
- goal: 'Change the string to "the quotes", starting from the beginning of the line.'
|
|
34
|
+
ft: python
|
|
35
|
+
start: |-
|
|
36
|
+
▮ci_quote_keeps = "nothing"
|
|
37
|
+
target: |-
|
|
38
|
+
ci_quote_keeps = "the quotes"
|
|
39
|
+
solution: 'ci"the quotes<Esc>'
|
|
40
|
+
hint: 'You don''t have to move first. ci" finds the next quotes on the line.'
|
|
41
|
+
variants:
|
|
42
|
+
- goal: 'Change the string to "the next quotes", starting from the beginning of the line.'
|
|
43
|
+
start: |-
|
|
44
|
+
▮ci_quote_finds = "nothing"
|
|
45
|
+
target: |-
|
|
46
|
+
ci_quote_finds = "the next quotes"
|
|
47
|
+
solution: 'ci"the next quotes<Esc>'
|
|
48
|
+
- goal: 'Empty the inner parentheses.'
|
|
49
|
+
ft: python
|
|
50
|
+
start: |-
|
|
51
|
+
di_paren(empties(▮this_part))
|
|
52
|
+
target: |-
|
|
53
|
+
di_paren(empties())
|
|
54
|
+
solution: 'di('
|
|
55
|
+
hint: 'di( deletes inside the innermost parentheses around the cursor.'
|
|
56
|
+
variants:
|
|
57
|
+
- start: |-
|
|
58
|
+
inner_paren(keeps(▮only_the_brackets))
|
|
59
|
+
target: |-
|
|
60
|
+
inner_paren(keeps())
|
|
61
|
+
- goal: 'Delete the argument list, parentheses included.'
|
|
62
|
+
ft: python
|
|
63
|
+
start: |-
|
|
64
|
+
da = deletes(▮around, it) + parens
|
|
65
|
+
target: |-
|
|
66
|
+
da = deletes + parens
|
|
67
|
+
solution: 'da('
|
|
68
|
+
hint: 'a is around: da( deletes the parentheses too. (dab is the same thing.)'
|
|
69
|
+
variants:
|
|
70
|
+
- start: |-
|
|
71
|
+
parens_go = da(▮inside, and, out) + too
|
|
72
|
+
target: |-
|
|
73
|
+
parens_go = da + too
|
|
74
|
+
- goal: 'Empty the list.'
|
|
75
|
+
ft: python
|
|
76
|
+
start: |-
|
|
77
|
+
di_bracket_leaves = [▮"just", "the", "brackets"]
|
|
78
|
+
target: |-
|
|
79
|
+
di_bracket_leaves = []
|
|
80
|
+
solution: 'di['
|
|
81
|
+
hint: 'di[ works like di(: the bracket names the pair.'
|
|
82
|
+
variants:
|
|
83
|
+
- start: |-
|
|
84
|
+
bracket_names_the_pair = [▮"square", "ones"]
|
|
85
|
+
target: |-
|
|
86
|
+
bracket_names_the_pair = []
|
|
87
|
+
- goal: 'Change the text inside the tag to "t is for tag".'
|
|
88
|
+
ft: html
|
|
89
|
+
start: |-
|
|
90
|
+
<b>t is for ti▮tle</b>
|
|
91
|
+
target: |-
|
|
92
|
+
<b>t is for tag</b>
|
|
93
|
+
solution: 'citt is for tag<Esc>'
|
|
94
|
+
hint: 't is the tag object. cit changes the tag''s content and keeps the tags.'
|
|
95
|
+
variants:
|
|
96
|
+
- goal: 'Change the text inside the tag to "the tags stay".'
|
|
97
|
+
start: |-
|
|
98
|
+
<b>the tags ▮go</b>
|
|
99
|
+
target: |-
|
|
100
|
+
<b>the tags stay</b>
|
|
101
|
+
solution: 'citthe tags stay<Esc>'
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
week: 1
|
|
2
|
+
day: 3
|
|
3
|
+
title: Sentences and paragraphs
|
|
4
|
+
intro: |
|
|
5
|
+
Bigger nouns: `s` is a *sentence* and `p` a *paragraph* (a block of lines
|
|
6
|
+
between empty lines). `is`/`ip` are the thing itself; `as`/`ap` take the
|
|
7
|
+
space or empty line after it too, so `dap` leaves no gap. Any verb works on
|
|
8
|
+
them, including `>` (the arrow points the way the text moves) and `y`.
|
|
9
|
+
keys: [dap, yap, cis, das, ">ip"]
|
|
10
|
+
tasks:
|
|
11
|
+
- goal: 'Delete the middle paragraph.'
|
|
12
|
+
start: |-
|
|
13
|
+
dap deletes a paragraph.
|
|
14
|
+
|
|
15
|
+
This paragraph ▮is padding.
|
|
16
|
+
It can go.
|
|
17
|
+
|
|
18
|
+
It leaves no double gap behind.
|
|
19
|
+
target: |-
|
|
20
|
+
dap deletes a paragraph.
|
|
21
|
+
|
|
22
|
+
It leaves no double gap behind.
|
|
23
|
+
solution: 'dap'
|
|
24
|
+
hint: 'd deletes, a takes the empty line after it, p is the paragraph.'
|
|
25
|
+
variants:
|
|
26
|
+
- start: |-
|
|
27
|
+
a is around: the paragraph and the blank line after it.
|
|
28
|
+
|
|
29
|
+
This line ▮is filler.
|
|
30
|
+
So is this one.
|
|
31
|
+
|
|
32
|
+
One gap stays.
|
|
33
|
+
target: |-
|
|
34
|
+
a is around: the paragraph and the blank line after it.
|
|
35
|
+
|
|
36
|
+
One gap stays.
|
|
37
|
+
- goal: 'Duplicate the first paragraph.'
|
|
38
|
+
start: |-
|
|
39
|
+
▮yap yanks a paragraph; P puts it above.
|
|
40
|
+
|
|
41
|
+
Done.
|
|
42
|
+
target: |-
|
|
43
|
+
yap yanks a paragraph; P puts it above.
|
|
44
|
+
|
|
45
|
+
yap yanks a paragraph; P puts it above.
|
|
46
|
+
|
|
47
|
+
Done.
|
|
48
|
+
solution: 'yapP'
|
|
49
|
+
hint: 'yap yanks a paragraph with its empty line; P puts it above the cursor.'
|
|
50
|
+
variants:
|
|
51
|
+
- start: |-
|
|
52
|
+
▮P puts above, p puts below.
|
|
53
|
+
|
|
54
|
+
Done.
|
|
55
|
+
target: |-
|
|
56
|
+
P puts above, p puts below.
|
|
57
|
+
|
|
58
|
+
P puts above, p puts below.
|
|
59
|
+
|
|
60
|
+
Done.
|
|
61
|
+
- goal: 'Fix the wrong sentence: it should say "A sentence ends at a full stop."'
|
|
62
|
+
start: |-
|
|
63
|
+
s is for sentence. A sentence ends at a ▮comma. cis changes just one.
|
|
64
|
+
target: |-
|
|
65
|
+
s is for sentence. A sentence ends at a full stop. cis changes just one.
|
|
66
|
+
solution: 'cisA sentence ends at a full stop.<Esc>'
|
|
67
|
+
hint: 'cis changes the inner sentence and leaves the spaces around it.'
|
|
68
|
+
variants:
|
|
69
|
+
- goal: 'Fix the wrong sentence: it should say "The i means inner."'
|
|
70
|
+
start: |-
|
|
71
|
+
cis keeps the spaces. The i means ▮around. das takes one along.
|
|
72
|
+
target: |-
|
|
73
|
+
cis keeps the spaces. The i means inner. das takes one along.
|
|
74
|
+
solution: 'cisThe i means inner.<Esc>'
|
|
75
|
+
- goal: 'Delete the middle sentence.'
|
|
76
|
+
start: |-
|
|
77
|
+
das deletes a sentence. This one ▮is wrong. Its space goes too.
|
|
78
|
+
target: |-
|
|
79
|
+
das deletes a sentence. Its space goes too.
|
|
80
|
+
solution: 'das'
|
|
81
|
+
hint: 'das deletes a sentence plus the space after it.'
|
|
82
|
+
variants:
|
|
83
|
+
- start: |-
|
|
84
|
+
a is around: a sentence and its space. This sentence ▮is spare. The next one moves up.
|
|
85
|
+
target: |-
|
|
86
|
+
a is around: a sentence and its space. The next one moves up.
|
|
87
|
+
- goal: 'Indent the three lines.'
|
|
88
|
+
start: |-
|
|
89
|
+
What ip covers:
|
|
90
|
+
|
|
91
|
+
▮this line
|
|
92
|
+
this line
|
|
93
|
+
and this one
|
|
94
|
+
target: |-
|
|
95
|
+
What ip covers:
|
|
96
|
+
|
|
97
|
+
this line
|
|
98
|
+
this line
|
|
99
|
+
and this one
|
|
100
|
+
solution: '>ip'
|
|
101
|
+
hint: '> points right, ip is the inner paragraph. (Indent here is 4 spaces.)'
|
|
102
|
+
variants:
|
|
103
|
+
- goal: 'Indent the three lines.'
|
|
104
|
+
start: |-
|
|
105
|
+
> pushes right:
|
|
106
|
+
|
|
107
|
+
▮one
|
|
108
|
+
two
|
|
109
|
+
three
|
|
110
|
+
target: |-
|
|
111
|
+
> pushes right:
|
|
112
|
+
|
|
113
|
+
one
|
|
114
|
+
two
|
|
115
|
+
three
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
week: 1
|
|
2
|
+
day: 4
|
|
3
|
+
title: Find and till on a line
|
|
4
|
+
intro: |
|
|
5
|
+
`f{char}` *finds* the next {char} on the line and lands *on* it; `t{char}`
|
|
6
|
+
goes *till* it and stops just before. Capital `F` and `T` look backwards.
|
|
7
|
+
`;` repeats the last one (a semicolon says *and so on*), `,` repeats it the
|
|
8
|
+
other way (a comma steps back). With a verb they become precise: `dt,`
|
|
9
|
+
deletes till the comma, `ct;` changes till the semicolon.
|
|
10
|
+
keys: [f, t, F, T, ";", ",", dt, ct]
|
|
11
|
+
tasks:
|
|
12
|
+
- goal: 'Delete everything up to "just".'
|
|
13
|
+
start: |-
|
|
14
|
+
t means till: it stops ▮way way just before the letter.
|
|
15
|
+
target: |-
|
|
16
|
+
t means till: it stops just before the letter.
|
|
17
|
+
solution: 'dtj'
|
|
18
|
+
hint: 'dtj deletes till the next j after the cursor; "way way" has none.'
|
|
19
|
+
variants:
|
|
20
|
+
- goal: 'Delete everything up to "just".'
|
|
21
|
+
start: |-
|
|
22
|
+
dt stops ▮a bit early: just before the letter.
|
|
23
|
+
target: |-
|
|
24
|
+
dt stops just before the letter.
|
|
25
|
+
solution: 'dtj'
|
|
26
|
+
- goal: 'Change the value to "till" (keep the semicolon).'
|
|
27
|
+
start: |-
|
|
28
|
+
let t = ▮"through"; let f = "find";
|
|
29
|
+
target: |-
|
|
30
|
+
let t = "till"; let f = "find";
|
|
31
|
+
solution: 'ct;"till"<Esc>'
|
|
32
|
+
hint: 'ct; changes till, not including, the semicolon.'
|
|
33
|
+
variants:
|
|
34
|
+
- goal: 'Change the value to "find" (keep the semicolon).'
|
|
35
|
+
start: |-
|
|
36
|
+
let f = ▮"till"; let t = "till";
|
|
37
|
+
target: |-
|
|
38
|
+
let f = "find"; let t = "till";
|
|
39
|
+
solution: 'ct;"find"<Esc>'
|
|
40
|
+
- goal: 'Keep only the folder path: delete the file name.'
|
|
41
|
+
start: |-
|
|
42
|
+
lessons/week-1/till/backwards.ya▮ml
|
|
43
|
+
target: |-
|
|
44
|
+
lessons/week-1/till/
|
|
45
|
+
solution: 'T/D'
|
|
46
|
+
hint: 'Capital T goes backwards: T/ stops just after the last slash; D deletes to the end of the line.'
|
|
47
|
+
variants:
|
|
48
|
+
- start: |-
|
|
49
|
+
vim/motions/capital-T/goes-back.tx▮t
|
|
50
|
+
target: |-
|
|
51
|
+
vim/motions/capital-T/
|
|
52
|
+
- goal: 'Turn the third comma into a semicolon.'
|
|
53
|
+
start: |-
|
|
54
|
+
▮count, then f, then the comma, done
|
|
55
|
+
target: |-
|
|
56
|
+
count, then f, then the comma; done
|
|
57
|
+
solution: '3f,r;'
|
|
58
|
+
hint: 'f, then ; ; walks comma by comma ("and so on"). A count is shorter: 3f, and then r; replaces the character.'
|
|
59
|
+
variants:
|
|
60
|
+
- start: |-
|
|
61
|
+
▮f, t, F, T
|
|
62
|
+
target: |-
|
|
63
|
+
f, t, F; T
|
|
64
|
+
- goal: 'Replace the whole before(char) call with on_it.'
|
|
65
|
+
ft: python
|
|
66
|
+
start: |-
|
|
67
|
+
f_lands = ▮before(char) # t stops before it
|
|
68
|
+
target: |-
|
|
69
|
+
f_lands = on_it # t stops before it
|
|
70
|
+
solution: 'ct on_it<Esc>'
|
|
71
|
+
hint: 't works with a space too. ct<Space> changes till the next space.'
|
|
72
|
+
variants:
|
|
73
|
+
- goal: 'Replace the whole at(char) call with till.'
|
|
74
|
+
start: |-
|
|
75
|
+
t_stops = ▮at(char) # one short of it
|
|
76
|
+
target: |-
|
|
77
|
+
t_stops = till # one short of it
|
|
78
|
+
solution: 'ct till<Esc>'
|
|
79
|
+
- goal: 'Delete the part in brackets: from the cursor up to and including the ")".'
|
|
80
|
+
start: |-
|
|
81
|
+
f lands on▮ (not before) the letter.
|
|
82
|
+
target: |-
|
|
83
|
+
f lands on the letter.
|
|
84
|
+
solution: 'df)'
|
|
85
|
+
hint: 'f finds and lands on the ), so df) deletes the bracket too.'
|
|
86
|
+
variants:
|
|
87
|
+
- start: |-
|
|
88
|
+
F finds backwards▮ (to the left) on the line.
|
|
89
|
+
target: |-
|
|
90
|
+
F finds backwards on the line.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
week: 1
|
|
2
|
+
day: 5
|
|
3
|
+
title: Whole lines and line ends
|
|
4
|
+
intro: |
|
|
5
|
+
Capitals go big: `D` deletes to the end of the line, `C` changes to the end.
|
|
6
|
+
Doubling a verb means the whole line: `dd` deletes it, `cc` changes it. `J`
|
|
7
|
+
*joins* the next line on. `A` *appends* at the end and `I` *inserts* at the
|
|
8
|
+
first non-blank character. `ddp` swaps two lines: cut, then put back one
|
|
9
|
+
further down.
|
|
10
|
+
keys: [D, C, cc, dd, J, ddp, A, I]
|
|
11
|
+
tasks:
|
|
12
|
+
- goal: 'Delete the rest of the line.'
|
|
13
|
+
start: |-
|
|
14
|
+
D is a big d: it deletes to the end.▮ Everything after the cursor goes.
|
|
15
|
+
target: |-
|
|
16
|
+
D is a big d: it deletes to the end.
|
|
17
|
+
solution: 'D'
|
|
18
|
+
hint: 'D deletes from the cursor to the end of the line.'
|
|
19
|
+
variants:
|
|
20
|
+
- start: |-
|
|
21
|
+
D deletes from the cursor to the end.▮ This part goes.
|
|
22
|
+
target: |-
|
|
23
|
+
D deletes from the cursor to the end.
|
|
24
|
+
- start: |-
|
|
25
|
+
Capital D goes big.▮ All of this disappears at once.
|
|
26
|
+
target: |-
|
|
27
|
+
Capital D goes big.
|
|
28
|
+
- goal: 'Change the rest of the line to "the end of the line".'
|
|
29
|
+
start: |-
|
|
30
|
+
C changes to: ▮somewhere in the middle
|
|
31
|
+
target: |-
|
|
32
|
+
C changes to: the end of the line
|
|
33
|
+
solution: 'Cthe end of the line<Esc>'
|
|
34
|
+
hint: 'C changes from the cursor to the end of the line.'
|
|
35
|
+
variants:
|
|
36
|
+
- goal: 'Change the rest of the line to "the rest of the line".'
|
|
37
|
+
start: |-
|
|
38
|
+
C is a big c: it changes ▮just a word
|
|
39
|
+
target: |-
|
|
40
|
+
C is a big c: it changes the rest of the line
|
|
41
|
+
solution: 'Cthe rest of the line<Esc>'
|
|
42
|
+
- goal: 'Replace the middle line with "cc changes a line".'
|
|
43
|
+
start: |-
|
|
44
|
+
c changes
|
|
45
|
+
▮typo
|
|
46
|
+
c twice, a whole line
|
|
47
|
+
target: |-
|
|
48
|
+
c changes
|
|
49
|
+
cc changes a line
|
|
50
|
+
c twice, a whole line
|
|
51
|
+
solution: 'cccc changes a line<Esc>'
|
|
52
|
+
hint: 'cc, the doubled verb, changes the whole line, wherever the cursor is.'
|
|
53
|
+
variants:
|
|
54
|
+
- goal: 'Replace the middle line with "cc changes a line".'
|
|
55
|
+
start: |-
|
|
56
|
+
dd deletes a line
|
|
57
|
+
▮xx changes a line
|
|
58
|
+
yy yanks a line
|
|
59
|
+
target: |-
|
|
60
|
+
dd deletes a line
|
|
61
|
+
cc changes a line
|
|
62
|
+
yy yanks a line
|
|
63
|
+
solution: 'cccc changes a line<Esc>'
|
|
64
|
+
- goal: 'Join the two lines.'
|
|
65
|
+
start: |-
|
|
66
|
+
▮J joins this line
|
|
67
|
+
and the next one.
|
|
68
|
+
target: |-
|
|
69
|
+
J joins this line and the next one.
|
|
70
|
+
solution: 'J'
|
|
71
|
+
hint: 'J joins the next line onto this one, with one space.'
|
|
72
|
+
variants:
|
|
73
|
+
- start: |-
|
|
74
|
+
▮gJ joins with no space;
|
|
75
|
+
J adds one.
|
|
76
|
+
target: |-
|
|
77
|
+
gJ joins with no space; J adds one.
|
|
78
|
+
- goal: 'Put the steps in order: delete first.'
|
|
79
|
+
start: |-
|
|
80
|
+
▮then p puts
|
|
81
|
+
dd deletes
|
|
82
|
+
and the lines swap
|
|
83
|
+
target: |-
|
|
84
|
+
dd deletes
|
|
85
|
+
then p puts
|
|
86
|
+
and the lines swap
|
|
87
|
+
solution: 'ddp'
|
|
88
|
+
hint: 'dd cuts the line, p puts it below the next one.'
|
|
89
|
+
variants:
|
|
90
|
+
- goal: 'Put the steps of ddp in order: cut first.'
|
|
91
|
+
start: |-
|
|
92
|
+
▮put
|
|
93
|
+
cut
|
|
94
|
+
and that is ddp
|
|
95
|
+
target: |-
|
|
96
|
+
cut
|
|
97
|
+
put
|
|
98
|
+
and that is ddp
|
|
99
|
+
- goal: 'Add a semicolon at the end.'
|
|
100
|
+
start: |-
|
|
101
|
+
▮console.log("A appends at the end")
|
|
102
|
+
target: |-
|
|
103
|
+
console.log("A appends at the end");
|
|
104
|
+
solution: 'A;<Esc>'
|
|
105
|
+
hint: 'A appends at the end of the line, wherever the cursor is.'
|
|
106
|
+
variants:
|
|
107
|
+
- goal: 'Add a semicolon at the end.'
|
|
108
|
+
start: |-
|
|
109
|
+
▮return "A is for append"
|
|
110
|
+
target: |-
|
|
111
|
+
return "A is for append";
|
|
112
|
+
- start: |-
|
|
113
|
+
▮let append = "A"
|
|
114
|
+
target: |-
|
|
115
|
+
let append = "A";
|
|
116
|
+
- start: |-
|
|
117
|
+
▮print("A goes to the end")
|
|
118
|
+
target: |-
|
|
119
|
+
print("A goes to the end");
|
|
120
|
+
- goal: 'Comment the line out with "# ".'
|
|
121
|
+
ft: python
|
|
122
|
+
start: |-
|
|
123
|
+
insert = ▮"I puts you at the start"
|
|
124
|
+
target: |-
|
|
125
|
+
# insert = "I puts you at the start"
|
|
126
|
+
solution: 'I# <Esc>'
|
|
127
|
+
hint: 'I inserts at the start of the line.'
|
|
128
|
+
variants:
|
|
129
|
+
- start: |-
|
|
130
|
+
start = ▮"I goes to the first letter"
|
|
131
|
+
target: |-
|
|
132
|
+
# start = "I goes to the first letter"
|