Merge #7028 from fmoralesc/vimtutor-disentangle2

Closes #4533
Closes #6389
Closes #4913 
Closes #7005
This commit is contained in:
Justin M. Keyes 2017-07-16 18:19:41 +02:00 committed by GitHub
commit a76da96e86
7 changed files with 236 additions and 292 deletions

View File

@ -15,30 +15,17 @@ function! tutor#SetupVim()
endif endif
endfunction endfunction
" Mappings: {{{1 " Loads metadata file, if available
function! tutor#LoadMetadata()
function! s:CheckMaps() let b:tutor_metadata = json_decode(join(readfile(expand('%').'.json'), "\n"))
nmap
endfunction endfunction
function! s:MapKeyWithRedirect(key, cmd) " Mappings: {{{1
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."'") function! tutor#SetNormalMappings()
if len(l:raw_map) == 0 nnoremap <silent> <buffer> <CR> :call tutor#FollowLink(0)<cr>
exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd nnoremap <silent> <buffer> <2-LeftMouse> :call tutor#MouseDoubleClick()<cr>
return nnoremap <buffer> >> :call tutor#InjectCommand()<cr>
endif
let l:map_data = split(l:raw_map[0], '\s*')
exe "nnoremap <buffer> <expr> ".l:map_data[0]." ".a:cmd
else
exe "nnoremap <buffer> <expr> ".a:key." ".a:cmd
endif
endfunction endfunction
function! tutor#MouseDoubleClick() function! tutor#MouseDoubleClick()
@ -46,7 +33,7 @@ function! tutor#MouseDoubleClick()
normal! zo normal! zo
else else
if match(getline('.'), '^#\{1,} ') > -1 if match(getline('.'), '^#\{1,} ') > -1
normal! zc silent normal! zc
else else
call tutor#FollowLink(0) call tutor#FollowLink(0)
endif endif
@ -59,114 +46,6 @@ function! tutor#InjectCommand()
redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd redraw | echohl WarningMsg | echon "tutor: ran" | echohl None | echon " " | echohl Statement | echon l:cmd
endfunction 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) function! tutor#FollowLink(force)
let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '') let l:stack_s = join(map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")'), '')
if l:stack_s =~# 'tutorLink' if l:stack_s =~# 'tutorLink'
@ -209,42 +88,40 @@ function! tutor#InfoText()
return join(l:info_parts, " ") return join(l:info_parts, " ")
endfunction endfunction
" Marks {{{1
function! tutor#PlaceXMarks() " Marks: {{{1
call cursor(1, 1)
let b:tutor_sign_id = 1 function! tutor#ApplyMarks()
while search('^--->', 'W') > 0 hi! link tutorExpect Special
call tutor#CheckText(getline('.')) if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
let b:tutor_sign_id+=1 let b:tutor_sign_id = 1
endwhile for expct in keys(b:tutor_metadata['expect'])
call cursor(1, 1) let lnum = eval(expct)
call matchaddpos('tutorExpect', [lnum])
call tutor#CheckLine(lnum)
endfor
endif
endfunction endfunction
function! tutor#CheckText(text) function! tutor#ApplyMarksOnChanged()
if match(a:text, '{expect:ANYTHING}\s*$') == -1 if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
if match(getline('.'), '^--->\s*$') > -1 let lnum = line('.')
exe "sign place ".b:tutor_sign_id." line=".line('.')." name=tutorbad buffer=".bufnr('%') if index(keys(b:tutor_metadata['expect']), string(lnum)) > -1
else call tutor#CheckLine(lnum)
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
endif endif
endif endif
endfunction endfunction
function! tutor#OnTextChanged() function! tutor#CheckLine(line)
let l:text = getline('.') if exists('b:tutor_metadata') && has_key(b:tutor_metadata, 'expect')
if match(l:text, '^--->') > -1 let bufn = bufnr('%')
call tutor#CheckText(l:text) 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 endif
endfunction endfunction

View File

@ -19,27 +19,30 @@ setlocal noundofile
setlocal keywordprg=:help setlocal keywordprg=:help
setlocal iskeyword=@,-,_ 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 foldexpr=tutor#TutorFolds()
setlocal foldcolumn=1
setlocal foldlevel=4 setlocal foldlevel=4
setlocal nowrap
setlocal statusline=%{toupper(expand('%:t:r'))}\ tutorial%= setlocal statusline=%{toupper(expand('%:t:r'))}\ tutorial%=
setlocal statusline+=%{tutor#InfoText()} setlocal statusline+=%{tutor#InfoText()}
" Load metadata if it exists: {{{1
if filereadable(expand('%').'.json')
call tutor#LoadMetadata()
endif
" Mappings: {{{1 " Mappings: {{{1
call tutor#SetNormalMappings() call tutor#SetNormalMappings()
call tutor#SetSampleTextMappings()
" Checks: {{{1 " Checks: {{{1
sign define tutorok text=texthl=tutorOK sign define tutorok text=texthl=tutorOK
sign define tutorbad text=texthl=tutorX sign define tutorbad text=texthl=tutorX
if !exists('g:tutor_debug') || g:tutor_debug == 0 if !exists('g:tutor_debug') || g:tutor_debug == 0
call tutor#PlaceXMarks() call tutor#ApplyMarks()
autocmd! TextChanged <buffer> call tutor#OnTextChanged() autocmd! TextChanged,TextChangedI <buffer> call tutor#ApplyMarksOnChanged()
autocmd! TextChangedI <buffer> call tutor#OnTextChanged()
endif endif

View File

@ -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 attention exercise
syn keyword tutorMarks Todo Note Tip Excersise 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 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 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 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 concealends 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 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 concealends 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 tutorInlineOK /✓/
syn match tutorInlineX /✗/ syn match tutorInlineX /✗/
@ -72,7 +66,7 @@ hi! tutorMarks cterm=bold gui=bold
hi! tutorEmphasis gui=italic cterm=italic hi! tutorEmphasis gui=italic cterm=italic
hi! tutorBold gui=bold cterm=bold 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! tutorOK ctermfg=green guifg=#00ff88 cterm=bold gui=bold
hi! tutorX ctermfg=red guifg=#ff2000 cterm=bold gui=bold hi! tutorX ctermfg=red guifg=#ff2000 cterm=bold gui=bold
hi! link tutorInlineOK tutorOK hi! link tutorInlineOK tutorOK

View File

@ -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. [<Esc>](<Esc>) and then [u](u) will undo the latest change.
This tutorial is interactive, and there are a few things you should know. 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 Pressing [<Enter>](<Enter>) over text highlighted [like this](holy-grail) will take you to some
help (hopefully), and pressing K over any word will try to do so too. Sometimes relevant help (hopefully), and pressing K over any word will try to do so too.
you will be required to modify text like Sometimes you will be required to modify text like
---> this here {expect:this here} this here
Once you have done the changes correctly, the ✗ sign at the left will change 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 ;) 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): 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. 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. 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. 4. As each error is fixed press <Esc> to return to Normal mode.
Repeat steps 2 through 4 to correct the sentence. 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 text misng this .
---> There is some text missing from this line. {expect:There is some text missing from this line.} There is some text missing from this line.
5. When you are comfortable inserting text move to lesson 1.5. 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 4. Move the cursor to the second line marked ---> and repeat
steps 2 and 3 to correct this sentence. 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 th
---> There is some text missing from this line. {expect:There is some text missing from this line.} 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 miss
---> There is also some text missing here. {expect:There is also some text missing here.} There is also some text missing here.
5. When you are comfortable appending text move to lesson 1.6. 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. 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. 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. 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. 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. 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. 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 3. Repeat steps 1 and 2 with a different count to delete the consecutive
UPPER CASE words with one command 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 # 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. 3. Now move to the fourth line.
4. Type `2dd`{normal} to delete two lines. 4. Type `2dd`{normal} to delete two lines.
---> 1) Roses are red, {expect:ANYTHING} 1) Roses are red,
---> 2) Mud is fun, {expect:ANYTHING} 2) Mud is fun,
---> 3) Violets are blue, {expect:ANYTHING} 3) Violets are blue,
---> 4) I have a car, {expect:ANYTHING} 4) I have a car,
---> 5) Clocks tell time, {expect:ANYTHING} 5) Clocks tell time,
---> 6) Sugar is sweet {expect:ANYTHING} 6) Sugar is sweet
---> 7) And so are you. {expect:ANYTHING} 7) And so are you.
# Lesson 2.7: THE UNDO COMMAND # 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. 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). 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. 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. 5. Repeat steps 2 through 4 to put all the lines in correct order.
---> d) Can you learn too? {expect:ANYTHING} d) Can you learn too?
---> b) Violets are blue, {expect:ANYTHING} b) Violets are blue,
---> c) Intelligence is learned, {expect:ANYTHING} c) Intelligence is learned,
---> a) Roses are red, {expect:ANYTHING} a) Roses are red,
# Lesson 3.2: THE REPLACE COMMAND # 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. 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!} Whan this lime was tuoed in, someone presswd some wrojg keys!
---> When this line was typed in, someone pressed some wrong keys! {expect:When this line was typed in, someone pressed some wrong keys!} When this line was typed in, someone pressed some wrong keys!
5. Now move on to Lesson 3.3. 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. 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 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. {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.
Notice that [c](c)e deletes the word and places you in Insert mode. 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}. 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 some help to make it like the second.
---> 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 to be corrected using the c$ command.
NOTE: You can use the Backspace key to correct mistakes while typing. 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 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. 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 NOTE: When the search reaches the end of the file it will continue at the
start, unless the ['wrapscan']('wrapscan') option has been reset. 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. 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! 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 Adding the g [flag](:s_flags) means to substitute globally in the line, change
all occurrences of "thee" in the line. 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 4. To change every occurrence of a character string between two lines, type
~~~ cmd ~~~ 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. 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 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. 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 # 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. 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 li will allow you to pract appendi 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 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 NOTE: [a](a), [i](i) and [A](A) all go to the same Insert mode, the only difference is where
the characters are inserted. 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". 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 xxx gives you xxx.
---> Adding 123 to 456 gives you 579. {expect:Adding 123 to 456 gives you 579.} Adding 123 to 456 gives you 579.
NOTE: Replace mode is like Insert mode, but every typed character deletes an NOTE: Replace mode is like Insert mode, but every typed character deletes an
existing character. 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 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}. the next line with `j$`{normal} and put the text there with `p`{normal}.
---> a) this is the first item. a) this is the first item.
---> b) {expect: b) this is the second item} b)
NOTE: you can also use `y`{normal} as an operator; `yw`{normal} yanks one word. 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/ - Vim Video-Tutorials by Derek Wyatt: http://derekwyatt.org/vim/tutorials/
- *Learn Vimscript the Hard Way*: http://learnvimscriptthehardway.stevelosh.com/ - *Learn Vimscript the Hard Way*: http://learnvimscriptthehardway.stevelosh.com/
- *7 Habits of Effective Text Editing*: http://www.moolenaar.net/habits.html - *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 This tutorial was written by Michael C. Pierce and Robert K. Ware, Colorado
School of Mines using ideas supplied by Charles Smith, Colorado State School of Mines using ideas supplied by Charles Smith, Colorado State

