Allow customisation of the signs

Too many plugins use the default priority of 10 so they race/chase.
Allow uses to configure the priorities and make sure that the defaults
are documented.
This commit is contained in:
Ben Jackson 2020-09-01 13:37:45 +01:00
commit c1b544fb3c
12 changed files with 370 additions and 113 deletions

View file

@ -66,16 +66,18 @@ For a tutorial and usage overview, take a look at the
* [Other servers](#other-servers) * [Other servers](#other-servers)
* [Customisation](#customisation) * [Customisation](#customisation)
* [Changing the default signs](#changing-the-default-signs) * [Changing the default signs](#changing-the-default-signs)
* [Sign priority](#sign-priority)
* [Changing the default window sizes](#changing-the-default-window-sizes) * [Changing the default window sizes](#changing-the-default-window-sizes)
* [Changing the terminal size](#changing-the-terminal-size) * [Changing the terminal size](#changing-the-terminal-size)
* [Advanced UI customisation](#advanced-ui-customisation) * [Advanced UI customisation](#advanced-ui-customisation)
* [Customising the WinBar](#customising-the-winbar)
* [Example](#example) * [Example](#example)
* [FAQ](#faq) * [FAQ](#faq)
* [Motivation](#motivation) * [Motivation](#motivation)
* [License](#license) * [License](#license)
* [Sponsorship](#sponsorship) * [Sponsorship](#sponsorship)
<!-- Added by: ben, at: Wed 22 Jul 2020 22:10:50 BST --> <!-- Added by: ben, at: Tue 1 Sep 2020 13:42:32 BST -->
<!--te--> <!--te-->
@ -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, Vimsector uses them, they will not be replaced. So to customise the signs,
define them in your `vimrc`. define them in your `vimrc`.
* `vimspectorBP`: A breakpoint.
* `vimspectorBPCond`: A conditional breakpoint. | Sign | Description | Priority |
* `vimspectorBPDisabled`: A disabled breakpoint |------------------------|-------------------------------------|----------|
* `vimspectorPC` The program counter, i.e. current line. | `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: 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 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 = {
\ '<sign-name>': <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 ## Changing the default window sizes

View file

@ -37,49 +37,68 @@ if ! exists( ':' . s:make_cmd )
endif endif
function! VimGetCurrentFunction() function! VimGetCurrentFunction()
echom s:GetCurrentFunction() echom s:GetCurrentFunction()[ 0 ]
endfunction endfunction
function! s:GetCurrentFunction() function! s:GetCurrentFunction()
" Store the cursor position; we'll need to reset it " 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 " Find the top-level method and class
while l:lnum > 0 while lnum > 0
call cursor( l:lnum, 1 ) call cursor( lnum, 1 )
let l:lnum = search( l:pattern, 'bcnWz' ) let lnum = search( pattern, 'bcnWz' )
if l:lnum <= 0 if lnum <= 0
call cursor( l:row, l:col ) call cursor( row, col )
return l:test_function return [ test_function, test_function_line ]
endif endif
let l:this_decl = substitute( getline( l:lnum ), l:pattern, '\1', '' ) let this_decl = substitute( getline( lnum ), pattern, '\1', '' )
let l:this_decl_is_test = match( l:this_decl, '\V\C\^Test_' ) >= 0 let this_decl_is_test = match( this_decl, '\V\C\^Test_' ) >= 0
if l:this_decl_is_test if this_decl_is_test
let l:test_function = l:this_decl let [ test_function, test_function_line ] = [ this_decl, lnum ]
if indent( l:lnum ) == 0 if indent( lnum ) == 0
call cursor( l:row, l:col ) call cursor( row, col )
return l:test_function return [ test_function, test_function_line ]
endif endif
endif endif
let l:lnum = prevnonblank( l:lnum - 1 ) let lnum = prevnonblank( lnum - 1 )
endwhile endwhile
return [ v:null, -1 ]
endfunction 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() function! s:RunTestUnderCursor()
update update
let l:test_func_name = s:GetCurrentFunction() let l:test_func_name = s:GetCurrentFunction()[ 0 ]
if l:test_func_name ==# '' if l:test_func_name ==# ''
echo 'No test method found' echo 'No test method found'
@ -132,10 +151,36 @@ if ! has( 'gui_running' )
nnoremap <buffer> Â :call <SID>RunAllTests()<CR> nnoremap <buffer> Â :call <SID>RunAllTests()<CR>
" † is right-option+t " † is right-option+t
nnoremap <buffer> † :call <SID>RunTestUnderCursor()<CR> nnoremap <buffer> † :call <SID>RunTestUnderCursor()<CR>
nnoremap <buffer> <leader>† :call <SID>RunTestUnderCursorInVimspector()<CR>
" å is the right-option+q " å is the right-option+q
nnoremap <buffer> å :cfirst<CR> nnoremap <buffer> å :cfirst<CR>
" å is the right-option+a " å is the right-option+a
nnoremap <buffer> œ :cnext<CR> nnoremap <buffer> œ :FuncLine<CR>
" Ω is the right-option+z " Ω is the right-option+z
nnoremap <buffer> Ω :cprevious<CR> nnoremap <buffer> Ω :cprevious<CR>
endif 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( <f-args> )

View file

@ -21,7 +21,7 @@ import os
import logging import logging
import json import json
from vimspector import utils from vimspector import utils, signs
class ServerBreakpointHandler( object ): class ServerBreakpointHandler( object ):
@ -52,18 +52,18 @@ class ProjectBreakpoints( object ):
self._next_sign_id = 1 self._next_sign_id = 1
if not utils.SignDefined( 'vimspectorBP' ): if not signs.SignDefined( 'vimspectorBP' ):
utils.DefineSign( 'vimspectorBP', signs.DefineSign( 'vimspectorBP',
text = '', text = '',
texthl = 'WarningMsg' ) texthl = 'WarningMsg' )
if not utils.SignDefined( 'vimspectorBPCond' ): if not signs.SignDefined( 'vimspectorBPCond' ):
utils.DefineSign( 'vimspectorBPCond', signs.DefineSign( 'vimspectorBPCond',
text = '', text = '',
texthl = 'WarningMsg' ) texthl = 'WarningMsg' )
if not utils.SignDefined( 'vimspectorBPDisabled' ): if not signs.SignDefined( 'vimspectorBPDisabled' ):
utils.DefineSign( 'vimspectorBPDisabled', signs.DefineSign( 'vimspectorBPDisabled',
text = '', text = '',
texthl = 'LineNr' ) texthl = 'LineNr' )
@ -130,8 +130,7 @@ class ProjectBreakpoints( object ):
for bp in breakpoints: for bp in breakpoints:
self._SignToLine( file_name, bp ) self._SignToLine( file_name, bp )
if 'sign_id' in bp: if 'sign_id' in bp:
vim.command( 'sign unplace {0} group=VimspectorBP'.format( signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
bp[ 'sign_id' ] ) )
self._line_breakpoints = defaultdict( list ) self._line_breakpoints = defaultdict( list )
self._func_breakpoints = [] self._func_breakpoints = []
@ -157,8 +156,7 @@ class ProjectBreakpoints( object ):
action = 'Disable' action = 'Disable'
else: else:
if 'sign_id' in bp: if 'sign_id' in bp:
vim.command( 'sign unplace {0} group=VimspectorBP'.format( signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
bp[ 'sign_id' ] ) )
del self._line_breakpoints[ file_name ][ index ] del self._line_breakpoints[ file_name ][ index ]
action = 'Delete' action = 'Delete'
break break
@ -249,8 +247,7 @@ class ProjectBreakpoints( object ):
for bp in line_breakpoints: for bp in line_breakpoints:
self._SignToLine( file_name, bp ) self._SignToLine( file_name, bp )
if 'sign_id' in bp: if 'sign_id' in bp:
vim.command( 'sign unplace {0} group=VimspectorBP'.format( signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
bp[ 'sign_id' ] ) )
del bp[ 'sign_id' ] del bp[ 'sign_id' ]
if bp[ 'state' ] != 'ENABLED': if bp[ 'state' ] != 'ENABLED':
@ -374,8 +371,7 @@ class ProjectBreakpoints( object ):
for bp in line_breakpoints: for bp in line_breakpoints:
self._SignToLine( file_name, bp ) self._SignToLine( file_name, bp )
if 'sign_id' in bp: if 'sign_id' in bp:
vim.command( 'sign unplace {0} group=VimspectorBP '.format( signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
bp[ 'sign_id' ] ) )
else: else:
bp[ 'sign_id' ] = self._next_sign_id bp[ 'sign_id' ] = self._next_sign_id
self._next_sign_id += 1 self._next_sign_id += 1
@ -384,12 +380,12 @@ class ProjectBreakpoints( object ):
else 'vimspectorBPCond' if 'condition' in bp[ 'options' ] else 'vimspectorBPCond' if 'condition' in bp[ 'options' ]
else 'vimspectorBP' ) else 'vimspectorBP' )
vim.command( signs.PlaceSign( bp[ 'sign_id' ],
'sign place {0} group=VimspectorBP line={1} name={2} file={3}'.format( 'VimspectorBP',
bp[ 'sign_id' ] , sign,
bp[ 'line' ], 9,
sign, file_name,
file_name ) ) bp[ 'line' ] )
def _SignToLine( self, file_name, bp ): def _SignToLine( self, file_name, bp ):
@ -398,7 +394,7 @@ class ProjectBreakpoints( object ):
signs = vim.eval( "sign_getplaced( '{}', {} )".format( signs = vim.eval( "sign_getplaced( '{}', {} )".format(
utils.Escape( file_name ), 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: if len( signs ) == 1 and len( signs[ 0 ][ 'signs' ] ) == 1:
bp[ 'line' ] = int( signs[ 0 ][ 'signs' ][ 0 ][ 'lnum' ] ) bp[ 'line' ] = int( signs[ 0 ][ 'signs' ][ 0 ][ 'lnum' ] )

View file

@ -18,7 +18,7 @@ import logging
import json import json
from collections import defaultdict from collections import defaultdict
from vimspector import utils, settings from vimspector import utils, settings, signs
class CodeView( object ): class CodeView( object ):
@ -50,8 +50,8 @@ class CodeView( object ):
vim.command( 'nnoremenu WinBar.⟲: :call vimspector#Restart()<CR>' ) vim.command( 'nnoremenu WinBar.⟲: :call vimspector#Restart()<CR>' )
vim.command( 'nnoremenu WinBar.✕ :call vimspector#Reset()<CR>' ) vim.command( 'nnoremenu WinBar.✕ :call vimspector#Reset()<CR>' )
if not utils.SignDefined( 'vimspectorPC' ): if not signs.SignDefined( 'vimspectorPC' ):
utils.DefineSign( 'vimspectorPC', signs.DefineSign( 'vimspectorPC',
text = '', text = '',
texthl = 'MatchParen' ) texthl = 'MatchParen' )
@ -62,8 +62,7 @@ class CodeView( object ):
(or don't have the data) or the code window no longer exits.""" (or don't have the data) or the code window no longer exits."""
if self._signs[ 'vimspectorPC' ]: if self._signs[ 'vimspectorPC' ]:
vim.command( 'sign unplace {} group=VimspectorCode'.format( signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' )
self._signs[ 'vimspectorPC' ] ) )
self._signs[ 'vimspectorPC' ] = None self._signs[ 'vimspectorPC' ] = None
if not frame or not frame.get( 'source' ): if not frame or not frame.get( 'source' ):
@ -76,12 +75,12 @@ class CodeView( object ):
self._next_sign_id += 1 self._next_sign_id += 1
try: try:
vim.command( 'sign place {0} group=VimspectorCode priority=20 ' signs.PlaceSign( self._signs[ 'vimspectorPC' ],
'line={1} name=vimspectorPC ' 'VimspectorCode',
'file={2}'.format( 'vimspectorPC',
self._signs[ 'vimspectorPC' ], 20,
frame[ 'line' ], frame[ 'source' ][ 'path' ],
frame[ 'source' ][ 'path' ] ) ) frame[ 'line' ] )
except vim.error as e: except vim.error as e:
# Ignore 'invalid buffer name' # Ignore 'invalid buffer name'
if 'E158' not in str( e ): if 'E158' not in str( e ):
@ -118,8 +117,7 @@ class CodeView( object ):
def Clear( self ): def Clear( self ):
if self._signs[ 'vimspectorPC' ]: if self._signs[ 'vimspectorPC' ]:
vim.command( 'sign unplace {} group=VimspectorCode'.format( signs.UnplaceSign( self._signs[ 'vimspectorPC' ], 'VimspectorCode' )
self._signs[ 'vimspectorPC' ] ) )
self._signs[ 'vimspectorPC' ] = None self._signs[ 'vimspectorPC' ] = None
self._UndisplaySigns() self._UndisplaySigns()
@ -163,7 +161,7 @@ class CodeView( object ):
def _UndisplaySigns( self ): def _UndisplaySigns( self ):
for sign_id in self._signs[ 'breakpoints' ]: for sign_id in self._signs[ 'breakpoints' ]:
vim.command( 'sign unplace {} group=VimspectorCode'.format( sign_id ) ) signs.UnplaceSign( sign_id, 'VimspectorCode' )
self._signs[ 'breakpoints' ] = [] self._signs[ 'breakpoints' ] = []
@ -182,16 +180,13 @@ class CodeView( object ):
sign_id = self._next_sign_id sign_id = self._next_sign_id
self._next_sign_id += 1 self._next_sign_id += 1
self._signs[ 'breakpoints' ].append( sign_id ) self._signs[ 'breakpoints' ].append( sign_id )
vim.command( signs.PlaceSign( sign_id,
'sign place {0} group=VimspectorCode priority=9 ' 'VimspectorCode',
'line={1} ' 'vimspectorBP' if breakpoint[ 'verified' ]
'name={2} ' else 'vimspectorBPDisabled',
'file={3}'.format( 9,
sign_id, file_name,
breakpoint[ 'line' ], breakpoint[ 'line' ] )
'vimspectorBP' if breakpoint[ 'verified' ]
else 'vimspectorBPDisabled',
file_name ) )
def BreakpointsAsQuickFix( self ): def BreakpointsAsQuickFix( self ):

View file

@ -31,3 +31,9 @@ def Int( option: str, default=0 ):
def List( option: str, default=[] ): def List( option: str, default=[] ):
return utils.GetVimList( vim.vars, f'vimspector_{ option }', default ) return utils.GetVimList( vim.vars, f'vimspector_{ option }', default )
def Dict( option: str, default={} ):
return utils.GetVimValue( vim.vars,
f'vimspector_{ option }',
default )

View file

@ -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 }' )

View file

@ -660,13 +660,6 @@ def Call( vimscript_function, *args ):
return vim.eval( call ) return vim.eval( call )
def SignDefined( name ):
if Exists( "*sign_getdefined" ):
return int( vim.eval( f"len( sign_getdefined( '{ Escape( name ) }' ) )" ) )
return False
MEMO = {} MEMO = {}
@ -780,13 +773,3 @@ def WindowID( window, tab=None ):
if tab is None: if tab is None:
tab = window.tabpage tab = window.tabpage
return int( Call( 'win_getid', window.number, tab.number ) ) 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 }' )

View file

@ -65,3 +65,10 @@ augroup TestUICustomistaion
autocmd User VimspectorTerminalOpened call s:SetUpTerminal() autocmd User VimspectorTerminalOpened call s:SetUpTerminal()
autocmd User VimspectorUICreated call s:CustomiseWinBar() autocmd User VimspectorUICreated call s:CustomiseWinBar()
augroup END augroup END
let g:vimspector_sign_priority = {
\ 'vimspectorBP': 3,
\ 'vimspectorBPCond': 2,
\ 'vimspectorBPDisabled': 1,
\ 'vimspectorPC': 999,
\ }

View file

@ -53,14 +53,16 @@ function! Test_Signs_Placed_Using_API_Are_Shown()
call assert_true( exists( '*vimspector#ToggleBreakpoint' ) ) call assert_true( exists( '*vimspector#ToggleBreakpoint' ) )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ line( '.' ), \ line( '.' ),
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
" Disable breakpoint " Disable breakpoint
call vimspector#ToggleBreakpoint() call vimspector#ToggleBreakpoint()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ line( '.' ), \ line( '.' ),
\ 'vimspectorBPDisabled' ) \ 'vimspectorBPDisabled',
\ 9 )
" Remove breakpoint " Remove breakpoint
call vimspector#ToggleBreakpoint() call vimspector#ToggleBreakpoint()
@ -92,14 +94,16 @@ function! Test_Use_Mappings_HUMAN()
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 15, \ 15,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
" Disable the breakpoint " Disable the breakpoint
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 15, \ 15,
\ 'vimspectorBPDisabled' ) \ 'vimspectorBPDisabled',
\ 9 )
" Delete the breakpoint " Delete the breakpoint
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
@ -110,7 +114,8 @@ function! Test_Use_Mappings_HUMAN()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 15, \ 15,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
" Here we go. Start Debugging " Here we go. Start Debugging
call feedkeys( "\<F5>", 'xt' ) call feedkeys( "\<F5>", 'xt' )
@ -184,7 +189,8 @@ function Test_DisableBreakpointWhileDebugging()
\ vimspector#test#signs#AssertSignGroupSingletonAtLine( \ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorCode', \ 'VimspectorCode',
\ 16, \ 16,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
\ } ) \ } )
" Remove the breakpoint " Remove the breakpoint
@ -200,7 +206,8 @@ function Test_DisableBreakpointWhileDebugging()
\ vimspector#test#signs#AssertSignGroupSingletonAtLine( \ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorCode', \ 'VimspectorCode',
\ 16, \ 16,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
\ } ) \ } )
" Run to breakpoint " Run to breakpoint
@ -224,7 +231,8 @@ function Test_DisableBreakpointWhileDebugging()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 16, \ 16,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
" Disable the breakpoint " Disable the breakpoint
call setpos( '.', [ bufnr( 'simple.cpp' ), 16, 1 ] ) call setpos( '.', [ bufnr( 'simple.cpp' ), 16, 1 ] )
@ -232,7 +240,8 @@ function Test_DisableBreakpointWhileDebugging()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 16, \ 16,
\ 'vimspectorBPDisabled' ) \ 'vimspectorBPDisabled',
\ 9 )
" And delete it " And delete it
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
@ -266,14 +275,16 @@ function! Test_Insert_Code_Above_Breakpoint()
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 25, \ 25,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
" Insert a line above the breakpoint " Insert a line above the breakpoint
call append( 22, ' # Test' ) call append( 22, ' # Test' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 5 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 5 )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 26, \ 26,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
" CHeck that we break at the right point " CHeck that we break at the right point
call setpos( '.', [ 0, 1, 1 ] ) call setpos( '.', [ 0, 1, 1 ] )
@ -286,12 +297,14 @@ function! Test_Insert_Code_Above_Breakpoint()
call setpos( '.', [ 0, 26, 1 ] ) call setpos( '.', [ 0, 26, 1 ] )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 26, \ 26,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 26, \ 26,
\ 'vimspectorBPDisabled' ) \ 'vimspectorBPDisabled',
\ 9 )
" Delete it " Delete it
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 26 ) call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 26 )
@ -314,14 +327,16 @@ function! Test_Conditional_Line_Breakpoint()
call feedkeys( "\\\<F9>argc==0\<CR>\<CR>", 'xt' ) call feedkeys( "\\\<F9>argc==0\<CR>\<CR>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 16, \ 16,
\ 'vimspectorBPCond' ) \ 'vimspectorBPCond',
\ 9 )
" Disable the breakpoint " Disable the breakpoint
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 16, \ 16,
\ 'vimspectorBPDisabled' ) \ 'vimspectorBPDisabled',
\ 9 )
" Delete the breakpoint " Delete the breakpoint
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
@ -335,20 +350,23 @@ function! Test_Conditional_Line_Breakpoint()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 16, \ 16,
\ 'vimspectorBPCond' ) \ 'vimspectorBPCond',
\ 9 )
call setpos( '.', [ 0, 9, 1 ] ) call setpos( '.', [ 0, 9, 1 ] )
call vimspector#ToggleBreakpoint() call vimspector#ToggleBreakpoint()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 9, \ 9,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
call setpos( '.', [ 0, 17, 1 ] ) call setpos( '.', [ 0, 17, 1 ] )
call vimspector#ToggleBreakpoint( { 'condition': 'argc == 1' } ) call vimspector#ToggleBreakpoint( { 'condition': 'argc == 1' } )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 17, \ 17,
\ 'vimspectorBPCond' ) \ 'vimspectorBPCond',
\ 9 )
call setpos( '.', [ 0, 1, 1 ] ) call setpos( '.', [ 0, 1, 1 ] )
@ -385,7 +403,8 @@ function! Test_Conditional_Line_Breakpoint_Hit()
call vimspector#test#signs#AssertSignGroupSingletonAtLine( call vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorBP', \ 'VimspectorBP',
\ 14, \ 14,
\ 'vimspectorBPCond' ) \ 'vimspectorBPCond',
\ 9 )
call vimspector#LaunchWithSettings( { 'configuration': 'run' } ) call vimspector#LaunchWithSettings( { 'configuration': 'run' } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 14, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 14, 1 )
@ -526,3 +545,94 @@ function! Test_ListBreakpoints()
call vimspector#test#setup#Reset() call vimspector#test#setup#Reset()
%bwipe! %bwipe!
endfunction 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

View file

@ -23,7 +23,8 @@ function! Test_Go_Simple()
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 4, \ 4,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
call setpos( '.', [ 0, 1, 1 ] ) call setpos( '.', [ 0, 1, 1 ] )

View file

@ -23,7 +23,8 @@ function! Test_Python_Simple()
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 6, \ 6,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
call setpos( '.', [ 0, 1, 1 ] ) call setpos( '.', [ 0, 1, 1 ] )
@ -79,7 +80,8 @@ function! Test_Python_Remote_Attach()
call feedkeys( "\<F9>", 'xt' ) call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP', call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 6, \ 6,
\ 'vimspectorBP' ) \ 'vimspectorBP',
\ 9 )
call setpos( '.', [ 0, 1, 1 ] ) call setpos( '.', [ 0, 1, 1 ] )

View file

@ -46,7 +46,8 @@ endfunction
function! vimspector#test#signs#AssertSignGroupSingletonAtLine( group, function! vimspector#test#signs#AssertSignGroupSingletonAtLine( group,
\ line, \ line,
\ sign_name ) \ sign_name,
\ priority )
\ abort \ abort
let signs = sign_getplaced( '%', { let signs = sign_getplaced( '%', {
@ -62,10 +63,46 @@ function! vimspector#test#signs#AssertSignGroupSingletonAtLine( group,
\ 'Num signs in ' . a:group . ' at ' . a:line ) || \ 'Num signs in ' . a:group . ' at ' . a:line ) ||
\ assert_equal( a:sign_name, \ assert_equal( a:sign_name,
\ signs[ 0 ].signs[ 0 ].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 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 function! vimspector#test#signs#AssertSignGroupEmptyAtLine( group, line ) abort
let signs = sign_getplaced( '%', { let signs = sign_getplaced( '%', {
\ 'group': a:group, \ 'group': a:group,