(require 'meow-var)
(defconst meow--tutor-content
"
███╗░░░███╗███████╗░█████╗░░██╗░░░░░░░██╗
████╗░████║██╔════╝██╔══██╗░██║░░██╗░░██║
██╔████╔██║█████╗░░██║░░██║░╚██╗████╗██╔╝
██║╚██╔╝██║██╔══╝░░██║░░██║░░████╔═████║░
██║░╚═╝░██║███████╗╚█████╔╝░░╚██╔╝░╚██╔╝░
╚═╝░░░░░╚═╝╚══════╝░╚════╝░░░░╚═╝░░░╚═╝░░
==================================================================
= MEOW INTRODUCTION =
==================================================================
Meow is yet another modal editing mode for Emacs.
What's modal editing? How do I use Meow? Let's start our journey!
If you wonder what a keystroke means when reading this, just ask
Emacs! Press C-h k then press the key you want to query.
==================================================================
= BASIC CURSOR MOVEMENT =
==================================================================
To move up, press \\[meow-prev]
To move down, press \\[meow-next]
To move left, press \\[meow-left]
To move right, press \\[meow-right]
↑
\\[meow-prev]
← \\[meow-left] \\[meow-right] →
\\[meow-next]
↓
You can move the cursor using the \\[meow-left], \\[meow-next], \\[meow-prev], \\[meow-right] keys, as shown
above. Arrow keys also work, but it is faster to use the \\[meow-left]\\[meow-next]\\[meow-prev]\\[meow-right]
keys as they are closer to the other keys you will be using.
Try moving around to get a feel for \\[meow-left]\\[meow-next]\\[meow-prev]\\[meow-right].
Once you're ready, hold \\[meow-next] to continue to the next lesson.
Meow provides modal editing which means you have different
modes for inserting and editing text. The primary modes you will
use are Normal mode and Insert mode. While in Normal mode, the
keys you press won't actually type text. Instead, they will
perform various actions with the text. This allows for more
efficient editing. This tutor will teach you how you can make
use of Meow's modal editing features. To begin, ensure your
caps-lock key is not pressed and hold the \\[meow-next] key until you reach
the first lesson.
=================================================================
= DELETION =
=================================================================
Pressing the \\[meow-delete] key deletes the character under the cursor.
\\[meow-backward-delete] key deletes the character before the cursor (backspace).
1. Move the cursor to the line below marked -->.
2. Move the cursor to each extra character, and press \\[meow-delete] to
delete it.
--> Thhiss senttencee haass exxtra charracterss.
This sentence has extra characters.
Once both sentences are identical, move to the next lesson.
=================================================================
= INSERT MODE =
=================================================================
Pressing the \\[meow-insert] key enters the Insert mode. In that mode you can
enter text. <ESC> returns you back to Normal mode. The modeline
will display your current mode. When you press \\[meow-insert], '%s'
changes to '%s'.
1. Move the cursor to the line below marked -->.
2. Insert the missing characters with \\[meow-insert] key.
3. Press <ESC> to return back to Normal mode.
4. Repeat until the line matches the line below it.
--> Th stce misg so.
This sentence is missing some text.
Note: If you want to move the cursor while in Insert mode, you
can use the arrow keys instead of exiting and re-entering
Insert mode.
=================================================================
= MORE ON INSERT MODE =
=================================================================
Pressing \\[meow-insert] is not the only way to enter Insert Mode. Here are
some other ways to enter Insert mode at different locations.
Common examples of insertion commands include:
\\[meow-insert] - Insert cursor before the selection.
\\[meow-append] - Insert cursor after the selection.
\\[meow-open-above] - Insert new line above the current line.
\\[meow-open-below] - Insert new line below the current line.
\\[meow-join] \\[meow-append] - Insert cursor at the start of the line.
\\[meow-line] \\[meow-append] - Insert cursor at the end of the line.
These commands are composable. \\[meow-join] will select the beginning of the
current line up until the end of the non-empty line above.
\\[meow-append] switches to Insert mode at the end of current selection.
Using both commands together will result in the cursor position being at
the beginning of the line (Insert mode). \\[meow-line] selects the whole
line and enables the use of the same insertion commands.
1. Move to anywhere in the line below marked -->.
2. Press \\[meow-line] \\[meow-append], your cursor will move to the end of the line
and you will be able to type.
3. Type the necessary text to match the line below.
4. Press \\[meow-join] \\[meow-append] for the cursor to move to the beginning of the line.
This will place the cursor before -->. For now just return to
Normal mode and move cursor past it.
--> sentence is miss
This sentence is missing some text.
=================================================================
= RECAP =
=================================================================
+ Use the \\[meow-left], \\[meow-next], \\[meow-prev], \\[meow-right] keys to move the cursor.
+ Press \\[meow-delete] to delete the character under the cursor.
+ Press \\[meow-backward-delete] to delete the character before the cursor.
+ Press \\[meow-insert] to enter Insert mode to input text. Press <ESC> to
return to Normal mode.
+ Press \\[meow-join] to select the start of the current line and
the non-empty line above.
+ Press \\[meow-append] to enter Insert mode, with the cursor position being
at the end of the selected region.
=================================================================
= MOTIONS AND SELECTIONS =
=================================================================
Pressing \\[meow-next-word] will select everything from the cursor position
until the end of the current word.
Numbers that show up on the screen indicate a quick way to extend your selection.
You can unselect the region with the \\[meow-cancel-selection] key.
Pressing \\[meow-kill] will delete the current selection.
The \\[meow-delete] key deletes the character below the cursor, while
\\[meow-kill] deletes all of the selected text.
1. Move the cursor to the line below marked -->.
2. Move to the beginning of a word that needs to be deleted.
3. Press \\[meow-next-word] to select a word.
4. Press \\[meow-kill] to delete the selection.
5. Repeat for all extra words in the line.
--> This sentence pencil has vacuum extra words in the it.
This sentence has vacuum words in it.
Note: Pressing \\[meow-kill] without a selection will delete everything
from cursor position until the end of line.
=================================================================
= WORDS VS SYMBOLS =
=================================================================
Pressing \\[meow-mark-word] will select the whole word under the cursor. \\[meow-mark-symbol] will
select the whole symbol. Symbols are separated only by whitespace,
whereas words can also be separated by other characters.
To understand the difference better, do the following exercise:
1. Move the cursor to the line below marked -->.
2. Use \\[meow-mark-word] and \\[meow-mark-symbol] on each word in a sentence.
3. Observe the difference in selection.
--> Select-this and this.
=================================================================
= EXTENDING SELECTION =
=================================================================
Motions are useful for extending the current selection and for
quick movement around the text. After selecting the word under
the cursor with \\[meow-mark-word] you can extend the selection with some common
movements listed below.
\\[meow-next-word] - Moves forward to the end of the current word.
\\[meow-back-word] - Moves backward to the beginning of the current word.
\\[meow-next-symbol] - Moves to the end of the current symbol.
\\[meow-back-symbol] - Moves to the start of the current symbol.
Cursor position can be reversed with \\[meow-reverse] to extend the selection
the other directions. In-case too much gets selected, you can
undo the previous selection with \\[meow-pop-selection] key.
1. Move the cursor to the line below marked -->.
2. Select the word with \\[meow-mark-word].
3. Extend the selection with \\[meow-next-word].
4. Press \\[meow-kill] to delete the selection.
5. (Optional) Try reversing the cursor and extending the selection.
--> This sentence is most definitelly not at all short.
This sentence is short.
=================================================================
= SELECTING LINES =
=================================================================
Pressing \\[meow-line] will select the whole line. Pressing it again will
add the next line to the selection. Numbers can also be used
to select multiple lines at once.
1. Move the cursor to the second line below marked -->.
2. Press \\[meow-line] to select the current line, and \\[meow-kill] to delete it.
3. Move to the fourth line.
4. Select 2 lines either by hitting \\[meow-line] twice or \\[meow-line] 1 in combination.
5. Delete the selection with \\[meow-kill].
--> 1) Roses are red,
--> 2) Mud is fun,
--> 3) Violets are blue,
--> 4) I have a car,
--> 5) Clocks tell time,
--> 6) Sugar is sweet,
--> 7) And so are you.
=================================================================
= EXTENDING SELECTION BY OBJECT =
=================================================================
Expanding the selected region is easy. In fact every motion
command has its own expand type. Motions can be expanded in
different directions and units.
Common selection expanding motions by a THING:
\\[meow-beginning-of-thing] - expand before cursor until beginning of...
\\[meow-end-of-thing] - expand after cursor until end of...
\\[meow-inner-of-thing] - select the inner part of...
\\[meow-bounds-of-thing] - select the whole part of...
Some of THING modifiers may include:
r - round parenthesis
s - square parenthesis
c - curly parenthesis
g - string
p - paragraph
l - line
d - defun
b - buffer
1. Move the cursor to the paragraph below.
2. Type \\[meow-bounds-of-thing] p to select the whole paragraph.
3. Type \\[meow-cancel-selection] to cancel the selection.
4. Type \\[meow-inner-of-thing] l to select one line.
5. Type \\[meow-cancel-selection] to cancel the selection.
6. Play with the commands you learned this section. You can do anything
you want with these powerful commands!
War and Peace by Leo Tolstoy, is considered one of the greatest works of
fiction.It is regarded, along with Anna Karenina (1873–1877), as Tolstoy's
finest literary achievement. Epic in scale, War and Peace delineates in graphic
detail events leading up to Napoleon's invasion of Russia, and the impact of the
Napoleonic era on Tsarist society, as seen through the eyes of five Russian
aristocratic families.Newsweek in 2009 ranked it top of its list of Top 100
Books.Tolstoy himself, somewhat enigmatically, said of War and Peace that it was
\"not a novel, even less is it a poem, and still less an historical chronicle.\"
=================================================================
= MOVE AROUND THINGs =
=================================================================
You can also move around things. In fact, Meow combines move and
selection together. Every time you select something, the cursor
will move to the beginning/end/inner/bound of things depending
on your commands. Let's practice!
* How to jump to the beginning of buffer quickly?
Type \\[meow-beginning-of-thing] and \"b\". Remember to come
back by typing \\[meow-pop-selection].
* How to jump to the end of buffer quickly?
I believe you could figure it out. Do it!
* How to jump to the end of the current function quickly?
1. Move cursor to the function below marked -->.
2. Type \\[meow-bounds-of-thing] and \"c\", then \"a\".
-->
fn count_ones(mut n: i64) -> usize {
let mut count: usize = 0;
while 0 < n {
count += (1 & n) as usize;
n >>= 1;
}
count
}
Note that Meow need the major mode for the programming language
to find functions correctly. Then if you type \\[meow-bounds-of-thing] and \"d\" to
select the whole function here, it won't work. Go to your
favorite programming language mode and practice!
=================================================================
= THE FIND/TILL COMMAND =
=================================================================
Type \\[meow-till] to select until the next specific character.
1. Move the cursor to the line below marked -->.
2. Press \\[meow-till]. A prompt will appear in minibuffer.
4. Type 'a'. The correct position for the next 'a' will be
selected.
--> I like to eat apples since my favorite fruit is apples.
Note: If you want to go backwards, use \\[negative-argument] as a prefix; there is also
a similar command on \\[meow-find], which will jump over that
character.
=================================================================
= RECAP =
=================================================================
+ Unselect region with \\[meow-cancel-selection] key.
+ Reverse cursor position in selected region with \\[meow-reverse] key.
+ Undo selection with \\[meow-pop-selection].
+ Press \\[meow-next-word] to select until the end of current word.
+ Press \\[meow-back-word] to select until the start of closest word.
+ Press \\[meow-next-symbol] to select until the end of symbol.
+ Press \\[meow-back-symbol] to select until the start of symbol.
+ Press \\[meow-line] to select the entire current line. Type \\[meow-line] again to
select the next line.
+ Motion can be repeated multiple times by using a number modifier.
+ Extend selection by using THING modifiers
Motion Prefix: (\\[meow-beginning-of-thing] \\[meow-end-of-thing] \\[meow-inner-of-thing] \\[meow-bounds-of-thing])
THING as a Suffix: (r,s,c,g,p,l,d,b)
+ Find by a single character with \\[meow-till] and \\[meow-find].
=================================================================
= THE CHANGE COMMAND =
=================================================================
Pressing \\[meow-change] will delete the current selection and switch to
Insert mode. If there is no selection it will only delete
the character under the cursor and switch to Insert mode.
It is a shorthand for \\[meow-delete] \\[meow-insert].
1. Move the cursor to the line below marked -->.
2. Select the incorrect word with \\[meow-next-word].
3. Press \\[meow-change] to delete the word and enter Insert mode.
4. Replace it with correct word and return to Normal mode.
5. Repeat until the line matches the line below it.
--> This paper has heavy words behind it.
This sentence has incorrect words in it.
=================================================================
= KILL AND YANK =
=================================================================
The \\[meow-kill] key also copies the deleted content which can then be
pasted with \\[meow-yank].
1. Move the cursor to the line below marked -->.
2. Type \\[meow-line] to select the line.
3. Type \\[meow-kill] to cut the current selection.
4. Type \\[meow-yank] to paste the copied content.
5. You can paste as many times as you want.
--> Violets are blue, and I love you.
=================================================================
= SAVE AND YANK =
=================================================================
Pressing \\[meow-save] copies the selection, which can then be pasted
with \\[meow-yank] under the cursor.
1. Move the cursor to the line below marked -->.
2. Press \\[meow-line] to select one line forward.
3. Press \\[meow-save] to copy the current selection.
4. Press \\[meow-yank] to paste the copied content.
5. You can paste as many times as you want.
--> Violets are blue, and I love you.
=================================================================
= UNDOING =
=================================================================
Pressing \\[meow-undo] triggers undo. The \\[meow-undo-in-selection] key will only undo the changes
in the selected region.
1. Move the cursor to the line below marked -->.
2. Move to the first error, and press \\[meow-delete] to delete it.
3. Type \\[meow-undo] to undo your deletion.
4. Fix all the errors on the line.
5. Type \\[meow-undo] several times to undo your fixes.
--> Fiix the errors on thhis line and reeplace them witth undo.
Fix the errors on this line and replace them with undo.
=================================================================
= RECAP =
=================================================================
+ Press \\[meow-change] to delete the selection and enter Insert mode.
+ Press \\[meow-save] to copy the selection.
+ Press \\[meow-yank] to paste the copied or deleted text.
+ Press \\[meow-undo] to undo last change.
+ Press \\[meow-undo-in-selection] to only undo changes in the selected region.
=================================================================
= BEACON (BATCHED KEYBOARD MACROS) =
=================================================================
Keyboard macro is a function that is built-in to Emacs. Now with Meow, it's
more powerful. We can do things like multi-editing with Beacon
mode in Meow.
Select a region, then press \\[meow-grab] to \"grab\" it, then enter
Insert mode, meow will now enter Beacon mode. Meow will create multiple
cursors and all edits you do to one cursor will be synced to other
cursors after you exit Insert mode. Type \\[meow-grab] again to cancel
grabbing.
1. Move the cursor to the first line below marked -->.
2. Select the six lines.
3. Type \\[meow-grab] to grab the selection. Edits you
make will be synced to the other cursors.
4. Use Insert mode to correct the lines. Then exit Insert mode.
Other cursors will fix the other lines after you exit Insert mode.
5. Type \\[meow-grab] to cancel the grabbing.
--> Fix th six nes at same ime.
--> Fix th six nes at same ime.
--> Fix th six nes at same ime.
--> Fix th six nes at same ime.
--> Fix th six nes at same ime.
--> Fix th six nes at same ime.
Fix these six lines at the same time.
=================================================================
= MORE ON BEACON =
=================================================================
BEACON is powerful! Let's do some more practice.
Ex. A. How to achieve this?
1 2 3
=>
[| \"1\" |] [| \"2\" |] [| \"3\" |]
1. Move the cursor to the line below marked -->
2. Select the whole line (you know how to do this)
3. Press \\[meow-grab] to grab the selection
4. Press \\[meow-back-word] to create fake cursors at the beginning of each word
in the backwards direction.
5. Enter Insert Mode then edit.
6. Press \\[meow-normal-mode] to stop macro recording and apply
your edits to all fake cursors.
7. Press \\[meow-grab] to cancel grab.
--> 1 2 3
[| \"1\" |] [| \"2\" |] [| \"3\" |]
Ex. B. How to achieve this?
x-y-foo-bar-baz
=>
x_y_foo_bar_baz
1. Move the cursor to the line below marked -->
2. Select the whole symbol with \\[meow-mark-symbol]
3. Press \\[meow-grab] to activate secondary selection
4. Press \\[negative-argument] \\[meow-find] and - to backward search for
character -, will create fake cursor at each -
5. Meow will start recording. Press \\[meow-change] to switch to Insert mode
(character under current cursor is deleted)
6. type _
7. Press ESC to go back to NORMAL, then the macro will
be applied to all fake cursors.
8. Press \\[meow-grab] again to cancel the grab
--> x-y-foo-bar-baz
x_y_foo_bar_baz
=================================================================
= QUICK VISIT AND SEARCH =
=================================================================
The visit command \\[meow-visit] can help to select a symbol in your
buffer with completion. Once you have something selected with the \\[meow-visit] key,
you can use \\[meow-search] to search for the next occurrence of that selection.
If you want a backward search, you can reverse the selection with \\[meow-reverse]
because \\[meow-search] will respect the direction of the current selection.
1. Move the cursor to the line below marked -->.
2. Select the word \"dog\" with \\[meow-visit] dog RET.
3. Change it to \"cat\" with \\[meow-change] cat ESC.
4. Save it with \\[meow-save].
5. Search for next \"dog\" and replace it with \\[meow-search] \\[meow-replace].
6. Repeat 5 to replace next \"dog\".
--> I'm going to tell you something:
dog is beautiful
and dog is agile
the last one, dog says meow
Note: You can also start searching after \\[meow-mark-word] or \\[meow-mark-symbol]. Actually, you
can use \\[meow-search] whenever you have any kind of selection. The search command
is built on regular expression. The symbol boundary will be
added to your search if the selection is created with \\[meow-visit], \\[meow-mark-word] and \\[meow-mark-symbol].
=================================================================
= KEYPAD AND MOTION MODE =
=================================================================
One of the most notable features of Meow is the Keypad. It
enables the use of modifier keybinds without pressing modifiers.
To enter Keypad mode, press SPC in Normal mode or Motion mode.
Once Keypad is started, your single key input, will be translated
based on following rules:
1. The first letter input, except x, c, h, m, g will be
translated to C-c <key>.
Example: a => C-c a
Press SPC a, call the command on C-c a, which is
undefined by default.
2. m will be translated to M-, means next input should be
modified with Meta.
Example: m h => M-h
Press SPC m h, call the command on M-h, which is
mark-paragraph by default.
3. Several keys are bound to prefixes similarly. Specifically,
x -> C-x
h -> C-h
c -> C-c
m -> M-
g -> C-M-
4. Any key following a prefix is interpreted as C-<key>.
Example: x f => C-x C-f
Press SPC x f, call the command on C-x C-f, which is
find-file by default.
5. Use SPC to indicate a literal key, which will not be modified with C-
Example: m g SPC g => M-g g
Press SPC m g SPC g, call the command on M-g g, which is
goto-line by default.
Sometimes, you can omit this SPC when there's no ambiguity.
6. After one execution, regardless of success or failure, Keypad will
quit automatically, and the previous mode will be enabled.
7. To undo one input, press BACKSPACE. To cancel and exit Keypad
immediately, press ESC or C-g.
=================================================================
= MEOW CHEAT SHEET =
=================================================================
All these keybinds are shown on the cheat sheet which can be
opened by pressing \\[meow-cheatsheet].
=================================================================
")
(defun meow-tutor ()
"Open a buffer with meow tutor."
(interactive)
(let ((buf (get-buffer-create "*Meow Tutor*")))
(with-current-buffer buf
(erase-buffer)
(insert (format (substitute-command-keys meow--tutor-content)
(alist-get 'normal meow-replace-state-name-list)
(alist-get 'insert meow-replace-state-name-list)))
(setq-local scroll-conservatively 1)
(setq-local scroll-margin 3)
(setq-local scroll-step 1)
(goto-char (point-min))
(display-line-numbers-mode))
(switch-to-buffer buf)))
(provide 'meow-tutor)