├── ruby_module ├── animal.rb ├── banker.rb ├── frog.rb └── person.rb ├── exercises ├── extra_01_switch_panes.md ├── 32_tab_complete_your_ex_command.md ├── 55_traverse_the_jump_list.md ├── 18_insert_unusual_characters.md ├── 31_repeat_last_ex_command.md ├── 49_find_by_character.md ├── 13_delete_in_insert_mode.md ├── 20_grokking_visual_mode.md ├── 21_defining_visual_selection.md ├── 82_count_the_matches_for_current_pattern.md ├── 01_insert_at_end_of_line.md ├── 56_traverse_the_change_list.md ├── 02_insert_at_beginning_of_line.md ├── 16_back_of_envelop_calculations_in_place.md ├── 26_append_after_a_ragged_visual_block.md ├── 76_stake_the_boundaries_of_a_word.md ├── 40_organize_window_layout_with_tab_pages.md ├── 33_insert_current_word_at_command_prompt.md ├── 03_one_step_back_two_forward.md ├── 66_play_back_with_a_count.md ├── 19_overwrite_existing_text_with_replace.md ├── 83_offset_cursor_to_the_end_of_a_search_match.md ├── 12_combine_and_conquer.md ├── 10_use_counts.md ├── 78_escape_problem_characters.md ├── 72_tune_the_case_sensitivity_of_search_patterns.md ├── 05_find_and_replace_by_hand.md ├── 58_snap_between_files_using_global_marks.md ├── 50_operate_with_a_search_motion.md ├── 39_split_windows.md ├── 79_meet_the_search_command.md ├── 22_repeat_likewise_visual_commands.md ├── 84_operate_on_complete_search_match.md ├── 64_record_and_execute_a_macro.md ├── 15_paste_from_register_in_insert_mode.md ├── 74_use_the_backslash_v_literal_switch_for_verbatim_search.md ├── 68_append_commands_to_macro.md ├── 29_duplicate_or_move_lines.md ├── 73_use_the_v_pattern_switch_for_regex_search.md ├── 23_prefer_operators_to_visual_commands.md ├── 51_trace_your_selection_with_precision_text_objects.md ├── 62_pasting_from_a_register.md ├── 77_stake_the_boundaries_of_a_match.md ├── 30_run_normal_mode_commands_across_range.md ├── 24_editing_tabular_data_with_visual_block_mode.md ├── 70_evaluate_an_iterator_to_number_items_in_a_list.md ├── 52_jump_between_matching_parentheses.md ├── 35_running_commands_in_shell.md ├── 71_edit_the_contents_of_a_macro.md ├── 28_exec_commands_on_one_or_more_consecutive_lines.md ├── 25_changing_column_of_text.md ├── 61_replace_visual_selection_with_a_register.md ├── 67_repeat_a_change_on_contiguous_lines.md ├── 69_act_upon_a_collection_of_files.md ├── extra_02_navigating_on_long_page.md ├── 85_create_complex_patterns_by_iterating_upon_search_history.md ├── 53_mark_your_place_and_snap_back_to_it.md ├── 59_delete_yank_and_put_with_unnamed_register.md └── 60_grok_vim_registers.md └── README.md /ruby_module/animal.rb: -------------------------------------------------------------------------------- 1 | # Copyright text 2 | class Animal 3 | # Some content here 4 | end 5 | -------------------------------------------------------------------------------- /ruby_module/banker.rb: -------------------------------------------------------------------------------- 1 | # Copyright text 2 | class Banker 3 | # Some content here 4 | end 5 | -------------------------------------------------------------------------------- /ruby_module/frog.rb: -------------------------------------------------------------------------------- 1 | # Copyright text 2 | class Frog 3 | # Some content here 4 | end 5 | -------------------------------------------------------------------------------- /ruby_module/person.rb: -------------------------------------------------------------------------------- 1 | # Copyright text 2 | class Person 3 | # Some content here 4 | end 5 | -------------------------------------------------------------------------------- /exercises/extra_01_switch_panes.md: -------------------------------------------------------------------------------- 1 | Create a vertical split with `vs` 2 | 3 | Switch between the two with `r`. Practice it a couple of times. 4 | 5 | -------------------------------------------------------------------------------- /exercises/32_tab_complete_your_ex_command.md: -------------------------------------------------------------------------------- 1 | ### Tab complete your ex command 2 | 3 | Type this in the command menu: 4 | 5 | `:col` 6 | 7 | The options 'colder colorscheme should be displayed 8 | -------------------------------------------------------------------------------- /exercises/55_traverse_the_jump_list.md: -------------------------------------------------------------------------------- 1 | ### Travers the jump list 2 | 3 | `` - is like the browser's back button, but here it's used for files 4 | `` - is like the browser's forward button 5 | 6 | `:jumps` - will list all the different jump points 7 | -------------------------------------------------------------------------------- /exercises/18_insert_unusual_characters.md: -------------------------------------------------------------------------------- 1 | ### Insert unusual characters 2 | 3 | Insert the following unusual characters: 4 | 5 | ¿ - ¢ 6 | 7 | `:digraphs` - Look up all the possible options 8 | `?I` - will give you ¿ 9 | `Ct` - will give you ¢ 10 | -------------------------------------------------------------------------------- /exercises/31_repeat_last_ex_command.md: -------------------------------------------------------------------------------- 1 | ### Repeat last ex command 2 | 3 | `:bn` - move to the next buffer 4 | `@:` - repeat last ex command 5 | `@@` - repeat previous `@{0-9a-z":*}` 6 | 7 | If you press `@@` before `@:` you will get an error because there is no `@{0-9a-z":*}` command to repeat. 8 | -------------------------------------------------------------------------------- /exercises/49_find_by_character.md: -------------------------------------------------------------------------------- 1 | ### Find by character 2 | 3 | Find the c in '{char}' 4 | 5 | Find the first occurrence of {char} and move to it. 6 | 7 | `fc` - finds the first char 8 | `;;` - move to it by repeating the search with ; 9 | `Fc` - search backwards to the previous character 10 | -------------------------------------------------------------------------------- /exercises/13_delete_in_insert_mode.md: -------------------------------------------------------------------------------- 1 | ### Delete in insert mode 2 | 3 | ```text 4 | This is again some text. 5 | ``` 6 | 7 | Type the sentence again and practice these: 8 | 9 | `` - delete back 1 char 10 | `` - delete back 1 word 11 | `` - delete back to the start of the line 12 | 13 | ```text 14 | This is again 15 | ``` 16 | -------------------------------------------------------------------------------- /exercises/20_grokking_visual_mode.md: -------------------------------------------------------------------------------- 1 | ### Grokking visual mode 2 | 3 | Given the following text: 4 | 5 | ```text 6 | I like March better than anything. 7 | ``` 8 | 9 | Change the word "March" to "April" 10 | 11 | Use `jfM` to jump to the beginning of "March" 12 | Visually select the word with `viw` 13 | Hit `c` to change selection 14 | Type `April` to add the word "April" 15 | -------------------------------------------------------------------------------- /exercises/21_defining_visual_selection.md: -------------------------------------------------------------------------------- 1 | ### Defining visual selection 2 | 3 | There are 3 visual modes: 4 | `v` - characterwise 5 | `` - block 6 | `V` - linewise 7 | 8 | `gv` - reselect last visual mode 9 | 10 | Practice those on this block of text: 11 | 12 | ```text 13 | This is some text. 14 | Another one is right here. 15 | Here is more and more text. 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /exercises/82_count_the_matches_for_current_pattern.md: -------------------------------------------------------------------------------- 1 | ### Count the matches for current pattern 2 | 3 | Use this text to search on: 4 | 5 | ```text 6 | Going to Union Station takes time, 7 | but this time can be an advantage. 8 | Use it right and travelling time 9 | will pay off. 10 | ``` 11 | 12 | `/time` - to search for the word 'time' 13 | `%s///gn` - to count the number of matches 14 | -------------------------------------------------------------------------------- /exercises/01_insert_at_end_of_line.md: -------------------------------------------------------------------------------- 1 | ### Insert at the end of line 2 | 3 | Change this text: 4 | 5 | ```javascript 6 | var foo = 1 7 | var bar = 'a' 8 | var foobar = foo + bar 9 | ``` 10 | 11 | to this: 12 | 13 | ```javascript 14 | var foo = 1; 15 | var bar = 'a'; 16 | var foobar = foo + bar; 17 | ``` 18 | 19 | Use `A` to insert at the end of line. 20 | 21 | Add ';' to the end of these lines using `A`! 22 | -------------------------------------------------------------------------------- /exercises/56_traverse_the_change_list.md: -------------------------------------------------------------------------------- 1 | ### Traverse the change list 2 | 3 | `:changes` - will list all the changes during an editing session 4 | 5 | `g;` - traverse backward the changelist 6 | `g,` - traverse forward the changelist 7 | 8 | `backtic .` - moves you to the last change 9 | `backtic ^` - moves you to the last insertion 10 | `gi` - live insert mode, move around, this takes you back to insert mode where I left off 11 | -------------------------------------------------------------------------------- /exercises/02_insert_at_beginning_of_line.md: -------------------------------------------------------------------------------- 1 | ### Insert at the beginning of line 2 | 3 | Change this text: 4 | 5 | ```javascript 6 | var foo = 1 7 | var bar = 'a' 8 | var foobar = foo + bar 9 | ``` 10 | 11 | to this: 12 | 13 | ```javascript 14 | ;var foo = 1 15 | ;var bar = 'a' 16 | ;var foobar = foo + bar 17 | ``` 18 | 19 | Use `I` to insert at the beginning of line. 20 | 21 | Add ';' to the beginning of these lines using `I`! 22 | -------------------------------------------------------------------------------- /exercises/16_back_of_envelop_calculations_in_place.md: -------------------------------------------------------------------------------- 1 | ### Back of envelope calculations in place 2 | 3 | Suppose that we've just typed the following: 4 | 5 | ```text 6 | 6 chairs, each costing $35, totals $ 7 | ``` 8 | 9 | `A` - append mode 10 | `=6*35` - put the calculation result in register 11 | `` paste the result at the cursor 12 | 13 | You should get this: 14 | 15 | ```text 16 | 6 chairs, each costing $35, totals $210 17 | ``` 18 | -------------------------------------------------------------------------------- /exercises/26_append_after_a_ragged_visual_block.md: -------------------------------------------------------------------------------- 1 | ### Append after a ragged visual block 2 | 3 | We already had this text before: 4 | 5 | ```javascript 6 | var foo = 1 7 | var bar = 'a' 8 | var foobar = foo + bar 9 | ```` 10 | 11 | Append ';' at the end of each line using visual mode. 12 | 13 | Start on the first line, at "1" 14 | `jj$` 15 | `A;` - appends the ';' at the end of each line 16 | `` - will apply it for each selected line 17 | -------------------------------------------------------------------------------- /exercises/76_stake_the_boundaries_of_a_word.md: -------------------------------------------------------------------------------- 1 | ### Stake the boundaries of a word 2 | 3 | ``` 4 | the problem with these new recruits is that 5 | they don't keep their boots clean. 6 | ``` 7 | 8 | `/the` - will yield results with words where "the" is embedded, like "they" 9 | `/\v` - will find only the exact matches 10 | 11 | The `<` and `>` are zero-width items, they represent boundaries. 12 | 13 | `/\` - will match the angle brackets as chars 14 | -------------------------------------------------------------------------------- /exercises/40_organize_window_layout_with_tab_pages.md: -------------------------------------------------------------------------------- 1 | ### Organize window layout with tab pages 2 | 3 | All about tab pages 4 | 5 | `:tabe 01..` - Open the 01 markdown file in a new tab 6 | `gt` - move to next tab 7 | `gT` - move to previous tab 8 | 9 | `:sp 02` - open the 02 markdown file in a horizontal split window 10 | `T` - move the current window into its own tab 11 | 12 | `:tabc` - close the current tab 13 | `:tabo` - keep the active page, close all tabs 14 | -------------------------------------------------------------------------------- /exercises/33_insert_current_word_at_command_prompt.md: -------------------------------------------------------------------------------- 1 | ### Insert current word at the command prompt 2 | 3 | Rename the variable 'tally' to 'counter': 4 | 5 | ```javascript 6 | var tally; 7 | for (tally=1; tally <= 10; tally++) { 8 | // Do something with tally 9 | }; 10 | ``` 11 | 12 | Start on line 6 at the 't' character 13 | `*` - selects all the words 'tally' 14 | `cwcounter` - replaces the word with counter 15 | `:%s///g` - gets the current word for the substitute command 16 | -------------------------------------------------------------------------------- /exercises/03_one_step_back_two_forward.md: -------------------------------------------------------------------------------- 1 | ### One step back, two forward 2 | 3 | Change this text: 4 | 5 | ```javascript 6 | var foo = "method("+argument1+","+argument2+")"; 7 | ``` 8 | 9 | to this: 10 | 11 | ```javascript 12 | var foo = "method(" + argument1 + "," + argument2 + ")"; 13 | ``` 14 | 15 | Steps: 16 | 17 | 1. find "+" with `f+` 18 | 2. delete and switch to insert mode with `s` 19 | 3. Type ` + ` 20 | 4. Leave insert mode 21 | 5. find the next "+" with `;` 22 | 6. Repeat with `.` 23 | -------------------------------------------------------------------------------- /exercises/66_play_back_with_a_count.md: -------------------------------------------------------------------------------- 1 | ### Play Back with a Count 2 | 3 | Make this text: 4 | 5 | ```javascript 6 | var x = "("+a+","+b+","+c+","+d+","+e+")"; 7 | ``` 8 | 9 | Look like this: 10 | 11 | ```javascript 12 | var x = "(" + a + "," + b + "," + c + "," + d + "," + e + ")"; 13 | ``` 14 | 15 | `f+` - find the first "+" 16 | `s+` - add spaces around "+" 17 | `qq;.q` - record the `;.` keystrokes in the q register 18 | `22@q` - run the macro 22 times, it's OK to run it more 19 | -------------------------------------------------------------------------------- /exercises/19_overwrite_existing_text_with_replace.md: -------------------------------------------------------------------------------- 1 | ### Overwrite existing text 2 | 3 | Example text: 4 | 5 | ```text 6 | Typing in insert mode extends the line. But in replace mode 7 | the line length does not change. 8 | ``` 9 | 10 | Change the ". But" to ", but" in replace mode 11 | 12 | `f.` - find the dot 13 | `R, b` - enter into replace mode, replace . with comma, space and replace "B" with "b" 14 | 15 | `gR` triggers the Virtual Replace Mode, which is better, as that handles the tab spaces. 16 | -------------------------------------------------------------------------------- /exercises/83_offset_cursor_to_the_end_of_a_search_match.md: -------------------------------------------------------------------------------- 1 | ### Offset cursor to the end of a search match 2 | 3 | Use this text as an example: 4 | 5 | ```text 6 | Aim to learn a new programming lang each year. 7 | Which lang did you pick up last year? 8 | Which langs would you like to learn? 9 | ``` 10 | 11 | Task: replace "lang" with "language". 12 | 13 | `{start} on A of Aim` - initial position 14 | `/lang/e` - find the word 'lang' 15 | `auage` - add "uage" to "lang" 16 | `n.n.` - repeat it twice 17 | -------------------------------------------------------------------------------- /exercises/12_combine_and_conquer.md: -------------------------------------------------------------------------------- 1 | ### Combine and conquer 2 | 3 | Use this text for practicing: 4 | 5 | ```text 6 | This is some text, I hope you like it. 7 | one more 8 | and more 9 | ``` 10 | 11 | Do the following exercises on it: 12 | 13 | `2cw` - change 2 words 14 | `2dw` - delete 2 words 15 | `2yw` - yank 2 words into register 16 | `g~` - swap case 17 | `gu` - make selection all lower case 18 | `gU` - make selection all UPPER case 19 | `>` - shift right 20 | `<` - shift left 21 | `=` - auto indent 22 | -------------------------------------------------------------------------------- /exercises/10_use_counts.md: -------------------------------------------------------------------------------- 1 | ### Use count 2 | 3 | Change this text: 4 | 5 | ```css 6 | .blog, .news { background-image: url(/sprite.png); } 7 | .blog { background-position: 0px 0px } 8 | ``` 9 | 10 | to this: 11 | 12 | ```css 13 | .blog, .news { background-image: url(/sprite.png); } 14 | .blog { background-position: 0px 0px } 15 | .news { background-position: -180px 0px } 16 | ``` 17 | 18 | Moves: 19 | 20 | 1. `yyp` to duplicate the last line 21 | 2. `cW.news` to replace the word 'blog' with 'news' 22 | 3. `180` 23 | -------------------------------------------------------------------------------- /exercises/78_escape_problem_characters.md: -------------------------------------------------------------------------------- 1 | ### Escape Problem Characters 2 | 3 | ```text 4 | Search items: [http://vimdoc.net/search?q=/\\][s] 5 | ... 6 | [s]: http://vimdoc.net/search?q=/\\ 7 | ``` 8 | 9 | `"uyi[` - yank the url into register 'u' 10 | `/\Vu` - to populate the search field 11 | 12 | We could escape the backslash, but that's tedious. 13 | 14 | Vim will search forward with `/` character, but with `?` it searches backwards. 15 | 16 | `?http://vimdoc.net/search?q=/\\` - will match everything until the '?' 17 | -------------------------------------------------------------------------------- /exercises/72_tune_the_case_sensitivity_of_search_patterns.md: -------------------------------------------------------------------------------- 1 | ### Tune the case sensitivity of search patterns 2 | 3 | Here is a small text snippet to search on: 4 | 5 | ``` 6 | foo 7 | foo & foo 8 | foo & Foo 9 | FOO & foo 10 | ``` 11 | 12 | Setting case sensitivity per search: 13 | `/foo` - Search for the word "foo" 14 | `/foo\C` - Search for the word "foo", case-sensitive 15 | `/foo\c` - Search for the word "foo", case-insensitive 16 | 17 | `set smartcase` - cancels out of case-insensitive search when first upper-cased character is typed 18 | -------------------------------------------------------------------------------- /exercises/05_find_and_replace_by_hand.md: -------------------------------------------------------------------------------- 1 | ### Find and replace by hand 2 | 3 | Replace the first and third occurrence of "content" with "copy" in this text: 4 | 5 | ```text 6 | "...We're waiting for content before the site can go live... 7 | 8 | ...If you are content with this, let's go ahead with it... 9 | 10 | ...We'll launch as soon as we have the content...” 11 | ``` 12 | 13 | Steps: 14 | 15 | 1. Find the word content by `/content` 16 | 2. Replace the word by `cw copy` 17 | 3. Go to the next one `n` 18 | 4. Go to the last one `n` 19 | 5. Repeat command `.` 20 | -------------------------------------------------------------------------------- /exercises/58_snap_between_files_using_global_marks.md: -------------------------------------------------------------------------------- 1 | ### Snap between files using global marks 2 | 3 | While `m{a-z}` sets a local mark in the current file 4 | `m{A-Z}` - sets a global mark 5 | 6 | `vs 01_` - open the 01_ markdown file 7 | `:10` - go to the 10th line 8 | `mA` - mark the position there 9 | switch back to this file 10 | `backticA` - takes you back to the file's location 11 | 12 | `:vimgrep /cursor/ **` - searches for the word in the current dir, 13 | takes you there 14 | `:cn` - takes you to next result 15 | `:cp` - take you to previous result 16 | -------------------------------------------------------------------------------- /exercises/50_operate_with_a_search_motion.md: -------------------------------------------------------------------------------- 1 | ### Operate with a search motion 2 | 3 | Given this text, delete the part "takes time but eventually". 4 | 5 | ``` 6 | This phrase takes time but 7 | eventually gets to the point. 8 | ``` 9 | 10 | `/ta` - move the cursor to the beginning of the word "takes" 11 | `v` - enter into character-wise visual mode 12 | `/ge` - highlight 'til the word 'gets' 13 | `h` - moves back 1 char 14 | `d` - deletes the content 15 | 16 | Here is a quicker way of doing the same thing: 17 | 18 | `d/ge` - does the whole thing in 1 move 19 | -------------------------------------------------------------------------------- /exercises/39_split_windows.md: -------------------------------------------------------------------------------- 1 | ### Split windows 2 | 3 | All about split windows 4 | 5 | `v` - Divide the window vertically 6 | `s` - Divide the window horizontally 7 | 8 | Switch between windows: 9 | `w` - cycle open windows 10 | `h`, `j`, `k`, `l` move around in the windows 11 | 12 | `:cl[ose]` or `c` - close active window 13 | `:on[ly]` or `o` - keep the active window, closing the others 14 | 15 | `=` - equalize all windows 16 | `_` - maximize height of the active window 17 | `|` - maximize width of the active window 18 | -------------------------------------------------------------------------------- /exercises/79_meet_the_search_command.md: -------------------------------------------------------------------------------- 1 | ### Meet the Search Command 2 | 3 | ```text 4 | Going to Union Station takes time, 5 | but this time can be an advantage. 6 | Use it right, and travelling time 7 | will pay off. 8 | ``` 9 | 10 | `/time` - search for time forward 11 | `?time` - search for time backwards 12 | `n` - go to the next result 13 | `N` - go to the previous result - it always goes in the opposite direction 14 | `/` - will execute the last search forward 15 | `?` - will execute the last search backwards 16 | 17 | Use the "Up" button to browse search history. 18 | -------------------------------------------------------------------------------- /exercises/22_repeat_likewise_visual_commands.md: -------------------------------------------------------------------------------- 1 | ### Repeat likewise visual commands 2 | 3 | Suppose we have this Python code: 4 | 5 | ```python 6 | def fib(n): 7 | a, b = 0, 1 8 | while a < n: 9 | print a, 10 | a, b = b, a+b 11 | fib(42) 12 | ``` 13 | 14 | Set `:set shiftwidth=4 softtabstop=4 expandtab` 15 | 16 | `Vj` - Visually select the line 17 | `>..`- Indent the text and repeat 18 | 19 | The result should look like this: 20 | 21 | ```python 22 | def fib(n): 23 | a, b = 0, 1 24 | while a < n: 25 | print a, 26 | a, b = b, a+b 27 | fib(42) 28 | ``` 29 | -------------------------------------------------------------------------------- /exercises/84_operate_on_complete_search_match.md: -------------------------------------------------------------------------------- 1 | ### Operate on complete search match 2 | 3 | Make this: 4 | 5 | ```ruby 6 | class XhtmlDocument < XmlDocument; end 7 | class XhtmlTag < XmlTag; end 8 | ``` 9 | to be like this: 10 | 11 | ```ruby 12 | class XHTMLDocument < XMLDocument; end 13 | class XHTMLTag < XMLTag; end 14 | ``` 15 | 16 | One possible solution: 17 | `/\vX(ht)?ml\C` - find the items to change 18 | `gU//e` - make the text uppercase - we use '//e' as a motion 19 | `//` - move to next item 20 | `.` - rerun the command 21 | `//.` - move to next item and rerun the command 22 | -------------------------------------------------------------------------------- /exercises/64_record_and_execute_a_macro.md: -------------------------------------------------------------------------------- 1 | ### Record and Execute a Macro 2 | 3 | Given this text: 4 | 5 | ```javascript 6 | foo = 1 7 | bar = 'a' 8 | foobar = foo + bar 9 | ``` 10 | 11 | Start on the first line 12 | `qa` - start recording your macro in the "a" register 13 | `A;` - append semicolon at the end of the line 14 | `Ivar` - add "var" to the beginning of the line 15 | `q` - quit recording the macro 16 | 17 | Inspect what's in register a with `:reg a` 18 | 19 | `@{register}` - will replay the macro 20 | 21 | `j` - go to next line 22 | `@a` - replay it on second line 23 | `j@@` - replay it on the next line 24 | -------------------------------------------------------------------------------- /exercises/15_paste_from_register_in_insert_mode.md: -------------------------------------------------------------------------------- 1 | ### Paste from register in insert mode 2 | 3 | Here is an unfinished excerpt of text: 4 | 5 | ```text 6 | Practical Vim, by Drew Neil 7 | Read Drew Neil's 8 | ``` 9 | 10 | Copy and paste the page title here: 11 | 12 | `yt,` - yanks the text 'Practical Vim 13 | `j` - move to the second line 14 | `A ` - go to the end of line, switch to insert mode and add a space 15 | `0` - pastes the text from register 16 | `.` - adds the dot to the very end 17 | 18 | Make it look like this: 19 | 20 | ```text 21 | Practical Vim, by Drew Neil 22 | Read Drew Neil's Practical Vim. 23 | ``` 24 | -------------------------------------------------------------------------------- /exercises/74_use_the_backslash_v_literal_switch_for_verbatim_search.md: -------------------------------------------------------------------------------- 1 | ### Use the \v literal switch for verbatim search 2 | 3 | Use this excerpt of text: 4 | 5 | ``` 6 | The N key searches backwards... 7 | ... the \v pattern swtich (a.k.a. very magic search)... 8 | ``` 9 | 10 | `/a.k.a.` - will match more than 1 result 11 | `/a\.k\.a\.` - will find the right word, but escaping the dots is a lot of work 12 | `/\Va.k.a.` - turns off all special char in regex, only backslash is escaped 13 | 14 | General rule: 15 | If you search for a regular expression use the `\v`, if you want to search for 16 | verbatim text, use the `\V` switch. 17 | 18 | -------------------------------------------------------------------------------- /exercises/68_append_commands_to_macro.md: -------------------------------------------------------------------------------- 1 | ### Append Command to Macro 2 | 3 | Let's say we recorded this macro: 4 | 5 | ```text 6 | 1. one 7 | 2. two 8 | 3. three 9 | 4. four 10 | ``` 11 | 12 | `qa` - record in "a" register 13 | `0f.r)w~` - replace "." with ")" and tile-case word 14 | `q` - quit recording macro 15 | 16 | We forgot adding the "j" to move to the next line. 17 | 18 | Inspect what got recorded: 19 | 20 | `:reg a` - look at what's in "a" register 21 | 22 | `qA` - append to the macro recorded in "a" register 23 | `j` - move to next line 24 | `q` - quit recording the macro 25 | 26 | Look at it again, you should have the "j" at the end 27 | -------------------------------------------------------------------------------- /exercises/29_duplicate_or_move_lines.md: -------------------------------------------------------------------------------- 1 | ### Duplicate or move lines 2 | 3 | Given this text: 4 | 5 | ``` 6 | Shopping list 7 | Hardware store 8 | Buy new hammer 9 | Beauty parlor 10 | Buy nail polish remover 11 | Buy nails 12 | ``` 13 | 14 | Do the following exercises on the text above: 15 | 16 | Start at 'H' on line 7 17 | `:11copy.` - copies line to current line 18 | `:11t.` - should do the same 19 | `:t.` - duplicate current line 20 | `:t$` - copy current line to end of file 21 | 22 | `:11m$` - move line 11 to the end of the file 23 | Visual select 2 lines 24 | `:'<,'>m$` move the selected lines to the end of the file 25 | -------------------------------------------------------------------------------- /exercises/73_use_the_v_pattern_switch_for_regex_search.md: -------------------------------------------------------------------------------- 1 | ### Use the \v pattern switch for regex search 2 | 3 | Let's use this snippet of CSS: 4 | 5 | ```css 6 | body { color: #3c3c3c; } 7 | a { color: #0000EE; } 8 | strong { color: #000; } 9 | ``` 10 | 11 | `/#\([0-9a-fA-F]\{6}\|[0-9a-fA-F]\{3\}\)` - this regex will match all the hex values 12 | 13 | The `\v` switch make Vim's regex search like Perl, Python and Ruby. 14 | 15 | `/\v#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})` - the search works the same way, but it does not need to escape the special characters. 16 | `/\v#(\x{6}|\x{3})` - will be the same as above, but it's using `\x` character class 17 | ` 18 | -------------------------------------------------------------------------------- /exercises/23_prefer_operators_to_visual_commands.md: -------------------------------------------------------------------------------- 1 | ### Prefer operators to visual commands 2 | 3 | Change the text in the tags to be upper-case. 4 | 5 | ```html 6 | one 7 | two 8 | three 9 | ``` 10 | 11 | `{start}` - on the first line, first char 12 | `gUit` - make the word inside the tag ('it' ~ inside tag) upper case 13 | `j.` - go to next line and repeat 14 | `j.` - go to next line and repeat 15 | 16 | This is what the HTML snippet should look like: 17 | 18 | ```html 19 | ONE 20 | TWO 21 | THREE 22 | ``` 23 | 24 | `gU{motion}` - visual mode equivalent in normal mode 25 | -------------------------------------------------------------------------------- /exercises/51_trace_your_selection_with_precision_text_objects.md: -------------------------------------------------------------------------------- 1 | ### Trace your selection with precision text objects 2 | 3 | Let's say there is this JS snippet: 4 | 5 | ```javascript 6 | var tpl = [ 7 | '{title}' 8 | ] 9 | ``` 10 | 11 | `vi}` - enter into visual mode, select inside } 12 | `a"` - select including " 13 | `i>` - select inside angle bracket 14 | `it` - select inside tag 15 | `at` - select at tag, or the whole tag 16 | `i]` - select inside square brackets 17 | `a]` - select at square brackets including ] 18 | 19 | Exercise: 20 | 21 | `ci"#` - change the {url} to # 22 | `cit click here` - change the {title} to 'click here' 23 | -------------------------------------------------------------------------------- /exercises/62_pasting_from_a_register.md: -------------------------------------------------------------------------------- 1 | ### Pasting from a register 2 | 3 | Use the yank register to fix this: 4 | 5 | ```javascript 6 | collection = getCollection(); 7 | process(somethingInTheWay, target); 8 | ``` 9 | 10 | `yiw` - yank the word into the yank register 11 | `jww` - move down 1 line to 'somethingInTheWay' 12 | `ciw0` - insert the text from the yank register 13 | 14 | Duplicate the `` tag content 15 | 16 | ```html 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
keystrokesbuffer contents
25 | ``` 26 | 27 | `yap` - yanks the paragraph 28 | `5j` - move down 5 lines 29 | `gP` - insert above 30 | -------------------------------------------------------------------------------- /exercises/77_stake_the_boundaries_of_a_match.md: -------------------------------------------------------------------------------- 1 | ### Stake the boundaries of a match 2 | 3 | Sometimes we might want to specify a broad pattern, then focus on a subset 4 | of that match. Vim's `\zs` and `\ze` items allow just to do that. 5 | 6 | ```text 7 | Practical Vim is really a great book. 8 | ``` 9 | 10 | `/Practical Vim` - will match the word "Practical Vim" 11 | `/Practical \zsVim` - will match the "Vim" from the matches 12 | 13 | ```test 14 | Match "quoted words" not quote marks. 15 | ``` 16 | 17 | `/\v"[^"]+"` - matches the word with quotes (`[^"]+` - match anything that's not a quote mark) 18 | `/\v"\zs[^"]+\ze"` - matches words inside the quote 19 | -------------------------------------------------------------------------------- /exercises/30_run_normal_mode_commands_across_range.md: -------------------------------------------------------------------------------- 1 | ### Run normal mode commands across range 2 | 3 | There is a block of text like this: 4 | 5 | ```javascript 6 | var foo = 1 7 | var bar = 'a' 8 | var baz = 'z' 9 | var foobar = foo + bar 10 | var foobarbaz = foo + bar + baz 11 | ``` 12 | 13 | `A;` - Add semicolon to the end of first line 14 | Visual select the rows 15 | `:'<,'>normal.` - repeats the command for all highlighted lines 16 | 17 | or solve it like this: 18 | `:'<,'>normal A;` - executes normal command for all highlighted lines 19 | 20 | Add semicolon to all lines in file: 21 | `:%normal A;` 22 | 23 | Comment out an entire JS file: 24 | `:%normal i//` 25 | -------------------------------------------------------------------------------- /exercises/24_editing_tabular_data_with_visual_block_mode.md: -------------------------------------------------------------------------------- 1 | ### Editing tabular data with visual block mode 2 | 3 | Change this text: 4 | 5 | ``` 6 | Chapter Page 7 | Normal Mode 15 8 | Insert Mode 31 9 | Visual Mode 44 10 | ``` 11 | 12 | Make it look like this 13 | 14 | ``` 15 | Chapter | Page 16 | ------------------- 17 | Normal Mode | 15 18 | Insert Mode | 31 19 | Visual Mode | 44 20 | ``` 21 | 22 | `3j` - block select the column to the point we need to delete back 23 | `d...` - delete the columns 24 | `gv` - reselects the same visual selection 25 | `r|` - repeats adding the pipe 26 | `yyp` - duplicate the first row 27 | `Vr-` - select the entire line, repeat the "-" for the row 28 | -------------------------------------------------------------------------------- /exercises/70_evaluate_an_iterator_to_number_items_in_a_list.md: -------------------------------------------------------------------------------- 1 | ### Evaluate an iterator to number items in a list 2 | 3 | Change this text: 4 | 5 | ```shell 6 | partridge in a pear tree 7 | turtle doves 8 | French hens 9 | calling birds 10 | golden rings 11 | ``` 12 | 13 | to: 14 | 15 | ```shell 16 | 1) partridge in a pear tree 17 | 2) turtle doves 18 | 3) French hens 19 | 4) calling birds 20 | 5) golden rings 21 | ``` 22 | 23 | Use the expression register to do the loop 24 | `:let i=1` - set the i var to 1 25 | `qa` - record the macro in the 'a' register 26 | `I=i)` - insert the value of i 27 | `let i += 1` - increment i by 1 28 | `q` - finish recording the macro 29 | 30 | `:'<,'>norm @a` - execute the macro on the visual selection in parallel 31 | -------------------------------------------------------------------------------- /exercises/52_jump_between_matching_parentheses.md: -------------------------------------------------------------------------------- 1 | ### Jump between matching parentheses 2 | 3 | Let's say there is this console statement: 4 | 5 | ```javascript 6 | console.log([{'a':1},{'b':2}]); 7 | ``` 8 | 9 | `f(` - forward to the first '(' 10 | `%` - jump to the closing ')' 11 | `h` - move left - to the last ']' bracket 12 | `%` - jump to the first '[' bracket 13 | `l` - move right - to the first curly '{' 14 | `%` - jump to the matching curly '}' 15 | 16 | ```ruby 17 | %w{London Berlin New\ York} 18 | ``` 19 | 20 | `dt{` - delete the '%w' part 21 | `%` - jump to the closing curly bracket 22 | `r]` - replace '}' with ']' 23 | `''` or `backtick backtick` (\`\`) - go to the position before the last jump, i.e. the location of the first curly bracket 24 | `r[` - replace '{' with ']' 25 | -------------------------------------------------------------------------------- /exercises/35_running_commands_in_shell.md: -------------------------------------------------------------------------------- 1 | ### Running commands in shell 2 | 3 | 1. Combine two commands with one shell execution: 4 | 5 | `:write !sh` - will write this file (a vim command) and start a shell 6 | 7 | 2. Sort the content of this text: 8 | 9 | ``` 10 | first name, last name, email 11 | john,smith,john@example.com 12 | drew,neil,drew@vimcast.org 13 | jane,doe,jane@example.com 14 | ``` 15 | 16 | Visual highlight the lines to be sorted 17 | `:'<,'>!sort -t',' -k2` - the sort shell command is used to sort the lines 18 | 19 | 3. Pull up command history in vim 20 | 21 | `q:` will show normal mode history 22 | `q/` will show search history 23 | 24 | You can navigate the history with `j`, `k` or arrow buttons and repeat the command with `Enter`. 25 | 26 | To close the history window press `:q`. 27 | -------------------------------------------------------------------------------- /exercises/71_edit_the_contents_of_a_macro.md: -------------------------------------------------------------------------------- 1 | ### Edit the contents of a macro 2 | 3 | ```text 4 | 1. One 5 | 2. Two 6 | 3. three 7 | 4. four 8 | ``` 9 | 10 | Some of the lines use capital letter, `~` would just switch casing, we need to use `vU` here, which makes the char upper-cased at the cursor. 11 | 12 | This is what is should look like after your changes: 13 | 14 | ```test 15 | 1) One 16 | 2) Two 17 | 3) Three 18 | 4) Four 19 | ``` 20 | 21 | `:put a` - paste the content of register a into the doc 22 | Edit the macro by replacing `~` with `vU` 23 | Remove the last J, as it will be added back 24 | `"add` - replaces the current line with register a 25 | 26 | Characterwise yank is a safer bet, try this instead: 27 | `0` - go back to the first char in line 28 | `"ay$` - yank the content of the line 29 | `dd` - delete the line 30 | -------------------------------------------------------------------------------- /exercises/28_exec_commands_on_one_or_more_consecutive_lines.md: -------------------------------------------------------------------------------- 1 | ### Exec commands on one or more consecutive lines 2 | 3 | Look at this HTML sample: 4 | 5 | ```html 6 | 7 | 8 | Practical Vim 9 | 10 |

