mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
merge upstream
This commit is contained in:
commit
2c89195afd
@ -16,6 +16,12 @@ function! s:selection.on_exit(jobid, data, event) abort
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:selection.on_stderr(jobid, data, event) abort
|
||||
echohl WarningMsg
|
||||
echomsg 'clipboard: error invoking '.get(self.argv, 0, '?').': '.join(a:data)
|
||||
echohl None
|
||||
endfunction
|
||||
|
||||
let s:selections = { '*': s:selection, '+': copy(s:selection)}
|
||||
|
||||
function! s:try_cmd(cmd, ...) abort
|
||||
@ -135,24 +141,17 @@ function! s:clipboard.set(lines, regtype, reg) abort
|
||||
end
|
||||
let selection.data = [a:lines, a:regtype]
|
||||
let argv = split(s:copy[a:reg], " ")
|
||||
let selection.argv = argv
|
||||
let selection.detach = s:cache_enabled
|
||||
let selection.cwd = "/"
|
||||
call extend(selection, {
|
||||
\ 'on_stdout': function('s:set_errhandler'),
|
||||
\ 'on_stderr': function('s:set_errhandler'),
|
||||
\ })
|
||||
let jobid = jobstart(argv, selection)
|
||||
if jobid > 0
|
||||
call jobsend(jobid, a:lines)
|
||||
call jobclose(jobid, 'stdin')
|
||||
let selection.owner = jobid
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! s:set_errhandler(job_id, data, event) abort
|
||||
if a:job_id <= 0
|
||||
else
|
||||
echohl WarningMsg
|
||||
echo 'clipboard: error when invoking provider: ' . join(a:data)
|
||||
echomsg 'clipboard: failed to execute: '.(s:copy[a:reg])
|
||||
echohl None
|
||||
endif
|
||||
endfunction
|
||||
|
@ -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
|
||||
|
||||
|
@ -4273,7 +4273,8 @@ getqflist([{what}]) *getqflist()*
|
||||
If the optional {what} dictionary argument is supplied, then
|
||||
returns only the items listed in {what} as a dictionary. The
|
||||
following string items are supported in {what}:
|
||||
nr get information for this quickfix list
|
||||
nr get information for this quickfix list; zero
|
||||
means the current quickfix list
|
||||
title get the list title
|
||||
winid get the |window-ID| (if opened)
|
||||
all all of the above quickfix properties
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -4239,11 +4239,17 @@ static int eval7(
|
||||
// use its contents.
|
||||
s = deref_func_name((const char *)s, &len, &partial, !evaluate);
|
||||
|
||||
// Need to make a copy, in case evaluating the arguments makes
|
||||
// the name invalid.
|
||||
s = xmemdupz(s, len);
|
||||
|
||||
// Invoke the function.
|
||||
ret = get_func_tv(s, len, rettv, arg,
|
||||
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
|
||||
&len, evaluate, partial, NULL);
|
||||
|
||||
xfree(s);
|
||||
|
||||
// If evaluate is false rettv->v_type was not set in
|
||||
// get_func_tv, but it's needed in handle_subscript() to parse
|
||||
// what follows. So set it here.
|
||||
|
@ -7039,8 +7039,11 @@ dict_T *get_winbuf_options(const int bufopt)
|
||||
if (opt->flags & P_STRING) {
|
||||
tv_dict_add_str(d, opt->fullname, strlen(opt->fullname),
|
||||
*(const char **)varp);
|
||||
} else if (opt->flags & P_NUM) {
|
||||
tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname),
|
||||
*(long *)varp);
|
||||
} else {
|
||||
tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), *varp);
|
||||
tv_dict_add_nr(d, opt->fullname, strlen(opt->fullname), *(int *)varp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -383,6 +383,8 @@ static int efm_to_regpat(char_u *efm, int len, efm_T *fmt_ptr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static efm_T *fmt_start = NULL; // cached across qf_parse_line() calls
|
||||
|
||||
static void free_efm_list(efm_T **efm_first)
|
||||
{
|
||||
for (efm_T *efm_ptr = *efm_first; efm_ptr != NULL; efm_ptr = *efm_first) {
|
||||
@ -390,6 +392,8 @@ static void free_efm_list(efm_T **efm_first)
|
||||
vim_regfree(efm_ptr->prog);
|
||||
xfree(efm_ptr);
|
||||
}
|
||||
|
||||
fmt_start = NULL;
|
||||
}
|
||||
|
||||
// Parse 'errorformat' option
|
||||
@ -671,7 +675,6 @@ static int qf_parse_line(qf_info_T *qi, char_u *linebuf, size_t linelen,
|
||||
efm_T *fmt_first, qffields_T *fields)
|
||||
{
|
||||
efm_T *fmt_ptr;
|
||||
static efm_T *fmt_start = NULL; // cached across calls
|
||||
size_t len;
|
||||
int i;
|
||||
int idx = 0;
|
||||
@ -875,36 +878,38 @@ restofline:
|
||||
qi->qf_multiignore = false; // reset continuation
|
||||
} else if (vim_strchr((char_u *)"CZ", idx)
|
||||
!= NULL) { // continuation of multi-line msg
|
||||
qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last;
|
||||
if (qfprev == NULL) {
|
||||
return QF_FAIL;
|
||||
}
|
||||
if (*fields->errmsg && !qi->qf_multiignore) {
|
||||
size_t len = STRLEN(qfprev->qf_text);
|
||||
qfprev->qf_text = xrealloc(qfprev->qf_text,
|
||||
len + STRLEN(fields->errmsg) + 2);
|
||||
qfprev->qf_text[len] = '\n';
|
||||
STRCPY(qfprev->qf_text + len + 1, fields->errmsg);
|
||||
}
|
||||
if (qfprev->qf_nr == -1) {
|
||||
qfprev->qf_nr = fields->enr;
|
||||
}
|
||||
if (vim_isprintc(fields->type) && !qfprev->qf_type) {
|
||||
qfprev->qf_type = fields->type; // only printable chars allowed
|
||||
}
|
||||
if (!qfprev->qf_lnum) {
|
||||
qfprev->qf_lnum = fields->lnum;
|
||||
}
|
||||
if (!qfprev->qf_col) {
|
||||
qfprev->qf_col = fields->col;
|
||||
}
|
||||
qfprev->qf_viscol = fields->use_viscol;
|
||||
if (!qfprev->qf_fnum) {
|
||||
qfprev->qf_fnum = qf_get_fnum(qi, qi->qf_directory,
|
||||
*fields->namebuf || qi->qf_directory
|
||||
? fields->namebuf
|
||||
: qi->qf_currfile && fields->valid
|
||||
? qi->qf_currfile : 0);
|
||||
if (!qi->qf_multiignore) {
|
||||
qfline_T *qfprev = qi->qf_lists[qi->qf_curlist].qf_last;
|
||||
if (qfprev == NULL) {
|
||||
return QF_FAIL;
|
||||
}
|
||||
if (*fields->errmsg && !qi->qf_multiignore) {
|
||||
size_t len = STRLEN(qfprev->qf_text);
|
||||
qfprev->qf_text = xrealloc(qfprev->qf_text,
|
||||
len + STRLEN(fields->errmsg) + 2);
|
||||
qfprev->qf_text[len] = '\n';
|
||||
STRCPY(qfprev->qf_text + len + 1, fields->errmsg);
|
||||
}
|
||||
if (qfprev->qf_nr == -1) {
|
||||
qfprev->qf_nr = fields->enr;
|
||||
}
|
||||
if (vim_isprintc(fields->type) && !qfprev->qf_type) {
|
||||
qfprev->qf_type = fields->type; // only printable chars allowed
|
||||
}
|
||||
if (!qfprev->qf_lnum) {
|
||||
qfprev->qf_lnum = fields->lnum;
|
||||
}
|
||||
if (!qfprev->qf_col) {
|
||||
qfprev->qf_col = fields->col;
|
||||
}
|
||||
qfprev->qf_viscol = fields->use_viscol;
|
||||
if (!qfprev->qf_fnum) {
|
||||
qfprev->qf_fnum = qf_get_fnum(qi, qi->qf_directory,
|
||||
*fields->namebuf || qi->qf_directory
|
||||
? fields->namebuf
|
||||
: qi->qf_currfile && fields->valid
|
||||
? qi->qf_currfile : 0);
|
||||
}
|
||||
}
|
||||
if (idx == 'Z') {
|
||||
qi->qf_multiline = qi->qf_multiignore = false;
|
||||
@ -967,6 +972,7 @@ qf_init_ext(
|
||||
NULL, 0, 0 };
|
||||
qffields_T fields = { NULL, NULL, 0, 0L, 0, false, NULL, 0, 0, 0 };
|
||||
qfline_T *old_last = NULL;
|
||||
bool adding = false;
|
||||
static efm_T *fmt_first = NULL;
|
||||
char_u *efm;
|
||||
static char_u *last_efm = NULL;
|
||||
@ -992,6 +998,7 @@ qf_init_ext(
|
||||
qf_new_list(qi, qf_title);
|
||||
} else if (qi->qf_lists[qi->qf_curlist].qf_count > 0) {
|
||||
// Adding to existing list, use last entry.
|
||||
adding = true;
|
||||
old_last = qi->qf_lists[qi->qf_curlist].qf_last;
|
||||
}
|
||||
|
||||
@ -1108,10 +1115,12 @@ qf_init_ext(
|
||||
}
|
||||
EMSG(_(e_readerrf));
|
||||
error2:
|
||||
qf_free(qi, qi->qf_curlist);
|
||||
qi->qf_listcount--;
|
||||
if (qi->qf_curlist > 0) {
|
||||
qi->qf_curlist--;
|
||||
if (!adding) {
|
||||
qf_free(qi, qi->qf_curlist);
|
||||
qi->qf_listcount--;
|
||||
if (qi->qf_curlist > 0) {
|
||||
qi->qf_curlist--;
|
||||
}
|
||||
}
|
||||
qf_init_end:
|
||||
if (state.fd != NULL) {
|
||||
@ -1408,7 +1417,7 @@ void copy_loclist(win_T *from, win_T *to)
|
||||
to->w_llist->qf_curlist = qi->qf_curlist; /* current list */
|
||||
}
|
||||
|
||||
// Get buffer number for file "directory.fname".
|
||||
// Get buffer number for file "directory/fname".
|
||||
// Also sets the b_has_qf_entry flag.
|
||||
static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname)
|
||||
{
|
||||
@ -2362,7 +2371,9 @@ static void qf_free(qf_info_T *qi, int idx)
|
||||
qi->qf_lists[idx].qf_index = 0;
|
||||
|
||||
qf_clean_dir_stack(&qi->qf_dir_stack);
|
||||
qi->qf_directory = NULL;
|
||||
qf_clean_dir_stack(&qi->qf_file_stack);
|
||||
qi->qf_currfile = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4025,9 +4036,12 @@ int get_errorlist_properties(win_T *wp, dict_T *what, dict_T *retdict)
|
||||
if ((di = tv_dict_find(what, S_LEN("nr"))) != NULL) {
|
||||
// Use the specified quickfix/location list
|
||||
if (di->di_tv.v_type == VAR_NUMBER) {
|
||||
qf_idx = (int)di->di_tv.vval.v_number - 1;
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {
|
||||
return FAIL;
|
||||
// for zero use the current list
|
||||
if (di->di_tv.vval.v_number != 0) {
|
||||
qf_idx = (int)di->di_tv.vval.v_number - 1;
|
||||
if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
flags |= QF_GETLIST_NR;
|
||||
} else {
|
||||
|
@ -87,9 +87,17 @@ function Test_get_buf_options()
|
||||
endfunc
|
||||
|
||||
function Test_get_win_options()
|
||||
if has('folding')
|
||||
set foldlevel=999
|
||||
endif
|
||||
set list
|
||||
let opts = getwinvar(1, '&')
|
||||
call assert_equal(v:t_dict, type(opts))
|
||||
call assert_equal(0, opts.linebreak)
|
||||
call assert_equal(1, opts.list)
|
||||
if has('folding')
|
||||
call assert_equal(999, opts.foldlevel)
|
||||
endif
|
||||
if has('signs')
|
||||
call assert_equal('auto', opts.signcolumn)
|
||||
endif
|
||||
@ -97,7 +105,12 @@ function Test_get_win_options()
|
||||
let opts = gettabwinvar(1, 1, '&')
|
||||
call assert_equal(v:t_dict, type(opts))
|
||||
call assert_equal(0, opts.linebreak)
|
||||
call assert_equal(1, opts.list)
|
||||
if has('signs')
|
||||
call assert_equal('auto', opts.signcolumn)
|
||||
endif
|
||||
set list&
|
||||
if has('folding')
|
||||
set foldlevel=0
|
||||
endif
|
||||
endfunc
|
||||
|
@ -418,6 +418,9 @@ func Test_function_with_funcref()
|
||||
let s:fref = function(s:f)
|
||||
call assert_equal(v:t_string, s:fref('x'))
|
||||
call assert_fails("call function('s:f')", 'E700:')
|
||||
|
||||
call assert_fails("call function('foo()')", 'E475:')
|
||||
call assert_fails("call function('foo()')", 'foo()')
|
||||
endfunc
|
||||
|
||||
func Test_funcref()
|
||||
|
@ -1,32 +1,42 @@
|
||||
"Tests for nested functions
|
||||
"
|
||||
function! NestedFunc()
|
||||
fu! Func1()
|
||||
func NestedFunc()
|
||||
func! Func1()
|
||||
let g:text .= 'Func1 '
|
||||
endfunction
|
||||
endfunc
|
||||
call Func1()
|
||||
fu! s:func2()
|
||||
func! s:func2()
|
||||
let g:text .= 's:func2 '
|
||||
endfunction
|
||||
endfunc
|
||||
call s:func2()
|
||||
fu! s:_func3()
|
||||
func! s:_func3()
|
||||
let g:text .= 's:_func3 '
|
||||
endfunction
|
||||
endfunc
|
||||
call s:_func3()
|
||||
let fn = 'Func4'
|
||||
fu! {fn}()
|
||||
func! {fn}()
|
||||
let g:text .= 'Func4 '
|
||||
endfunction
|
||||
endfunc
|
||||
call {fn}()
|
||||
let fn = 'func5'
|
||||
fu! s:{fn}()
|
||||
func! s:{fn}()
|
||||
let g:text .= 's:func5'
|
||||
endfunction
|
||||
endfunc
|
||||
call s:{fn}()
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Test_nested_functions()
|
||||
func Test_nested_functions()
|
||||
let g:text = ''
|
||||
call NestedFunc()
|
||||
call assert_equal('Func1 s:func2 s:_func3 Func4 s:func5', g:text)
|
||||
endfunction
|
||||
|
||||
func Test_nested_argument()
|
||||
func g:X()
|
||||
let g:Y = function('sort')
|
||||
endfunc
|
||||
let g:Y = function('sort')
|
||||
echo g:Y([], g:X())
|
||||
delfunc g:X
|
||||
unlet g:Y
|
||||
endfunc
|
||||
|
@ -6,7 +6,7 @@ endif
|
||||
|
||||
set encoding=utf-8
|
||||
|
||||
function! s:setup_commands(cchar)
|
||||
func s:setup_commands(cchar)
|
||||
if a:cchar == 'c'
|
||||
command! -nargs=* -bang Xlist <mods>clist<bang> <args>
|
||||
command! -nargs=* Xgetexpr <mods>cgetexpr <args>
|
||||
@ -68,10 +68,10 @@ function! s:setup_commands(cchar)
|
||||
let g:Xgetlist = function('getloclist', [0])
|
||||
let g:Xsetlist = function('setloclist', [0])
|
||||
endif
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the :clist and :llist commands
|
||||
function XlistTests(cchar)
|
||||
func XlistTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" With an empty list, command should return error
|
||||
@ -128,17 +128,17 @@ function XlistTests(cchar)
|
||||
let l = split(result, "\n")
|
||||
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
|
||||
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_clist()
|
||||
func Test_clist()
|
||||
call XlistTests('c')
|
||||
call XlistTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the :colder, :cnewer, :lolder and :lnewer commands
|
||||
" Note that this test assumes that a quickfix/location list is
|
||||
" already set by the caller.
|
||||
function XageTests(cchar)
|
||||
func XageTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" Jumping to a non existent list should return error
|
||||
@ -171,20 +171,20 @@ function XageTests(cchar)
|
||||
Xnewer 2
|
||||
let l = g:Xgetlist()
|
||||
call assert_equal('Line3', l[0].text)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_cage()
|
||||
func Test_cage()
|
||||
let list = [{'bufnr': 1, 'lnum': 1}]
|
||||
call setqflist(list)
|
||||
call XageTests('c')
|
||||
|
||||
call setloclist(0, list)
|
||||
call XageTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
|
||||
" commands
|
||||
function XwindowTests(cchar)
|
||||
func XwindowTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" Create a list with no valid entries
|
||||
@ -227,16 +227,16 @@ function XwindowTests(cchar)
|
||||
" Calling cwindow should close the quickfix window with no valid errors
|
||||
Xwindow
|
||||
call assert_true(winnr('$') == 1)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_cwindow()
|
||||
func Test_cwindow()
|
||||
call XwindowTests('c')
|
||||
call XwindowTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
|
||||
" commands.
|
||||
function XfileTests(cchar)
|
||||
func XfileTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call writefile(['Xtestfile1:700:10:Line 700',
|
||||
@ -275,16 +275,16 @@ function XfileTests(cchar)
|
||||
\ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
|
||||
|
||||
call delete('Xqftestfile1')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_cfile()
|
||||
func Test_cfile()
|
||||
call XfileTests('c')
|
||||
call XfileTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
|
||||
" :lgetbuffer commands.
|
||||
function XbufferTests(cchar)
|
||||
func XbufferTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
enew!
|
||||
@ -316,26 +316,26 @@ function XbufferTests(cchar)
|
||||
\ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
|
||||
enew!
|
||||
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_cbuffer()
|
||||
func Test_cbuffer()
|
||||
call XbufferTests('c')
|
||||
call XbufferTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function XexprTests(cchar)
|
||||
func XexprTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call assert_fails('Xexpr 10', 'E777:')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_cexpr()
|
||||
func Test_cexpr()
|
||||
call XexprTests('c')
|
||||
call XexprTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for :cnext, :cprev, :cfirst, :clast commands
|
||||
function Xtest_browse(cchar)
|
||||
func Xtest_browse(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call s:create_test_file('Xqftestfile1')
|
||||
@ -366,14 +366,14 @@ function Xtest_browse(cchar)
|
||||
|
||||
call delete('Xqftestfile1')
|
||||
call delete('Xqftestfile2')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_browse()
|
||||
func Test_browse()
|
||||
call Xtest_browse('c')
|
||||
call Xtest_browse('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! s:test_xhelpgrep(cchar)
|
||||
func s:test_xhelpgrep(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
Xhelpgrep quickfix
|
||||
Xopen
|
||||
@ -385,9 +385,9 @@ function! s:test_xhelpgrep(cchar)
|
||||
call assert_true(w:quickfix_title =~ title_text, w:quickfix_title)
|
||||
" This wipes out the buffer, make sure that doesn't cause trouble.
|
||||
Xclose
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_helpgrep()
|
||||
func Test_helpgrep()
|
||||
call s:test_xhelpgrep('c')
|
||||
helpclose
|
||||
call s:test_xhelpgrep('l')
|
||||
@ -425,7 +425,7 @@ func Test_vimgreptitle()
|
||||
augroup! QfBufWinEnter
|
||||
endfunc
|
||||
|
||||
function XqfTitleTests(cchar)
|
||||
func XqfTitleTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
Xgetexpr ['file:1:1:message']
|
||||
@ -444,16 +444,16 @@ function XqfTitleTests(cchar)
|
||||
endif
|
||||
call assert_equal(title, w:quickfix_title)
|
||||
Xclose
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for quickfix window's title
|
||||
function Test_qf_title()
|
||||
func Test_qf_title()
|
||||
call XqfTitleTests('c')
|
||||
call XqfTitleTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for 'errorformat'
|
||||
function Test_efm()
|
||||
func Test_efm()
|
||||
let save_efm = &efm
|
||||
set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
|
||||
cgetexpr ['WWWW', 'EEEE', 'CCCC']
|
||||
@ -466,7 +466,7 @@ function Test_efm()
|
||||
let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
|
||||
call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
|
||||
let &efm = save_efm
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" This will test for problems in quickfix:
|
||||
" A. incorrectly copying location lists which caused the location list to show
|
||||
@ -477,7 +477,7 @@ endfunction
|
||||
" window it belongs to.
|
||||
"
|
||||
" Set up the test environment:
|
||||
function! ReadTestProtocol(name)
|
||||
func ReadTestProtocol(name)
|
||||
let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
|
||||
let word = substitute(base, '\v(.*)\..*', '\1', '')
|
||||
|
||||
@ -496,9 +496,9 @@ function! ReadTestProtocol(name)
|
||||
setl nomodifiable
|
||||
setl readonly
|
||||
exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_locationlist()
|
||||
func Test_locationlist()
|
||||
enew
|
||||
|
||||
augroup testgroup
|
||||
@ -578,15 +578,15 @@ function Test_locationlist()
|
||||
wincmd n | only
|
||||
|
||||
augroup! testgroup
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_locationlist_curwin_was_closed()
|
||||
func Test_locationlist_curwin_was_closed()
|
||||
augroup testgroup
|
||||
au!
|
||||
autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
|
||||
augroup END
|
||||
|
||||
function! R(n)
|
||||
func! R(n)
|
||||
quit
|
||||
endfunc
|
||||
|
||||
@ -597,9 +597,9 @@ function Test_locationlist_curwin_was_closed()
|
||||
call assert_fails('lrewind', 'E924:')
|
||||
|
||||
augroup! testgroup
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_locationlist_cross_tab_jump()
|
||||
func Test_locationlist_cross_tab_jump()
|
||||
call writefile(['loclistfoo'], 'loclistfoo')
|
||||
call writefile(['loclistbar'], 'loclistbar')
|
||||
set switchbuf=usetab
|
||||
@ -613,10 +613,10 @@ function Test_locationlist_cross_tab_jump()
|
||||
set switchbuf&vim
|
||||
call delete('loclistfoo')
|
||||
call delete('loclistbar')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" More tests for 'errorformat'
|
||||
function! Test_efm1()
|
||||
func Test_efm1()
|
||||
if !has('unix')
|
||||
" The 'errorformat' setting is different on non-Unix systems.
|
||||
" This test works only on Unix-like systems.
|
||||
@ -734,10 +734,10 @@ function! Test_efm1()
|
||||
call delete('Xerrorfile1')
|
||||
call delete('Xerrorfile2')
|
||||
call delete('Xtestfile')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Test for quickfix directory stack support
|
||||
function! s:dir_stack_tests(cchar)
|
||||
func s:dir_stack_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
let save_efm=&efm
|
||||
@ -779,10 +779,10 @@ function! s:dir_stack_tests(cchar)
|
||||
call assert_equal(5, qf[11].lnum)
|
||||
|
||||
let &efm=save_efm
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for %D and %X errorformat options
|
||||
function! Test_efm_dirstack()
|
||||
func Test_efm_dirstack()
|
||||
" Create the directory stack and files
|
||||
call mkdir('dir1')
|
||||
call mkdir('dir1/a')
|
||||
@ -814,10 +814,33 @@ function! Test_efm_dirstack()
|
||||
call delete('dir1', 'rf')
|
||||
call delete('dir2', 'rf')
|
||||
call delete('habits1.txt')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Test for resync after continuing an ignored message
|
||||
func Xefm_ignore_continuations(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
let save_efm = &efm
|
||||
|
||||
let &efm =
|
||||
\ '%Eerror %m %l,' .
|
||||
\ '%-Wignored %m %l,' .
|
||||
\ '%+Cmore ignored %m %l,' .
|
||||
\ '%Zignored end'
|
||||
Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
|
||||
let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
|
||||
call assert_equal([['resync', 1, 4, 'E']], l)
|
||||
|
||||
let &efm = save_efm
|
||||
endfunc
|
||||
|
||||
func Test_efm_ignore_continuations()
|
||||
call Xefm_ignore_continuations('c')
|
||||
call Xefm_ignore_continuations('l')
|
||||
endfunc
|
||||
|
||||
" Tests for invalid error format specifies
|
||||
function Xinvalid_efm_Tests(cchar)
|
||||
func Xinvalid_efm_Tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
let save_efm = &efm
|
||||
@ -850,17 +873,17 @@ function Xinvalid_efm_Tests(cchar)
|
||||
call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
|
||||
|
||||
let &efm = save_efm
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_invalid_efm()
|
||||
func Test_invalid_efm()
|
||||
call Xinvalid_efm_Tests('c')
|
||||
call Xinvalid_efm_Tests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" TODO:
|
||||
" Add tests for the following formats in 'errorformat'
|
||||
" %r %O
|
||||
function! Test_efm2()
|
||||
func Test_efm2()
|
||||
let save_efm = &efm
|
||||
|
||||
" Test for %s format in efm
|
||||
@ -946,19 +969,19 @@ function! Test_efm2()
|
||||
call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
|
||||
|
||||
let &efm = save_efm
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function XquickfixChangedByAutocmd(cchar)
|
||||
func XquickfixChangedByAutocmd(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
if a:cchar == 'c'
|
||||
let ErrorNr = 'E925'
|
||||
function! ReadFunc()
|
||||
func! ReadFunc()
|
||||
colder
|
||||
cgetexpr []
|
||||
endfunc
|
||||
else
|
||||
let ErrorNr = 'E926'
|
||||
function! ReadFunc()
|
||||
func! ReadFunc()
|
||||
lolder
|
||||
lgetexpr []
|
||||
endfunc
|
||||
@ -981,10 +1004,10 @@ function XquickfixChangedByAutocmd(cchar)
|
||||
augroup! testgroup
|
||||
endfunc
|
||||
|
||||
function Test_quickfix_was_changed_by_autocmd()
|
||||
func Test_quickfix_was_changed_by_autocmd()
|
||||
call XquickfixChangedByAutocmd('c')
|
||||
call XquickfixChangedByAutocmd('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
func Test_caddbuffer_to_empty()
|
||||
helpgr quickfix
|
||||
@ -1006,7 +1029,7 @@ func Test_cgetexpr_works()
|
||||
endfunc
|
||||
|
||||
" Tests for the setqflist() and setloclist() functions
|
||||
function SetXlistTests(cchar, bnum)
|
||||
func SetXlistTests(cchar, bnum)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
|
||||
@ -1041,9 +1064,9 @@ function SetXlistTests(cchar, bnum)
|
||||
call g:Xsetlist([])
|
||||
let l = g:Xgetlist()
|
||||
call assert_equal(0, len(l))
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_setqflist()
|
||||
func Test_setqflist()
|
||||
new Xtestfile | only
|
||||
let bnum = bufnr('%')
|
||||
call setline(1, range(1,5))
|
||||
@ -1053,9 +1076,9 @@ function Test_setqflist()
|
||||
|
||||
enew!
|
||||
call delete('Xtestfile')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Xlist_empty_middle(cchar)
|
||||
func Xlist_empty_middle(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" create three quickfix lists
|
||||
@ -1078,12 +1101,12 @@ function Xlist_empty_middle(cchar)
|
||||
call assert_equal(matchlen, len(g:Xgetlist()))
|
||||
endfunc
|
||||
|
||||
function Test_setqflist_empty_middle()
|
||||
func Test_setqflist_empty_middle()
|
||||
call Xlist_empty_middle('c')
|
||||
call Xlist_empty_middle('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Xlist_empty_older(cchar)
|
||||
func Xlist_empty_older(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" create three quickfix lists
|
||||
@ -1104,14 +1127,14 @@ function Xlist_empty_older(cchar)
|
||||
call assert_equal(twolen, len(g:Xgetlist()))
|
||||
Xnewer
|
||||
call assert_equal(threelen, len(g:Xgetlist()))
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_setqflist_empty_older()
|
||||
func Test_setqflist_empty_older()
|
||||
call Xlist_empty_older('c')
|
||||
call Xlist_empty_older('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! XquickfixSetListWithAct(cchar)
|
||||
func XquickfixSetListWithAct(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
let list1 = [{'filename': 'fnameA', 'text': 'A'},
|
||||
@ -1185,12 +1208,12 @@ function! XquickfixSetListWithAct(cchar)
|
||||
call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
|
||||
endfunc
|
||||
|
||||
function Test_quickfix_set_list_with_act()
|
||||
func Test_quickfix_set_list_with_act()
|
||||
call XquickfixSetListWithAct('c')
|
||||
call XquickfixSetListWithAct('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function XLongLinesTests(cchar)
|
||||
func XLongLinesTests(cchar)
|
||||
let l = g:Xgetlist()
|
||||
|
||||
call assert_equal(4, len(l))
|
||||
@ -1208,9 +1231,9 @@ function XLongLinesTests(cchar)
|
||||
call assert_equal(10, len(l[3].text))
|
||||
|
||||
call g:Xsetlist([], 'r')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function s:long_lines_tests(cchar)
|
||||
func s:long_lines_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
let testfile = 'samples/quickfix.txt'
|
||||
@ -1231,22 +1254,22 @@ function s:long_lines_tests(cchar)
|
||||
exe 'edit' testfile
|
||||
exe 'Xbuffer' bufnr('%')
|
||||
call XLongLinesTests(a:cchar)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_long_lines()
|
||||
func Test_long_lines()
|
||||
call s:long_lines_tests('c')
|
||||
call s:long_lines_tests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! s:create_test_file(filename)
|
||||
func s:create_test_file(filename)
|
||||
let l = []
|
||||
for i in range(1, 20)
|
||||
call add(l, 'Line' . i)
|
||||
endfor
|
||||
call writefile(l, a:filename)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Test_switchbuf()
|
||||
func Test_switchbuf()
|
||||
call s:create_test_file('Xqftestfile1')
|
||||
call s:create_test_file('Xqftestfile2')
|
||||
call s:create_test_file('Xqftestfile3')
|
||||
@ -1333,9 +1356,9 @@ function! Test_switchbuf()
|
||||
call delete('Xqftestfile1')
|
||||
call delete('Xqftestfile2')
|
||||
call delete('Xqftestfile3')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Xadjust_qflnum(cchar)
|
||||
func Xadjust_qflnum(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
enew | only
|
||||
@ -1360,17 +1383,17 @@ function! Xadjust_qflnum(cchar)
|
||||
|
||||
enew!
|
||||
call delete(fname)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Test_adjust_lnum()
|
||||
func Test_adjust_lnum()
|
||||
call setloclist(0, [])
|
||||
call Xadjust_qflnum('c')
|
||||
call setqflist([])
|
||||
call Xadjust_qflnum('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
|
||||
function! s:test_xgrep(cchar)
|
||||
func s:test_xgrep(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" The following lines are used for the grep test. Don't remove.
|
||||
@ -1389,9 +1412,9 @@ function! s:test_xgrep(cchar)
|
||||
set makeef=Temp_File_##
|
||||
silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
|
||||
call assert_true(len(g:Xgetlist()) == 6)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Test_grep()
|
||||
func Test_grep()
|
||||
if !has('unix')
|
||||
" The grepprg may not be set on non-Unix systems
|
||||
return
|
||||
@ -1399,9 +1422,9 @@ function! Test_grep()
|
||||
|
||||
call s:test_xgrep('c')
|
||||
call s:test_xgrep('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Test_two_windows()
|
||||
func Test_two_windows()
|
||||
" Use one 'errorformat' for two windows. Add an expression to each of them,
|
||||
" make sure they each keep their own state.
|
||||
set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
|
||||
@ -1427,12 +1450,10 @@ function! Test_two_windows()
|
||||
laddexpr 'one.txt:3:one one one'
|
||||
|
||||
let loc_one = getloclist(one_id)
|
||||
echo string(loc_one)
|
||||
call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
|
||||
call assert_equal(3, loc_one[1].lnum)
|
||||
|
||||
let loc_two = getloclist(two_id)
|
||||
echo string(loc_two)
|
||||
call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
|
||||
call assert_equal(5, loc_two[1].lnum)
|
||||
|
||||
@ -1444,7 +1465,7 @@ echo string(loc_two)
|
||||
call delete('Xtwo', 'rf')
|
||||
endfunc
|
||||
|
||||
function XbottomTests(cchar)
|
||||
func XbottomTests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
|
||||
@ -1460,12 +1481,12 @@ function XbottomTests(cchar)
|
||||
endfunc
|
||||
|
||||
" Tests for the :cbottom and :lbottom commands
|
||||
function Test_cbottom()
|
||||
func Test_cbottom()
|
||||
call XbottomTests('c')
|
||||
call XbottomTests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function HistoryTest(cchar)
|
||||
func HistoryTest(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
call assert_fails(a:cchar . 'older 99', 'E380:')
|
||||
@ -1505,7 +1526,7 @@ func Test_duplicate_buf()
|
||||
endfunc
|
||||
|
||||
" Quickfix/Location list set/get properties tests
|
||||
function Xproperty_tests(cchar)
|
||||
func Xproperty_tests(cchar)
|
||||
call s:setup_commands(a:cchar)
|
||||
|
||||
" Error cases
|
||||
@ -1532,6 +1553,11 @@ function Xproperty_tests(cchar)
|
||||
call assert_equal('N1', g:Xgetlist({'all':1}).title)
|
||||
call g:Xsetlist([], ' ', {'title' : 'N2'})
|
||||
call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
|
||||
|
||||
let res = g:Xgetlist({'nr': 0})
|
||||
call assert_equal(qfnr + 1, res.nr)
|
||||
call assert_equal(['nr'], keys(res))
|
||||
|
||||
call g:Xsetlist([], ' ', {'title' : 'N3'})
|
||||
call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
|
||||
|
||||
@ -1544,21 +1570,21 @@ function Xproperty_tests(cchar)
|
||||
call assert_equal({}, g:Xgetlist({'abc':1}))
|
||||
|
||||
if a:cchar == 'l'
|
||||
call assert_equal({}, getloclist(99, ['title']))
|
||||
call assert_equal({}, getloclist(99, {'title': 1}))
|
||||
endif
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_qf_property()
|
||||
func Test_qf_property()
|
||||
call Xproperty_tests('c')
|
||||
call Xproperty_tests('l')
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
|
||||
function QfAutoCmdHandler(loc, cmd)
|
||||
func QfAutoCmdHandler(loc, cmd)
|
||||
call add(g:acmds, a:loc . a:cmd)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function Test_Autocmd()
|
||||
func Test_Autocmd()
|
||||
autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
|
||||
autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
|
||||
|
||||
@ -1586,9 +1612,9 @@ function Test_Autocmd()
|
||||
\ 'precaddbuffer',
|
||||
\ 'postcaddbuffer']
|
||||
call assert_equal(l, g:acmds)
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
function! Test_Autocmd_Exception()
|
||||
func Test_Autocmd_Exception()
|
||||
set efm=%m
|
||||
lgetexpr '?'
|
||||
|
||||
@ -1603,4 +1629,47 @@ function! Test_Autocmd_Exception()
|
||||
call assert_equal('1', getloclist(0)[0].text)
|
||||
|
||||
set efm&vim
|
||||
endfunction
|
||||
endfunc
|
||||
|
||||
func Test_caddbuffer_wrong()
|
||||
" This used to cause a memory access in freed memory.
|
||||
let save_efm = &efm
|
||||
set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
|
||||
cgetexpr ['WWWW', 'EEEE', 'CCCC']
|
||||
let &efm = save_efm
|
||||
caddbuffer
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_caddexpr_wrong()
|
||||
" This used to cause a memory access in freed memory.
|
||||
cbuffer
|
||||
cbuffer
|
||||
copen
|
||||
let save_efm = &efm
|
||||
set efm=%
|
||||
call assert_fails('caddexpr ""', 'E376:')
|
||||
let &efm = save_efm
|
||||
endfunc
|
||||
|
||||
func Test_dirstack_cleanup()
|
||||
" This used to cause a memory access in freed memory.
|
||||
let save_efm = &efm
|
||||
lexpr '0'
|
||||
lopen
|
||||
fun X(c)
|
||||
let save_efm=&efm
|
||||
set efm=%D%f
|
||||
if a:c == 'c'
|
||||
caddexpr '::'
|
||||
else
|
||||
laddexpr ':0:0'
|
||||
endif
|
||||
let &efm=save_efm
|
||||
endfun
|
||||
call X('c')
|
||||
call X('l')
|
||||
call setqflist([], 'r')
|
||||
caddbuffer
|
||||
let &efm = save_efm
|
||||
endfunc
|
||||
|
2832
src/nvim/version.c
2832
src/nvim/version.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user