diff --git a/autoload/vimspector/internal/neopopup.vim b/autoload/vimspector/internal/neopopup.vim index 189c78c..9f35914 100644 --- a/autoload/vimspector/internal/neopopup.vim +++ b/autoload/vimspector/internal/neopopup.vim @@ -82,29 +82,52 @@ endfunction function! vimspector#internal#neopopup#Confirm( confirm_id, \ text, - \ default_value ) abort + \ options, + \ default_value, + \ keys ) 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 ) + let prompt = a:text + for opt in a:options + let prompt .= ' ' . opt + endfor + let prompt .= ': ' + + " Annoyingly we can't use confirm() here because for some reason it doesn't + " render properly in a channel callback. So we use input() and mimic dialog + " behaviour. + try + let result = input( prompt, a:keys[ a:default_value - 1 ] ) + catch /.*/ + let result = -1 + endtry " 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 + if result == '' " User pressed ESC/ctrl-c let result = -1 - elseif result == 3 - " Default - let result = a:default_value + else + let index = 1 + for k in a:keys + if k ==? result + let result = index + break + endif + let index += 2 + endfor + + if index >= len( a:keys ) + let result = -1 + endif 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 diff --git a/autoload/vimspector/internal/popup.vim b/autoload/vimspector/internal/popup.vim index 5978987..db2c2fd 100644 --- a/autoload/vimspector/internal/popup.vim +++ b/autoload/vimspector/internal/popup.vim @@ -42,13 +42,10 @@ function! s:UpdatePopup( id ) call popup_settext( a:id, buf ) endfunction -function! s:YesNoDefaultFilter( default_value, id, key ) abort +function! s:ConfirmKeyFilter( keys, id, key ) abort if a:key ==# "\" 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( [ "\", "\" ], a:key ) >= 0 let s:current_selection = ( s:current_selection + 1 ) % len( s:selections ) call s:UpdatePopup( a:id ) @@ -58,9 +55,19 @@ function! s:YesNoDefaultFilter( default_value, id, key ) abort \ ? len( s:selections ) - 1: s:current_selection - 1 call s:UpdatePopup( a:id ) return 1 + elseif a:key ==# "\" || a:key ==# "\" + call popup_close( a:id, -1 ) + return 1 endif - return popup_filter_yesno( a:id, a:key ) + let index = 1 + for key in a:keys + if a:key ==? key + call popup_close( a:id, index ) + return 1 + endif + let index += 1 + endfor endfunction function! s:ConfirmCallback( confirm_id, id, result ) abort @@ -90,7 +97,8 @@ function! vimspector#internal#popup#Confirm( \ confirm_id, \ text, \ options, - \ default_value ) abort + \ default_value, + \ keys ) abort silent! call prop_type_add( 'VimspectorSelectedItem', { \ 'highlight': 'PMenuSel' @@ -112,7 +120,7 @@ function! vimspector#internal#popup#Confirm( let config = { \ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ), - \ 'filter': function( 's:YesNoDefaultFilter', [ a:default_value ] ), + \ 'filter': function( 's:ConfirmKeyFilter', [ a:keys ] ), \ 'mapping': v:false, \ } let config = vimspector#internal#popup#SetBorderChars( config ) diff --git a/python3/vimspector/custom/java.py b/python3/vimspector/custom/java.py index 83705c1..c2a2264 100644 --- a/python3/vimspector/custom/java.py +++ b/python3/vimspector/custom/java.py @@ -14,7 +14,7 @@ # limitations under the License. from vimspector.debug_session import DebugSession -from vimspector import utils +from vimspector import utils, settings class JavaDebugAdapter( object ): @@ -36,8 +36,16 @@ class JavaDebugAdapter( object ): 'arguments': {}, } ) - utils.Confirm( self.debug_session._api_prefix, - 'Code has changed, hot reload?', - handler ) + mode = settings.Get( 'java_hotcodereplace_mode' ) + if mode == 'ask': + utils.Confirm( self.debug_session._api_prefix, + 'Code has changed, hot reload?', + handler, + default_value = 1 ) + elif mode == 'always': + self.debug_session._connection.DoRequest( None, { + 'command': 'redefineClasses', + 'arguments': {}, + } ) elif body.get( 'message' ): utils.UserMessage( 'Hot code replace: ' + body[ 'message' ] ) diff --git a/python3/vimspector/debug_session.py b/python3/vimspector/debug_session.py index 12e4563..255e072 100644 --- a/python3/vimspector/debug_session.py +++ b/python3/vimspector/debug_session.py @@ -949,10 +949,12 @@ class DebugSession( object ): def handle_choice( choice ): arguments = {} if choice == 1: + # yes arguments[ 'terminateDebuggee' ] = True - elif choice == 0: + elif choice == 2: + # no arguments[ 'terminateDebuggee' ] = False - elif choice == -1: + else: # Abort return @@ -961,7 +963,9 @@ class DebugSession( object ): utils.Confirm( self._api_prefix, "Terminate debuggee?", handle_choice, - default_value = 3 ) + default_value = 3, + options = [ '(Y)es', '(N)o', '(D)efault' ], + keys = [ 'y', 'n', 'd' ] ) def _PrepareAttach( self, adapter_config, launch_config ): diff --git a/python3/vimspector/settings.py b/python3/vimspector/settings.py index e9e76ea..a060543 100644 --- a/python3/vimspector/settings.py +++ b/python3/vimspector/settings.py @@ -59,7 +59,10 @@ DEFAULTS = { 'expand_or_jump': [ '', '<2-LeftMouse>' ], 'focus_thread': [ '' ], } - } + }, + + # Custom + 'java_hotcodereplace_mode': 'ask', } diff --git a/python3/vimspector/utils.py b/python3/vimspector/utils.py index ca0b80a..53ebd3b 100644 --- a/python3/vimspector/utils.py +++ b/python3/vimspector/utils.py @@ -390,18 +390,26 @@ def ConfirmCallback( confirm_id, result ): handler( result ) -def Confirm( api_prefix, prompt, handler, default_value = 3, options = None ): - global CONFIRM_ID +def Confirm( api_prefix, + prompt, + handler, + default_value = 2, + options: list = None, + keys: list = None ): if not options: - options = [ '(Y)es', '(N)o', '(D)efault' ] + options = [ '(Y)es', '(N)o' ] + if not keys: + keys = [ 'y', 'n' ] + global CONFIRM_ID CONFIRM_ID += 1 CONFIRM[ CONFIRM_ID ] = handler Call( f'vimspector#internal#{ api_prefix }popup#Confirm', CONFIRM_ID, prompt, options, - default_value ) + default_value, + keys ) def AppendToBuffer( buf, line_or_lines, modified=False ):