Practical Vim

11 | 12 | 13 | ``` 14 | 15 | Do the following exercises on the text above: 16 | 17 | `:7` - move to line 7 18 | `:print` print current line 19 | `:9p` - move to line 9, print it 20 | `:10d` - move to line 10 and delete it in 1 command 21 | `:8,11p` - print range 22 | `:.,$p` - print from current line ('.') to the end ('$') 23 | `:%p` - % means the entire file 24 | visual select multiple lines, `:'<,'>p` - prints the visual selection 25 | `://,/<\/html>/p` - print out everything within html 26 | `://+1,/<\/html>/-1p` - without the html tags 27 | -------------------------------------------------------------------------------- /exercises/25_changing_column_of_text.md: -------------------------------------------------------------------------------- 1 | ### Changing column of text 2 | 3 | Suppose there is this text: 4 | 5 | ```css 6 | li.one a{ background-image: url('/images/sprite.png'); } 7 | li.two a{ background-image: url('/images/sprite.png'); } 8 | li.three a{ background-image: url('/images/sprite.png'); } 9 | ``` 10 | 11 | Change 'images' to 'components' to look like this: 12 | 13 | ```css 14 | li.one a{ background-image: url('/components/sprite.png'); } 15 | li.two a{ background-image: url('/components/sprite.png'); } 16 | li.three a{ background-image: url('/components/sprite.png'); } 17 | ``` 18 | 19 | Steps to get there: 20 | 21 | `jje` - visual select the entire block 22 | `c` - change the selection 23 | `components` - type in the text 'components' 24 | `` - add the word 'components' to the other lines 25 | Note, `` is not `` :-( 26 | 27 | -------------------------------------------------------------------------------- /exercises/61_replace_visual_selection_with_a_register.md: -------------------------------------------------------------------------------- 1 | ### Replace visual selection with a register 2 | 3 | There is an easier way to swap the word "somethingInTheWay" with "collection" 4 | 5 | ```javascript 6 | collection = getCollection(); 7 | process(somethingInTheWay, target); 8 | ``` 9 | 10 | `yiw` - to yank the word into the yank register 11 | `jww` - to move to 's' char in "somethingInTheWay" 12 | `ve` - visually selects the entire word 13 | `p` - will insert the yanked word over the visually selected text 14 | 15 | Another exercise: swap the 2 words "chips" and "fish" 16 | 17 | I like chips and fish. 18 | 19 | Start on 'I' 20 | `fc` - find the first word to swap 21 | `de` - delete the word 22 | `mm` - mark the place 23 | `ww` - move to 'f' in "fish" 24 | `ve` - visually select the word 25 | `p` - paste the word over "fish" 26 | `backtickm` - to take back to the mark position 27 | `P` - to insert the word fish 28 | -------------------------------------------------------------------------------- /exercises/67_repeat_a_change_on_contiguous_lines.md: -------------------------------------------------------------------------------- 1 | ### Repeat a Change on Contiguous Lines 2 | 3 | Given this text: 4 | ``` 5 | 1. one 6 | 2. two 7 | 3. three 8 | 4. four 9 | 5. five 10 | ``` 11 | 12 | Change it to be like this: 13 | ``` 14 | 1) One 15 | 2) Two 16 | 3) Three 17 | 4) Four 18 | 5) Five 19 | ``` 20 | 21 | `qa` - record the macro in the "a" register 22 | `0f.` - find the dot on the first line 23 | `r)` - replace the dot with a ")" 24 | `w~` - title-case the word 25 | `j` - move down 1 line 26 | `q` - quit recording the macro 27 | 28 | We can replay the macro with this: 29 | `@a` - and `@@` after that 30 | 31 | But what if there is line barrier in the text like this? 32 | ``` 33 | 1. one 34 | 2. two 35 | 3. three 36 | // Some comment 37 | 4. four 38 | 5. five 39 | ``` 40 | 41 | Replay it with the highlighted text: 42 | `'<,'>norm @a` - this will replay the macro from the "a" register on the highlighted lines 43 | -------------------------------------------------------------------------------- /exercises/69_act_upon_a_collection_of_files.md: -------------------------------------------------------------------------------- 1 | ### Act Upon a Collection of Files 2 | 3 | `:cd ruby_module` - move into the "ruby_module" dir 4 | `:args *.rb` - open all the .rb files there 5 | `:args` - review all the files 6 | 7 | `:first` - move to the first 8 | `:last` - move to the last 9 | 10 | Start on the first one 11 | `qa` - record the macro into "a" register 12 | `gg/class` - find the "class" word 13 | `Omodule Rank` - add the "module Rank" above 14 | `j>G` - indent the file 15 | `Goend` - add the "end" to the bottom 16 | `q` - end recording the macro 17 | 18 | `:edit!` - undo all edits of the first file 19 | `:argdo normal @a` - run the macro in parallel 20 | 21 | `qA` - append to the previously recorded macro 22 | `:next` - go to the next file in buffer 23 | `q` - quit recording 24 | `22@a` - repeat the macro 22 times - in series 25 | 26 | Executing the macro in series might be slower, but if error occurs, it stops on the file where the error is. 27 | -------------------------------------------------------------------------------- /exercises/extra_02_navigating_on_long_page.md: -------------------------------------------------------------------------------- 1 | You can move around: 2 | `H` - move to the top of the screen 3 | `M` - move to the middle of the screen 4 | `L` - move to the bottom of the screen 5 | `z.` - moves the page to the middle of the current line 6 | `zt` - scroll the line with the cursor to the top 7 | `zb` - scroll the line with the cursor to the bottom 8 | `` - move half page down 9 | `` - page down 10 | `` - page up 11 | 12 | 1 13 | 2 14 | 3 15 | 4 16 | 5 17 | 6 18 | 7 19 | 8 20 | 9 21 | 10 22 | 11 23 | 12 24 | 13 25 | 14 26 | 15 27 | 16 28 | 17 29 | 18 30 | 19 31 | 20 32 | 21 33 | 22 34 | 23 35 | 24 36 | 25 37 | 26 38 | 27 39 | 28 40 | 29 41 | 30 42 | 31 43 | 32 44 | 33 45 | 34 46 | 35 47 | 36 48 | 37 49 | 38 50 | 39 51 | 40 52 | 41 53 | 42 54 | 43 55 | 44 56 | 45 57 | 46 58 | 47 59 | 48 60 | 49 61 | 50 62 | 51 63 | 52 64 | 53 65 | 54 66 | 55 67 | 56 68 | 57 69 | 58 70 | 59 71 | 60 72 | 61 73 | 62 74 | 63 75 | 64 76 | 65 77 | 66 78 | 67 79 | 68 80 | 69 81 | 70 82 | -------------------------------------------------------------------------------- /exercises/85_create_complex_patterns_by_iterating_upon_search_history.md: -------------------------------------------------------------------------------- 1 | ### Create complex patterns by iterating upon search history 2 | 3 | Change the single quotes to double quotes. 4 | 5 | ``` 6 | This string contains a "quoted" word. 7 | This string contains "two" quoted "words". 8 | This "string doesn't make things easy". 9 | ``` 10 | 11 | `/\v".+"` - will match everything in single quote, quote included 12 | `/` - Use search history get this search string back 13 | `/\v"[^"]+` - this will be better, but not perfect 14 | Use search history again 15 | `/\v"([^"]|"\w])+"` - this should be an even better match 16 | `q/` - let's use the search command-line window 17 | Find this search: `/\v"[^"]+` - to edit 18 | `f[` - jump to the first square bracket 19 | `c%(")` - cut and paste + insert parens 20 | `i|'\w` - inserts the remaining search 21 | 22 | We want to capture everything in the quotes, wrap it in parens 23 | `/\v'(([^']|'\w)+)'` - this is perfect 24 | `:%s//'\1'/g` - replace double quotes with single quotes by using a %1 capture register 25 | -------------------------------------------------------------------------------- /exercises/53_mark_your_place_and_snap_back_to_it.md: -------------------------------------------------------------------------------- 1 | ### Mark Your Place and Snap Back to It 2 | 3 | `m{a-zA-Z}` - marks the location of the cursor 4 | 5 | `:18` - go to the 18th row 6 | `ma` - mark the line 7 | `G` - go to the bottom of the page 8 | `'a` - jump back to the mark 9 | 10 | _Built in marks_ 11 | 12 | `'.` - location of last change 13 | `'^` - location of last insert 14 | `'[` - start of last change or yank 15 | `']` - end of last change or yank 16 | `'<` - start of last visual selection 17 | `'>` - end of last visual selection 18 | 19 | 1 20 | 2 21 | 3 22 | 4 23 | 5 24 | 6 25 | 7 26 | 8 27 | 9 28 | 10 29 | 11 30 | 12 31 | 13 32 | 14 33 | 15 34 | 16 35 | 17 36 | 18 37 | 19 38 | 20 39 | 21 40 | 22 41 | 23 42 | 24 43 | 25 44 | 26 45 | 27 46 | 28 47 | 29 48 | 30 49 | 31 50 | 32 51 | 33 52 | 34 53 | 35 54 | 36 55 | 37 56 | 38 57 | 39 58 | 40 59 | 41 60 | 42 61 | 43 62 | 44 63 | 45 64 | 46 65 | 47 66 | 48 67 | 49 68 | 50 69 | 51 70 | 52 71 | 53 72 | 54 73 | 55 74 | 56 75 | 57 76 | 58 77 | 59 78 | 60 79 | 61 80 | 62 81 | 63 82 | 64 83 | 65 84 | 66 85 | 67 86 | 68 87 | 69 88 | 70 89 | -------------------------------------------------------------------------------- /exercises/59_delete_yank_and_put_with_unnamed_register.md: -------------------------------------------------------------------------------- 1 | ### Delete yank and put with unnamed register 2 | 3 | Let's say we made a mistake of typing this text: 4 | 5 | ``` 6 | Practica lvim 7 | ``` 8 | 9 | Start on the last character 'm' 10 | `F space` - to search for space backwards 11 | `x` - to cut 12 | `p` - to paste 13 | 14 | `xp` - transpose two chars 15 | 16 | Similar concept can be used for lines 17 | 18 | ``` 19 | 2) line two 20 | 1) line one 21 | 3) line three 22 | ``` 23 | 24 | Start on the first line 25 | `dd` - to cut out the line 26 | `p` - to insert 27 | 28 | `ddp` - to transpose lines 29 | `yyp` - to duplicate lines 30 | 31 | ## Using the unnamed register 32 | 33 | ```javascript 34 | collection = getCollection(); 35 | process(somethingInTheWay, target); 36 | ``` 37 | 38 | `yiw` - yanks the word collection into the register 39 | `jww` - moved to the beginning of "somethingInTheWay" 40 | `dw` - deletes the word 41 | `P` - pastes before comma 42 | 43 | But oops, try this instead of `dw` 44 | `"_de` - deletes the word, but does not put it into register 45 | 46 | `"_d{motion}` - deletes the word without putting it into the register 47 | -------------------------------------------------------------------------------- /exercises/60_grok_vim_registers.md: -------------------------------------------------------------------------------- 1 | ### Grok Vim registers 2 | 3 | Given this text 4 | 5 | ```text 6 | 1) This is the first block of text 7 | 2) Another block of text 8 | ``` 9 | 10 | `"ayy` - will yank the first line into register "a" 11 | `"byy` - yank the 2nd line into register "b" 12 | `"bp` - paste in from register "b" first 13 | `"ap` - paste in from register "a" after 14 | 15 | Use the yank register to fix the text from previous kata 16 | 17 | ```javascript 18 | collection = getCollection(); 19 | process(somethingInTheWay, target); 20 | ``` 21 | 22 | `yiw` - to yank the word into yank register 23 | `jww` - to go to next line to the beginning of "somethingInTheWay" 24 | `dw` - will delete the word 25 | `"0P` - will insert the word from the yank register 26 | 27 | `:reg "0` - will inspect the yank and unnamed registers 28 | 29 | `"_` - is the black hole register, nothing returns from there 30 | 31 | `"+` - system clip board 32 | `"*` - system selection 33 | 34 | Visual select this entire doc, yank its content into `"+yy`, go to 35 | Pages and insert it into a new document there 36 | 37 | `"=` - expressions register 38 | 39 | `i` - switch to insert mode 40 | `=` - switches to expression register 41 | `6*35` - will provide the text "210" and drop back into insert mode 42 | 43 | ## More registers 44 | `%` - name of the current file 45 | `#` - name of the alternate file 46 | `.` - last inserted text 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## VIM Katas 2 | 3 | Daily exercises from the book [Practical Vim](https://pragprog.com/book/dnvim/practical-vim). 4 | 5 | It was about 5 years ago when I watched Jim Weirich solving the [Roman Numeral kata](https://vimeo.com/33841375) at an SCNA conference in Chicago. I was amazed by how he mastered his editor of choice: Emacs. His fingers were flying on the keyboard, and he wrangled the code I have rarely seen anybody before that. 6 | 7 | ![vim-screen](https://github.com/adomokos/climb_that_mountain/blob/master/resources/2016/10/vim_logo.png) 8 | 9 | I started using Vim in 2008 or 2009, but I never really invested the time to be good at it. I read the man pages, I went through Vim tutor, but I never really picked up or started using most of the advanced features. 10 | 11 | I remember how great I felt when I reset my Caps Lock key to function as Ctrl key. The power of hitting `` with my pinky and index finger just to trigger `` without reaching up to the top left on the keyboard made me feel I've just found kryptonite. 12 | 13 | I've had the book [Practical Vim](http://pragprog.com/practical_vim) for some time, but I never really practiced the examples from it. I looked at them here and there, tried them out, but I've never made a habit of practicing those daily. Then one day I got sick and tired of my inabilities, I started a new markdown document where I jotted down the [first exercise](https://github.com/adomokos/Vim-Katas/blob/master/exercises/24_editing_tabular_data_with_visual_block_mode.md) and the project of [Vim Katas](http://www.github.com) was born. Every time I commuted to work, I started with the first one and practiced all of them. Once I got to the end of it, I read the book further and added new exercises to it. 14 | 15 | I might have covered 60% of the book by now, but when I bump into a repeatable task and I leverage a macro for it, it always puts a smile on my face. 16 | 17 | Using Vim reminds me of learning to play a musical instrument. It takes time and effort to be good at it, and the keystrokes have to be in your fingertips. Once you slow down and think about it, the effectiveness of the text-based editor fades away, you would be more efficient by using visual editor instead (like Sublime Text, IntelliJ or Visual Studio). 18 | 19 | Vim (and I am sure many other tools) has this huge wall that people have to climb first to appreciate it. Clone this repo, open the first markdown file in Vim, and start practicing. 20 | --------------------------------------------------------------------------------