diff --git a/README.md b/README.md index cfe8c18..40c2b7f 100644 --- a/README.md +++ b/README.md @@ -829,6 +829,28 @@ It allows you to debug scripts running inside chrome from within Vim. comment](https://github.com/puremourning/vimspector/issues/3#issuecomment-576916076) for instructions. +# Customisation + +There is very limited support for customistaion of the UI. + +## Changing the default signs + +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. +* `vimspectorBPDisabled`: A disabled breakpoint +* `vimspectorPC` The program counter, i.e. current line. + +For example, to use some unicode symbols, you could put this in your `vimrc`: + +```viml +sign define vimspectorBP text=🔴 texthl=Normal +sign define vimspectorBPDisabled text=🔵 texthl=Normal +sign define vimspectorPC text=🔶 texthl=SpellBad +``` + # FAQ 1. Q: Does it work? A: Yeah, sort of. It's _incredibly_ buggy and unpolished. diff --git a/python3/vimspector/breakpoints.py b/python3/vimspector/breakpoints.py index 7e767d0..6e0b76f 100644 --- a/python3/vimspector/breakpoints.py +++ b/python3/vimspector/breakpoints.py @@ -52,9 +52,11 @@ class ProjectBreakpoints( object ): self._next_sign_id = 1 - # TODO: Change to sign_define ? - vim.command( 'sign define vimspectorBP text==> texthl=Error' ) - vim.command( 'sign define vimspectorBPDisabled text=!> texthl=Warning' ) + if not utils.SignDefined( 'vimspectorBP' ): + vim.command( 'sign define vimspectorBP text==> texthl=Error' ) + + if not utils.SignDefined( 'vimspectorBPDisabled' ): + vim.command( 'sign define vimspectorBPDisabled text=!> texthl=Warning' ) def ConnectionUp( self, connection ): diff --git a/python3/vimspector/code.py b/python3/vimspector/code.py index 27d9586..4b21192 100644 --- a/python3/vimspector/code.py +++ b/python3/vimspector/code.py @@ -50,7 +50,8 @@ class CodeView( object ): vim.command( 'nnoremenu WinBar.Restart :call vimspector#Restart()' ) vim.command( 'nnoremenu WinBar.Reset :call vimspector#Reset()' ) - vim.command( 'sign define vimspectorPC text=-> texthl=Search' ) + if not utils.SignDefined( 'vimspectorPC' ): + vim.command( 'sign define vimspectorPC text=-> texthl=Search' ) def SetCurrentFrame( self, frame ): diff --git a/python3/vimspector/utils.py b/python3/vimspector/utils.py index a9f55df..b04f28f 100644 --- a/python3/vimspector/utils.py +++ b/python3/vimspector/utils.py @@ -20,6 +20,8 @@ import contextlib import vim import json import string +import functools + _log_handler = logging.FileHandler( os.path.expanduser( '~/.vimspector.log' ), mode = 'w' ) @@ -103,7 +105,7 @@ def SetUpHiddenBuffer( buf, name ): def SetUpPromptBuffer( buf, name, prompt, callback, hidden=False ): # This feature is _super_ new, so only enable when available - if not int( vim.eval( "exists( '*prompt_setprompt' )" ) ): + if not Exists( '*prompt_setprompt' ): return SetUpHiddenBuffer( buf, name ) buf.options[ 'buftype' ] = 'prompt' @@ -467,3 +469,35 @@ def Call( vimscript_function, *args ): call += ')' _logger.debug( 'Calling: {}'.format( 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 = {} + + +def memoize( func ): + global MEMO + + @functools.wraps( func ) + def wrapper( *args, **kwargs ): + dct = MEMO.setdefault( func, {} ) + key = ( args, frozenset( kwargs.items() ) ) + try: + return dct[ key ] + except KeyError: + result = func( *args, **kwargs ) + dct[ key ] = result + return result + + return wrapper + + +@memoize +def Exists( expr ): + return int( vim.eval( f'exists( "{ expr }" )' ) )