mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge #7028 from fmoralesc/vimtutor-disentangle2
Closes #4533 Closes #6389 Closes #4913 Closes #7005
This commit is contained in:
commit
a76da96e86
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
45
runtime/tutor/en/vim-01-beginner.tutor.json
Normal file
45
runtime/tutor/en/vim-01-beginner.tutor.json
Normal 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."
|
||||
}
|
||||
}
|
@ -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).
|
||||
|
35
runtime/tutor/tutor.tutor.json
Normal file
35
runtime/tutor/tutor.tutor.json
Normal 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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user