diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2017-07-16 18:19:41 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-16 18:19:41 +0200 |
commit | a76da96e86cc338dd5d8ff2f6014cff68e055ce9 (patch) | |
tree | 58c51de6c1210276e333728cc9d831ceb1c5b003 | |
parent | 4dee942e732d41ad62b732c0a39719d9405bc928 (diff) | |
parent | 3241bce6116cdd17f93651f12b5908e57e1d3136 (diff) | |
download | rneovim-a76da96e86cc338dd5d8ff2f6014cff68e055ce9.tar.gz rneovim-a76da96e86cc338dd5d8ff2f6014cff68e055ce9.tar.bz2 rneovim-a76da96e86cc338dd5d8ff2f6014cff68e055ce9.zip |
Merge #7028 from fmoralesc/vimtutor-disentangle2
Closes #4533
Closes #6389
Closes #4913
Closes #7005
-rw-r--r-- | runtime/autoload/tutor.vim | 197 | ||||
-rw-r--r-- | runtime/ftplugin/tutor.vim | 19 | ||||
-rw-r--r-- | runtime/syntax/tutor.vim | 22 | ||||
-rw-r--r-- | runtime/tutor/en/vim-01-beginner.tutor | 92 | ||||
-rw-r--r-- | runtime/tutor/en/vim-01-beginner.tutor.json | 45 | ||||
-rw-r--r-- | runtime/tutor/tutor.tutor | 118 | ||||
-rw-r--r-- | runtime/tutor/tutor.tutor.json | 35 |
7 files changed, 236 insertions, 292 deletions
diff --git a/runtime/autoload/tutor.vim b/runtime/autoload/tutor.vim index 43d8a87886..56e2283465 100644 --- a/runtime/autoload/tutor.vim +++ b/runtime/autoload/tutor.vim @@ -15,30 +15,17 @@ function! tutor#SetupVim() endif endfunction -" Mappings: {{{1 - -function! s:CheckMaps() - nmap +" Loads metadata file, if available +function! tutor#LoadMetadata() + let b:tutor_metadata = json_decode(join(readfile(expand('%').'.json'), "\n")) endfunction -function! s:MapKeyWithRedirect(key, cmd) - if maparg(a:key) !=# '' - redir => l:keys - silent call s:CheckMaps() - redir END - let l:key_list = split(l:keys, '\n') - - let l:raw_map = filter(copy(l:key_list), "v:val =~# '\\* ".a:key."'") - if len(l:raw_map) == 0 - exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd - return - endif - let l:map_data = split(l:raw_map[0], '\s*') +" Mappings: {{{1 - exe "nnoremap <buffer> <expr> ".l:map_data[0]." ".a:cmd - else - exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd - endif +function! tutor#SetNormalMappings() + nnoremap <silent> <buffer> <CR> :call tutor#FollowLink(0)<cr> + nnoremap <silent> <buffer> <2-LeftMouse> :call tutor#MouseDoubleClick()<cr> + nnoremap <buffer> >> :call tutor#InjectCommand()<cr> endfunction function! tutor#MouseDoubleClick() @@ -46,7 +33,7 @@ function! tutor#MouseDoubleClick() normal! zo else if match(getline('.'), '^#\{1,} ') > -1 - normal! zc + silent normal! zc else call tutor#FollowLink(0) endif @@ -59,114 +46,6 @@ function! tutor#InjectCommand() redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd endfunction -function! tutor#SetNormalMappings() - call s:MapKeyWithRedirect('l', 'tutor#ForwardSkipConceal(v:count1)') - call s:MapKeyWithRedirect('h', 'tutor#BackwardSkipConceal(v:count1)') - call s:MapKeyWithRedirect('<right>', 'tutor#ForwardSkipConceal(v:count1)') - call s:MapKeyWithRedirect('<left>', 'tutor#BackwardSkipConceal(v:count1)') - - nnoremap <silent> <buffer> <CR> :call tutor#FollowLink(0)<cr> - nnoremap <silent> <buffer> <2-LeftMouse> :call tutor#MouseDoubleClick()<cr> - nnoremap <buffer> >> :call tutor#InjectCommand()<cr> -endfunction - -function! tutor#SetSampleTextMappings() - noremap <silent> <buffer> A :if match(getline('.'), '^--->') > -1 \| call search('\s{\@=', 'Wc') \| startinsert \| else \| startinsert! \| endif<cr> - noremap <silent> <buffer> $ :if match(getline('.'), '^--->') > -1 \| call search('.\s{\@=', 'Wc') \| else \| call search('$', 'Wc') \| endif<cr> - onoremap <silent> <buffer> $ :if match(getline('.'), '^--->') > -1 \| call search('.\s{\@=', 'Wc') \| else \| call search('$', 'Wc') \| endif<cr> - noremap <silent> <buffer> ^ :if match(getline('.'), '^--->') > -1 \| call search('\(--->\s\)\@<=.', 'bcW') \| else \| call search('^', 'bcW') \|endif<cr> - onoremap <silent> <buffer> ^ :if match(getline('.'), '^--->') > -1 \| call search('\(--->\s\)\@<=.', 'bcW') \| else \| call search('^', 'bcW') \|endif<cr> - nmap <silent> <buffer> 0 ^<esc> - nmap <silent> <buffer> <Home> ^<esc> - nmap <silent> <buffer> <End> $ - imap <silent> <buffer> <Home> <esc>^<esc>:startinsert<cr> - imap <silent> <buffer> <End> <esc>$:startinsert<cr> - noremap <silent> <buffer> I :exe "normal! 0" \| startinsert<cr> -endfunction - -" Navigation: {{{1 - -" taken from http://stackoverflow.com/a/24224578 - -function! tutor#ForwardSkipConceal(count) - let cnt=a:count - let mvcnt=0 - let c=col('.') - let l=line('.') - let lc=col('$') - let line=getline('.') - while cnt - if c>=lc - let mvcnt+=cnt - break - endif - if stridx(&concealcursor, 'n')==-1 - let isconcealed=0 - else - let [isconcealed, cchar, group] = synconcealed(l, c) - endif - if isconcealed - let cnt-=strchars(cchar) - let oldc=c - let c+=1 - while c < lc - let [isconcealed2, cchar2, group2] = synconcealed(l, c) - if !isconcealed2 || cchar2 != cchar - break - endif - let c+= 1 - endwhile - let mvcnt+=strchars(line[oldc-1:c-2]) - else - let cnt-=1 - let mvcnt+=1 - let c+=len(matchstr(line[c-1:], '.')) - endif - endwhile - return mvcnt.'l' -endfunction - -function! tutor#BackwardSkipConceal(count) - let cnt=a:count - let mvcnt=0 - let c=col('.') - let l=line('.') - let lc=0 - let line=getline('.') - while cnt - if c<=1 - let mvcnt+=cnt - break - endif - if stridx(&concealcursor, 'n')==-1 || c == 0 - let isconcealed=0 - else - let [isconcealed, cchar, group]=synconcealed(l, c-1) - endif - if isconcealed - let cnt-=strchars(cchar) - let oldc=c - let c-=1 - while c>1 - let [isconcealed2, cchar2, group2] = synconcealed(l, c-1) - if !isconcealed2 || cchar2 != cchar - break - endif - let c-=1 - endwhile - let c = max([c, 1]) - let mvcnt+=strchars(line[c-1:oldc-2]) - else - let cnt-=1 - let mvcnt+=1 - let c-=len(matchstr(line[:c-2], '.$')) - endif - endwhile - return mvcnt.'h' -endfunction - -" Hypertext: {{{1 - function! tutor#FollowLink(force) let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '') if l:stack_s =~# 'tutorLink' @@ -209,42 +88,40 @@ function! tutor#InfoText() return join(l:info_parts, " ") endfunction -" Marks {{{1 -function! tutor#PlaceXMarks() - call cursor(1, 1) - let b:tutor_sign_id = 1 - while search('^--->', 'W') > 0 - call tutor#CheckText(getline('.')) - let b:tutor_sign_id+=1 - endwhile - call cursor(1, 1) + +" 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#CheckText(text) - if match(a:text, '{expect:ANYTHING}\s*$') == -1 - if match(getline('.'), '^--->\s*$') > -1 - exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%') - else - if match(getline('.'), '|expect:.\+|') == -1 - let l:cur_text = matchstr(a:text, '---> \zs.\{-}\ze {expect:') - let l:expected_text = matchstr(a:text, '{expect:\zs.*\ze}\s*$') - else - let l:cur_text = matchstr(a:text, '---> \zs.\{-}\ze |expect:') - let l:expected_text = matchstr(a:text, '|expect:\zs.*\ze|\s*$') - endif - if l:cur_text ==# l:expected_text - exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorok buffer=".bufnr('%') - else - exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%') - endif +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#OnTextChanged() - let l:text = getline('.') - if match(l:text, '^--->') > -1 - call tutor#CheckText(l:text) +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 diff --git a/runtime/ftplugin/tutor.vim b/runtime/ftplugin/tutor.vim index 1579753170..ec55472b78 100644 --- a/runtime/ftplugin/tutor.vim +++ b/runtime/ftplugin/tutor.vim @@ -19,27 +19,30 @@ setlocal noundofile setlocal keywordprg=:help setlocal iskeyword=@,-,_ -setlocal foldmethod=expr +" The user will have to enable the folds himself, but we provide the foldexpr +" function. +setlocal foldmethod=manual setlocal foldexpr=tutor#TutorFolds() -setlocal foldcolumn=1 setlocal foldlevel=4 -setlocal nowrap setlocal statusline=%{toupper(expand('%:t:r'))}\ tutorial%= setlocal statusline+=%{tutor#InfoText()} +" Load metadata if it exists: {{{1 +if filereadable(expand('%').'.json') + call tutor#LoadMetadata() +endif + " Mappings: {{{1 call tutor#SetNormalMappings() -call tutor#SetSampleTextMappings() " 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#PlaceXMarks() - autocmd! TextChanged <buffer> call tutor#OnTextChanged() - autocmd! TextChangedI <buffer> call tutor#OnTextChanged() +if !exists('g:tutor_debug') || g:tutor_debug == 0 + call tutor#ApplyMarks() + autocmd! TextChanged,TextChangedI <buffer> call tutor#ApplyMarksOnChanged() endif diff --git a/runtime/syntax/tutor.vim b/runtime/syntax/tutor.vim index bce9189660..fbf159582a 100644 --- a/runtime/syntax/tutor.vim +++ b/runtime/syntax/tutor.vim @@ -31,26 +31,20 @@ syn keyword tutorMarks TODO NOTE IMPORTANT TIP ATTENTION EXERCISE syn keyword tutorMarks todo note tip attention exercise syn keyword tutorMarks Todo Note Tip Excersise -syn match tutorTextMark /\\\@<!--->/ conceal cchar=→ -syn region tutorSampleText start=/^\(--->\)\@=/ end=/$/ keepend contains=@SPELL -syn match tutorSampleTextMark /^--->/ contained containedin=tutorSampleText conceal cchar=→ -syn match tutorSampleTextExpect /\}\@<! {expect:.\+}\s*$/ contained containedin=tutorSampleText conceal -syn match tutorSampleTextExpect /|\@<! |expect:.\+|\s*$/ contained containedin=tutorSampleText conceal - syn region tutorCodeblock matchgroup=Delimiter start=/^\~\{3}.*$/ end=/^\~\{3}/ -syn region tutorShell matchgroup=Delimiter start=/^\~\{3} sh\s*$/ end=/^\~\{3}/ keepend contains=@TUTORSHELL concealends +syn region tutorShell matchgroup=Delimiter start=/^\~\{3} sh\s*$/ end=/^\~\{3}/ keepend contains=@TUTORSHELL syn match tutorShellPrompt /\(^\s*\)\@<=[$#]/ contained containedin=tutorShell -syn region tutorInlineCode matchgroup=Delimiter start=/\\\@<!`/ end=/\\\@<!\(`{\@!\|`\s\)/ concealends +syn region tutorInlineCode matchgroup=Delimiter start=/\\\@<!`/ end=/\\\@<!\(`{\@!\|`\s\)/ -syn region tutorCommand matchgroup=Delimiter start=/^\~\{3} cmd\( :\)\?\s*$/ end=/^\~\{3}/ keepend contains=@VIM concealends -syn region tutorInlineCommand matchgroup=Delimiter start=/\\\@<!`\(.*{vim}\)\@=/ end=/\\\@<!`\({vim}\)\@=/ nextgroup=tutorInlineType contains=@VIM concealends +syn region tutorCommand matchgroup=Delimiter start=/^\~\{3} cmd\( :\)\?\s*$/ end=/^\~\{3}/ keepend contains=@VIM +syn region tutorInlineCommand matchgroup=Delimiter start=/\\\@<!`\(.*{vim}\)\@=/ end=/\\\@<!`\({vim}\)\@=/ nextgroup=tutorInlineType contains=@VIM -syn region tutorNormal matchgroup=Delimiter start=/^\~\{3} norm\(al\?\)\?\s*$/ end=/^\~\{3}/ contains=@VIMNORMAL concealends -syn region tutorInlineNormal matchgroup=Delimiter start=/\\\@<!`\(\S*{normal}\)\@=/ end=/\\\@<!`\({normal}\)\@=/ nextgroup=tutorInlineType contains=@VIMNORMAL concealends +syn region tutorNormal matchgroup=Delimiter start=/^\~\{3} norm\(al\?\)\?\s*$/ end=/^\~\{3}/ contains=@VIMNORMAL +syn region tutorInlineNormal matchgroup=Delimiter start=/\\\@<!`\(\S*{normal}\)\@=/ end=/\\\@<!`\({normal}\)\@=/ nextgroup=tutorInlineType contains=@VIMNORMAL -syn match tutorInlineType /{\(normal\|vim\)}/ contained conceal +syn match tutorInlineType /{\(normal\|vim\)}/ contained syn match tutorInlineOK /✓/ syn match tutorInlineX /✗/ @@ -72,7 +66,7 @@ hi! tutorMarks cterm=bold gui=bold hi! tutorEmphasis gui=italic cterm=italic hi! tutorBold gui=bold cterm=bold -hi! link tutorSampleText Special +hi! link tutorExpect Special hi! tutorOK ctermfg=green guifg=#00ff88 cterm=bold gui=bold hi! tutorX ctermfg=red guifg=#ff2000 cterm=bold gui=bold hi! link tutorInlineOK tutorOK diff --git a/runtime/tutor/en/vim-01-beginner.tutor b/runtime/tutor/en/vim-01-beginner.tutor index 47d4ed06a1..fee7de21d2 100644 --- a/runtime/tutor/en/vim-01-beginner.tutor +++ b/runtime/tutor/en/vim-01-beginner.tutor @@ -18,10 +18,10 @@ be saved. Don't worry about messing things up; just remember that pressing [<Esc>](<Esc>) and then [u](u) will undo the latest change. This tutorial is interactive, and there are a few things you should know. -Pressing [<Enter>](<Enter>) over text highlighted [like this](holy-grail) will take you to some relevant -help (hopefully), and pressing K over any word will try to do so too. Sometimes -you will be required to modify text like ----> this here {expect:this here} +Pressing [<Enter>](<Enter>) over text highlighted [like this](holy-grail) will take you to some +relevant help (hopefully), and pressing K over any word will try to do so too. +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): @@ -99,7 +99,7 @@ NOTE: [:q!](:q) <Enter> discards any changes you made. In a few lessons you 4. Repeat steps 2 through 4 until the sentence is correct. ----> The ccow jumpedd ovverr thhe mooon. {expect:The cow jumped over the moon.} +The ccow jumpedd ovverr thhe mooon. 5. Now that the line is correct, go on to Lesson 1.4. @@ -119,8 +119,8 @@ NOTE: As you go through this tutor, do not try to memorize, learn by usage. 4. As each error is fixed press <Esc> to return to Normal mode. Repeat steps 2 through 4 to correct the sentence. ----> There is text misng this . {expect:There is some text missing from this line.} ----> There is some text missing from this line. {expect:There is some text missing from this line.} +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. @@ -138,10 +138,10 @@ NOTE: As you go through this tutor, do not try to memorize, learn by usage. 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 {expect:There is some text missing from this line.} ----> There is some text missing from this line. {expect:There is some text missing from this line.} ----> There is also some text miss {expect:There is also some text missing here.} ----> There is also some text missing here. {expect:There is also some text missing here.} +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. @@ -212,7 +212,7 @@ Now continue with Lesson 2. 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. {expect:There are some words that don't belong in this sentence.} +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. @@ -228,7 +228,7 @@ Now continue with Lesson 2. 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. {expect:ANYTHING} +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. @@ -268,7 +268,7 @@ NOTE: Pressing just the motion while in Normal mode without an operator will 5. Repeat steps 2 and 3 with different numbers. ----> This is just a line with words you can move around in. {expect:ANYTHING} +This is just a line with words you can move around in. 6. Move on to Lesson 2.5. @@ -287,7 +287,7 @@ insert a count before the motion to delete more: 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. {expect:this line of words is cleaned up.} +this ABC DE line FGHI JK LMN OP of words is Q RS TUV cleaned up. # Lesson 2.6: OPERATING ON LINES @@ -301,13 +301,13 @@ insert a count before the motion to delete more: 3. Now move to the fourth line. 4. Type `2dd`{normal} to delete two lines. ----> 1) Roses are red, {expect:ANYTHING} ----> 2) Mud is fun, {expect:ANYTHING} ----> 3) Violets are blue, {expect:ANYTHING} ----> 4) I have a car, {expect:ANYTHING} ----> 5) Clocks tell time, {expect:ANYTHING} ----> 6) Sugar is sweet {expect:ANYTHING} ----> 7) And so are you. {expect:ANYTHING} +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 @@ -322,7 +322,7 @@ insert a count before the motion to delete more: 6. Now type `u`{normal} a few times to undo the U and preceding commands. 7. Now type `<Ctrl-r>`{normal} a few times to redo the commands (undo the undo's). ----> Fiix the errors oon thhis line and reeplace them witth undo. {expect:Fix the errors on this line and replace them with undo.} +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. @@ -362,10 +362,10 @@ insert a count before the motion to delete more: 5. Repeat steps 2 through 4 to put all the lines in correct order. ----> d) Can you learn too? {expect:ANYTHING} ----> b) Violets are blue, {expect:ANYTHING} ----> c) Intelligence is learned, {expect:ANYTHING} ----> a) Roses are red, {expect:ANYTHING} +d) Can you learn too? +b) Violets are blue, +c) Intelligence is learned, +a) Roses are red, # Lesson 3.2: THE REPLACE COMMAND @@ -379,8 +379,8 @@ insert a count before the motion to delete more: 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! {expect:When this line was typed in, someone pressed some wrong keys!} ----> When this line was typed in, someone pressed some wrong keys! {expect:When this line was typed in, someone pressed some wrong keys!} +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. @@ -400,8 +400,8 @@ NOTE: Remember that you should be learning by doing, not memorization. 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. {expect:This line has a few words that need changing using the change operator.} ----> This line has a few words that need changing using the change operator. {expect:This line has a few words that need changing using the change operator.} +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. @@ -421,8 +421,8 @@ Notice that [c](c)e deletes the word and places you in Insert mode. 5. Type `c$`{normal} and type the rest of the line like the second and press `<Esc>`{normal}. ----> The end of this line needs some help to make it like the second. {expect:The end of this line needs to be corrected using the c$ command.} ----> The end of this line needs to be corrected using the c$ command. {expect:The end of this line needs to be corrected using the c$ command.} +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$ command. NOTE: You can use the Backspace key to correct mistakes while typing. @@ -484,7 +484,7 @@ NOTE: You may see the cursor position in the lower right corner of the screen 5. To go back to where you came from press `<Ctrl-o>`{normal} (Keep Ctrl down while pressing the letter o). Repeat to go back further. `<Ctrl-i>`{normal} goes forward. ----> "errroor" is not the way to spell error; errroor is an error. {expect:ANYTHING} +"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. @@ -503,7 +503,7 @@ NOTE: When the search reaches the end of the file it will continue at the 5. Move the cursor to another (,),[,],{ or } and see what `%`{normal} does. ----> This ( is a test line with ('s, ['s ] and {'s } in it. )) {expect:ANYTHING} +This ( is a test line with ('s, ['s ] and {'s } in it. )) NOTE: This is very useful in debugging a program with unmatched parentheses! @@ -528,7 +528,7 @@ NOTE: This is very useful in debugging a program with unmatched parentheses! Adding the g [flag](:s_flags) means to substitute globally in the line, change all occurrences of "thee" in the line. ----> thee best time to see thee flowers is in thee spring. {expect:the best time to see the flowers is in the spring.} +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 @@ -719,12 +719,12 @@ NOTE: You can also read the output of an external command. For example, 3. Now type some text and press `<Esc>`{normal} to exit Insert mode. ----> After typing o the cursor is placed on the open line in Insert mode. {expect:ANYTHING} +After typing o 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. {expect:ANYTHING} +Open up a line above this by typing O while the cursor is on this line. # Lesson 6.2: THE APPEND COMMAND @@ -741,8 +741,8 @@ NOTE: You can also read the output of an external command. For example, 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. {expect:This line will allow you to practice appending text to a line.} ----> This line will allow you to practice appending text to a line. {expect:This line will allow you to practice appending text to a line.} +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. @@ -762,8 +762,8 @@ NOTE: [a](a), [i](i) and [A](A) all go to the same Insert mode, the only differ 4. Repeat the steps to replace the remaining "xxx". ----> Adding 123 to xxx gives you xxx. {expect:Adding 123 to 456 gives you 579.} ----> Adding 123 to 456 gives you 579. {expect:Adding 123 to 456 gives you 579.} +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. @@ -785,8 +785,8 @@ NOTE: Replace mode is like Insert mode, but every typed character deletes an 6. 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) {expect: b) this is the second item} +a) this is the first item. + b) NOTE: you can also use `y`{normal} as an operator; `yw`{normal} yanks one word. @@ -947,8 +947,10 @@ There are many resources online to learn more about vim. Here's a bunch of them: - 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, *Practival Vim* by Drew Neil is recommended often. +If you prefer a book, *Practical Vim* by Drew Neil is recommended often (the sequel, *Modern +Vim*, includes material specific to nvim!). This tutorial was written by Michael C. Pierce and Robert K. Ware, Colorado School of Mines using ideas supplied by Charles Smith, Colorado State diff --git a/runtime/tutor/en/vim-01-beginner.tutor.json b/runtime/tutor/en/vim-01-beginner.tutor.json new file mode 100644 index 0000000000..3f55971a09 --- /dev/null +++ b/runtime/tutor/en/vim-01-beginner.tutor.json @@ -0,0 +1,45 @@ +{ + "expect": { + "24": -1, + "102": "The cow jumped over the moon.", + "122": "There is some text missing from this line.", + "123": "There is some text missing from this line.", + "141": "There is some text missing from this line.", + "142": "There is some text missing from this line.", + "143": "There is also some text missing here.", + "144": "There is also some text missing here.", + "215": "There are some words that don't belong in this sentence.", + "231": "Somebody typed the end of this line twice.", + "271": -1, + "290": "this line of words is cleaned up.", + "304": -1, + "305": -1, + "306": -1, + "307": -1, + "308": -1, + "309": -1, + "310": -1, + "325": "Fix the errors on this line and replace them with undo.", + "365": -1, + "366": -1, + "367": -1, + "368": -1, + "382": "When this line was typed in, someone pressed some wrong keys!", + "383": "When this line was typed in, someone pressed some wrong keys!", + "403": "This line has a few words that need changing using the change operator.", + "404": "This line has a few words that need changing using the change operator.", + "424": "The end of this line needs to be corrected using the c$ command.", + "425": "The end of this line needs to be corrected using the c$ command.", + "487": -1, + "506": -1, + "531": "the best time to see the flowers is in the spring.", + "722": -1, + "727": -1, + "744": "This line will allow you to practice appending text to a line.", + "745": "This line will allow you to practice appending text to a line.", + "765": "Adding 123 to 456 gives you 579.", + "766": "Adding 123 to 456 gives you 579.", + "788": "a) this is the first item.", + "789": " b) this is the second item." + } +} diff --git a/runtime/tutor/tutor.tutor b/runtime/tutor/tutor.tutor index 1ad64a18ff..c937bd686a 100644 --- a/runtime/tutor/tutor.tutor +++ b/runtime/tutor/tutor.tutor @@ -60,27 +60,27 @@ is displayed like 1. Format the line below so it becomes a lesson description: ----> This is text with important information {expect:This is text with **important information**} ----> This is text with **important information** {expect:This is text with **important information**} +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' {expect:TODO: Document '&variable'} ----> TODO: Document '&variable' {expect:TODO: Document '&variable'} +Document '&variable' +TODO: Document '&variable' ### Headers *headers* 3. Practice fixing the lines below: ----> This is a level 1 header {expect:# This is a level 1 header} ----> # This is a level 1 header {expect:# This is a level 1 header} ----> This is a level 3 header {expect:### This is a level 3 header} ----> ### This is a level 3 header {expect:### This is a level 3 header} ----> This is a header with a label {expect:# This is a header with a label {*label*}} ----> # This is a header with a label {*label*} {expect:# This is a header with a label {*label*}} +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: @@ -105,8 +105,8 @@ 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 {expect:A link to help for the ['breakindent']('breakindent') option} ----> A link to help for the ['breakindent']('breakindent') option {expect:A link to help for the ['breakindent']('breakindent') option} +A link to help for the 'breakindent' option +A link to help for the ['breakindent']('breakindent') option #### Anchor links @@ -120,8 +120,8 @@ and are hidden by default. Links to them look like 6. Add the appropiate link: ----> A link to the Links section {expect:A link to the [Links](*links*) section} ----> A link to the [Links](*links*) section {expect:A link to the [Links](*links*) section} +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. @@ -136,8 +136,8 @@ You can also have links to other tutorials. For this, you'll write the anchor in 7. Create a link to this tutorial: ----> A link to the vim-tutor-mode tutorial {expect:A link to [the vim-tutor-mode tutorial](@tutor:tutor)} ----> A link to [the vim-tutor-mode tutorial](@tutor:tutor) {expect:A link to [the vim-tutor-mode tutorial](@tutor:tutor)} +A link to the vim-tutor-mode tutorial +A link to [the vim-tutor-mode tutorial](@tutor:tutor) ### Codeblocks *codeblocks* @@ -154,13 +154,13 @@ echom "hello" 8. Copy the viml section below ----> {expect:~~~ viml} ----> {expect:echom "the value of &number is".string(&number)} ----> {expect:~~~} ----> ~~~ viml {expect:~~~ viml} ----> echom "the value of &number is".string(&number) {expect:echom "the value of &number is".string(&number)} ----> ~~~ {expect:~~~} + + + +~~~ viml +echom 'the value of &number is'.string(&number) +~~~ You can inline viml code using "\`" and "\`{vim}": @@ -185,13 +185,13 @@ Note: you can also write `norm` or `normal`. 9. Copy the normal section below ----> {expect:~~~ normal} ----> {expect:d2w} ----> {expect:~~~} ----> ~~~ normal {expect:~~~ normal} ----> d2w {expect:d2w} ----> ~~~ {expect:~~~} + + + +~~~ normal +d2w +~~~ You can also inline normal commands by using "\`" and "\`{normal}": @@ -203,10 +203,11 @@ is displayed: 10. Complete the line as shown ----> d {expect:«d2w»} ----> «d2w» {expect:«d2w»} +d +`d2w`{normal} -Commands to run in the system shell can be highlighted by indenting a line starting with "$". +Commands to run in the system shell can be highlighted by indenting a line +starting with "$". ~~~ sh $ vim --version @@ -215,45 +216,32 @@ Commands to run in the system shell can be highlighted by indenting a line start ## 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. These elements -all have the syntax - - \---> TEXT {CLAUSE} - -where \---> must start at the beginning of the line. If TEXT satisfies CLAUSE, -a ✓ sign will appear to the left. A ✗ sign is displayed otherwise. The CLAUSE -itself is hidden unless debug mode is set or ['conceallevel']('conceallevel') -is 2. +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* -The basic clause is "expect", which is satisfied if TEXT is the same as the -content of the clause. For example - - \---> TEXT {expect:TEXT} - -is satisfied, but - - \---> OTHER TEXT {expect:TEXT} - -is not. +"expect" lines check that the contents of the line are identical to some preset text +(like in the exercises above). -13. Make both lines the same: +These elements are specified in separate JSON files like this ----> this is not right {expect:---> this is right} |expect:---> this is right {expect:---> this is right}| ----> ---> this is right {expect:---> this is right} |expect:---> this is right {expect:---> this is right}| - - -If the content of a expect clause is ANYTHING, no checks will be performed. This is -useful to create a line that is highlighted you want the user to play with. - - \---> TEXT {expect:ANYTHING} - -is displayed +~~~ json +{ + "expect": { + "1": "This is how this line should look.", + "2": "This is how this line should look.", + "3": -1 + } +} +~~~ ----> this is free text {expect:ANYTHING} +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). -14. Turn the line below into free text: +This is an "expect" line that is always satisfied. Try changing it. ----> this is some text |expect:---> this is some text {expect:ANYTHING}| ----> ---> this is some text {expect:ANYTHING} |expect:---> this is some text {expect:ANYTHING}| +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 index 0000000000..bf3eae8586 --- /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 + } +} |