View File

@ -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."
}
}

View File

@ -60,27 +60,27 @@ is displayed like
1. Format the line below so it becomes a lesson description: 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
---> This is text with **important information** {expect: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 Note: Some words (e.g., NOTE, IMPORTANT, tip, ATTENTION, etc.) will also be
highlighted. You don't need to mark them specially. highlighted. You don't need to mark them specially.
2. Turn the line below into a TODO item: 2. Turn the line below into a TODO item:
---> Document '&variable' {expect:TODO: Document '&variable'} Document '&variable'
---> TODO: Document '&variable' {expect:TODO: Document '&variable'} TODO: Document '&variable'
### Headers *headers* ### Headers *headers*
3. Practice fixing the lines below: 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
---> # This is a level 1 header {expect:# This is a level 1 header} # 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
---> ### This is a level 3 header {expect:### This is a level 3 header} ### 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
---> # This is a header with a label {*label*} {expect:# This is a header with a label {*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 4. Now, create a 4th level section here, and add a label like in the previous
exercise: 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: 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' 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']('breakindent') option
#### Anchor links #### Anchor links
@ -120,8 +120,8 @@ and are hidden by default. Links to them look like
6. Add the appropiate link: 6. Add the appropiate link:
---> A link to the Links section {expect:A link to the [Links](*links*) section} A link to the Links section
---> A link to the [Links](*links*) section {expect:A link to the [Links](*links*) section} A link to the [Links](*links*) section
7. Now, create a link to the section you created on exercise 4 7. Now, create a link to the section you created on exercise 4
above. 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: 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
---> 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](@tutor:tutor)
### Codeblocks *codeblocks* ### Codeblocks *codeblocks*
@ -154,13 +154,13 @@ echom "hello"
8. Copy the viml section below 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}": 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 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}": You can also inline normal commands by using "\`" and "\`{normal}":
@ -203,10 +203,11 @@ is displayed:
10. Complete the line as shown 10. Complete the line as shown
---> d {expect:«d2w»} d
---> «d2w» {expect:«d2w»} `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 ~~~ sh
$ vim --version $ vim --version
@ -215,45 +216,32 @@ Commands to run in the system shell can be highlighted by indenting a line start
## INTERACTIVE ELEMENTS *interactive* ## INTERACTIVE ELEMENTS *interactive*
As visible in this very document, vim-tutor-mode includes some 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 elements to provide feedback to the user about his progress. If the text in
all have the syntax these elements satisfies some set condition, a ✓ sign will appear in the gutter
to the left. Otherwise, a ✗ sign is displayed.
\---> 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.
### expect *expect* ### expect *expect*
The basic clause is "expect", which is satisfied if TEXT is the same as the "expect" lines check that the contents of the line are identical to some preset text
content of the clause. For example (like in the exercises above).
\---> TEXT {expect:TEXT} These elements are specified in separate JSON files like this
is satisfied, but ~~~ json
{
"expect": {
"1": "This is how this line should look.",
"2": "This is how this line should look.",
"3": -1
}
}
~~~
\---> OTHER TEXT {expect:TEXT} 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).
is not. This is an "expect" line that is always satisfied. Try changing it.
13. Make both lines the same: 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).
---> 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
---> this is free text {expect:ANYTHING}
14. Turn the line below into free text:
---> this is some text |expect:---> this is some text {expect:ANYTHING}|
---> ---> this is some text {expect:ANYTHING} |expect:---> this is some text {expect:ANYTHING}|

View File

@ -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
}
}