Compare commits

...
Sign in to create a new pull request.

13 commits

Author SHA1 Message Date
Ben Jackson
208d18ef14 Ignore ATTENTION! when removing mappings 2021-03-10 12:36:28 +00:00
Ben Jackson
938dce1351 FixUp: add test for default-from-calculus 2021-03-10 12:36:28 +00:00
Ben Jackson
b7ca458672 Make any key press dismiss the keyboard popup 2021-03-10 12:36:28 +00:00
Ben Jackson
81fa79ce58 Add up and down frame mappings 2021-03-10 12:36:28 +00:00
Ben Jackson
e99559f6ad Fix default variable values having substitutions from the calculus 2021-03-10 12:36:28 +00:00
Ben Jackson
251a0ff314 Try and be a bit smarter in auto mode 2021-03-10 12:36:28 +00:00
Ben Jackson
5c8143a710 Add vertical (i.e. narrow) layout
This puts the 3 utility windows at the top, horizontally split, with the
code view below.  The terminal window is drawn either vertically split
(if there's room) or horizontally split otherwise.  The output window
remains at tht bottom.

We add equivalent sizing options too, setting some defauts that roughly
work on my macbook pro.

By default we switch to the narrow layout if there are fewer than 160
columns, but this can be overridden by setting g:vimspector_ui_mode.
2021-03-10 12:36:28 +00:00
Ben Jackson
4fbafaa462 Create a messagebox-like interface in vim 2021-03-10 12:36:28 +00:00
Ben Jackson
810946a1c1 Allow forcing selection from the menu with <leader>F5 2021-03-10 12:36:28 +00:00
Ben Jackson
68edda842a Use popup for confirmations (note these have to be async) 2021-03-10 12:36:28 +00:00
Ben Jackson
48076ba2ef Print hotcodereplace messages 2021-03-10 12:36:28 +00:00
Ben Jackson
7b37d4cbf5 Add a way to have adapter specific message handlers 2021-03-10 12:36:28 +00:00
Ben Jackson
57da7ff59b Add rebuild script for fidessa 2021-03-10 12:36:28 +00:00
17 changed files with 493 additions and 70 deletions

View file

@ -41,11 +41,11 @@ function! s:Enabled() abort
return s:enabled
endfunction
function! vimspector#Launch() abort
function! vimspector#Launch( ... ) abort
if !s:Enabled()
return
endif
py3 _vimspector_session.Start()
py3 _vimspector_session.Start( *vim.eval( 'a:000' ) )
endfunction
function! vimspector#LaunchWithSettings( settings ) abort
@ -234,6 +234,20 @@ function! vimspector#GoToFrame() abort
py3 _vimspector_session.ExpandFrameOrThread()
endfunction
function! vimspector#UpFrame() abort
if !s:Enabled()
return
endif
py3 _vimspector_session.UpFrame()
endfunction
function! vimspector#DownFrame() abort
if !s:Enabled()
return
endif
py3 _vimspector_session.DownFrame()
endfunction
function! vimspector#AddWatch( ... ) abort
if !s:Enabled()
return

View file

@ -72,11 +72,7 @@ function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
\ 'mapping': 0
\ }
" When ambiwidth is single, use prettier characters for the border. This
" would look silly when ambiwidth is double.
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
let config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
endif
let config = vimspector#internal#popup#SetBorderChars( config )
if a:is_hover
let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter'
@ -177,9 +173,13 @@ function! vimspector#internal#balloon#CursorFilter( winid, key ) abort
\ . 'line_num = ' . line( '.', a:winid )
\ . ')' )
return 1
elseif popup_filter_menu( a:winid, a:key )
return 1
else
" Any other key dismisses the popup
call vimspector#internal#balloon#Close()
return 1
endif
return popup_filter_menu( a:winid, a:key )
endfunction
" }}}

View file

