# HG changeset patch # User Christian Brabandt # Date 1730628903 -3600 # Node ID 8917088e2df9529565ce46cee14f8437293f0c62 # Parent 6d746d9952c21174625635e2c8531d4b67411732 patch 9.1.0836: The vimtutor can be improved Commit: https://github.com/vim/vim/commit/a54816b884157f6b7973a188f85c708d15cbf72f Author: Yegappan Lakshmanan Date: Sun Nov 3 10:49:23 2024 +0100 patch 9.1.0836: The vimtutor can be improved Problem: the vimtutor can be improved Solution: port and include the interactive vimtutor plugin from Neovim (by Felipe Morales) (Yegappan Lakshmanan) closes: #6414 Signed-off-by: Christian Brabandt Signed-off-by: Yegappan Lakshmanan diff --git a/Filelist b/Filelist --- a/Filelist +++ b/Filelist @@ -762,6 +762,10 @@ RT_ALL = \ runtime/tools/[a-z]*[a-z0-9] \ runtime/tutor/README.txt \ runtime/tutor/tutor \ + runtime/tutor/en/vim-01-beginner.tutor \ + runtime/tutor/en/vim-01-beginner.tutor.json \ + runtime/tutor/tutor.tutor \ + runtime/tutor/tutor.tutor.json \ runtime/tutor/tutor.vim \ runtime/vimrc_example.vim \ runtime/pack/dist/opt/cfilter/plugin/cfilter.vim \ diff --git a/runtime/autoload/tutor.vim b/runtime/autoload/tutor.vim new file mode 100644 --- /dev/null +++ b/runtime/autoload/tutor.vim @@ -0,0 +1,219 @@ +" vim: fdm=marker et ts=4 sw=4 + +" Setup: {{{1 +function! tutor#SetupVim() + if !exists('g:did_load_ftplugin') || g:did_load_ftplugin != 1 + filetype plugin on + endif + if has('syntax') + if !exists('g:syntax_on') || g:syntax_on == 0 + syntax on + endif + endif +endfunction + +" Loads metadata file, if available +function! tutor#LoadMetadata() + let b:tutor_metadata = json_decode(join(readfile(expand('%').'.json'), "\n")) +endfunction + +" Mappings: {{{1 + +function! tutor#SetNormalMappings() + nnoremap :call tutor#FollowLink(0) + nnoremap <2-LeftMouse> :call tutor#MouseDoubleClick() + nnoremap >> :call tutor#InjectCommand() +endfunction + +function! tutor#MouseDoubleClick() + if foldclosed(line('.')) > -1 + normal! zo + else + if match(getline('.'), '^#\{1,} ') > -1 + silent normal! zc + else + call tutor#FollowLink(0) + endif + endif +endfunction + +function! tutor#InjectCommand() + let l:cmd = substitute(getline('.'), '^\s*', '', '') + exe l:cmd + redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd +endfunction + +function! tutor#FollowLink(force) + let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '') + if l:stack_s =~# 'tutorLink' + let l:link_start = searchpairpos('\[', '', ')', 'nbcW') + let l:link_end = searchpairpos('\[', '', ')', 'ncW') + if l:link_start[0] == l:link_end[0] + let l:linkData = getline(l:link_start[0])[l:link_start[1]-1:l:link_end[1]-1] + else + return + endif + let l:target = matchstr(l:linkData, '(\@<=.*)\@=') + if a:force != 1 && match(l:target, '\*.\+\*') > -1 + call cursor(l:link_start[0], l:link_end[1]) + call search(l:target, '') + normal! ^ + elseif a:force != 1 && match(l:target, '^@tutor:') > -1 + let l:tutor = matchstr(l:target, '@tutor:\zs.*') + exe "Tutor ".l:tutor + else + exe "help ".l:target + endif + endif +endfunction + +" Folding And Info: {{{1 + +function! tutor#TutorFolds() + if getline(v:lnum) =~# '^#\{1,6}' + return ">". len(matchstr(getline(v:lnum), '^#\{1,6}')) + else + return "=" + endif +endfunction + +" Marks: {{{1 + +function! tutor#ApplyMarks() + hi! link tutorExpect Special + if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect') + let b:tutor_sign_id = 1 + for expct in keys(b:tutor_metadata['expect']) + let lnum = eval(expct) + call matchaddpos('tutorExpect', [lnum]) + call tutor#CheckLine(lnum) + endfor + endif +endfunction + +function! tutor#ApplyMarksOnChanged() + if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect') + let lnum = line('.') + if index(keys(b:tutor_metadata['expect']), string(lnum)) > -1 + call tutor#CheckLine(lnum) + endif + endif +endfunction + +function! tutor#CheckLine(line) + if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect') + let bufn = bufnr('%') + let ctext = getline(a:line) + if b:tutor_metadata['expect'][string(a:line)] == -1 || ctext ==# b:tutor_metadata['expect'][string(a:line)] + exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorok buffer=".bufn + else + exe "sign place ".b:tutor_sign_id." line=".a:line." name=tutorbad buffer=".bufn + endif + let b:tutor_sign_id+=1 + endif +endfunction + +" Tutor Cmd: {{{1 + +function! s:Locale() + if exists('v:lang') && v:lang =~ '\a\a' + let l:lang = v:lang + elseif $LC_ALL =~ '\a\a' + let l:lang = $LC_ALL + elseif $LANG =~ '\a\a' + let l:lang = $LANG + else + let l:lang = 'en_US' + endif + return split(l:lang, '_') +endfunction + +function! s:GlobPath(lp, pat) + if version >= 704 && has('patch279') + return globpath(a:lp, a:pat, 1, 1) + else + return split(globpath(a:lp, a:pat, 1), '\n') + endif +endfunction + +function! s:Sort(a, b) + let mod_a = fnamemodify(a:a, ':t') + let mod_b = fnamemodify(a:b, ':t') + if mod_a == mod_b + let retval = 0 + elseif mod_a > mod_b + if match(mod_a, '^vim-') > -1 && match(mod_b, '^vim-') == -1 + let retval = -1 + else + let retval = 1 + endif + else + if match(mod_b, '^vim-') > -1 && match(mod_a, '^vim-') == -1 + let retval = 1 + else + let retval = -1 + endif + endif + return retval +endfunction + +function! s:GlobTutorials(name) + " search for tutorials: + " 1. non-localized + let l:tutors = s:GlobPath(&rtp, 'tutor/'.a:name.'.tutor') + " 2. localized for current locale + let l:locale_tutors = s:GlobPath(&rtp, 'tutor/'.s:Locale()[0].'/'.a:name.'.tutor') + " 3. fallback to 'en' + if len(l:locale_tutors) == 0 + let l:locale_tutors = s:GlobPath(&rtp, 'tutor/en/'.a:name.'.tutor') + endif + call extend(l:tutors, l:locale_tutors) + return uniq(sort(l:tutors, 's:Sort'), 's:Sort') +endfunction + +function! tutor#TutorCmd(tutor_name) + if match(a:tutor_name, '[[:space:]]') > 0 + echom "Only one argument accepted (check spaces)" + return + endif + + if a:tutor_name == '' + let l:tutor_name = 'vim-01-beginner.tutor' + else + let l:tutor_name = a:tutor_name + endif + + if match(l:tutor_name, '\.tutor$') > 0 + let l:tutor_name = fnamemodify(l:tutor_name, ':r') + endif + + let l:tutors = s:GlobTutorials(l:tutor_name) + + if len(l:tutors) == 0 + echom "No tutorial with that name found" + return + endif + + if len(l:tutors) == 1 + let l:to_open = l:tutors[0] + else + let l:idx = 0 + let l:candidates = ['Several tutorials with that name found. Select one:'] + for candidate in map(copy(l:tutors), + \'fnamemodify(v:val, ":h:h:t")."/".s:Locale()[0]."/".fnamemodify(v:val, ":t")') + let l:idx += 1 + call add(l:candidates, l:idx.'. '.candidate) + endfor + let l:tutor_to_open = inputlist(l:candidates) + let l:to_open = l:tutors[l:tutor_to_open-1] + endif + + call tutor#SetupVim() + exe "edit ".l:to_open +endfunction + +function! tutor#TutorCmdComplete(lead,line,pos) + let l:tutors = s:GlobTutorials('*') + let l:names = uniq(sort(map(l:tutors, 'fnamemodify(v:val, ":t:r")'), 's:Sort')) + return join(l:names, "\n") +endfunction diff --git a/runtime/defaults.vim b/runtime/defaults.vim --- a/runtime/defaults.vim +++ b/runtime/defaults.vim @@ -1,7 +1,7 @@ " The default vimrc file. " " Maintainer: The Vim Project -" Last change: 2023 Aug 10 +" Last Change: 2024 Nov 03 " Former Maintainer: Bram Moolenaar " " This is loaded if no vimrc file was found. @@ -107,11 +107,11 @@ if 1 " (happens when dropping a file on gvim), for a commit or rebase message " (likely a different one than last time), and when using xxd(1) to filter " and edit binary files (it transforms input files back and forth, causing - " them to have dual nature, so to speak) + " them to have dual nature, so to speak) or when running the new tutor autocmd BufReadPost * \ let line = line("'\"") \ | if line >= 1 && line <= line("$") && &filetype !~# 'commit' - \ && index(['xxd', 'gitrebase'], &filetype) == -1 + \ && index(['xxd', 'gitrebase', 'tutor'], &filetype) == -1 \ | execute "normal! g`\"" \ | endif diff --git a/runtime/doc/Make_all.mak b/runtime/doc/Make_all.mak --- a/runtime/doc/Make_all.mak +++ b/runtime/doc/Make_all.mak @@ -75,6 +75,7 @@ DOCS = \ pi_paren.txt \ pi_spec.txt \ pi_tar.txt \ + pi_tutor.txt \ pi_vimball.txt \ pi_zip.txt \ popup.txt \ @@ -228,6 +229,7 @@ HTMLS = \ pi_paren.html \ pi_spec.html \ pi_tar.html \ + pi_tutor.html \ pi_vimball.html \ pi_zip.html \ popup.html \ diff --git a/runtime/doc/pi_tutor.txt b/runtime/doc/pi_tutor.txt new file mode 100644 --- /dev/null +++ b/runtime/doc/pi_tutor.txt @@ -0,0 +1,51 @@ +*pi_tutor.txt* For Vim version 9.1. Last change: 2024 Nov 02 + +INTERACTIVE TUTORIALS FOR VIM *vim-tutor-mode* + +vim-tutor-mode provides a system to follow and create interactive tutorials +for vim and third party plugins. It replaces the venerable `vimtutor` system. + +============================================================================== +1. Usage *vim-tutor-usage* + +vim-tutor-mode tutorials are hypertext documents, they have rich text and +contain links. To stand out from the rest of the text, links are underlined. +You can follow them by placing the cursor over them and pressing , or +by double-clicking them. + +1.1 Commands +------------ + *:Tutor* +:Tutor {tutorial} Opens a tutorial. Command-line completion for + {tutorial} is provided, the candidates are a list of + '.tutor' files found in the 'tutor/' folder in + the 'runtimepath'. Tutorials prefixed with 'vim-' will + always be shown first. + + If no {tutorial} is provided, the command starts the + 'vim-01-beginner' tutorial, which is equivalent to + Vim's `vimtutor`. + +============================================================================= +2. Creating tutorials *vim-tutor-create* + +Writing vim-tutor-mode tutorials is easy. For an overview of the format used, +please consult the 'tutor.tutor' file: > + + :Tutor tutor +< +New tutorials must be placed in the 'tutor/' folder in the 'runtimepath' +to be detected by the :Tutor command. + +It is recommended to use a less formal style when writing tutorials than in +regular documentation (unless the content requires it). + +============================================================================ +3. Contributing + +Development of the plugin is done over at github [1]. Feel free to report +issues and make suggestions. + +[1]: https://github.com/fmoralesc/vim-tutor-mode + +" vim: set ft=help : diff --git a/runtime/doc/tags b/runtime/doc/tags --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -2177,6 +2177,7 @@ 90.5 usr_90.txt /*90.5* :Termdebug terminal.txt /*:Termdebug* :TermdebugCommand terminal.txt /*:TermdebugCommand* :Texplore pi_netrw.txt /*:Texplore* +:Tutor pi_tutor.txt /*:Tutor* :Until terminal.txt /*:Until* :Up terminal.txt /*:Up* :UseVimball pi_vimball.txt /*:UseVimball* @@ -9438,6 +9439,7 @@ pi_netrw.txt pi_netrw.txt /*pi_netrw.txt pi_paren.txt pi_paren.txt /*pi_paren.txt* pi_spec.txt pi_spec.txt /*pi_spec.txt* pi_tar.txt pi_tar.txt /*pi_tar.txt* +pi_tutor.txt pi_tutor.txt /*pi_tutor.txt* pi_vimball.txt pi_vimball.txt /*pi_vimball.txt* pi_zip.txt pi_zip.txt /*pi_zip.txt* pkzip options.txt /*pkzip* @@ -11244,6 +11246,9 @@ vim-script-intro usr_41.txt /*vim-script vim-script-library eval.txt /*vim-script-library* vim-security intro.txt /*vim-security* vim-shebang various.txt /*vim-shebang* +vim-tutor-create pi_tutor.txt /*vim-tutor-create* +vim-tutor-mode pi_tutor.txt /*vim-tutor-mode* +vim-tutor-usage pi_tutor.txt /*vim-tutor-usage* vim-use intro.txt /*vim-use* vim-variable eval.txt /*vim-variable* vim.b if_lua.txt /*vim.b* diff --git a/runtime/doc/usr_01.txt b/runtime/doc/usr_01.txt --- a/runtime/doc/usr_01.txt +++ b/runtime/doc/usr_01.txt @@ -1,4 +1,4 @@ -*usr_01.txt* For Vim version 9.1. Last change: 2024 May 11 +*usr_01.txt* For Vim version 9.1. Last change: 2024 Nov 03 VIM USER MANUAL - by Bram Moolenaar @@ -107,6 +107,8 @@ For more info see |vimrc| and |compatibl ============================================================================== *01.3* Using the Vim tutor *tutor* *vimtutor* +For the interactive tutor, see |vim-tutor-mode| + Instead of reading the text (boring!) you can use the vimtutor to learn your first Vim commands. This is a 30-minute tutorial that teaches the most basic Vim functionality hands-on. diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt --- a/runtime/doc/version9.txt +++ b/runtime/doc/version9.txt @@ -1,4 +1,4 @@ -*version9.txt* For Vim version 9.1. Last change: 2024 Nov 02 +*version9.txt* For Vim version 9.1. Last change: 2024 Nov 03 VIM REFERENCE MANUAL by Bram Moolenaar @@ -41603,6 +41603,8 @@ Changed~ - the putty terminal is detected using an |TermResponse| autocommand in |defaults.vim| and Vim switches to a dark background - the |help-TOC| package is included to ease navigating the documentation. +- an interactive tutor plugin has been included |vim-tutor-mode|, can be + started via |:Tutor| *added-9.2* Added ~ diff --git a/runtime/filetype.vim b/runtime/filetype.vim --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -2589,6 +2589,9 @@ au BufNewFile,BufReadPost *.tsscl setf " TSV Files au BufNewFile,BufRead *.tsv setf tsv +" Tutor mode +au BufNewFile,BufReadPost *.tutor setf tutor + " TWIG files au BufNewFile,BufReadPost *.twig setf twig diff --git a/runtime/ftplugin/tutor.vim b/runtime/ftplugin/tutor.vim new file mode 100644 --- /dev/null +++ b/runtime/ftplugin/tutor.vim @@ -0,0 +1,45 @@ +" vim: fdm=marker + +" Base: {{{1 +call tutor#SetupVim() + +" Buffer Settings: {{{1 +setlocal noreadonly +if !exists('g:tutor_debug') || g:tutor_debug == 0 + setlocal buftype=nofile + setlocal concealcursor+=inv + setlocal conceallevel=2 +else + setlocal buftype= + setlocal concealcursor& + setlocal conceallevel=0 +endif +setlocal noundofile + +setlocal keywordprg=:help +setlocal iskeyword=@,-,_ + +" The user will have to enable the folds himself, but we provide the foldexpr +" function. +setlocal foldmethod=manual +setlocal foldexpr=tutor#TutorFolds() +setlocal foldlevel=4 + +" Load metadata if it exists: {{{1 +if filereadable(expand('%').'.json') + call tutor#LoadMetadata() +endif + +" Mappings: {{{1 + +call tutor#SetNormalMappings() + +" Checks: {{{1 + +sign define tutorok text=✓ texthl=tutorOK +sign define tutorbad text=✗ texthl=tutorX + +if !exists('g:tutor_debug') || g:tutor_debug == 0 + call tutor#ApplyMarks() + autocmd! TextChanged,TextChangedI call tutor#ApplyMarksOnChanged() +endif diff --git a/runtime/plugin/tutor.vim b/runtime/plugin/tutor.vim new file mode 100644 --- /dev/null +++ b/runtime/plugin/tutor.vim @@ -0,0 +1,6 @@ +if exists('g:loaded_tutor_mode_plugin') || &compatible + finish +endif +let g:loaded_tutor_mode_plugin = 1 + +command! -nargs=? -complete=custom,tutor#TutorCmdComplete Tutor call tutor#TutorCmd() diff --git a/runtime/syntax/tutor.vim b/runtime/syntax/tutor.vim new file mode 100644 --- /dev/null +++ b/runtime/syntax/tutor.vim @@ -0,0 +1,77 @@ +if exists("b:current_syntax") + finish +endif + +syn include @VIM syntax/vim.vim +unlet b:current_syntax +syn include @TUTORSHELL syntax/sh.vim +unlet b:current_syntax +syn include @VIMNORMAL syntax/vimnormal.vim + +syn match tutorLink /\[.\{-}\](.\{-})/ contains=tutorInlineNormal +syn match tutorLinkBands /\[\|\]\|(\|)/ contained containedin=tutorLink,tutorLinkAnchor conceal +syn match tutorLinkAnchor /(.\{-})/ contained containedin=tutorLink conceal +syn match tutorURL /\(https\?\|file\):\/\/[[:graph:]]\+\>\/\?/ +syn match tutorEmail /\<[[:graph:]]\+@[[:graph:]]\+\>/ +syn match tutorInternalAnchor /\*[[:alnum:]-]\+\*/ contained conceal containedin=tutorSection + +syn match tutorSection /^#\{1,6}\s.\+$/ fold contains=tutorInlineNormal +syn match tutorSectionBullet /#/ contained containedin=tutorSection + +syn match tutorTOC /\ctable of contents:/ + +syn match tutorConcealedEscapes /\\[`*!\[\]():$-]\@=/ conceal + +syn region tutorEmphasis matchgroup=Delimiter start=/[\*]\@=?@ABCDGHIJKLMNOPQRSUVWXYZgmqstz~iu]/ nextgroup=normalMod +syn match normalMod /m\@BW\[\]`bstweE{}ftFT;,$]/ +syn match normalCount /[0-9]/ +syn region normalSearch start=/[/?]\@<=./ end=/.\@=/ contains=normalKey keepend +syn region normalChange start=/\([cr][wWbBeE()\[\]{}pst]\)\@<=./ end=/.\@=/ contains=normalKey keepend +syn match normalCharSearch /\c[ftr]\@<=\w/ +syn match normalMark /\(f\@'\@!/ + +hi! link normalOp Operator +hi! link normalMod PreProc +hi! link normalObject Structure +hi! link normalCount Number +hi! link normalMark Identifier +hi! link normalKey Special diff --git a/runtime/tutor/en/vim-01-beginner.tutor b/runtime/tutor/en/vim-01-beginner.tutor new file mode 100644 --- /dev/null +++ b/runtime/tutor/en/vim-01-beginner.tutor @@ -0,0 +1,980 @@ +# Welcome to the VIM Tutor + +Vim is a very powerful editor that has many commands, too many to explain in +a tutor such as this. This tutor is designed to describe enough of the +commands that you will be able to easily use Vim as an all-purpose editor. +It is IMPORTANT to remember that this tutor is set up to teach by use. That +means that you need to do the exercises to learn them properly. If you only +read the text, you will soon forget what is most important! + +For now, make sure that your Shift-Lock key is NOT depressed and press the +`j`{normal} key enough times to move the cursor so that Lesson 0 completely +fills the screen. + +# Lesson 0 + +NOTE: The commands in the lessons will modify the text, but those changes +won't be saved. Don't worry about messing things up; just remember that +pressing []() and then [u](u) will undo the latest change. + +This tutorial is interactive, and there are a few things you should know. +- Type []() on links [like this](holy-grail ) to open the linked help section. +- Or simply type [K](K) on any word to find its documentation! +- Sometimes you will be required to modify text like +this here +Once you have done the changes correctly, the ✗ sign at the left will change +to ✓. I imagine you can already see how neat Vim can be. ;) +Other times, you'll be prompted to run a command (I'll explain this later): +~~~ cmd + :help +~~~ +or press a sequence of keys +~~~ normal + 0fd3wP$P +~~~ + +Text within <'s and >'s (like ``{normal}) describes a key to press +instead of text to type. + +Now, move to the next lesson (use the `j`{normal} key to scroll down). + +## Lesson 1.1: MOVING THE CURSOR + +** To move the cursor, press the `h`, `j`, `k`, `l` keys as indicated. ** + + ↑ + k Hint: The `h`{normal} key is at the left and moves left. + ← h l → The `l`{normal} key is at the right and moves right. + j The `j`{normal} key looks like a down arrow. + ↓ + + 1. Move the cursor around the screen until you are comfortable. + + 2. Hold down the down key (`j`{normal}) until it repeats. + Now you know how to move to the next lesson. + + 3. Using the down key, move to Lesson 1.2. + +NOTE: If you are ever unsure about something you typed, press to place + you in Normal mode. Then retype the command you wanted. + +NOTE: The cursor keys should also work. But using hjkl you will be able to + move around much faster, once you get used to it. Really! + +# Lesson 1.2: EXITING VIM + +!! NOTE: Before executing any of the steps below, +read this entire lesson !! + + 1. Press the key (to make sure you are in Normal mode). + + 2. Type: + + `:q!`{vim} ``{normal}. + + This exits the editor, DISCARDING any changes you have made. + + 3. Open vim and get back here by executing the command that got you into + this tutor. That might be: + + :Tutor + + 4. If you have these steps memorized and are confident, execute steps + 1 through 3 to exit and re-enter the editor. + +NOTE: [:q!](:q) discards any changes you made. In a few lessons you + will learn how to save the changes to a file. + + 5. Move the cursor down to Lesson 1.3. + +## Lesson 1.3: TEXT EDITING - DELETION + +** Press `x`{normal} to delete the character under the cursor. ** + + 1. Move the cursor to the line below marked ✗. + + 2. To fix the errors, move the cursor until it is on top of the + character to be deleted. + + 3. Press [the x key](x) to delete the unwanted character. + + 4. Repeat steps 2 through 4 until the sentence is correct. + +The ccow jumpedd ovverr thhe mooon. + + 5. Now that the line is correct, go on to Lesson 1.4. + +NOTE: As you go through this tutor, do not try to memorize, learn by + usage. + +# Lesson 1.4: TEXT EDITING: INSERTION + +** Press `i`{normal} to insert text. ** + + 1. Move the cursor to the first line below marked ✗. + + 2. To make the first line the same as the second, move the cursor on top + of the first character AFTER where the text is to be inserted. + + 3. Press `i`{normal} and type in the necessary additions. + + 4. As each error is fixed press ``{normal} to return to Normal mode. + Repeat steps 2 through 4 to correct the sentence. + +There is text misng this . +There is some text missing from this line. + + 5. When you are comfortable inserting text move to Lesson 1.5. + +# Lesson 1.5: TEXT EDITING: APPENDING + +** Press `A`{normal} to append text. ** + + 1. Move the cursor to the first line below marked ✗. + It does not matter on what character the cursor is in that line. + + 2. Press [A](A) and type in the necessary additions. + + 3. As the text has been appended press ``{normal} to return to Normal + mode. + + 4. Move the cursor to the second line marked ✗ and repeat + steps 2 and 3 to correct this sentence. + +There is some text missing from th +There is some text missing from this line. +There is also some text miss +There is also some text missing here. + + 5. When you are comfortable appending text move to Lesson 1.6. + +# Lesson 1.6: EDITING A FILE + +** Use `:wq`{vim} to save a file and exit. ** + +!! NOTE: Before executing any of the steps below, read this entire lesson !! + + 1. Exit this tutor as you did in Lesson 1.2: `:q!`{vim} + Or, if you have access to another terminal, do the following there. + + 2. At the shell prompt type this command: +~~~ sh + $ vim tutor +~~~ + 'vim' is the command to start the Vim editor, 'tutor' is the name of + the file you wish to edit. Use a file that may be changed. + + 3. Insert and delete text as you learned in the previous lessons. + + 4. Save the file with changes and exit Vim with: +~~~ cmd + :wq +~~~ + + Note you'll need to press `` to execute the command. + + 5. If you have quit vimtutor in step 1 restart the vimtutor and move down + to the following summary. + + 6. After reading the above steps and understanding them: do it. + +# Lesson 1 SUMMARY + + 1. The cursor is moved using either the arrow keys or the hjkl keys. + h (left) j (down) k (up) l (right) + + 2. To start Vim from the shell prompt type: + +~~~ sh + $ vim FILENAME +~~~ + + 3. To exit Vim type: ``{normal} `:q!`{vim} ``{normal} to trash + all changes. + OR type: ``{normal} `:wq`{vim} ``{normal} to save + the changes. + + 4. To delete the character at the cursor type: `x`{normal} + + 5. To insert or append text type: + `i`{normal} insert text ``{normal} insert before the cursor. + `A`{normal} append text ``{normal} append after the line. + +NOTE: Pressing ``{normal} will place you in Normal mode or will cancel + an unwanted and partially completed command. + +Now continue with Lesson 2. + +# Lesson 2.1: DELETION COMMANDS + +** Type `dw`{normal} to delete a word. ** + + 1. Press ``{normal} to make sure you are in Normal mode. + + 2. Move the cursor to the line below marked ✗. + + 3. Move the cursor to the beginning of a word that needs to be deleted. + + 4. Type [d](d)[w](w) to make the word disappear. + +There are a some words fun that don't belong paper in this sentence. + + 5. Repeat steps 3 and 4 until the sentence is correct and go to Lesson 2.2. + +# Lesson 2.2: MORE DELETION COMMANDS + +** Type `d$`{normal} to delete to the end of the line. ** + + 1. Press ``{normal} to make sure you are in Normal mode. + + 2. Move the cursor to the line below marked ✗. + + 3. Move the cursor to the end of the correct line (AFTER the first . ). + + 4. Type `d$`{normal} to delete to the end of the line. + +Somebody typed the end of this line twice. end of this line twice. + + 5. Move on to Lesson 2.3 to understand what is happening. + +# Lesson 2.3: ON OPERATORS AND MOTIONS + +Many commands that change text are made from an [operator](operator) and +a [motion](navigation). +The format for a delete command with the [d](d) delete operator is as follows: + + d motion + + Where: + d - is the delete operator. + motion - is what the operator will operate on (listed below). + + A short list of motions: + [w](w) - until the start of the next word, EXCLUDING its first character. + [e](e) - to the end of the current word, INCLUDING the last character. + [$]($) - to the end of the line, INCLUDING the last character. + + Thus typing `de`{normal} will delete from the cursor to the end of the word. + +NOTE: Pressing just the motion while in Normal mode without an operator + will move the cursor as specified. + +# Lesson 2.4: USING A COUNT FOR A MOTION + +** Typing a number before a motion repeats it that many times. ** + + 1. Move the cursor to the start of the line marked ✓ below. + + 2. Type `2w`{normal} to move the cursor two words forward. + + 3. Type `3e`{normal} to move the cursor to the end of the third word forward. + + 4. Type `0`{normal} ([zero](0)) to move to the start of the line. + + 5. Repeat steps 2 and 3 with different numbers. + +This is just a line with words you can move around in. + + 6. Move on to Lesson 2.5. + +# Lesson 2.5: USING A COUNT TO DELETE MORE + +** Typing a number with an operator repeats it that many times. ** + +In the combination of the delete operator and a motion mentioned above you +insert a count before the motion to delete more: + d number motion + + 1. Move the cursor to the first UPPER CASE word in the line marked ✗. + + 2. Type `d2w`{normal} to delete the two UPPER CASE words + + 3. Repeat steps 1 and 2 with a different count to delete the consecutive + UPPER CASE words with one command + +This ABC DE line FGHI JK LMN OP of words is Q RS TUV cleaned up. + +# Lesson 2.6: OPERATING ON LINES + +** Type `dd`{normal} to delete a whole line. ** + +Due to the frequency of whole line deletion, the designers of Vi decided +it would be easier to simply type two d's to delete a line. + + 1. Move the cursor to the second line in the phrase below. + 2. Type [dd](dd) to delete the line. + 3. Now move to the fourth line. + 4. Type `2dd`{normal} to delete two lines. + +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. + +# Lesson 2.7: THE UNDO COMMAND + +** Press `u`{normal} to undo the last commands, `U`{normal} to fix a whole line. ** + + 1. Move the cursor to the line below marked ✗ and place it on the + first error. + 2. Type `x`{normal} to delete the first unwanted character. + 3. Now type `u`{normal} to undo the last command executed. + 4. This time fix all the errors on the line using the `x`{normal} command. + 5. Now type a capital `U`{normal} to return the line to its original state. + 6. Now type `u`{normal} a few times to undo the `U`{normal} and preceding + commands. + 7. Now type ``{normal} (Control + R) a few times to redo the commands + (undo the undos). + +Fiix the errors oon thhis line and reeplace them witth undo. + + 8. These are very useful commands. Now move on to the Lesson 2 Summary. + +# Lesson 2 SUMMARY + + 1. To delete from the cursor up to the next word type: `dw`{normal} + 2. To delete from the cursor to the end of a line type: `d$`{normal} + 3. To delete a whole line type: `dd`{normal} + 4. To repeat a motion prepend it with a number: `2w`{normal} + + 5. The format for a change command is: + operator [number] motion + where: + operator - is what to do, such as [d](d) for delete + [number] - is an optional count to repeat the motion + motion - moves over the text to operate on, such as: + [w](w) (word), + [$]($) (to the end of line), etc. + + 6. To move to the start of the line use a zero: [0](0) + + 7. To undo previous actions, type: `u`{normal} (lowercase u) + To undo all the changes on a line, type: `U`{normal} (capital U) + To undo the undo's, type: ``{normal} + +# Lesson 3.1: THE PUT COMMAND + +** Type `p`{normal} to put previously deleted text after the cursor. ** + + 1. Move the cursor to the first ✓ line below. + + 2. Type `dd`{normal} to delete the line and store it in a Vim register. + + 3. Move the cursor to the c) line, ABOVE where the deleted line should go. + + 4. Type `p`{normal} to put the line below the cursor. + + 5. Repeat steps 2 through 4 to put all the lines in correct order. + +d) Can you learn too? +b) Violets are blue, +c) Intelligence is learned, +a) Roses are red, + +# Lesson 3.2: THE REPLACE COMMAND + +** Type `rx`{normal} to replace the character at the cursor with x. ** + + 1. Move the cursor to the first line below marked ✗. + + 2. Move the cursor so that it is on top of the first error. + + 3. Type `r`{normal} and then the character which should be there. + + 4. Repeat steps 2 and 3 until the first line is equal to the second one. + +Whan this lime was tuoed in, someone presswd some wrojg keys! +When this line was typed in, someone pressed some wrong keys! + + 5. Now move on to Lesson 3.3. + +NOTE: Remember that you should be learning by doing, not memorization. + +# Lesson 3.3: THE CHANGE OPERATOR + +** To change until the end of a word, type `ce`{normal}. ** + + 1. Move the cursor to the first line below marked ✗. + + 2. Place the cursor on the "u" in "lubw". + + 3. Type `ce`{normal} and the correct word (in this case, type "ine" ). + + 4. Press ``{normal} and move to the next character that needs to be + changed. + + 5. Repeat steps 3 and 4 until the first sentence is the same as the second. + +This lubw has a few wptfd that mrrf changing usf the change operator. +This line has a few words that need changing using the change operator. + +Notice that [c](c)e deletes the word and places you in Insert mode. + +# Lesson 3.4: MORE CHANGES USING `c`{normal} + +** The change operator is used with the same motions as delete. ** + + 1. The change operator works in the same way as delete. The format is: + + c [number] motion + + 2. The motions are the same, such as `w`{normal} (word) and `$`{normal} (end of line). + + 3. Move to the first line below marked ✗. + + 4. Move the cursor to the first error. + + 5. Type `c$`{normal} and type the rest of the line like the second and press ``{normal}. + +The end of this line needs some help to make it like the second. +The end of this line needs to be corrected using the `c$`{normal} command. + +NOTE: You can use the Backspace key to correct mistakes while typing. + +# Lesson 3 SUMMARY + + 1. To put back text that has just been deleted, type [p](p). This puts the + deleted text AFTER the cursor (if a line was deleted it will go on the + line below the cursor). + + 2. To replace the character under the cursor, type [r](r) and then the + character you want to have there. + + 3. The [change operator](c) allows you to change from the cursor to where + the motion takes you. Type `ce`{normal} to change from the cursor to the + end of the word, `c$`{normal} to change to the end of a line. + + 4. The format for change is: + + c [number] motion + +Now go on to the next lesson. + +# Lesson 4.1: CURSOR LOCATION AND FILE STATUS + +** Type ``{normal} to show your location in a file and the file status. + Type `G`{normal} to move to a line in the file. ** + +NOTE: Read this entire lesson before executing any of the steps!! + + 1. Hold down the ``{normal} key and press `g`{normal}. We call this + ``{normal}. A message will appear at the bottom of the page with the + filename and the position in the file. Remember the line number for + Step 3. + +NOTE: You may see the cursor position in the lower right corner of the + screen. This happens when the ['ruler']('ruler') option is set. + 2. Press [G](G) to move you to the bottom of the file. + Type [gg](gg) to move you to the start of the file. + + 3. Type the number of the line you were on and then `G`{normal}. This will + return you to the line you were on when you first pressed ``{normal}. + + 4. If you feel confident to do this, execute steps 1 through 3. + +# Lesson 4.2: THE SEARCH COMMAND + +** Type `/`{normal} followed by a phrase to search for the phrase. ** + + 1. In Normal mode type the `/`{normal} character. Notice that it and the + cursor appear at the bottom of the screen as with the `:`{normal} command. + + 2. Now type 'errroor' ``{normal}. This is the word you want to search + for. + + 3. To search for the same phrase again, simply type [n](n). + To search for the same phrase in the opposite direction, type [N](N). + + 4. To search for a phrase in the backward direction, use [?](?) instead + of `/`{normal}. + + 5. To go back to where you came from press ``{normal} (keep ``{normal} pressed down while pressing the letter `o`{normal}). Repeat to go back + further. ``{normal} goes forward. + +"errroor" is not the way to spell error; errroor is an error. + +NOTE: When the search reaches the end of the file it will continue at the + start, unless the ['wrapscan']('wrapscan') option has been reset. + +# Lesson 4.3: MATCHING PARENTHESES SEARCH + +** Type `%`{normal} to find a matching ),], or }. ** + + 1. Place the cursor on any (, [, or { in the line below marked ✓. + + 2. Now type the [%](%) character. + + 3. The cursor will move to the matching parenthesis or bracket. + + 4. Type `%`{normal} to move the cursor to the other matching bracket. + + 5. Move the cursor to another (,),[,],{ or } and see what `%`{normal} does. + +This ( is a test line with ('s, ['s ] and {'s } in it. )) + +NOTE: This is very useful in debugging a program with unmatched parentheses! + +# Lesson 4.4: THE SUBSTITUTE COMMAND + +** Type `:s/old/new/g` to substitute "new" for "old". ** + + 1. Move the cursor to the line below marked ✗. + + 2. Type +~~~ cmd + :s/thee/the/ +~~~ + + NOTE that the [:s](:s) command only changed the first occurrence of "thee" in the line. + + 3. Now type +~~~ cmd + :s/thee/the/g +~~~ + + Adding the g [flag](:s_flags) means to substitute globally in the line, + change all occurrences of "thee" in the line. + +Usually thee best time to see thee flowers is in thee spring. + + 4. To change every occurrence of a character string between two lines, type +~~~ cmd + :#,#s/old/new/g +~~~ + where #,# are the line numbers of the range of lines where the + substitution is to be done. + + Type +~~~ cmd + :%s/old/new/g +~~~ + to change every occurrence in the whole file. + + Type +~~~ cmd + :%s/old/new/gc +~~~ + to find every occurrence in the whole file, with a prompt whether to + substitute or not. + +# Lesson 4 SUMMARY + + 1. ``{normal} displays your location and the file status. + `G`{normal} moves to the end of the file. + number `G`{normal} moves to that line number. + `gg`{normal} moves to the first line. + + 2. Typing `/`{normal} followed by a phrase searches FORWARD for the phrase. + Typing `?`{normal} followed by a phrase searches BACKWARD for the phrase. + After a search type `n`{normal} to find the next occurrence in the same + direction or `N`{normal} to search in the opposite direction. + ``{normal} takes you back to older positions, ``{normal} to + newer positions. + + 3. Typing `%`{normal} while the cursor is on a (,),[,],{, or } goes to its + match. + + 4. To substitute new for the first old in a line type +~~~ cmd + :s/old/new +~~~ + To substitute new for all 'old's on a line type +~~~ cmd + :s/old/new/g +~~~ + To substitute phrases between two line #'s type +~~~ cmd + :#,#s/old/new/g +~~~ + To substitute all occurrences in the file type +~~~ cmd + :%s/old/new/g +~~~ + To ask for confirmation each time add 'c' +~~~ cmd + :%s/old/new/gc +~~~ + +# Lesson 5.1: HOW TO EXECUTE AN EXTERNAL COMMAND + +** Type `:!`{vim} followed by an external command to execute that command. ** + + 1. Type the familiar command `:`{normal} to set the cursor at the bottom of + the screen. This allows you to enter a command-line command. + + 2. Now type the [!](!cmd) (exclamation point) character. This allows you to + execute any external shell command. + + 3. As an example type "ls" following the "!" and then hit ``{normal}. + This will show you a listing of your directory, just as if you were + at the shell prompt. + +NOTE: It is possible to execute any external command this way, also with + arguments. + +NOTE: All `:`{vim} commands must be finished by hitting ``{normal}. + From here on we will not always mention it. + +# Lesson 5.2: MORE ON WRITING FILES + +** To save the changes made to the text, type `:w`{vim} FILENAME. ** + + 1. Type `:!ls`{vim} to get a listing of your directory. + You already know you must hit ``{normal} after this. + + 2. Choose a filename that does not exist yet, such as TEST. + + 3. Now type: +~~~ cmd + :w TEST +~~~ + (where TEST is the filename you chose.) + + 4. This saves the whole file (the Vim Tutor) under the name TEST. + To verify this, type `:!ls`{vim} again to see your directory. + +NOTE: If you were to exit Vim and start it again with `vim TEST`, the file + would be an exact copy of the tutor when you saved it. + + 5. Now remove the file by typing: +~~~ cmd + :!rm TEST +~~~ + +# Lesson 5.3: SELECTING TEXT TO WRITE + +** To save part of the file, type `v`{normal} motion `:w FILENAME`{vim}. ** + + 1. Move the cursor to this line. + + 2. Press [v](v) and move the cursor to the fifth item below. Notice that the + text is highlighted. + + 3. Press the `:`{normal} character. At the bottom of the screen + + :'<,'> + + will appear. + + 4. Type + + `:w TEST`{vim} + + where TEST is a filename that does not exist yet. Verify that you see + + `:'<,'>w TEST`{vim} + + before you press ``{normal}. + + 5. Vim will write the selected lines to the file TEST. Use `:!ls`{vim} to see it. Do not remove it yet! We will use it in the next lesson. + +NOTE: Pressing [v](v) starts [Visual selection](visual-mode). You can move + the cursor around to make the selection bigger or smaller. Then you can + use an operator to do something with the text. For example, `d`{normal} + deletes the text. + +# Lesson 5.4: RETRIEVING AND MERGING FILES + +** To insert the contents of a file, type `:r FILENAME`{vim}. ** + + 1. Place the cursor just above this line. + +NOTE: After executing Step 2 you will see text from Lesson 5.3. Then move + DOWN to see this lesson again. + + 2. Now retrieve your TEST file using the command + + `:r TEST`{vim} + + where TEST is the name of the file you used. + The file you retrieve is placed below the cursor line. + + 3. To verify that a file was retrieved, cursor back and notice that there + are now two copies of Lesson 5.3, the original and the file version. + +NOTE: You can also read the output of an external command. For example, + + `:r !ls`{vim} + + reads the output of the `ls` command and puts it below the cursor. + +# Lesson 5 SUMMARY + + 1. [:!command](:!cmd) executes an external command. + + Some useful examples are: + `:!ls`{vim} - shows a directory listing + `:!rm FILENAME`{vim} - removes file FILENAME + + 2. [:w](:w) FILENAME writes the current Vim file to disk with + name FILENAME. + + 3. [v](v) motion :w FILENAME saves the Visually selected lines in file + FILENAME. + + 4. [:r](:r) FILENAME retrieves disk file FILENAME and puts it + below the cursor position. + + 5. [:r !dir](:r!) reads the output of the dir command and + puts it below the cursor position. + +# Lesson 6.1: THE OPEN COMMAND + +** Type `o`{normal} to open a line below the cursor and place you in Insert mode. ** + + 1. Move the cursor to the line below marked ✓. + + 2. Type the lowercase letter `o`{normal} to [open](o) up a line BELOW the + cursor and place you in Insert mode. + + 3. Now type some text and press ``{normal} to exit Insert mode. + +After typing `o`{normal} the cursor is placed on the open line in Insert mode. + + 4. To open up a line ABOVE the cursor, simply type a [capital O](O), rather + than a lowercase `o`{normal}. Try this on the line below. + +Open up a line above this by typing O while the cursor is on this line. + +# Lesson 6.2: THE APPEND COMMAND + +** Type `a`{normal} to insert text AFTER the cursor. ** + + 1. Move the cursor to the start of the line below marked ✗. + + 2. Press `e`{normal} until the cursor is on the end of "li". + + 3. Type the lowercase letter `a`{normal} to [append](a) text AFTER the + cursor. + + 4. Complete the word like the line below it. Press ``{normal} to exit + Insert mode. + + 5. Use `e`{normal} to move to the next incomplete word and repeat steps 3 + and 4. + +This li will allow you to pract appendi text to a line. +This line will allow you to practice appending text to a line. + +NOTE: [a](a), [i](i) and [A](A) all go to the same Insert mode, the only + difference is where the characters are inserted. + +# Lesson 6.3: ANOTHER WAY TO REPLACE + +** Type a capital `R`{normal} to replace more than one character. ** + + 1. Move the cursor to the first line below marked ✗. Move the cursor to + the beginning of the first "xxx". + + 2. Now press `R`{normal} ([capital R](R)) and type the number below it in the + second line, so that it replaces the "xxx". + + 3. Press ``{normal} to leave [Replace mode](mode-replace). Notice that + the rest of the line remains unmodified. + + 4. Repeat the steps to replace the remaining "xxx". + +Adding 123 to xxx gives you xxx. +Adding 123 to 456 gives you 579. + +NOTE: Replace mode is like Insert mode, but every typed character deletes an + existing character. + +# Lesson 6.4: COPY AND PASTE TEXT + +** Use the `y`{normal} operator to copy text and `p`{normal} to paste it. ** + + 1. Go to the line marked with ✓ below and place the cursor after "a)". + + 2. Start Visual mode with `v`{normal} and move the cursor to just before + "first". + + 3. Type `y`{normal} to [yank](yank) (copy) the highlighted text. + + 4. Move the cursor to the end of the next line: `j$`{normal} + + 5. Type `p`{normal} to [put](put) (paste) the text. + + 6. Press `a`{normal} and then type "second". Press ``{normal} to leave + Insert mode. + + 7. Use Visual mode to select "item.", yank it with `y`{normal}, move to the + end of the next line with `j$`{normal} and put the text there with `p`{normal} + +a) This is the first item. +b) + +NOTE: you can use `y`{normal} as an operator: `yw`{normal} yanks one word. + +# Lesson 6.5: SET OPTION + +** Set an option so a search or substitute ignores case. ** + + 1. Search for 'ignore' by entering: `/ignore` + Repeat several times by pressing `n`{normal}. + + 2. Set the 'ic' (Ignore case) option by entering: +~~~ cmd + :set ic +~~~ + 3. Now search for 'ignore' again by pressing `n`{normal}. + Notice that Ignore and IGNORE are now also found. + + 4. Set the 'hlsearch' and 'incsearch' options: +~~~ cmd + :set hls is +~~~ + 5. Now type the search command again and see what happens: /ignore + + 6. To disable ignoring case enter: +~~~ cmd + :set noic +~~~ + 7. To toggle the value of a setting, prepend it with "inv": +~~~ cmd + :set invic +~~~ +NOTE: To remove the highlighting of matches enter: +~~~ cmd + :nohlsearch +~~~ +NOTE: If you want to ignore case for just one search command, use [\c](/\c) + in the phrase: /ignore\c + +# Lesson 6 SUMMARY + + 1. Type `o`{normal} to open a line BELOW the cursor and start Insert mode. + Type `O`{normal} to open a line ABOVE the cursor. + + 2. Type `a`{normal} to insert text AFTER the cursor. + Type `A`{normal} to insert text after the end of the line. + + 3. The `e`{normal} command moves to the end of a word. + + 4. The `y`{normal} operator copies text, `p`{normal} pastes it. + + 5. Typing a capital `R`{normal} enters Replace mode until ``{normal} is + pressed. + + 6. Typing "[:set](:set) xxx" sets the option "xxx". Some options are: + + 'ic' 'ignorecase' ignore upper/lower case when searching + 'is' 'incsearch' show partial matches for a search phrase + 'hls' 'hlsearch' highlight all matching phrases + + You can either use the long or the short option name. + + 7. Prepend "no" to switch an option off: +~~~ cmd + :set noic +~~~ + 8. Prepend "inv" to toggle an option: +~~~ cmd + :set invic +~~~ + +# Lesson 7.1: GETTING HELP + +** Use the on-line help system. ** + +Vim has a comprehensive on-line help system. To get started, try one of +these three: + - press the ``{normal} key (if you have one) + - press the ``{normal} key (if you have one) + - type + `:help`{vim} + +Read the text in the help window to find out how the help works. +Type ``{normal} to jump from one window to another. +Type `:q`{vim} to close the help window. + +You can find help on just about any subject, by giving an argument to the +":help" command. Try these (don't forget pressing ): +~~~ cmd + :help w + :help c_CTRL-D + :help insert-index + :help user-manual +~~~ +# Lesson 7.2: CREATE A STARTUP SCRIPT + +** Enable Vim features. ** + +Vim has many more features than Vi, but most of them are disabled by +default. To start using more features you have to create a "vimrc" file. + + 1. Start editing the "vimrc" file. + `:call mkdir(stdpath('config'),'p')`{vim} + `:exe 'edit' stdpath('config').'/init.vim'`{vim} + + 2. Write the file with: + `:w`{vim} + + You can add all your preferred settings to this "vimrc" file. + For more information type `:help vimrc-intro`{vim}. + +# Lesson 7.3: COMPLETION + +** Command line completion with ``{normal} and ``{normal}. ** + + 1. Look what files exist in the directory: `:!ls`{vim} + + 2. Type the start of a command: `:e`{vim} + + 3. Press ``{normal} and Vim will show a list of commands that start + with "e". + + 4. Press ``{normal} and Vim will complete the command name to ":edit". + + 5. Now add a space and the start of an existing file name: `:edit FIL`{vim} + + 6. Press ``{normal}. Vim will complete the name (if it is unique). + +NOTE: Completion works for many commands. It is especially useful for + `:help`{vim}. + +# Lesson 7 SUMMARY + + 1. Type `:help`{vim} + or press ``{normal} or ``{normal} to open a help window. + + 2. Type `:help TOPIC`{vim} to find help on TOPIC. + + 3. Type ``{normal} to jump to another window + + 4. Type `:q`{vim} to close the help window + + 5. Create a vimrc startup script to keep your preferred settings. + + 6. While in command mode, press ``{normal} to see possible completions. + Press ``{normal} to use one completion. + +# CONCLUSION + +This was intended to give a brief overview of the Vim editor, just enough to +allow you to use the editor fairly easily. It is far from complete as Vim has +many many more commands. Consult the help often. + +There are many resources online to learn more about vim. Here's a bunch of +them: + +- *Learn Vim Progressively*: http://yannesposito.com/Scratch/en/blog/Learn-Vim-Progressively/ +- *Learning Vim in 2014*: http://benmccormick.org/learning-vim-in-2014/ +- *Vimcasts*: http://vimcasts.org/ +- *Vim Video-Tutorials by Derek Wyatt*: http://derekwyatt.org/vim/tutorials/ +- *Learn Vimscript the Hard Way*: http://learnvimscriptthehardway.stevelosh.com/ +- *7 Habits of Effective Text Editing*: http://www.moolenaar.net/habits.html +- *vim-galore*: https://github.com/mhinz/vim-galore + +If you prefer a book, *Practical Vim* and the sequel *Modern Vim* by Drew Neil +are recommended often. + +This tutorial was written by Michael C. Pierce and Robert K. Ware, Colorado +School of Mines using ideas supplied by Charles Smith, Colorado State +University. E-mail: bware@mines.colorado.edu. + +Modified for Vim by Bram Moolenaar. +Modified for vim-tutor-mode by Felipe Morales. diff --git a/runtime/tutor/en/vim-01-beginner.tutor.json b/runtime/tutor/en/vim-01-beginner.tutor.json new file mode 100644 --- /dev/null +++ b/runtime/tutor/en/vim-01-beginner.tutor.json @@ -0,0 +1,45 @@ +{ + "expect": { + "24": -1, + "103": "The cow jumped over the moon.", + "124": "There is some text missing from this line.", + "125": "There is some text missing from this line.", + "144": "There is some text missing from this line.", + "145": "There is some text missing from this line.", + "146": "There is also some text missing here.", + "147": "There is also some text missing here.", + "220": "There are some words that don't belong in this sentence.", + "236": "Somebody typed the end of this line twice.", + "276": -1, + "295": "This line of words is cleaned up.", + "309": -1, + "310": -1, + "311": -1, + "312": -1, + "313": -1, + "314": -1, + "315": -1, + "332": "Fix the errors on this line and replace them with undo.", + "372": -1, + "373": -1, + "374": -1, + "375": -1, + "389": "When this line was typed in, someone pressed some wrong keys!", + "390": "When this line was typed in, someone pressed some wrong keys!", + "411": "This line has a few words that need changing using the change operator.", + "412": "This line has a few words that need changing using the change operator.", + "432": "The end of this line needs to be corrected using the `c$` command.", + "433": "The end of this line needs to be corrected using the `c$` command.", + "497": -1, + "516": -1, + "541": "Usually the best time to see the flowers is in the spring.", + "735": -1, + "740": -1, + "759": "This line will allow you to practice appending text to a line.", + "760": "This line will allow you to practice appending text to a line.", + "780": "Adding 123 to 456 gives you 579.", + "781": "Adding 123 to 456 gives you 579.", + "807": "a) This is the first item.", + "808": "b) This is the second item." + } +} diff --git a/runtime/tutor/tutor.tutor b/runtime/tutor/tutor.tutor new file mode 100644 --- /dev/null +++ b/runtime/tutor/tutor.tutor @@ -0,0 +1,247 @@ +# CREATING A VIM TUTORIAL WITH VIM-TUTOR-MODE + +This tutorial will guide you through the steps required to create a tutorial +file for vim-tutor-mode. It is also meant as a demo of vim-tutor-mode +capabilities. + +Table of contents: + +- [Setting up](*setting-up*) +- [vim-tutor-mode's markup](*markup*) + - [emphasis](*emphasis*) + - [headers](*headers*) + - [links](*links*) + - [codeblocks](*codeblocks*) +- [Interactive elements](*interactive*) + - [expect](*expect*) + +## SETTING UP *setting-up* + +First, you'll need to enable "debug" mode +~~~ cmd + :let g:tutor_debug = 1 +~~~ +This will allow saving changes to the tutor files and will disable conceals, so +you can more easily check your changes. + +After this, create a new .tutor file (we will be practicing on this very file, so you +don't need to do this now): +~~~ cmd + :e new-tutorial.tutor +~~~ + +## VIM-TUTOR-MODE's MARKDOWN *markup* + +vim-tutor-mode uses a subset of markdown's syntax to format the tutorials. The +subset supported should be enough for most tutorials and the maintainers will +try to keep it as small as possible (if regular markdown allows for several +ways to do the same thing, tutor markdown will only provide the one the +maintainers think is easier to handle). + +### Emphasis *emphasis* + +For emphasized text (italics), as in normal markdown, you use \*. E.g.: + + \*text\* + +is displayed like + + *text* + +Note: The underscores variant is not supported. + +For strong emphasis (bold), you use \*\*. E.g.: + + \*\*this\*\* + +is displayed like + + **this** + +1. Format the line below so it becomes a lesson description: + +This is text with important information +This is text with **important information** + +Note: Some words (e.g., NOTE, IMPORTANT, tip, ATTENTION, etc.) will also be +highlighted. You don't need to mark them specially. + +2. Turn the line below into a TODO item: + +Document '&variable' +TODO: Document '&variable' + +### Headers *headers* + +3. Practice fixing the lines below: + +This is a level 1 header +# This is a level 1 header +This is a level 3 header +### This is a level 3 header +This is a header with a label +# This is a header with a label {*label*} + +4. Now, create a 4th level section here, and add a label like in the previous +exercise: + + + + ATTENTION We will use this label later, so remember it. + +### Links *links* + +It is good practice to include links in your tutorials to reference materials, +like vim's own help or external documents. You can also link to other parts of +the document. + +Links have the syntax + + \[label\]\(target\) + +#### Help links + +If the target of a link matches a help topic, opening it will open it. + +5. Fix the following line: + +A link to help for the 'breakindent' option +A link to help for the ['breakindent']('breakindent') option + +#### Anchor links + +A link can also lead to a place in the file itself. Anchors are written + + \*anchor\* + +and are hidden by default. Links to them look like + + \[label\]\(\*anchor\*\) + +6. Add the appropriate link: + +A link to the Links section +A link to the [Links](*links*) section + +7. Now, create a link to the section you created on exercise 4 + above. + + + +# Tutorial links + +You can also have links to other tutorials. For this, you'll write the anchor in the format + + @tutor:TUTORIAL + +7. Create a link to this tutorial: + +A link to the vim-tutor-mode tutorial +A link to [the vim-tutor-mode tutorial](@tutor:tutor) + +### Codeblocks *codeblocks* + +vim-tutor-mode tutorials can include viml sections + + ~~~ cmd + echom "hello" + ~~~ + +is displayed as +~~~ cmd +echom "hello" +~~~ + +8. Copy the viml section below + + + + + +~~~ viml +echom 'the value of &number is'.string(&number) +~~~ + +You can inline viml code using "\`" and "\`{vim}": + + \`call myFunction()\`{vim} + +is displayed as + + `call myFunction()`{vim} + +[normal](Normal-mode) commands can also be embedded in tutorials. + + ~~~ normal + ftdaW + ~~~ + +is displayed as +~~~ normal +ftdaW +~~~ + +Note: you can also write `norm` or `normal`. + +9. Copy the normal section below + + + + + +~~~ normal +d2w +~~~ + +You can also inline normal commands by using "\`" and "\`{normal}": + + \`gq\`{normal} is very useful. + +is displayed: + + `gq`{normal} is very useful. + +10. Complete the line as shown + +d +`d2w`{normal} + +Commands to run in the system shell can be highlighted by indenting a line +starting with "$". + +~~~ sh + $ vim --version +~~~ + +## INTERACTIVE ELEMENTS *interactive* + +As visible in this very document, vim-tutor-mode includes some interactive +elements to provide feedback to the user about his progress. If the text in +these elements satisfies some set condition, a ✓ sign will appear in the gutter +to the left. Otherwise, a ✗ sign is displayed. + +### expect *expect* + +"expect" lines check that the contents of the line are identical to some preset text +(like in the exercises above). + +These elements are specified in separate JSON files like this + +~~~ json +{ + "expect": { + "1": "This is how this line should look.", + "2": "This is how this line should look.", + "3": -1 + } +} +~~~ + +These files contain an "expect" dictionary, for which the keys are line numbers and +the values are the expected text. A value of -1 means that the condition for the line +will always be satisfied, no matter what (this is useful for letting the user play a bit). + +This is an "expect" line that is always satisfied. Try changing it. + +These files conventionally have the same name as the tutorial document with the `.json` +extension appended (for a full example, see the file that corresponds to this tutorial). diff --git a/runtime/tutor/tutor.tutor.json b/runtime/tutor/tutor.tutor.json new file mode 100644 --- /dev/null +++ b/runtime/tutor/tutor.tutor.json @@ -0,0 +1,35 @@ +{ + "expect": { + "63": "This is text with **important information**", + "64": "This is text with **important information**", + "71": "Document '&variable'", + "72": "Document '&variable'", + "78": "# This is a level 1 header", + "79": "# This is a level 1 header", + "80": "### This is a level 3 header", + "81": "### This is a level 3 header", + "82": "# This is a header with a label {*label*}", + "83": "# This is a header with a label {*label*}", + "108": "A link to help for the ['breakindent']('breakindent') option", + "109": "A link to help for the ['breakindent']('breakindent') option", + "123": "A link to the [Links](*links*) section", + "124": "A link to the [Links](*links*) section", + "139": "A link to [the vim-tutor-mode tutorial](@tutor:tutor)", + "140": "A link to [the vim-tutor-mode tutorial](@tutor:tutor)", + "157": "~~~ viml", + "158": "echom 'the value of &number is'.string(&number)", + "159": "~~~", + "161": "~~~ viml", + "162": "echom 'the value of &number is'.string(&number)", + "163": "~~~", + "188": "~~~ normal", + "189": "d2w", + "190": "~~~", + "192": "~~~ normal", + "193": "d2w", + "194": "~~~", + "206": "`d2w`{normal}", + "207": "`d2w`{normal}", + "244": -1 + } +} diff --git a/src/Makefile b/src/Makefile --- a/src/Makefile +++ b/src/Makefile @@ -2346,7 +2346,7 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DES $(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml \ $(DEST_AUTO)/rust $(DEST_AUTO)/cargo \ $(DEST_IMPORT) $(DEST_IMPORT)/dist \ - $(DEST_PLUG) $(DEST_TUTOR) $(DEST_SPELL) $(DEST_COMP) + $(DEST_PLUG) $(DEST_TUTOR) $(DEST_TUTOR)/en $(DEST_SPELL) $(DEST_COMP) -$(SHELL) ./installman.sh install $(DEST_MAN) "" $(INSTALLMANARGS) # Generate the help tags with ":helptags" to handle all languages. # Move the distributed tags file aside and restore it, to avoid it being @@ -2473,8 +2473,10 @@ installgtutorbin: $(DEST_BIN) installtutor: $(DEST_RT) $(DEST_TUTOR) -$(INSTALL_DATA) $(TUTORSOURCE)/README* $(TUTORSOURCE)/tutor* $(DEST_TUTOR) + -$(INSTALL_DATA) $(TUTORSOURCE)/en/* $(DEST_TUTOR)/en/ -rm -f $(DEST_TUTOR)/*.info chmod $(HELPMOD) $(DEST_TUTOR)/* + chmod $(DIRMOD) $(DEST_TUTOR)/en # Install the spell files, if they exist. This assumes at least the English # spell file is there. @@ -2671,7 +2673,8 @@ install-icons: $(DEST_SYN)/modula2 $(DEST_SYN)/modula2/opt \ $(DEST_IND) $(DEST_FTP) \ $(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) $(DEST_MACRO) \ - $(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \ + $(DEST_PACK) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_TUTOR)/en \ + $(DEST_SPELL) \ $(DEST_AUTO) $(DEST_AUTO)/dist $(DEST_AUTO)/xml \ $(DEST_AUTO)/cargo $(DEST_AUTO)/rust \ $(DEST_IMPORT) $(DEST_IMPORT)/dist $(DEST_PLUG): @@ -2854,6 +2857,7 @@ uninstall_runtime: -rm -f $(DEST_IND)/*.vim $(DEST_IND)/README.txt -rm -rf $(DEST_MACRO) -rm -rf $(DEST_PACK) + -rm -rf $(DEST_TUTOR)/en -rm -rf $(DEST_TUTOR) -rm -rf $(DEST_SPELL) -rm -rf $(DEST_TOOLS) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 836, +/**/ 835, /**/ 834,