diff --git a/README.md b/README.md index 1ee251b..d354108 100644 --- a/README.md +++ b/README.md @@ -66,16 +66,18 @@ For a tutorial and usage overview, take a look at the * [Other servers](#other-servers) * [Customisation](#customisation) * [Changing the default signs](#changing-the-default-signs) + * [Sign priority](#sign-priority) * [Changing the default window sizes](#changing-the-default-window-sizes) * [Changing the terminal size](#changing-the-terminal-size) * [Advanced UI customisation](#advanced-ui-customisation) + * [Customising the WinBar](#customising-the-winbar) * [Example](#example) * [FAQ](#faq) * [Motivation](#motivation) * [License](#license) * [Sponsorship](#sponsorship) - + @@ -1362,10 +1364,13 @@ Vimsector uses the following signs internally. If they are defined before Vimsector uses them, they will not be replaced. So to customise the signs, define them in your `vimrc`. -* `vimspectorBP`: A breakpoint. -* `vimspectorBPCond`: A conditional breakpoint. -* `vimspectorBPDisabled`: A disabled breakpoint -* `vimspectorPC` The program counter, i.e. current line. + +| Sign | Description | Priority | +|------------------------|-------------------------------------|----------| +| `vimspectorBP` | Line breakpoint | 9 | +| `vimspectorBPCond` | Conditional line breakpiont | 9 | +| `vimspectorBPDisabled` | Disabled breakpoint | 9 | +| `vimspectorPC` | Program counter (i.e. current line) | 20 | The default symbols are the equivalent of something like the following: @@ -1387,6 +1392,37 @@ sign define vimspectorBPDisabled text=!> texthl=LineNr sign define vimspectorPC text=-> texthl=MatchParen ``` +## Sign priority + +Many different plugins provide signs for various purposes. Examples include +diagnostic signs for code errors, etc. Vim provides only a single priority to +determine which sign should be displayed when multiple signs are placed at a +single line. If you are finding that other signs are interfering with +vimspector's (or vice-versa), you can customise the priority used by vimspector +by setting the following dictionary: + +```viml +let g:vimspector_sign_priority = { + \ '': , + \ } +``` + +For example: + +```viml +let g:vimspector_sign_priority = { + \ 'vimspectorBP': 3, + \ 'vimspectorBPCond': 2, + \ 'vimspectorBPDisabled': 1, + \ 'vimspectorPC': 999, + \ } +``` + +All keys are optional. If a sign is not customised, the default priority it used +(as shown above). + +See `:help sign-priority`. The default priority is 10, larger numbers override +smaller ones. ## Changing the default window sizes diff --git a/compiler/vimspector_test.vim b/compiler/vimspector_test.vim index 5264b4b..d0c6def 100644 --- a/compiler/vimspector_test.vim +++ b/compiler/vimspector_test.vim @@ -37,49 +37,68 @@ if ! exists( ':' . s:make_cmd ) endif function! VimGetCurrentFunction() - echom s:GetCurrentFunction() + echom s:GetCurrentFunction()[ 0 ] 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 [ buf, row, col, offset ] = getpos( '.' ) - let l:test_function = '' + let [ test_function, test_function_line ] = [ v:null, -1 ] - let l:pattern = '\V\C\s\*function!\?\s\+\(\<\w\+\>\)\.\*\$' + let pattern = '\V\C\s\*func\%\(tion\)\?!\?\s\+\(\<\w\+\>\)\.\*\$' - let l:lnum = prevnonblank( '.' ) + let 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' ) + while lnum > 0 + call cursor( lnum, 1 ) + let lnum = search( pattern, 'bcnWz' ) - if l:lnum <= 0 - call cursor( l:row, l:col ) - return l:test_function + if lnum <= 0 + call cursor( row, col ) + return [ test_function, test_function_line ] 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 + let this_decl = substitute( getline( lnum ), pattern, '\1', '' ) + let this_decl_is_test = match( this_decl, '\V\C\^Test_' ) >= 0 - if l:this_decl_is_test - let l:test_function = l:this_decl + if this_decl_is_test + let [ test_function, test_function_line ] = [ this_decl, lnum ] - if indent( l:lnum ) == 0 - call cursor( l:row, l:col ) - return l:test_function + if indent( lnum ) == 0 + call cursor( row, col ) + return [ test_function, test_function_line ] endif endif - let l:lnum = prevnonblank( l:lnum - 1 ) + let lnum = prevnonblank( lnum - 1 ) endwhile + return [ v:null, -1 ] endfunction +function! s:RunTestUnderCursorInVimspector() + update + let l:test_func_name = s:GetCurrentFunction()[ 0 ] + + if l:test_func_name ==# '' + echo 'No test method found' + return + endif + + echo "Running test '" . l:test_func_name . "'" + + call vimspector#LaunchWithSettings( { + \ 'configuration': 'Run test', + \ 'TestFunction': l:test_func_name + \ } ) +endfunction + + function! s:RunTestUnderCursor() update - let l:test_func_name = s:GetCurrentFunction() + let l:test_func_name = s:GetCurrentFunction()[ 0 ] if l:test_func_name ==# '' echo 'No test method found' @@ -132,10 +151,36 @@ if ! has( 'gui_running' ) nnoremap  :call RunAllTests() " † is right-option+t nnoremap † :call RunTestUnderCursor() + nnoremap † :call RunTestUnderCursorInVimspector() " å is the right-option+q nnoremap å :cfirst " å is the right-option+a - nnoremap œ :cnext + nnoremap œ :FuncLine " Ω is the right-option+z nnoremap Ω :cprevious endif + +function! s:GoToCurrentFunctionLine( ... ) + if a:0 < 1 + call inputsave() + let lnum = str2nr( input( 'Enter line num: ' ) ) + call inputrestore() + else + let lnum = a:1 + endif + + let [ f, l ] = s:GetCurrentFunction() + if f is v:null + return + endif + + let lnum += l + + echo 'Function' f 'at line' l '(jump to line ' lnum . ')' + + call cursor( [ lnum, indent( lnum ) ] ) +endfunction + +command! -buffer -nargs=? -bar + \ FuncLine + \ :call s:GoToCurrentFunctionLine( ) diff --git a/python3/vimspector/breakpoints.py b/python3/vimspector/breakpoints.py index b2632e9..6539c81 100644 --- a/python3/vimspector/breakpoints.py +++ b/python3/vimspector/breakpoints.py @@ -21,7 +21,7 @@ import os import logging import json -from vimspector import utils +from vimspector import utils, signs class ServerBreakpointHandler( object ): @@ -52,18 +52,18 @@ class ProjectBreakpoints( object ): self._next_sign_id = 1 - if not utils.SignDefined( 'vimspectorBP' ): - utils.DefineSign( 'vimspectorBP', + if not signs.SignDefined( 'vimspectorBP' ): + signs.DefineSign( 'vimspectorBP', text = '●', texthl = 'WarningMsg' ) - if not utils.SignDefined( 'vimspectorBPCond' ): - utils.DefineSign( 'vimspectorBPCond', + if not signs.SignDefined( 'vimspectorBPCond' ): + signs.DefineSign( 'vimspectorBPCond', text = '◆', texthl = 'WarningMsg' ) - if not utils.SignDefined( 'vimspectorBPDisabled' ): - utils.DefineSign( 'vimspectorBPDisabled', + if not signs.SignDefined( 'vimspectorBPDisabled' ): + signs.DefineSign( 'vimspectorBPDisabled', text = '●', texthl = 'LineNr' ) @@ -130,8 +130,7 @@ class ProjectBreakpoints( object ): for bp in breakpoints: self._SignToLine( file_name, bp ) if 'sign_id' in bp: - vim.command( 'sign unplace {0} group=VimspectorBP'.format( - bp[ 'sign_id' ] ) ) + signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' ) self._line_breakpoints = defaultdict( list ) self._func_breakpoints = [] @@ -157,8 +156,7 @@ class ProjectBreakpoints( object ): action = 'Disable' else: if 'sign_id' in bp: - vim.command( 'sign unplace {0} group=VimspectorBP'.format( - bp[ 'sign_id' ] ) ) + signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' ) del self._line_breakpoints[ file_name ][ index ] action = 'Delete' break @@ -249,8 +247,7 @@ class ProjectBreakpoints( object ): for bp in line_breakpoints: self._SignToLine( file_name, bp ) if 'sign_id' in bp: - vim.command( 'sign unplace {0} group=VimspectorBP'.format( - bp[ 'sign_id' ] ) ) + signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' ) del bp[ 'sign_id' ] if bp[ 'state' ] != 'ENABLED': @@ -374,8 +371,7 @@ class ProjectBreakpoints( object ): for bp in line_breakpoints: self._SignToLine( file_name, bp ) if 'sign_id' in bp: - vim.command( 'sign unplace {0} group=VimspectorBP '.format( - bp[ 'sign_id' ] ) ) + signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' ) else: bp[ 'sign_id' ] = self._next_sign_id self._next_sign_id += 1 @@ -384,12 +380,12 @@ class ProjectBreakpoints( object ): else 'vimspectorBPCond' if 'condition' in bp[ 'options' ] else 'vimspectorBP' ) - vim.command( - 'sign place {0} group=VimspectorBP line={1} name={2} file={3}'.format( - bp[ 'sign_id' ] , - bp[ 'line' ], - sign, - file_name ) ) + signs.PlaceSign( bp[ 'sign_id' ], + 'VimspectorBP', + sign, + 9, + file_name, + bp[ 'line' ] ) def _SignToLine( self, file_name, bp ): @@ -398,7 +394,7 @@ class ProjectBreakpoints( object ): signs = vim.eval( "sign_getplaced( '{}', {} )".format( utils.Escape( file_name ), - json.dumps( { 'id': file_name, 'group': 'VimspectorBP', } ) ) ) + json.dumps( { 'id': bp[ 'sign_id' ], 'group': 'VimspectorBP', } ) ) ) if len( signs ) == 1 and len( signs[ 0 ][ 'signs' ] ) == 1: bp[ 'line' ] = int( signs[ 0 ][ 'signs' ][ 0 ][ 'lnum' ] ) diff --git a/python3/vimspector/code.py b/python3/vimspector/code.py index d8bd208..3cbe77b 100644 --- a/python3/vimspector/code.py +++ b/python3/vimspector/code.py @@ -18,7 +18,7 @@ import logging import json from collections import defaultdict -from vimspector import utils, settings +from vimspector import utils, settings, signs class CodeView( object ): @@ -50,8 +50,8 @@ class CodeView( object ): vim.command( 'nnoremenu WinBar.⟲: :call vimspector#Restart()' ) vim.command( 'nnoremenu WinBar.✕ :call vimspector#Reset()' ) - if not utils.SignDefined( 'vimspectorPC' ): - utils.DefineSign( 'vimspectorPC', + if not signs.SignDefined( 'vimspectorPC' ): + signs.DefineSign( 'vimspectorPC', text = '▶', texthl = 'MatchParen' ) @@ -62,8 +62,7 @@ class CodeView( object ): (or don't have the data) or the code window no longer exits.""" if self._signs[ 'vimspectorPC' ]: - vim.command( 'sign unplace {} group=VimspectorCode'.format( - self._signs[ 'vimspectorPC' ] ) ) + signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' ) self._signs[ 'vimspectorPC' ] = None if not frame or not frame.get( 'source' ): @@ -76,12 +75,12 @@ class CodeView( object ): self._next_sign_id += 1 try: - vim.command( 'sign place {0} group=VimspectorCode priority=20 ' - 'line={1} name=vimspectorPC ' - 'file={2}'.format( - self._signs[ 'vimspectorPC' ], - frame[ 'line' ], - frame[ 'source' ][ 'path' ] ) ) + signs.PlaceSign( self._signs[ 'vimspectorPC' ], + 'VimspectorCode', + 'vimspectorPC', + 20, + frame[ 'source' ][ 'path' ], + frame[ 'line' ] ) except vim.error as e: # Ignore 'invalid buffer name' if 'E158' not in str( e ): @@ -118,8 +117,7 @@ class CodeView( object ): def Clear( self ): if self._signs[ 'vimspectorPC' ]: - vim.command( 'sign unplace {} group=VimspectorCode'.format( - self._signs[ 'vimspectorPC' ] ) ) + signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' ) self._signs[ 'vimspectorPC' ] = None self._UndisplaySigns() @@ -163,7 +161,7 @@ class CodeView( object ): def _UndisplaySigns( self ): for sign_id in self._signs[ 'breakpoints' ]: - vim.command( 'sign unplace {} group=VimspectorCode'.format( sign_id ) ) + signs.UnplaceSign( sign_id, 'VimspectorCode' ) self._signs[ 'breakpoints' ] = [] @@ -182,16 +180,13 @@ class CodeView( object ): sign_id = self._next_sign_id self._next_sign_id += 1 self._signs[ 'breakpoints' ].append( sign_id ) - vim.command( - 'sign place {0} group=VimspectorCode priority=9 ' - 'line={1} ' - 'name={2} ' - 'file={3}'.format( - sign_id, - breakpoint[ 'line' ], - 'vimspectorBP' if breakpoint[ 'verified' ] - else 'vimspectorBPDisabled', - file_name ) ) + signs.PlaceSign( sign_id, + 'VimspectorCode', + 'vimspectorBP' if breakpoint[ 'verified' ] + else 'vimspectorBPDisabled', + 9, + file_name, + breakpoint[ 'line' ] ) def BreakpointsAsQuickFix( self ): diff --git a/python3/vimspector/settings.py b/python3/vimspector/settings.py index 08f3066..d186e42 100644 --- a/python3/vimspector/settings.py +++ b/python3/vimspector/settings.py @@ -31,3 +31,9 @@ def Int( option: str, default=0 ): def List( option: str, default=[] ): return utils.GetVimList( vim.vars, f'vimspector_{ option }', default ) + + +def Dict( option: str, default={} ): + return utils.GetVimValue( vim.vars, + f'vimspector_{ option }', + default ) diff --git a/python3/vimspector/signs.py b/python3/vimspector/signs.py new file mode 100644 index 0000000..ac98983 --- /dev/null +++ b/python3/vimspector/signs.py @@ -0,0 +1,39 @@ +import vim + +from vimspector import settings, utils + + +def SignDefined( name ): + if utils.Exists( "*sign_getdefined" ): + return int( + vim.eval( f"len( sign_getdefined( '{ utils.Escape( name ) }' ) )" ) + ) + + return False + + +def DefineSign( name, text, texthl, col = 'right' ): + if col == 'right': + if int( utils.Call( 'strdisplaywidth', text ) ) < 2: + text = ' ' + text + + text = text.replace( ' ', r'\ ' ) + + vim.command( f'sign define { name } text={ text } texthl={ texthl }' ) + + +def PlaceSign( sign_id, group, name, priority, file, line ): + priority = settings.Dict( 'sign_priority' ).get( name, priority ) + + cmd = ( f'sign place { sign_id } ' + f'group={ group } ' + f'name={ name } ' + f'priority={ priority } ' + f'line={ line } ' + f'file={ file }' ) + + vim.command( cmd ) + + +def UnplaceSign( sign_id, group ): + vim.command( f'sign unplace { sign_id } group={ group }' ) diff --git a/python3/vimspector/utils.py b/python3/vimspector/utils.py index ec2d54d..b850090 100644 --- a/python3/vimspector/utils.py +++ b/python3/vimspector/utils.py @@ -660,13 +660,6 @@ def Call( vimscript_function, *args ): return vim.eval( call ) -def SignDefined( name ): - if Exists( "*sign_getdefined" ): - return int( vim.eval( f"len( sign_getdefined( '{ Escape( name ) }' ) )" ) ) - - return False - - MEMO = {} @@ -780,13 +773,3 @@ def WindowID( window, tab=None ): if tab is None: tab = window.tabpage return int( Call( 'win_getid', window.number, tab.number ) ) - - -def DefineSign( name, text, texthl, col = 'right' ): - if col == 'right': - if int( Call( 'strdisplaywidth', text ) ) < 2: - text = ' ' + text - - text = text.replace( ' ', r'\ ' ) - - vim.command( f'sign define { name } text={ text } texthl={ texthl }' ) diff --git a/support/custom_ui_vimrc b/support/custom_ui_vimrc index 944ff93..95c3360 100644 --- a/support/custom_ui_vimrc +++ b/support/custom_ui_vimrc @@ -65,3 +65,10 @@ augroup TestUICustomistaion autocmd User VimspectorTerminalOpened call s:SetUpTerminal() autocmd User VimspectorUICreated call s:CustomiseWinBar() augroup END + +let g:vimspector_sign_priority = { + \ 'vimspectorBP': 3, + \ 'vimspectorBPCond': 2, + \ 'vimspectorBPDisabled': 1, + \ 'vimspectorPC': 999, + \ } diff --git a/tests/breakpoints.test.vim b/tests/breakpoints.test.vim index acc10e2..ca57157 100644 --- a/tests/breakpoints.test.vim +++ b/tests/breakpoints.test.vim @@ -53,14 +53,16 @@ function! Test_Signs_Placed_Using_API_Are_Shown() call assert_true( exists( '*vimspector#ToggleBreakpoint' ) ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ line( '.' ), - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) " Disable breakpoint call vimspector#ToggleBreakpoint() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ line( '.' ), - \ 'vimspectorBPDisabled' ) + \ 'vimspectorBPDisabled', + \ 9 ) " Remove breakpoint call vimspector#ToggleBreakpoint() @@ -92,14 +94,16 @@ function! Test_Use_Mappings_HUMAN() call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 15, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) " Disable the breakpoint call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 15, - \ 'vimspectorBPDisabled' ) + \ 'vimspectorBPDisabled', + \ 9 ) " Delete the breakpoint call feedkeys( "\", 'xt' ) @@ -110,7 +114,8 @@ function! Test_Use_Mappings_HUMAN() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 15, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) " Here we go. Start Debugging call feedkeys( "\", 'xt' ) @@ -184,7 +189,8 @@ function Test_DisableBreakpointWhileDebugging() \ vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorCode', \ 16, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) \ } ) " Remove the breakpoint @@ -200,7 +206,8 @@ function Test_DisableBreakpointWhileDebugging() \ vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorCode', \ 16, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) \ } ) " Run to breakpoint @@ -224,7 +231,8 @@ function Test_DisableBreakpointWhileDebugging() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 16, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) " Disable the breakpoint call setpos( '.', [ bufnr( 'simple.cpp' ), 16, 1 ] ) @@ -232,7 +240,8 @@ function Test_DisableBreakpointWhileDebugging() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 16, - \ 'vimspectorBPDisabled' ) + \ 'vimspectorBPDisabled', + \ 9 ) " And delete it call feedkeys( "\", 'xt' ) @@ -266,14 +275,16 @@ function! Test_Insert_Code_Above_Breakpoint() call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 25, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) " Insert a line above the breakpoint call append( 22, ' # Test' ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 5 ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 26, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) " CHeck that we break at the right point call setpos( '.', [ 0, 1, 1 ] ) @@ -286,12 +297,14 @@ function! Test_Insert_Code_Above_Breakpoint() call setpos( '.', [ 0, 26, 1 ] ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 26, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 26, - \ 'vimspectorBPDisabled' ) + \ 'vimspectorBPDisabled', + \ 9 ) " Delete it call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 26 ) @@ -314,14 +327,16 @@ function! Test_Conditional_Line_Breakpoint() call feedkeys( "\\\argc==0\\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 16, - \ 'vimspectorBPCond' ) + \ 'vimspectorBPCond', + \ 9 ) " Disable the breakpoint call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 16, - \ 'vimspectorBPDisabled' ) + \ 'vimspectorBPDisabled', + \ 9 ) " Delete the breakpoint call feedkeys( "\", 'xt' ) @@ -335,20 +350,23 @@ function! Test_Conditional_Line_Breakpoint() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 16, - \ 'vimspectorBPCond' ) + \ 'vimspectorBPCond', + \ 9 ) call setpos( '.', [ 0, 9, 1 ] ) call vimspector#ToggleBreakpoint() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 9, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) call setpos( '.', [ 0, 17, 1 ] ) call vimspector#ToggleBreakpoint( { 'condition': 'argc == 1' } ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 17, - \ 'vimspectorBPCond' ) + \ 'vimspectorBPCond', + \ 9 ) call setpos( '.', [ 0, 1, 1 ] ) @@ -385,7 +403,8 @@ function! Test_Conditional_Line_Breakpoint_Hit() call vimspector#test#signs#AssertSignGroupSingletonAtLine( \ 'VimspectorBP', \ 14, - \ 'vimspectorBPCond' ) + \ 'vimspectorBPCond', + \ 9 ) call vimspector#LaunchWithSettings( { 'configuration': 'run' } ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 14, 1 ) @@ -526,3 +545,94 @@ function! Test_ListBreakpoints() call vimspector#test#setup#Reset() %bwipe! endfunction + +function! Test_Custom_Breakpoint_Priority() + let g:vimspector_sign_priority = { + \ 'vimspectorPC': 1, + \ 'vimspectorBP': 2, + \ 'vimspectorBPCond': 3, + \ 'vimspectorBPDisabled': 4 + \ } + + " While not debugging + lcd testdata/cpp/simple + edit simple.cpp + + call setpos( '.', [ 0, 15, 1 ] ) + call vimspector#ToggleBreakpoint() + call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', + \ 15, + \ 'vimspectorBP', + \ 2 ) + call setpos( '.', [ 0, 16, 1 ] ) + call vimspector#ToggleBreakpoint() + call vimspector#ToggleBreakpoint() + call vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorBP', + \ 16, + \ 'vimspectorBPDisabled', + \ 4 ) + call vimspector#ToggleBreakpoint() + call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 15 ) + + call setpos( '.', [ 0, 17, 1 ] ) + call vimspector#ToggleBreakpoint( { 'condition': '1' } ) + call vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorBP', + \ 17, + \ 'vimspectorBPCond', + \ 3 ) + + " While debugging + call vimspector#Launch() + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 15, 1 ) + call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 15 ) + call vimspector#test#signs#AssertSignAtLine( + \ 'VimspectorCode', + \ 15, + \ 'vimspectorBP', + \ 2 ) + call vimspector#test#signs#AssertSignAtLine( + \ 'VimspectorCode', + \ 15, + \ 'vimspectorPC', + \ 1 ) + call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorCode', + \ 17, + \ 'vimspectorBP', + \ 2 ) + + call vimspector#StepOver() + " No sign as disabled + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 16, 1 ) + call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 16 ) + + call vimspector#StepOver() + call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 17, 1 ) + call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 17 ) + + call vimspector#test#signs#AssertSignGroupSingletonAtLine( + \ 'VimspectorCode', + \ 15, + \ 'vimspectorBP', + \ 2 ) + call vimspector#test#signs#AssertSignAtLine( + \ 'VimspectorCode', + \ 17, + \ 'vimspectorBP', + \ 2 ) + call vimspector#test#signs#AssertSignAtLine( + \ 'VimspectorCode', + \ 17, + \ 'vimspectorPC', + \ 1 ) + + + call vimspector#test#setup#Reset() + lcd - + %bwipeout! +endfunction + +function! TearDown_Test_Custom_Breakpoint_Priority() + unlet! g:vimspector_sign_priority +endfunction diff --git a/tests/language_go.test.vim b/tests/language_go.test.vim index 7fb9c9d..b6a7da4 100644 --- a/tests/language_go.test.vim +++ b/tests/language_go.test.vim @@ -23,7 +23,8 @@ function! Test_Go_Simple() call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 4, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) call setpos( '.', [ 0, 1, 1 ] ) diff --git a/tests/language_python.test.vim b/tests/language_python.test.vim index dccdc72..cc49adb 100644 --- a/tests/language_python.test.vim +++ b/tests/language_python.test.vim @@ -23,7 +23,8 @@ function! Test_Python_Simple() call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 6, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) call setpos( '.', [ 0, 1, 1 ] ) @@ -79,7 +80,8 @@ function! Test_Python_Remote_Attach() call feedkeys( "\", 'xt' ) call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', \ 6, - \ 'vimspectorBP' ) + \ 'vimspectorBP', + \ 9 ) call setpos( '.', [ 0, 1, 1 ] ) diff --git a/tests/lib/autoload/vimspector/test/signs.vim b/tests/lib/autoload/vimspector/test/signs.vim index 571353e..926a972 100644 --- a/tests/lib/autoload/vimspector/test/signs.vim +++ b/tests/lib/autoload/vimspector/test/signs.vim @@ -46,7 +46,8 @@ endfunction function! vimspector#test#signs#AssertSignGroupSingletonAtLine( group, \ line, - \ sign_name ) + \ sign_name, + \ priority ) \ abort let signs = sign_getplaced( '%', { @@ -62,10 +63,46 @@ function! vimspector#test#signs#AssertSignGroupSingletonAtLine( group, \ 'Num signs in ' . a:group . ' at ' . a:line ) || \ assert_equal( a:sign_name, \ signs[ 0 ].signs[ 0 ].name, - \ 'Sign in group ' . a:group . ' at ' . a:line ) + \ 'Sign in group ' . a:group . ' at ' . a:line ) || + \ assert_equal( a:priority, + \ signs[ 0 ].signs[ 0 ].priority, + \ 'Sign priority in group ' . a:group . ' at ' . a:line ) endfunction +function! vimspector#test#signs#AssertSignAtLine( group, line, sign_name, priority ) abort + + let signs = sign_getplaced( '%', { + \ 'group': a:group, + \ 'lnum': a:line, + \ } ) + + let errors_before = v:errors + let result = 1 + let errors = [ 'No signs were found' ] + + for sign in signs[ 0 ].signs + let v:errors = [] + + let result = + \ assert_equal( a:sign_name, + \ sign.name, + \ 'Sign in group ' . a:group . ' at ' . a:line ) || + \ assert_equal( a:priority, + \ sign.priority, + \ 'Sign priority in group ' . a:group . ' at ' . a:line ) + if result + let errors = v:errors + else + let errors = [] + break + endif + endfor + + let v:errors = errors_before + errors + return result +endfunction + function! vimspector#test#signs#AssertSignGroupEmptyAtLine( group, line ) abort let signs = sign_getplaced( '%', { \ 'group': a:group,