@ -80,6 +80,31 @@ function! vimspector#internal#neopopup#HideSplash( id ) abort
unlet s:db[ a:id ]
endfunction
function! vimspector#internal#neopopup#Confirm( confirm_id,
\ text,
\ default_value ) abort
" Neovim doesn't have an equivalent of popup_dialog, and it's way too much
" effort to write one, so we just use confirm().
let result = confirm( a:text, '&Yes &No &Default', 3 )
" Map the results to what popup_menu_filter would return (ok s:ConfirmCallback
" in popup.vim)
if result == 2
" No is represented as 0
let result = 0
elseif result == 0
" User pressed ESC/ctrl-c
let result = -1
elseif result == 3
" Default
let result = a:default_value
endif
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
\ int( vim.eval( 'a:confirm_id' ) ),
\ int( vim.eval( 'result' ) ) )
endfunction
" Boilerplate {{{
let &cpoptions=s:save_cpo
unlet s:save_cpo

View file

@ -32,6 +32,105 @@ function! vimspector#internal#popup#HideSplash( id ) abort
call popup_hide( a:id )
endfunction
let s:current_selection = 0
let s:selections = []
let s:text = []
function! s:UpdatePopup( id )
let buf = copy( s:text )
call extend( buf, s:DrawButtons() )
call popup_settext( a:id, buf )
endfunction
function! s:YesNoDefaultFilter( default_value, id, key ) abort
if a:key ==# "\<CR>"
call popup_close( a:id, s:current_selection + 1 )
return 1
elseif a:key ==# 'D' || a:key ==# 'd'
call popup_close( a:id, a:default_value )
return 1
elseif index( [ "\<Tab>", "\<Right>" ], a:key ) >= 0
let s:current_selection = ( s:current_selection + 1 ) % len( s:selections )
call s:UpdatePopup( a:id )
return 1
elseif index( [ "\<S-Tab>", "\<Left>" ], a:key ) >= 0
let s:current_selection = s:current_selection == 0
\ ? len( s:selections ) - 1: s:current_selection - 1
call s:UpdatePopup( a:id )
return 1
endif
return popup_filter_yesno( a:id, a:key )
endfunction
function! s:ConfirmCallback( confirm_id, id, result ) abort
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
\ int( vim.eval( 'a:confirm_id' ) ),
\ int( vim.eval( 'a:result' ) ) )
endfunction
function! s:SelectionPosition( idx ) abort
return a:idx == 0 ? 0 : len( join( s:selections[ : a:idx - 1 ], ' ' ) ) + 1
endfunction
function! s:DrawButtons() abort
return [ {
\ 'text': join( s:selections, ' ' ),
\ 'props': [
\ {
\ 'col': s:SelectionPosition( s:current_selection ) + 1,
\ 'length': len( s:selections[ s:current_selection ] ),
\ 'type': 'VimspectorSelectedItem'
\ },
\ ]
\ } ]
endfunction
function! vimspector#internal#popup#Confirm(
\ confirm_id,
\ text,
\ options,
\ default_value ) abort
silent! call prop_type_add( 'VimspectorSelectedItem', {
\ 'highlight': 'PMenuSel'
\ } )
let lines = split( a:text, "\n", v:true )
let buf = []
for line in lines
call add( buf, { 'text': line, 'props': [] } )
endfor
call add( buf, { 'text': '', 'props': [] } )
let s:selections = a:options
let s:current_selection = ( a:default_value - 1 )
let s:text = copy( buf )
call extend( buf, s:DrawButtons() )
let config = {
\ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ),
\ 'filter': function( 's:YesNoDefaultFilter', [ a:default_value ] ),
\ 'mapping': v:false,
\ }
let config = vimspector#internal#popup#SetBorderChars( config )
return popup_dialog( buf, config )
endfunction
function! vimspector#internal#popup#SetBorderChars( config )
" When ambiwidth is single, use prettier characters for the border. This
" would look silly when ambiwidth is double.
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
let a:config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
endif
return a:config
endfunction
" Boilerplate {{{
let &cpoptions=s:save_cpo
unlet s:save_cpo

View file

