Use the same version as the current macvim
This commit is contained in:
parent
de3c513b24
commit
d458d06bc5
12 changed files with 733 additions and 4 deletions
|
|
@ -27,14 +27,17 @@ endfunction
|
||||||
|
|
||||||
function! s:_OnServerError( channel, data ) abort
|
function! s:_OnServerError( channel, data ) abort
|
||||||
echom 'Channel received error: ' . a:data
|
echom 'Channel received error: ' . a:data
|
||||||
|
redraw
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:_OnExit( channel, status ) abort
|
function! s:_OnExit( channel, status ) abort
|
||||||
echom 'Channel exit with status ' . a:status
|
echom 'Channel exit with status ' . a:status
|
||||||
|
redraw
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:_OnClose( channel ) abort
|
function! s:_OnClose( channel ) abort
|
||||||
echom 'Channel closed'
|
echom 'Channel closed'
|
||||||
|
redraw
|
||||||
" py3 _vimspector_session.OnChannelClosed()
|
" py3 _vimspector_session.OnChannelClosed()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
@ -68,6 +71,7 @@ function! vimspector#internal#channel#StartDebugSession( config ) abort
|
||||||
|
|
||||||
if ch_status( s:ch ) !=# 'open'
|
if ch_status( s:ch ) !=# 'open'
|
||||||
echom 'Unable to connect to debug adapter'
|
echom 'Unable to connect to debug adapter'
|
||||||
|
redraw
|
||||||
return v:none
|
return v:none
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,28 +29,33 @@ endfunction
|
||||||
|
|
||||||
function! s:_OnExit( channel, status ) abort
|
function! s:_OnExit( channel, status ) abort
|
||||||
echom 'Channel exit with status ' . a:status
|
echom 'Channel exit with status ' . a:status
|
||||||
|
redraw
|
||||||
unlet s:job
|
unlet s:job
|
||||||
py3 _vimspector_session.OnServerExit( vim.eval( 'a:status' ) )
|
py3 _vimspector_session.OnServerExit( vim.eval( 'a:status' ) )
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:_OnClose( channel ) abort
|
function! s:_OnClose( channel ) abort
|
||||||
echom 'Channel closed'
|
echom 'Channel closed'
|
||||||
|
redraw
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:_Send( msg ) abort
|
function! s:_Send( msg ) abort
|
||||||
if ! exists( 's:job' )
|
if ! exists( 's:job' )
|
||||||
echom "Can't send message: Job was not initialised correctly"
|
echom "Can't send message: Job was not initialised correctly"
|
||||||
|
redraw
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if job_status( s:job ) !=# 'run'
|
if job_status( s:job ) !=# 'run'
|
||||||
echom "Can't send message: Job is not running"
|
echom "Can't send message: Job is not running"
|
||||||
|
redraw
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let ch = job_getchannel( s:job )
|
let ch = job_getchannel( s:job )
|
||||||
if ch ==# 'channel fail'
|
if ch ==# 'channel fail'
|
||||||
echom 'Channel was closed unexpectedly!'
|
echom 'Channel was closed unexpectedly!'
|
||||||
|
redraw
|
||||||
return 0
|
return 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
@ -61,6 +66,7 @@ endfunction
|
||||||
function! vimspector#internal#job#StartDebugSession( config ) abort
|
function! vimspector#internal#job#StartDebugSession( config ) abort
|
||||||
if exists( 's:job' )
|
if exists( 's:job' )
|
||||||
echom 'Not starging: Job is already running'
|
echom 'Not starging: Job is already running'
|
||||||
|
redraw
|
||||||
return v:none
|
return v:none
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
@ -80,9 +86,11 @@ function! vimspector#internal#job#StartDebugSession( config ) abort
|
||||||
\ )
|
\ )
|
||||||
|
|
||||||
echom 'Started job, status is: ' . job_status( s:job )
|
echom 'Started job, status is: ' . job_status( s:job )
|
||||||
|
redraw
|
||||||
|
|
||||||
if job_status( s:job ) !=# 'run'
|
if job_status( s:job ) !=# 'run'
|
||||||
echom 'Unable to start job, status is: ' . job_status( s:job )
|
echom 'Unable to start job, status is: ' . job_status( s:job )
|
||||||
|
redraw
|
||||||
return v:none
|
return v:none
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
@ -92,11 +100,13 @@ endfunction
|
||||||
function! vimspector#internal#job#StopDebugSession() abort
|
function! vimspector#internal#job#StopDebugSession() abort
|
||||||
if !exists( 's:job' )
|
if !exists( 's:job' )
|
||||||
echom "Not stopping session: Job doesn't exist"
|
echom "Not stopping session: Job doesn't exist"
|
||||||
|
redraw
|
||||||
return
|
return
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if job_status( s:job ) ==# 'run'
|
if job_status( s:job ) ==# 'run'
|
||||||
echom 'Terminating job'
|
echom 'Terminating job'
|
||||||
|
redraw
|
||||||
call job_stop( s:job, 'kill' )
|
call job_stop( s:job, 'kill' )
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
@ -140,6 +150,7 @@ function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort
|
||||||
|
|
||||||
if job_status( s:commands[ a:category ][ index ] ) !=# 'run'
|
if job_status( s:commands[ a:category ][ index ] ) !=# 'run'
|
||||||
echom 'Unable to start job for ' . a:cmd
|
echom 'Unable to start job for ' . a:cmd
|
||||||
|
redraw
|
||||||
return v:none
|
return v:none
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
115
compiler/vimspector_test.vim
Normal file
115
compiler/vimspector_test.vim
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
" vimspector - A multi-language debugging system for Vim
|
||||||
|
" Copyright 2018 Ben Jackson
|
||||||
|
"
|
||||||
|
" Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
" you may not use this file except in compliance with the License.
|
||||||
|
" You may obtain a copy of the License at
|
||||||
|
"
|
||||||
|
" http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
"
|
||||||
|
" Unless required by applicable law or agreed to in writing, software
|
||||||
|
" distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
" See the License for the specific language governing permissions and
|
||||||
|
" limitations under the License.
|
||||||
|
|
||||||
|
" Compiler plugin to help running vimspector tests
|
||||||
|
|
||||||
|
if exists("current_compiler")
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
let current_compiler = "vimspector_test"
|
||||||
|
|
||||||
|
setlocal errorformat=
|
||||||
|
\Found\ errors\ in\ %f:%.%#:
|
||||||
|
|
||||||
|
let &l:makeprg=fnamemodify( findfile( 'run_tests', '.;' ), ':p' )
|
||||||
|
\ . ' $* 2>&1'
|
||||||
|
|
||||||
|
let s:make_cmd = get( g:, 'vimspector_test_make_cmd', 'Make' )
|
||||||
|
|
||||||
|
" If :Make doesn't exist, then use :make
|
||||||
|
if ! exists( ':' . s:make_cmd )
|
||||||
|
let s:make_cmd = 'make'
|
||||||
|
endif
|
||||||
|
|
||||||
|
function! VimGetCurrentFunction()
|
||||||
|
echom s:GetCurrentFunction()
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:GetCurrentFunction()
|
||||||
|
" Store the cursor position; we'll need to reset it
|
||||||
|
let [ l:buf, l:row, l:col, l:offset ] = getpos( '.' )
|
||||||
|
|
||||||
|
let l:test_function = ''
|
||||||
|
|
||||||
|
let l:pattern = '\V\C\s\*function!\?\s\+\(\<\w\+\>\)\.\*\$'
|
||||||
|
|
||||||
|
let l:lnum = prevnonblank( '.' )
|
||||||
|
|
||||||
|
" Find the top-level method and class
|
||||||
|
while l:lnum > 0
|
||||||
|
call cursor( l:lnum, 1 )
|
||||||
|
let l:lnum = search( l:pattern, 'bcnWz' )
|
||||||
|
|
||||||
|
if l:lnum <= 0
|
||||||
|
call cursor( l:row, l:col )
|
||||||
|
return l:test_function
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:this_decl = substitute( getline( l:lnum ), l:pattern, '\1', '' )
|
||||||
|
let l:this_decl_is_test = match( l:this_decl, '\V\C\^Test_' ) >= 0
|
||||||
|
|
||||||
|
if l:this_decl_is_test
|
||||||
|
let l:test_function = l:this_decl
|
||||||
|
|
||||||
|
if indent( l:lnum ) == 0
|
||||||
|
call cursor( l:row, l:col )
|
||||||
|
return l:test_function
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:lnum = prevnonblank( l:lnum - 1 )
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:RunTestUnderCursor()
|
||||||
|
update
|
||||||
|
let l:test_func_name = s:GetCurrentFunction()
|
||||||
|
|
||||||
|
if l:test_func_name ==# ''
|
||||||
|
echo "No test method found"
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
echo "Running test '" . l:test_func_name . "'"
|
||||||
|
|
||||||
|
let l:test_arg = expand( '%:p:t' ) . ':' . l:test_func_name
|
||||||
|
execute s:make_cmd . ' ' . l:test_arg
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:RunTest()
|
||||||
|
update
|
||||||
|
execute s:make_cmd . ' %:p:t'
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:RunAllTests()
|
||||||
|
update
|
||||||
|
execute s:make_cmd
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
if ! has( 'gui_running' )
|
||||||
|
" ® is right-option+r
|
||||||
|
nnoremap <buffer> ® :call <SID>RunTest()<CR>
|
||||||
|
" ® is right-option+r
|
||||||
|
nnoremap <buffer> Â :call <SID>RunAllTests()<CR>
|
||||||
|
" † is right-option+t
|
||||||
|
nnoremap <buffer> † :call <SID>RunTestUnderCursor()<CR>
|
||||||
|
" å is the right-option+q
|
||||||
|
nnoremap <buffer> å :cfirst<CR>
|
||||||
|
" å is the right-option+a
|
||||||
|
nnoremap <buffer> œ :cnext<CR>
|
||||||
|
" Ω is the right-option+z
|
||||||
|
nnoremap <buffer> Ω :cprevious<CR>
|
||||||
|
endif
|
||||||
|
|
@ -70,7 +70,8 @@ class CodeView( object ):
|
||||||
frame[ 'source' ][ 'path' ] ) )
|
frame[ 'source' ][ 'path' ] ) )
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self._window.cursor = ( frame[ 'line' ], frame[ 'column' ] )
|
# SIC: column is 0-based, line is 1-based in vim. Why? Nobody knows.
|
||||||
|
self._window.cursor = ( frame[ 'line' ], frame[ 'column' ] - 1 )
|
||||||
|
|
||||||
self._signs[ 'vimspectorPC' ] = self._next_sign_id
|
self._signs[ 'vimspectorPC' ] = self._next_sign_id
|
||||||
self._next_sign_id += 1
|
self._next_sign_id += 1
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,7 @@ def UserMessage( msg, persist=False ):
|
||||||
cmd = 'echom' if persist else 'echo'
|
cmd = 'echom' if persist else 'echo'
|
||||||
for line in msg.split( '\n' ):
|
for line in msg.split( '\n' ):
|
||||||
vim.command( "{0} '{1}'".format( cmd, Escape( line ) ) )
|
vim.command( "{0} '{1}'".format( cmd, Escape( line ) ) )
|
||||||
|
vim.command( 'redraw' )
|
||||||
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
@contextlib.contextmanager
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
RUN_VIM="vim --clean --not-a-term"
|
RUN_VIM="vim --clean --not-a-term"
|
||||||
RUN_TEST="${RUN_VIM} -S run_test.vim"
|
RUN_TEST="${RUN_VIM} -S lib/run_test.vim"
|
||||||
|
|
||||||
if [ -z "$VIMSPECTOR_MIMODE" ]; then
|
if [ -z "$VIMSPECTOR_MIMODE" ]; then
|
||||||
if which -s lldb; then
|
if which -s lldb; then
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
source lib/shared.vim
|
||||||
|
|
||||||
function! SetUp()
|
function! SetUp()
|
||||||
if exists ( 'g:loaded_vimpector' )
|
if exists ( 'g:loaded_vimpector' )
|
||||||
unlet g:loaded_vimpector
|
unlet g:loaded_vimpector
|
||||||
|
|
@ -160,6 +162,63 @@ function! Test_Use_Mappings_HUMAN()
|
||||||
let cur_tabnr = tabpagenr()
|
let cur_tabnr = tabpagenr()
|
||||||
call assert_equal( 5, len( gettabinfo( cur_tabnr )[ 0 ].windows ) )
|
call assert_equal( 5, len( gettabinfo( cur_tabnr )[ 0 ].windows ) )
|
||||||
|
|
||||||
|
call WaitForAssert( {->
|
||||||
|
\ assert_equal( 'simple.cpp', bufname( '%' ), 'Current buffer' )
|
||||||
|
\ } )
|
||||||
|
call assert_equal( 15, line( '.' ), 'Current line' )
|
||||||
|
call assert_equal( 1, col( '.' ), 'Current column' )
|
||||||
|
|
||||||
|
let signs = sign_getplaced( '%', {
|
||||||
|
\ 'group': 'VimspectorCode',
|
||||||
|
\ } )
|
||||||
|
|
||||||
|
call assert_equal( 1, len( signs ), 'Sign-buffers' )
|
||||||
|
call assert_equal( 2, len( signs[ 0 ].signs ), 'Signs in buffer' )
|
||||||
|
|
||||||
|
let pc_index = -1
|
||||||
|
let index = 0
|
||||||
|
while index < len( signs[ 0 ].signs )
|
||||||
|
let s = signs[ 0 ].signs[ index ]
|
||||||
|
if s.name ==# 'vimspectorPC'
|
||||||
|
if pc_index >= 0
|
||||||
|
call assert_report( 'Found too many PC signs!' )
|
||||||
|
endif
|
||||||
|
let pc_index = index
|
||||||
|
endif
|
||||||
|
let index = index + 1
|
||||||
|
endwhile
|
||||||
|
call assert_true( pc_index >= 0 )
|
||||||
|
call assert_equal( 15, signs[ 0 ].signs[ pc_index ].lnum )
|
||||||
|
|
||||||
|
" Step
|
||||||
|
call feedkeys( "\<F10>", 'xt' )
|
||||||
|
|
||||||
|
call WaitForAssert( {-> assert_equal( 16, line( '.' ), 'Current line' ) } )
|
||||||
|
call assert_equal( 'simple.cpp', bufname( '%' ), 'Current buffer' )
|
||||||
|
call assert_equal( 1, col( '.' ), 'Current column' )
|
||||||
|
|
||||||
|
let signs = sign_getplaced( '%', {
|
||||||
|
\ 'group': 'VimspectorCode',
|
||||||
|
\ } )
|
||||||
|
|
||||||
|
call assert_equal( 1, len( signs ), 'Sign-buffers' )
|
||||||
|
call assert_equal( 2, len( signs[ 0 ].signs ), 'Signs in buffer' )
|
||||||
|
|
||||||
|
let pc_index = -1
|
||||||
|
let index = 0
|
||||||
|
while index < len( signs[ 0 ].signs )
|
||||||
|
let s = signs[ 0 ].signs[ index ]
|
||||||
|
if s.name ==# 'vimspectorPC'
|
||||||
|
if pc_index >= 0
|
||||||
|
call assert_report( 'Found too many PC signs!' )
|
||||||
|
endif
|
||||||
|
let pc_index = index
|
||||||
|
endif
|
||||||
|
let index = index + 1
|
||||||
|
endwhile
|
||||||
|
call assert_true( pc_index >= 0 )
|
||||||
|
call assert_equal( 16, signs[ 0 ].signs[ pc_index ].lnum )
|
||||||
|
|
||||||
call vimspector#Reset()
|
call vimspector#Reset()
|
||||||
|
|
||||||
call vimspector#ClearBreakpoints()
|
call vimspector#ClearBreakpoints()
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,17 @@ RUN apt-get update && \
|
||||||
RUN ln -fs /usr/share/zoneinfo/Europe/London /etc/localtime && \
|
RUN ln -fs /usr/share/zoneinfo/Europe/London /etc/localtime && \
|
||||||
dpkg-reconfigure --frontend noninteractive tzdata
|
dpkg-reconfigure --frontend noninteractive tzdata
|
||||||
|
|
||||||
|
ARG VIM_VERSION=v8.1.1270
|
||||||
|
|
||||||
RUN mkdir -p $HOME/vim && \
|
RUN mkdir -p $HOME/vim && \
|
||||||
cd $HOME/vim && \
|
cd $HOME/vim && \
|
||||||
git clone https://github.com/vim/vim && \
|
git clone https://github.com/vim/vim && \
|
||||||
cd vim && \
|
cd vim && \
|
||||||
git checkout v8.1.1302 && \
|
git checkout ${VIM_VERSION} && \
|
||||||
./configure --with-features=huge \
|
./configure --with-features=huge \
|
||||||
--enable-python3interp \
|
--enable-python3interp \
|
||||||
--enable-terminal \
|
--enable-terminal \
|
||||||
--enable-multibyte \
|
--enable-multibyte \
|
||||||
--enable-fail-if-missing && \
|
--enable-fail-if-missing && \
|
||||||
make -j 8 install
|
make -j 4 install
|
||||||
|
|
||||||
|
|
|
||||||
171
tests/lib/screendump.vim
Normal file
171
tests/lib/screendump.vim
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
" Functions shared by tests making screen dumps.
|
||||||
|
|
||||||
|
" Only load this script once.
|
||||||
|
if exists('*CanRunVimInTerminal')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
" For most tests we need to be able to run terminal Vim with 256 colors. On
|
||||||
|
" MS-Windows the console only has 16 colors and the GUI can't run in a
|
||||||
|
" terminal.
|
||||||
|
func CanRunVimInTerminal()
|
||||||
|
return has('terminal') && !has('win32')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Skip the rest if there is no terminal feature at all.
|
||||||
|
if !has('terminal')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
source lib/shared.vim
|
||||||
|
|
||||||
|
" Run Vim with "arguments" in a new terminal window.
|
||||||
|
" By default uses a size of 20 lines and 75 columns.
|
||||||
|
" Returns the buffer number of the terminal.
|
||||||
|
"
|
||||||
|
" Options is a dictionary, these items are recognized:
|
||||||
|
" "rows" - height of the terminal window (max. 20)
|
||||||
|
" "cols" - width of the terminal window (max. 78)
|
||||||
|
" "statusoff" - number of lines the status is offset from default
|
||||||
|
func RunVimInTerminal(arguments, options)
|
||||||
|
" If Vim doesn't exit a swap file remains, causing other tests to fail.
|
||||||
|
" Remove it here.
|
||||||
|
call delete(".swp")
|
||||||
|
|
||||||
|
if exists('$COLORFGBG')
|
||||||
|
" Clear $COLORFGBG to avoid 'background' being set to "dark", which will
|
||||||
|
" only be corrected if the response to t_RB is received, which may be too
|
||||||
|
" late.
|
||||||
|
let $COLORFGBG = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Make a horizontal and vertical split, so that we can get exactly the right
|
||||||
|
" size terminal window. Works only when the current window is full width.
|
||||||
|
call assert_equal(&columns, winwidth(0))
|
||||||
|
split
|
||||||
|
vsplit
|
||||||
|
|
||||||
|
" Always do this with 256 colors and a light background.
|
||||||
|
set t_Co=256 background=light
|
||||||
|
hi Normal ctermfg=NONE ctermbg=NONE
|
||||||
|
|
||||||
|
" Make the window 20 lines high and 75 columns, unless told otherwise.
|
||||||
|
let rows = get(a:options, 'rows', 20)
|
||||||
|
let cols = get(a:options, 'cols', 75)
|
||||||
|
let statusoff = get(a:options, 'statusoff', 1)
|
||||||
|
|
||||||
|
let cmd = GetVimCommandClean()
|
||||||
|
|
||||||
|
" Add -v to have gvim run in the terminal (if possible)
|
||||||
|
let cmd .= ' -v ' . a:arguments
|
||||||
|
let buf = term_start(cmd, {
|
||||||
|
\ 'curwin': 1,
|
||||||
|
\ 'term_rows': rows,
|
||||||
|
\ 'term_cols': cols,
|
||||||
|
\ })
|
||||||
|
if &termwinsize == ''
|
||||||
|
" in the GUI we may end up with a different size, try to set it.
|
||||||
|
if term_getsize(buf) != [rows, cols]
|
||||||
|
call term_setsize(buf, rows, cols)
|
||||||
|
endif
|
||||||
|
call assert_equal([rows, cols], term_getsize(buf))
|
||||||
|
else
|
||||||
|
let rows = term_getsize(buf)[0]
|
||||||
|
let cols = term_getsize(buf)[1]
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Wait for "All" or "Top" of the ruler to be shown in the last line or in
|
||||||
|
" the status line of the last window. This can be quite slow (e.g. when
|
||||||
|
" using valgrind).
|
||||||
|
" If it fails then show the terminal contents for debugging.
|
||||||
|
try
|
||||||
|
call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - statusoff)) >= cols - 1})
|
||||||
|
catch /timed out after/
|
||||||
|
let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
|
||||||
|
call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
|
||||||
|
endtry
|
||||||
|
|
||||||
|
return buf
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Stop a Vim running in terminal buffer "buf".
|
||||||
|
func StopVimInTerminal(buf)
|
||||||
|
call assert_equal("running", term_getstatus(a:buf))
|
||||||
|
|
||||||
|
" CTRL-O : works both in Normal mode and Insert mode to start a command line.
|
||||||
|
" In Command-line it's inserted, the CTRL-U removes it again.
|
||||||
|
call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
|
||||||
|
|
||||||
|
call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
|
||||||
|
only!
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Verify that Vim running in terminal buffer "buf" matches the screen dump.
|
||||||
|
" "options" is passed to term_dumpwrite().
|
||||||
|
" The file name used is "dumps/{filename}.dump".
|
||||||
|
" Optionally an extra argument can be passed which is prepended to the error
|
||||||
|
" message. Use this when using the same dump file with different options.
|
||||||
|
" Will wait for up to a second for the screen dump to match.
|
||||||
|
" Returns non-zero when verification fails.
|
||||||
|
func VerifyScreenDump(buf, filename, options, ...)
|
||||||
|
let reference = 'dumps/' . a:filename . '.dump'
|
||||||
|
let testfile = 'failed/' . a:filename . '.dump'
|
||||||
|
|
||||||
|
" Redraw to execute the code that updates the screen. Otherwise we get the
|
||||||
|
" text and attributes only from the internal buffer.
|
||||||
|
redraw
|
||||||
|
|
||||||
|
let did_mkdir = 0
|
||||||
|
if !isdirectory('failed')
|
||||||
|
let did_mkdir = 1
|
||||||
|
call mkdir('failed')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let i = 0
|
||||||
|
while 1
|
||||||
|
" leave some time for updating the original window
|
||||||
|
sleep 10m
|
||||||
|
call delete(testfile)
|
||||||
|
call term_dumpwrite(a:buf, testfile, a:options)
|
||||||
|
let testdump = readfile(testfile)
|
||||||
|
if filereadable(reference)
|
||||||
|
let refdump = readfile(reference)
|
||||||
|
else
|
||||||
|
" Must be a new screendump, always fail
|
||||||
|
let refdump = []
|
||||||
|
endif
|
||||||
|
if refdump == testdump
|
||||||
|
call delete(testfile)
|
||||||
|
if did_mkdir
|
||||||
|
call delete('failed', 'd')
|
||||||
|
endif
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
if i == 100
|
||||||
|
" Leave the failed dump around for inspection.
|
||||||
|
if filereadable(reference)
|
||||||
|
let msg = 'See dump file difference: call term_dumpdiff("' . testfile . '", "' . reference . '")'
|
||||||
|
if a:0 == 1
|
||||||
|
let msg = a:1 . ': ' . msg
|
||||||
|
endif
|
||||||
|
if len(testdump) != len(refdump)
|
||||||
|
let msg = msg . '; line count is ' . len(testdump) . ' instead of ' . len(refdump)
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
let msg = 'See new dump file: call term_dumpload("' . testfile . '")'
|
||||||
|
endif
|
||||||
|
for i in range(len(refdump))
|
||||||
|
if i >= len(testdump)
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
if testdump[i] != refdump[i]
|
||||||
|
let msg = msg . '; difference in line ' . (i + 1) . ': "' . testdump[i] . '"'
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
call assert_report(msg)
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
let i += 1
|
||||||
|
endwhile
|
||||||
|
return 0
|
||||||
|
endfunc
|
||||||
358
tests/lib/shared.vim
Normal file
358
tests/lib/shared.vim
Normal file
|
|
@ -0,0 +1,358 @@
|
||||||
|
|
||||||
|
" Functions shared by several tests.
|
||||||
|
|
||||||
|
" Only load this script once.
|
||||||
|
if exists('*WaitFor')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
" Get the name of the Python executable.
|
||||||
|
" Also keeps it in s:python.
|
||||||
|
func PythonProg()
|
||||||
|
" This test requires the Python command to run the test server.
|
||||||
|
" This most likely only works on Unix and Windows.
|
||||||
|
if has('unix')
|
||||||
|
" We also need the job feature or the pkill command to make sure the server
|
||||||
|
" can be stopped.
|
||||||
|
if !(executable('python') && (has('job') || executable('pkill')))
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
let s:python = 'python'
|
||||||
|
elseif has('win32')
|
||||||
|
" Use Python Launcher for Windows (py.exe) if available.
|
||||||
|
if executable('py.exe')
|
||||||
|
let s:python = 'py.exe'
|
||||||
|
elseif executable('python.exe')
|
||||||
|
let s:python = 'python.exe'
|
||||||
|
else
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
return ''
|
||||||
|
endif
|
||||||
|
return s:python
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Run "cmd". Returns the job if using a job.
|
||||||
|
func RunCommand(cmd)
|
||||||
|
let job = 0
|
||||||
|
if has('job')
|
||||||
|
let job = job_start(a:cmd, {"stoponexit": "hup"})
|
||||||
|
call job_setoptions(job, {"stoponexit": "kill"})
|
||||||
|
elseif has('win32')
|
||||||
|
exe 'silent !start cmd /c start "test_channel" ' . a:cmd
|
||||||
|
else
|
||||||
|
exe 'silent !' . a:cmd . '&'
|
||||||
|
endif
|
||||||
|
return job
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Read the port number from the Xportnr file.
|
||||||
|
func GetPort()
|
||||||
|
let l = []
|
||||||
|
" with 200 it sometimes failed
|
||||||
|
for i in range(400)
|
||||||
|
try
|
||||||
|
let l = readfile("Xportnr")
|
||||||
|
catch
|
||||||
|
endtry
|
||||||
|
if len(l) >= 1
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
sleep 10m
|
||||||
|
endfor
|
||||||
|
call delete("Xportnr")
|
||||||
|
|
||||||
|
if len(l) == 0
|
||||||
|
" Can't make the connection, give up.
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
return l[0]
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Run a Python server for "cmd" and call "testfunc".
|
||||||
|
" Always kills the server before returning.
|
||||||
|
func RunServer(cmd, testfunc, args)
|
||||||
|
" The Python program writes the port number in Xportnr.
|
||||||
|
call delete("Xportnr")
|
||||||
|
|
||||||
|
if len(a:args) == 1
|
||||||
|
let arg = ' ' . a:args[0]
|
||||||
|
else
|
||||||
|
let arg = ''
|
||||||
|
endif
|
||||||
|
let pycmd = s:python . " " . a:cmd . arg
|
||||||
|
|
||||||
|
try
|
||||||
|
let g:currentJob = RunCommand(pycmd)
|
||||||
|
|
||||||
|
" Wait for up to 2 seconds for the port number to be there.
|
||||||
|
let port = GetPort()
|
||||||
|
if port == 0
|
||||||
|
call assert_false(1, "Can't start " . a:cmd)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
call call(function(a:testfunc), [port])
|
||||||
|
catch
|
||||||
|
call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
|
||||||
|
finally
|
||||||
|
call s:kill_server(a:cmd)
|
||||||
|
endtry
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func s:kill_server(cmd)
|
||||||
|
if has('job')
|
||||||
|
if exists('g:currentJob')
|
||||||
|
call job_stop(g:currentJob)
|
||||||
|
unlet g:currentJob
|
||||||
|
endif
|
||||||
|
elseif has('win32')
|
||||||
|
let cmd = substitute(a:cmd, ".py", '', '')
|
||||||
|
call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"')
|
||||||
|
else
|
||||||
|
call system("pkill -f " . a:cmd)
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Wait for up to five seconds for "expr" to become true. "expr" can be a
|
||||||
|
" stringified expression to evaluate, or a funcref without arguments.
|
||||||
|
" Using a lambda works best. Example:
|
||||||
|
" call WaitFor({-> status == "ok"})
|
||||||
|
"
|
||||||
|
" A second argument can be used to specify a different timeout in msec.
|
||||||
|
"
|
||||||
|
" When successful the time slept is returned.
|
||||||
|
" When running into the timeout an exception is thrown, thus the function does
|
||||||
|
" not return.
|
||||||
|
func WaitFor(expr, ...)
|
||||||
|
let timeout = get(a:000, 0, 5000)
|
||||||
|
let slept = s:WaitForCommon(a:expr, v:null, timeout)
|
||||||
|
if slept < 0
|
||||||
|
throw 'WaitFor() timed out after ' . timeout . ' msec'
|
||||||
|
endif
|
||||||
|
return slept
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Wait for up to five seconds for "assert" to return zero. "assert" must be a
|
||||||
|
" (lambda) function containing one assert function. Example:
|
||||||
|
" call WaitForAssert({-> assert_equal("dead", job_status(job)})
|
||||||
|
"
|
||||||
|
" A second argument can be used to specify a different timeout in msec.
|
||||||
|
"
|
||||||
|
" Return zero for success, one for failure (like the assert function).
|
||||||
|
func WaitForAssert(assert, ...)
|
||||||
|
let timeout = get(a:000, 0, 5000)
|
||||||
|
if s:WaitForCommon(v:null, a:assert, timeout) < 0
|
||||||
|
return 1
|
||||||
|
endif
|
||||||
|
return 0
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Common implementation of WaitFor() and WaitForAssert().
|
||||||
|
" Either "expr" or "assert" is not v:null
|
||||||
|
" Return the waiting time for success, -1 for failure.
|
||||||
|
func s:WaitForCommon(expr, assert, timeout)
|
||||||
|
" using reltime() is more accurate, but not always available
|
||||||
|
let slept = 0
|
||||||
|
if has('reltime')
|
||||||
|
let start = reltime()
|
||||||
|
endif
|
||||||
|
|
||||||
|
while 1
|
||||||
|
if type(a:expr) == v:t_func
|
||||||
|
let success = a:expr()
|
||||||
|
elseif type(a:assert) == v:t_func
|
||||||
|
let success = a:assert() == 0
|
||||||
|
else
|
||||||
|
let success = eval(a:expr)
|
||||||
|
endif
|
||||||
|
if success
|
||||||
|
return slept
|
||||||
|
endif
|
||||||
|
|
||||||
|
if slept >= a:timeout
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
if type(a:assert) == v:t_func
|
||||||
|
" Remove the error added by the assert function.
|
||||||
|
call remove(v:errors, -1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
sleep 10m
|
||||||
|
if has('reltime')
|
||||||
|
let slept = float2nr(reltimefloat(reltime(start)) * 1000)
|
||||||
|
else
|
||||||
|
let slept += 10
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
|
||||||
|
return -1 " timed out
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
" Wait for up to a given milliseconds.
|
||||||
|
" With the +timers feature this waits for key-input by getchar(), Resume()
|
||||||
|
" feeds key-input and resumes process. Return time waited in milliseconds.
|
||||||
|
" Without +timers it uses simply :sleep.
|
||||||
|
func Standby(msec)
|
||||||
|
if has('timers')
|
||||||
|
let start = reltime()
|
||||||
|
let g:_standby_timer = timer_start(a:msec, function('s:feedkeys'))
|
||||||
|
call getchar()
|
||||||
|
return float2nr(reltimefloat(reltime(start)) * 1000)
|
||||||
|
else
|
||||||
|
execute 'sleep ' a:msec . 'm'
|
||||||
|
return a:msec
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Resume()
|
||||||
|
if exists('g:_standby_timer')
|
||||||
|
call timer_stop(g:_standby_timer)
|
||||||
|
call s:feedkeys(0)
|
||||||
|
unlet g:_standby_timer
|
||||||
|
endif
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func s:feedkeys(timer)
|
||||||
|
call feedkeys('x', 'nt')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get $VIMPROG to run Vim executable.
|
||||||
|
" The Makefile writes it as the first line in the "vimcmd" file.
|
||||||
|
func GetVimProg()
|
||||||
|
if !filereadable('vimcmd')
|
||||||
|
" Assume the script was sourced instead of running "make".
|
||||||
|
return '../vim'
|
||||||
|
endif
|
||||||
|
return readfile('vimcmd')[0]
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
let g:valgrind_cnt = 1
|
||||||
|
|
||||||
|
" Get the command to run Vim, with -u NONE and --not-a-term arguments.
|
||||||
|
" If there is an argument use it instead of "NONE".
|
||||||
|
func GetVimCommand(...)
|
||||||
|
if !filereadable('vimcmd')
|
||||||
|
echo 'Cannot read the "vimcmd" file, falling back to ../vim.'
|
||||||
|
let lines = ['../vim']
|
||||||
|
else
|
||||||
|
let lines = readfile('vimcmd')
|
||||||
|
endif
|
||||||
|
if a:0 == 0
|
||||||
|
let name = 'NONE'
|
||||||
|
else
|
||||||
|
let name = a:1
|
||||||
|
endif
|
||||||
|
" For Unix Makefile writes the command to use in the second line of the
|
||||||
|
" "vimcmd" file, including environment options.
|
||||||
|
" Other Makefiles just write the executable in the first line, so fall back
|
||||||
|
" to that if there is no second line or it is empty.
|
||||||
|
if len(lines) > 1 && lines[1] != ''
|
||||||
|
let cmd = lines[1]
|
||||||
|
else
|
||||||
|
let cmd = lines[0]
|
||||||
|
endif
|
||||||
|
|
||||||
|
let cmd = substitute(cmd, '-u \f\+', '-u ' . name, '')
|
||||||
|
if cmd !~ '-u '. name
|
||||||
|
let cmd = cmd . ' -u ' . name
|
||||||
|
endif
|
||||||
|
let cmd .= ' --not-a-term'
|
||||||
|
let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
|
||||||
|
|
||||||
|
" If using valgrind, make sure every run uses a different log file.
|
||||||
|
if cmd =~ 'valgrind.*--log-file='
|
||||||
|
let cmd = substitute(cmd, '--log-file=\(^\s*\)', '--log-file=\1.' . g:valgrind_cnt, '')
|
||||||
|
let g:valgrind_cnt += 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get the command to run Vim, with --clean.
|
||||||
|
func GetVimCommandClean()
|
||||||
|
let cmd = GetVimCommand()
|
||||||
|
let cmd = substitute(cmd, '-u NONE', '--clean', '')
|
||||||
|
let cmd = substitute(cmd, '--not-a-term', '', '')
|
||||||
|
|
||||||
|
" Optionally run Vim under valgrind
|
||||||
|
" let cmd = 'valgrind --tool=memcheck --leak-check=yes --num-callers=25 --log-file=valgrind ' . cmd
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Run Vim, using the "vimcmd" file and "-u NORC".
|
||||||
|
" "before" is a list of Vim commands to be executed before loading plugins.
|
||||||
|
" "after" is a list of Vim commands to be executed after loading plugins.
|
||||||
|
" Plugins are not loaded, unless 'loadplugins' is set in "before".
|
||||||
|
" Return 1 if Vim could be executed.
|
||||||
|
func RunVim(before, after, arguments)
|
||||||
|
return RunVimPiped(a:before, a:after, a:arguments, '')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func RunVimPiped(before, after, arguments, pipecmd)
|
||||||
|
let cmd = GetVimCommand()
|
||||||
|
let args = ''
|
||||||
|
if len(a:before) > 0
|
||||||
|
call writefile(a:before, 'Xbefore.vim')
|
||||||
|
let args .= ' --cmd "so Xbefore.vim"'
|
||||||
|
endif
|
||||||
|
if len(a:after) > 0
|
||||||
|
call writefile(a:after, 'Xafter.vim')
|
||||||
|
let args .= ' -S Xafter.vim'
|
||||||
|
endif
|
||||||
|
|
||||||
|
exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments
|
||||||
|
|
||||||
|
if len(a:before) > 0
|
||||||
|
call delete('Xbefore.vim')
|
||||||
|
endif
|
||||||
|
if len(a:after) > 0
|
||||||
|
call delete('Xafter.vim')
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func CanRunGui()
|
||||||
|
return has('gui') && ($DISPLAY != "" || has('gui_running'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func WorkingClipboard()
|
||||||
|
if !has('clipboard')
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
if has('x11')
|
||||||
|
return $DISPLAY != ""
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Get line "lnum" as displayed on the screen.
|
||||||
|
" Trailing white space is trimmed.
|
||||||
|
func! Screenline(lnum)
|
||||||
|
let chars = []
|
||||||
|
for c in range(1, winwidth(0))
|
||||||
|
call add(chars, nr2char(screenchar(a:lnum, c)))
|
||||||
|
endfor
|
||||||
|
let line = join(chars, '')
|
||||||
|
return matchstr(line, '^.\{-}\ze\s*$')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Stops the shell running in terminal "buf".
|
||||||
|
func Stop_shell_in_terminal(buf)
|
||||||
|
call term_sendkeys(a:buf, "exit\r")
|
||||||
|
let job = term_getjob(a:buf)
|
||||||
|
call WaitFor({-> job_status(job) == "dead"})
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
" Gets the text of a terminal line, using term_scrape()
|
||||||
|
func Get_terminal_text(bufnr, row)
|
||||||
|
let list = term_scrape(a:bufnr, a:row)
|
||||||
|
let text = ''
|
||||||
|
for item in list
|
||||||
|
let text .= item.chars
|
||||||
|
endfor
|
||||||
|
return text
|
||||||
|
endfunc
|
||||||
7
tests/testdata/cpp/simple/.ycm_extra_conf.py
vendored
Normal file
7
tests/testdata/cpp/simple/.ycm_extra_conf.py
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
def Settings( **kwargs ):
|
||||||
|
return {
|
||||||
|
'flags': [
|
||||||
|
'-x', 'c++',
|
||||||
|
'-Wextra', '-Werror', '-Wall'
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue