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

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

View file

@ -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()<CR>' )
vim.command( 'nnoremenu WinBar.✕ :call vimspector#Reset()<CR>' )
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 ):

View file

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

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