@ -35,6 +35,8 @@ let s:mappings = get( g:, 'vimspector_enable_mappings', '' )
nnoremap <silent> <Plug>VimspectorContinue
\ :<c-u>call vimspector#Continue()<CR>
nnoremap <silent> <Plug>VimspectorLaunch
\ :<c-u>call vimspector#Launch( v:true )<CR>
nnoremap <silent> <Plug>VimspectorStop
\ :<c-u>call vimspector#Stop()<CR>
nnoremap <silent> <Plug>VimspectorRestart
@ -67,6 +69,11 @@ nnoremap <silent> <Plug>VimspectorBalloonEval
xnoremap <silent> <Plug>VimspectorBalloonEval
\ :<c-u>call vimspector#ShowEvalBalloon( 1 )<CR>
nnoremap <silent> <Plug>VimspectorUpFrame
\ :<c-u>call vimspector#UpFrame()<CR>
nnoremap <silent> <Plug>VimspectorDownFrame
\ :<c-u>call vimspector#DownFrame()<CR>
if s:mappings ==# 'VISUAL_STUDIO'
nmap <F5> <Plug>VimspectorContinue
nmap <S-F5> <Plug>VimspectorStop
@ -79,6 +86,7 @@ if s:mappings ==# 'VISUAL_STUDIO'
nmap <S-F11> <Plug>VimspectorStepOut
elseif s:mappings ==# 'HUMAN'
nmap <F5> <Plug>VimspectorContinue
nmap <leader><F5> <Plug>VimspectorLaunch
nmap <F3> <Plug>VimspectorStop
nmap <F4> <Plug>VimspectorRestart
nmap <F6> <Plug>VimspectorPause

View file

@ -0,0 +1,43 @@
# vimspector - A multi-language debugging system for Vim
# Copyright 2021 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.
from vimspector.debug_session import DebugSession
from vimspector import utils
class JavaDebugAdapter( object ):
def __init__( self, debug_session: DebugSession ):
self.debug_session = debug_session
def OnEvent_hotcodereplace( self, message ):
# Hack for java debug server hot-code-replace
body = message.get( 'body' ) or {}
if body.get( 'type' ) != 'hotcodereplace':
return
if body.get( 'changeType' ) == 'BUILD_COMPLETE':
def handler( result ):
if result == 1:
self.debug_session._connection.DoRequest( None, {
'command': 'redefineClasses',
'arguments': {},
} )
utils.Confirm( self.debug_session._api_prefix,
'Code has changed, hot reload?',
handler )
elif body.get( 'message' ):
utils.UserMessage( 'Hot code replace: ' + body[ 'message' ] )

View file

@ -29,14 +29,14 @@ class PendingRequest( object ):
class DebugAdapterConnection( object ):
def __init__( self, handler, send_func ):
def __init__( self, handlers, send_func ):
self._logger = logging.getLogger( __name__ )
utils.SetUpLogging( self._logger )
self._Write = send_func
self._SetState( 'READ_HEADER' )
self._buffer = bytes()
self._handler = handler
self._handlers = handlers
self._next_message_id = 0
self._outstanding_requests = {}
@ -124,7 +124,7 @@ class DebugAdapterConnection( object ):
def Reset( self ):
self._Write = None
self._handler = None
self._handlers = None
while self._outstanding_requests:
_, request = self._outstanding_requests.popitem()
@ -237,7 +237,7 @@ class DebugAdapterConnection( object ):
def _OnMessageReceived( self, message ):
if not self._handler:
if not self._handlers:
return
if message[ 'type' ] == 'response':
@ -270,25 +270,21 @@ class DebugAdapterConnection( object ):
self._logger.error( 'Request failed: {0}'.format( reason ) )
if request.failure_handler:
request.failure_handler( reason, message )
elif 'OnFailure' in dir( self._handler ):
self._handler.OnFailure( reason, request.msg, message )
else:
utils.UserMessage( 'Request failed: {0}'.format( reason ) )
for h in self._handlers:
if 'OnFailure' in dir( h ):
h.OnFailure( reason, request.msg, message )
elif message[ 'type' ] == 'event':
method = 'OnEvent_' + message[ 'event' ]
if method in dir( self._handler ):
getattr( self._handler, method )( message )
else:
utils.UserMessage( 'Unhandled event: {0}'.format( message[ 'event' ] ),
persist = True )
for h in self._handlers:
if method in dir( h ):
getattr( h, method )( message )
elif message[ 'type' ] == 'request':
method = 'OnRequest_' + message[ 'command' ]
if method in dir( self._handler ):
getattr( self._handler, method )( message )
else:
utils.UserMessage(
'Unhandled request: {0}'.format( message[ 'command' ] ),
persist = True )
for h in self._handlers:
if method in dir( h ):
getattr( h, method )( message )
def _KillTimer( request ):

