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
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')
" Mappings: {{{1
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*')
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

View File

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

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

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.
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

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:
---> 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
"expect" lines check that the contents of the line are identical to some preset text
(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:
---> 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}|
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).

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