View file

@ -21,6 +21,7 @@ import shlex
import subprocess
import functools
import vim
import importlib
from vimspector import ( breakpoints,
code,
@ -99,7 +100,7 @@ class DebugSession( object ):
return launch_config_file, configurations
def Start( self, launch_variables = None ):
def Start( self, force_choose=False, launch_variables = None ):
# We mutate launch_variables, so don't mutate the default argument.
# https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
if launch_variables is None:
@ -134,6 +135,11 @@ class DebugSession( object ):
if 'configuration' in launch_variables:
configuration_name = launch_variables.pop( 'configuration' )
elif force_choose:
# Always display the menu
configuration_name = utils.SelectFromList(
'Which launch configuration?',
sorted( configurations.keys() ) )
elif ( len( configurations ) == 1 and
next( iter( configurations.values() ) ).get( "autoselect", True ) ):
configuration_name = next( iter( configurations.keys() ) )
@ -571,6 +577,14 @@ class DebugSession( object ):
def ExpandFrameOrThread( self ):
self._stackTraceView.ExpandFrameOrThread()
@IfConnected()
def UpFrame( self ):
self._stackTraceView.UpFrame()
@IfConnected
def DownFrame( self ):
self._stackTraceView.DownCFrame()
def ToggleLog( self ):
if self._HasUI():
return self.ShowOutput( 'Vimspector' )
@ -655,6 +669,30 @@ class DebugSession( object ):
vim.command( 'tab split' )
self._uiTab = vim.current.tabpage
mode = settings.Get( 'ui_mode' )
if mode == 'auto':
# Go vertical if there isn't enough horizontal space for at least:
# the left bar width
# + the code min width
# + the terminal min width
# + enough space for a sign column and number column?
min_width = ( settings.Int( 'sidebar_width' )
+ 1 + 2 + 3
+ settings.Int( 'code_minwidth' )
+ 1 + settings.Int( 'terminal_minwidth' ) )
mode = ( 'vertical'
if vim.options[ 'columns' ] < min_width
else 'horizontal' )
if mode == 'vertical':
self._SetUpUIVertical()
else:
self._SetUpUIHorizontal()
def _SetUpUIHorizontal( self ):
# Code window
code_window = vim.current.window
self._codeView = code.CodeView( code_window, self._api_prefix )
@ -695,6 +733,66 @@ class DebugSession( object ):
# TODO: If/when we support multiple sessions, we'll need some way to
# indicate which tab was created and store all the tabs
vim.vars[ 'vimspector_session_windows' ] = {
'mode': 'horizontal',
'tabpage': self._uiTab.number,
'code': utils.WindowID( code_window, self._uiTab ),
'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ),
'variables': utils.WindowID( vars_window, self._uiTab ),
'watches': utils.WindowID( watch_window, self._uiTab ),
'output': utils.WindowID( output_window, self._uiTab ),
'eval': None # this is going to be updated every time eval popup is opened
}
with utils.RestoreCursorPosition():
with utils.RestoreCurrentWindow():
with utils.RestoreCurrentBuffer( vim.current.window ):
vim.command( 'doautocmd User VimspectorUICreated' )
def _SetUpUIVertical( self ):
# Code window
code_window = vim.current.window
self._codeView = code.CodeView( code_window, self._api_prefix )
# Call stack
vim.command(
f'topleft { settings.Int( "topbar_height" ) }new' )
stack_trace_window = vim.current.window
one_third = int( vim.eval( 'winwidth( 0 )' ) ) / 3
self._stackTraceView = stack_trace.StackTraceView( self,
stack_trace_window )
# Watches
vim.command( 'leftabove vertical new' )
watch_window = vim.current.window
# Variables
vim.command( 'leftabove vertical new' )
vars_window = vim.current.window
with utils.LetCurrentWindow( vars_window ):
vim.command( f'{ one_third }wincmd |' )
with utils.LetCurrentWindow( watch_window ):
vim.command( f'{ one_third }wincmd |' )
with utils.LetCurrentWindow( stack_trace_window ):
vim.command( f'{ one_third }wincmd |' )
self._variablesView = variables.VariablesView( vars_window,
watch_window )
# Output/logging
vim.current.window = code_window
vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' )
output_window = vim.current.window
self._outputView = output.DAPOutputView( output_window,
self._api_prefix )
# TODO: If/when we support multiple sessions, we'll need some way to
# indicate which tab was created and store all the tabs
vim.vars[ 'vimspector_session_windows' ] = {
'mode': 'vertical',
'tabpage': self._uiTab.number,
'code': utils.WindowID( code_window, self._uiTab ),
'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ),
@ -781,8 +879,21 @@ class DebugSession( object ):
self._splash_screen,
"Unable to start adapter" )
else:
if 'custom_handler' in self._adapter:
spec = self._adapter[ 'custom_handler' ]
if isinstance( spec, dict ):
module = spec[ 'module' ]
cls = spec[ 'class' ]
else:
module, cls = spec.rsplit( '.', 1 )
CustomHandler = getattr( importlib.import_module( module ), cls )
handlers = [ CustomHandler( self ), self ]
else:
handlers = [ self ]
self._connection = debug_adapter_connection.DebugAdapterConnection(
self,
handlers,
lambda msg: utils.Call(
"vimspector#internal#{}#Send".format( self._connection_type ),
msg ) )
@ -790,39 +901,52 @@ class DebugSession( object ):
self._logger.info( 'Debug Adapter Started' )
def _StopDebugAdapter( self, interactive = False, callback = None ):
self._splash_screen = utils.DisplaySplash(
self._api_prefix,
self._splash_screen,
"Shutting down debug adapter..." )
def disconnect( arguments = {} ):
self._splash_screen = utils.DisplaySplash(
self._api_prefix,
self._splash_screen,
"Shutting down debug adapter..." )
def handler( *args ):
self._splash_screen = utils.HideSplash( self._api_prefix,
self._splash_screen )
def handler( *args ):
self._splash_screen = utils.HideSplash( self._api_prefix,
self._splash_screen )
if callback:
self._logger.debug( "Setting server exit handler before disconnect" )
assert not self._run_on_server_exit
self._run_on_server_exit = callback
if callback:
self._logger.debug( "Setting server exit handler before disconnect" )
assert not self._run_on_server_exit
self._run_on_server_exit = callback
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
self._connection_type ) )
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
self._connection_type ) )
arguments = {}
if ( interactive and
self._server_capabilities.get( 'supportTerminateDebuggee' ) ):
if self._stackTraceView.AnyThreadsRunning():
choice = utils.AskForInput( "Terminate debuggee [Y/N/default]? ", "" )
if choice == "Y" or choice == "y":
self._connection.DoRequest( handler, {
'command': 'disconnect',
'arguments': {},
}, failure_handler = handler, timeout = 5000 )
if not interactive:
disconnect()
elif not self._server_capabilities.get( 'supportTerminateDebuggee' ):
disconnect()
elif not self._stackTraceView.AnyThreadsRunning():
disconnect()
else:
def handle_choice( choice ):
arguments = {}
if choice == 1:
arguments[ 'terminateDebuggee' ] = True
elif choice == "N" or choice == 'n':
elif choice == 0:
arguments[ 'terminateDebuggee' ] = False
elif choice == -1:
# Abort
return
self._connection.DoRequest( handler, {
'command': 'disconnect',
'arguments': arguments,
}, failure_handler = handler, timeout = 5000 )
disconnect( arguments )
# TODO: Use the 'tarminate' request if supportsTerminateRequest set
utils.Confirm( self._api_prefix,
"Terminate debuggee?",
handle_choice,
default_value = 3 )
def _PrepareAttach( self, adapter_config, launch_config ):

View file

@ -159,7 +159,8 @@ GADGETS = {
"port": "${DAPPort}",
"configuration": {
"cwd": "${workspaceRoot}"
}
},
'custom_handler': 'vimspector.custom.java.JavaDebugAdapter'
}
},
},

View file

@ -20,11 +20,20 @@ from vimspector import utils
DEFAULTS = {
# UI
'bottombar_height': 10,
'sidebar_width': 50,
'code_minwidth': 82,
'terminal_maxwidth': 80,
'terminal_minwidth': 10,
'ui_mode': 'auto',
'bottombar_height': 10,
# For ui_mode = 'horizontal':
'sidebar_width': 50,
'code_minwidth': 82,
'terminal_maxwidth': 80,
'terminal_minwidth': 10,
# For ui_mode = 'vertical':
'topbar_height': 15,
'code_minheight': 20,
'terminal_maxheight': 15,
'terminal_minheight': 5,
# Signs
'sign_priority': {

View file

@ -367,6 +367,42 @@ class StackTraceView( object ):
self._JumpToFrame( frame )
def _GetFrameOffset( self, delta ):
thread: Thread
for thread in self._threads:
if thread != self._current_thread:
continue
if not thread.stacktrace:
return
frame_idx = None
for index, frame in enumerate( thread.stacktrace ):
if frame == self._current_frame:
frame_idx = index
break
if frame_idx is not None:
target_idx = frame_idx + delta
if target_idx >= 0 and target_idx < len( thread.stacktrace ):
return thread.stacktrace[ target_idx ]
break
def UpFrame( self ):
frame = self._GetFrameOffset( self, -1 )
if frame:
self._JumpToFrame( frame, 'up' )
def DownFrame( self ):
frame = self._GetFrameOffset( self, 1 )
if frame:
self._JumpToFrame( frame, 'down' )
def AnyThreadsRunning( self ):
for thread in self._threads:
if thread.state != Thread.TERMINATED:

View file

@ -23,7 +23,18 @@ def LaunchTerminal( api_prefix,
env = params.get( 'env' ) or {}
term_options = {
'vertical': 1,
# Use a vsplit in widw mode, and a horizontal split in narrow mode
'vertical': (
# Use a vsplit if we're in horizontal mode, or if we're in vertical mode,
# but there's enough space for the code and the terminal horizontally
# (this gives more vertical space, which becomes at at premium)
vim.vars[ 'vimspector_session_windows' ][ 'mode' ] == 'horizontal' or
vim.options[ 'columns' ] >= (
settings.Int( 'terminal_maxwidth' ) +
settings.Int( 'code_minwidth' ) +
1 # for the split decoration
)
),
'norestore': 1,
'cwd': cwd,
'env': env,
@ -50,13 +61,23 @@ def LaunchTerminal( api_prefix,
# If we're making a vertical split from the code window, make it no more
# than 80 columns and no fewer than 10. Also try and keep the code window
# at least 82 columns
if term_options[ 'vertical' ] and not term_options.get( 'curwin', 0 ):
if term_options.get( 'curwin', 0 ):
pass
elif term_options[ 'vertical' ]:
term_options[ 'term_cols' ] = max(
min ( int( vim.eval( 'winwidth( 0 )' ) )
- settings.Int( 'code_minwidth' ),
settings.Int( 'terminal_maxwidth' ) ),
settings.Int( 'terminal_minwidth' )
)
else:
term_options[ 'term_rows' ] = max(
min ( int( vim.eval( 'winheight( 0 )' ) )
- settings.Int( 'code_minheight' ),
settings.Int( 'terminal_maxheight' ) ),
settings.Int( 'terminal_minheight' )
)
buffer_number = int(
utils.Call(

View file

@ -375,6 +375,35 @@ def AskForInput( prompt, default_value = None, completion = None ):
return None
CONFIRM = {}
CONFIRM_ID = 0
def ConfirmCallback( confirm_id, result ):
try:
handler = CONFIRM.pop( confirm_id )
except KeyError:
UserMessage( f"Internal error: unexpected callback id { confirm_id }",
persist = True,
error = True )
return
handler( result )
def Confirm( api_prefix, prompt, handler, default_value = 3, options = None ):
global CONFIRM_ID
if not options:
options = [ '(Y)es', '(N)o', '(D)efault' ]
CONFIRM_ID += 1
CONFIRM[ CONFIRM_ID ] = handler
Call( f'vimspector#internal#{ api_prefix }popup#Confirm',
CONFIRM_ID,
prompt,
options,
default_value )
def AppendToBuffer( buf, line_or_lines, modified=False ):
line = 1
try:
@ -403,8 +432,10 @@ def AppendToBuffer( buf, line_or_lines, modified=False ):
def ClearBuffer( buf ):
def ClearBuffer( buf, modified = False ):
buf[ : ] = None
if not modified:
buf.options[ 'modified' ] = False
def SetBufferContents( buf, lines, modified=False ):
@ -494,7 +525,6 @@ def _Substitute( template, mapping ):
if mo.group( 'braceddefault' ) is not None:
named = mo.group( 'defname' )
if named not in mapping:
''
raise MissingSubstitution(
named,
mo.group( 'default' ).replace( '\\}', '}' ) )
@ -536,8 +566,11 @@ def ExpandReferencesInString( orig_s,
if default_value is None and e.default_value is not None:
try:
default_value = _Substitute( e.default_value, mapping )
except MissingSubstitution:
default_value = e.default_value
except MissingSubstitution as e2:
if e2.name in calculus:
default_value = calculus[ e2.name ]()
else:
default_value = e.default_value
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
default_value )

6
rebuild Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/env bash
set -e
./install_gadget.py --all --force-all --basedir ../vimspector-fidessa

View file

@ -115,12 +115,16 @@ function! s:OnDebugEnd() abort
let original_buf = bufnr()
let hidden = &hidden
augroup VimspectorSwapExists
au!
autocmd SwapExists * let v:swapchoice='o'
augroup END
try
set hidden
for bufnr in keys( s:mapped )
try
execute 'noautocmd buffer' bufnr
execute 'buffer' bufnr
silent! nunmap <buffer> <LocalLeader>dn
silent! nunmap <buffer> <LocalLeader>ds
silent! nunmap <buffer> <LocalLeader>df
@ -136,13 +140,15 @@ function! s:OnDebugEnd() abort
let &hidden = hidden
endtry
au! VimspectorSwapExists
let s:mapped = {}
endfunction
augroup TestCustomMappings
au!
autocmd User VimspectorJumpedToFrame call s:OnJumpToFrame()
autocmd User VimspectorDebugEnded call s:OnDebugEnd()
autocmd User VimspectorDebugEnded ++nested call s:OnDebugEnd()
augroup END
" }}}

View file

@ -4,7 +4,7 @@
<artifactId>TestApplication</artifactId>
<version>1</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>

View file

@ -35,6 +35,7 @@ class TestExpandReferencesInDict( unittest.TestCase ):
'one': '${one}',
'two': '${one} and ${two}',
'three': '${three}',
'three_with_default': '${three_with_default:${three\\}}', # uses calculus
'four': '${four}',
'five': '${five}',
'list': [ '*${words}' ],
@ -58,6 +59,7 @@ class TestExpandReferencesInDict( unittest.TestCase ):
'one': 'one',
'two': 'one and TWO',
'three': '3',
'three_with_default': '3',
'four': 'typed text',
'five': '5ive!',
'list': [ 'these', 'are', 'some', 'words' ],