Merge branch 'master' into master

This commit is contained in:
Ben Jackson 2021-03-19 23:05:19 +00:00 committed by GitHub
commit 2d589475eb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 709 additions and 50 deletions

View file

@ -17,12 +17,12 @@ assignees: ''
> Please answer the following questions > Please answer the following questions
* Does your issue reproduce using `vim -Nu /path/to/vimspector/support/minimal_vimrc` ? \[Yes/No] * Does your issue reproduce using `vim --clean -Nu /path/to/vimspector/support/minimal_vimrc` ? \[Yes/No]
* If you are using Neovim, does your issue reproduce using Vim? \[Yes/No] * If you are using Neovim, does your issue reproduce using Vim? \[Yes/No]
> List of steps to reproduce: > List of steps to reproduce:
> 1. Run `vim -Nu /path/to/vimspector/support/minimal_vimrc` > 1. Run `vim ---clean Nu /path/to/vimspector/support/minimal_vimrc`
> 2. Open _this project_... > 2. Open _this project_...
> 3. Press _this sequence of keys_ > 3. Press _this sequence of keys_

View file

@ -83,7 +83,7 @@ in the issue report.
The minimal vimrc is in `support/test/minimal_vimrc` and can be used as follows: The minimal vimrc is in `support/test/minimal_vimrc` and can be used as follows:
``` ```
vim -Nu /path/to/vimspector/support/minimal_vimrc vim --clean -Nu /path/to/vimspector/support/minimal_vimrc
``` ```
## Pull Requests ## Pull Requests

View file

@ -656,18 +656,23 @@ personal and so you should work out what you like and use vim's powerful mapping
features to set your own mappings. To that end, Vimspector defines the following features to set your own mappings. To that end, Vimspector defines the following
`<Plug>` mappings: `<Plug>` mappings:
* `<Plug>VimspectorContinue` | Mapping | Function | API |
* `<Plug>VimspectorStop` | --- | --- | --- |
* `<Plug>VimspectorRestart` | `<Plug>VimspectorContinue` | When debugging, continue. Otherwise start debugging. | `vimspector#Continue()` |
* `<Plug>VimspectorPause` | `<Plug>VimspectorStop` | Stop debugging. | `vimspector#Stop()` |
* `<Plug>VimspectorToggleBreakpoint` | `<Plug>VimpectorRestart` | Restart debugging with the same configuration. | `vimspector#Restart()` |
* `<Plug>VimspectorToggleConditionalBreakpoint` | `<Plug>VimspectorPause` | Pause debuggee. | `vimspector#Pause()` |
* `<Plug>VimspectorAddFunctionBreakpoint` | `<Plug>VimspectorToggleBreakpoint` | Toggle line breakpoint on the current line. | `vimspector#ToggleBreakpoint()` |
* `<Plug>VimspectorStepOver` | `<Plug>VimspectorToggleConditionalBreakpoint` | Toggle conditional line breakpoint on the current line. | `vimspector#ToggleBreakpoint( { trigger expr, hit count expr } )` |
* `<Plug>VimspectorStepInto` | `<Plug>VimspectorAddFunctionBreakpoint` | Add a function breakpoint for the expression under cursor | `vimspector#AddFunctionBreakpoint( '<cexpr>' )` |
* `<Plug>VimspectorStepOut` | `<Plug>VimspectorRunToCursor` | Run to Cursor | `vimspector#RunToCursor()` |
* `<Plug>VimspectorRunToCursor` | `<Plug>VimspectorStepOver` | Step Over | `vimspector#StepOver()` |
* `<Plug>VimspectorBalloonEval` | `<Plug>VimspectorStepInto` | Step Into | `vimspector#StepInto()` |
| `<Plug>VimspectorStepOut` | Step out of current function scope | `vimspector#StepOut()` |
| `<Plug>VimspectorUpFrame` | Move up a frame in the current call stack | `vimspector#UpFrame()` |
| `<Plug>VimspectorDownFrame` | Move down a frame in the current call stack | `vimspector#DownFrame()` |
| `<Plug>VimspectorBalloonEval` | Evaluate expression under cursor (or visual) in popup | *internal* |
These map roughly 1-1 with the API functions below. These map roughly 1-1 with the API functions below.
@ -695,17 +700,17 @@ loading vimspector**:
let g:vimspector_enable_mappings = 'VISUAL_STUDIO' let g:vimspector_enable_mappings = 'VISUAL_STUDIO'
``` ```
| Key | Function | API | | Key | Mapping | Function
| --- | --- | --- | | --- | --- | ---
| `F5` | When debugging, continue. Otherwise start debugging. | `vimspector#Continue()` | | `F5` | `<Plug>VimspectorContinue` | When debugging, continue. Otherwise start debugging.
| `Shift F5` | Stop debugging. | `vimspector#Stop()` | | `Shift F5` | `<Plug>VimspectorStop` | Stop debugging.
| `Ctrl Shift F5` | Restart debugging with the same configuration. | `vimspector#Restart()` | | `Ctrl Shift F5` | `<Plug>VimspectorRestart` | Restart debugging with the same configuration.
| `F6` | Pause debuggee. | `vimspector#Pause()` | | `F6` | `<Plug>VimspectorPause` | Pause debuggee.
| `F9` | Toggle line breakpoint on the current line. | `vimspector#ToggleBreakpoint()` | | `F9` | `<Plug>VimspectorToggleBreakpoint` | Toggle line breakpoint on the current line.
| `Shift F9` | Add a function breakpoint for the expression under cursor | `vimspector#AddFunctionBreakpoint( '<cexpr>' )` | | `Shift F9` | `<Plug>VimspectorAddFunctionBreakpoint` | Add a function breakpoint for the expression under cursor
| `F10` | Step Over | `vimspector#StepOver()` | | `F10` | `<Plug>VimspectorStepOver` | Step Over
| `F11` | Step Into | `vimspector#StepInto()` | | `F11` | `<Plug>VimspectorStepInto` | Step Into
| `Shift F11` | Step out of current function scope | `vimspector#StepOut()` | | `Shift F11` | `<Plug>VimspectorStepOut` | Step out of current function scope
## Human Mode ## Human Mode
@ -720,19 +725,19 @@ loading vimspector**:
let g:vimspector_enable_mappings = 'HUMAN' let g:vimspector_enable_mappings = 'HUMAN'
``` ```
| Key | Function | API | | Key | Mapping | Function
| --- | --- | --- | | --- | --- | ---
| `F5` | When debugging, continue. Otherwise start debugging. | `vimspector#Continue()` | | `F5` | `<Plug>VimspectorContinue` | When debugging, continue. Otherwise start debugging.
| `F3` | Stop debugging. | `vimspector#Stop()` | | `F3` | `<Plug>VimspectorStop` | Stop debugging.
| `F4` | Restart debugging with the same configuration. | `vimspector#Restart()` | | `F4` | `<Plug>VimspectorRestart` | Restart debugging with the same configuration.
| `F6` | Pause debuggee. | `vimspector#Pause()` | | `F6` | `<Plug>VimspectorPause` | Pause debuggee.
| `F9` | Toggle line breakpoint on the current line. | `vimspector#ToggleBreakpoint()` | | `F9` | `<Plug>VimspectorToggleBreakpoint` | Toggle line breakpoint on the current line.
| `<leader>F9` | Toggle conditional line breakpoint on the current line. | `vimspector#ToggleBreakpoint( { trigger expr, hit count expr } )` | | `<leader>F9` | `<Plug>VimspectorToggleConditionalBreakpoint` | Toggle conditional line breakpoint on the current line.
| `F8` | Add a function breakpoint for the expression under cursor | `vimspector#AddFunctionBreakpoint( '<cexpr>' )` | | `F8` | `<Plug>VimspectorAddFunctionBreakpoint` | Add a function breakpoint for the expression under cursor
| `<leader>F8` | Run to Cursor | `vimspector#RunToCursor()` | | `<leader>F8` | `<Plug>VimspectorRunToCursor` | Run to Cursor
| `F10` | Step Over | `vimspector#StepOver()` | | `F10` | `<Plug>VimspectorStepOver` | Step Over
| `F11` | Step Into | `vimspector#StepInto()` | | `F11` | `<Plug>VimspectorStepInto` | Step Into
| `F12` | Step out of current function scope | `vimspector#StepOut()` | | `F12` | `<Plug>VimspectorStepOut` | Step out of current function scope
In addition, I recommend adding a mapping to `<Plug>VimspectorBalloonEval`, in In addition, I recommend adding a mapping to `<Plug>VimspectorBalloonEval`, in
normal and visual modes, for example: normal and visual modes, for example:
@ -746,6 +751,13 @@ nmap <Leader>di <Plug>VimspectorBalloonEval
xmap <Leader>di <Plug>VimspectorBalloonEval xmap <Leader>di <Plug>VimspectorBalloonEval
``` ```
You may also wish to add mappings for up/down the stack, for example:
```viml
nmap <LocalLeader><F11> <Plug>VimspectorUpFrame
nmap <LocalLeader><F12> <Plug>VimspectorDownFrame
```
# Usage and API # Usage and API
This section defines detailed usage instructions, organised by feature. For most This section defines detailed usage instructions, organised by feature. For most

View file

@ -234,6 +234,20 @@ function! vimspector#GoToFrame() abort
py3 _vimspector_session.ExpandFrameOrThread() py3 _vimspector_session.ExpandFrameOrThread()
endfunction 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 function! vimspector#AddWatch( ... ) abort
if !s:Enabled() if !s:Enabled()
return return

View file

@ -69,7 +69,6 @@ function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
\ 'resize': 1, \ 'resize': 1,
\ 'close': 'button', \ 'close': 'button',
\ 'callback': 'vimspector#internal#balloon#CloseCallback', \ 'callback': 'vimspector#internal#balloon#CloseCallback',
\ 'mapping': 0
\ } \ }
" When ambiwidth is single, use prettier characters for the border. This " When ambiwidth is single, use prettier characters for the border. This
@ -86,6 +85,7 @@ function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
let config[ 'filter' ] = 'vimspector#internal#balloon#CursorFilter' let config[ 'filter' ] = 'vimspector#internal#balloon#CursorFilter'
let config[ 'moved' ] = 'any' let config[ 'moved' ] = 'any'
let config[ 'cursorline' ] = 1 let config[ 'cursorline' ] = 1
let config[ 'mapping' ] = 0
let s:popup_win_id = popup_atcursor( body, config ) let s:popup_win_id = popup_atcursor( body, config )
endif endif

View file

@ -67,6 +67,11 @@ nnoremap <silent> <Plug>VimspectorBalloonEval
xnoremap <silent> <Plug>VimspectorBalloonEval xnoremap <silent> <Plug>VimspectorBalloonEval
\ :<c-u>call vimspector#ShowEvalBalloon( 1 )<CR> \ :<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' if s:mappings ==# 'VISUAL_STUDIO'
nmap <F5> <Plug>VimspectorContinue nmap <F5> <Plug>VimspectorContinue
nmap <S-F5> <Plug>VimspectorStop nmap <S-F5> <Plug>VimspectorStop

View file

@ -571,6 +571,14 @@ class DebugSession( object ):
def ExpandFrameOrThread( self ): def ExpandFrameOrThread( self ):
self._stackTraceView.ExpandFrameOrThread() self._stackTraceView.ExpandFrameOrThread()
@IfConnected()
def UpFrame( self ):
self._stackTraceView.UpFrame()
@IfConnected()
def DownFrame( self ):
self._stackTraceView.DownFrame()
def ToggleLog( self ): def ToggleLog( self ):
if self._HasUI(): if self._HasUI():
return self.ShowOutput( 'Vimspector' ) return self.ShowOutput( 'Vimspector' )
@ -655,6 +663,45 @@ class DebugSession( object ):
vim.command( 'tab split' ) vim.command( 'tab split' )
self._uiTab = vim.current.tabpage 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' ) )
min_height = ( settings.Int( 'code_minheight' ) + 1 +
settings.Int( 'topbar_height' ) + 1 +
settings.Int( 'bottombar_height' ) + 1 +
2 )
mode = ( 'vertical'
if vim.options[ 'columns' ] < min_width
else 'horizontal' )
if vim.options[ 'lines' ] < min_height:
mode = 'horizontal'
self._logger.debug( 'min_width/height: %s/%s, actual: %s/%s - result: %s',
min_width,
min_height,
vim.options[ 'columns' ],
vim.options[ 'lines' ],
mode )
if mode == 'vertical':
self._SetUpUIVertical()
else:
self._SetUpUIHorizontal()
def _SetUpUIHorizontal( self ):
# Code window # Code window
code_window = vim.current.window code_window = vim.current.window
self._codeView = code.CodeView( code_window, self._api_prefix ) self._codeView = code.CodeView( code_window, self._api_prefix )
@ -695,6 +742,66 @@ class DebugSession( object ):
# TODO: If/when we support multiple sessions, we'll need some way to # TODO: If/when we support multiple sessions, we'll need some way to
# indicate which tab was created and store all the tabs # indicate which tab was created and store all the tabs
vim.vars[ 'vimspector_session_windows' ] = { 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, 'tabpage': self._uiTab.number,
'code': utils.WindowID( code_window, self._uiTab ), 'code': utils.WindowID( code_window, self._uiTab ),
'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ), 'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ),

View file

@ -20,11 +20,20 @@ from vimspector import utils
DEFAULTS = { DEFAULTS = {
# UI # UI
'bottombar_height': 10, 'ui_mode': 'auto',
'sidebar_width': 50, 'bottombar_height': 10,
'code_minwidth': 82,
'terminal_maxwidth': 80, # For ui_mode = 'horizontal':
'terminal_minwidth': 10, '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 # Signs
'sign_priority': { 'sign_priority': {

View file

@ -367,6 +367,46 @@ class StackTraceView( object ):
self._JumpToFrame( frame ) self._JumpToFrame( frame )
def _GetFrameOffset( self, delta ):
thread: Thread
for thread in self._threads:
if thread.id != 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( 1 )
if not frame:
utils.UserMessage( 'Top of stack' )
else:
self._JumpToFrame( frame, 'up' )
def DownFrame( self ):
frame = self._GetFrameOffset( -1 )
if not frame:
utils.UserMessage( 'Bottom of stack' )
else:
self._JumpToFrame( frame, 'down' )
def AnyThreadsRunning( self ): def AnyThreadsRunning( self ):
for thread in self._threads: for thread in self._threads:
if thread.state != Thread.TERMINATED: if thread.state != Thread.TERMINATED:

View file

@ -23,12 +23,53 @@ def LaunchTerminal( api_prefix,
env = params.get( 'env' ) or {} env = params.get( 'env' ) or {}
term_options = { term_options = {
'vertical': 1,
'norestore': 1, 'norestore': 1,
'cwd': cwd, 'cwd': cwd,
'env': env, 'env': env,
} }
if settings.Get( 'ui_mode' ) == 'horizontal':
# force-horizontal
term_options[ 'vertical' ] = 1
elif utils.GetVimValue( vim.vars[ 'vimspector_session_windows' ],
'mode' ) == 'horizontal':
# horizontal, which means that we should have enough space for:
# - sidebar
# - code min
# - term min width
# - + 2 vertical spaders
# - + 3 columns for signs
term_options[ 'vertical' ] = 1
# if we don't have enough space for terminal_maxwidth, then see if we have
# enough vertically for terminal_maxheight, in which case,
# that seems a better fit
term_horiz_max = ( settings.Int( 'sidebar_width' ) +
1 + 2 + 3 +
settings.Int( 'code_minwidth' ) +
1 + settings.Int( 'terminal_maxwidth' ) )
term_vert_max = ( settings.Int( 'bottombar_height' ) + 1 +
settings.Int( 'code_minheight' ) + 1 +
settings.Int( 'terminal_minheight' ) )
if ( vim.options[ 'columns' ] < term_horiz_max and
vim.options[ 'lines' ] >= term_vert_max ):
# Looks like it, let's try that layout
term_options[ 'vertical' ] = 0
else:
# vertical - we need enough space horizontally for the code+terminal, but we
# may fit better with code above terminal
term_options[ 'vertical' ] = 0
term_horiz_max = ( settings.Int( 'code_minwidth' ) + 3 +
settings.Int( 'terminal_maxwidth' ) + 1 )
if vim.options[ 'columns' ] > term_horiz_max:
term_options[ 'vertical' ] = 1
if not window_for_start or not window_for_start.valid: if not window_for_start or not window_for_start.valid:
# TOOD: Where? Maybe we should just use botright vertical ... # TOOD: Where? Maybe we should just use botright vertical ...
window_for_start = vim.current.window window_for_start = vim.current.window
@ -50,13 +91,23 @@ def LaunchTerminal( api_prefix,
# If we're making a vertical split from the code window, make it no more # 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 # than 80 columns and no fewer than 10. Also try and keep the code window
# at least 82 columns # 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( term_options[ 'term_cols' ] = max(
min ( int( vim.eval( 'winwidth( 0 )' ) ) min ( int( vim.eval( 'winwidth( 0 )' ) )
- settings.Int( 'code_minwidth' ), - settings.Int( 'code_minwidth' ),
settings.Int( 'terminal_maxwidth' ) ), settings.Int( 'terminal_maxwidth' ) ),
settings.Int( 'terminal_minwidth' ) 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( buffer_number = int(
utils.Call( utils.Call(

View file

@ -494,7 +494,6 @@ def _Substitute( template, mapping ):
if mo.group( 'braceddefault' ) is not None: if mo.group( 'braceddefault' ) is not None:
named = mo.group( 'defname' ) named = mo.group( 'defname' )
if named not in mapping: if named not in mapping:
''
raise MissingSubstitution( raise MissingSubstitution(
named, named,
mo.group( 'default' ).replace( '\\}', '}' ) ) mo.group( 'default' ).replace( '\\}', '}' ) )
@ -536,8 +535,11 @@ def ExpandReferencesInString( orig_s,
if default_value is None and e.default_value is not None: if default_value is None and e.default_value is not None:
try: try:
default_value = _Substitute( e.default_value, mapping ) default_value = _Substitute( e.default_value, mapping )
except MissingSubstitution: except MissingSubstitution as e2:
default_value = e.default_value if e2.name in calculus:
default_value = calculus[ e2.name ]()
else:
default_value = e.default_value
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ), mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
default_value ) default_value )

View file

@ -50,3 +50,59 @@ function! vimspector#test#setup#Reset() abort
call popup_clear() call popup_clear()
endfunction endfunction
let s:g_stack = {}
function! vimspector#test#setup#PushGlobal( name, value ) abort
if !has_key( s:g_stack, a:name )
let s:g_stack[ a:name ] = []
endif
let old_value = get( g:, a:name, v:null )
call add( s:g_stack[ a:name ], old_value )
let g:[ a:name ] = a:value
return old_value
endfunction
function! vimspector#test#setup#PopGlobal( name ) abort
if !has_key( s:g_stack, a:name ) || len( s:g_stack[ a:name ] ) == 0
return v:null
endif
let old_value = s:g_stack[ a:name ][ -1 ]
call remove( s:g_stack[ a:name ], -1 )
if old_value is v:null
silent! call remove( g:, a:name )
else
let g:[ a:name ] = old_value
endif
return old_value
endfunction
let s:o_stack = {}
function! vimspector#test#setup#PushOption( name, value ) abort
if !has_key( s:o_stack, a:name )
let s:o_stack[ a:name ] = []
endif
let old_value = v:null
execute 'let old_value = &' . a:name
call add( s:o_stack[ a:name ], old_value )
execute 'set ' . a:name . '=' . a:value
return old_value
endfunction
function! vimspector#test#setup#PopOption( name ) abort
if !has_key( s:o_stack, a:name ) || len( s:o_stack[ a:name ] ) == 0
return v:null
endif
let old_value = s:o_stack[ a:name ][ -1 ]
call remove( s:o_stack[ a:name ], -1 )
execute 'set ' . a:name . '=' . old_value
return old_value
endfunction

View file

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

View file

@ -356,3 +356,117 @@ function! Test_Multiple_Threads_Step()
call vimspector#test#setup#Reset() call vimspector#test#setup#Reset()
%bwipe! %bwipe!
endfunction endfunction
function! Test_UpDownStack()
let fn='../support/test/python/simple_python/main.py'
exe 'edit ' . fn
call setpos( '.', [ 0, 6, 1 ] )
call vimspector#SetLineBreakpoint( fn, 15 )
call vimspector#LaunchWithSettings( { 'configuration': 'run' } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {->
\ AssertMatchist(
\ [
\ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15',
\ ' 3: __init__@main.py:8',
\ ' 4: Main@main.py:23',
\ ' 5: <module>@main.py:29',
\ ],
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#DownFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {->
\ AssertMatchist(
\ [
\ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15',
\ ' 3: __init__@main.py:8',
\ ' 4: Main@main.py:23',
\ ' 5: <module>@main.py:29',
\ ],
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#UpFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
call WaitForAssert( {->
\ AssertMatchist(
\ [
\ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15',
\ ' 3: __init__@main.py:8',
\ ' 4: Main@main.py:23',
\ ' 5: <module>@main.py:29',
\ ],
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
\ 1,
\ '$' )
\ )
\ } )
call feedkeys( "\<Plug>VimspectorUpFrame", 'x' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 23, 1 )
call WaitForAssert( {->
\ AssertMatchist(
\ [
\ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15',
\ ' 3: __init__@main.py:8',
\ ' 4: Main@main.py:23',
\ ' 5: <module>@main.py:29',
\ ],
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
\ 1,
\ '$' )
\ )
\ } )
call feedkeys( "\<Plug>VimspectorDownFrame", 'x' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
call WaitForAssert( {->
\ AssertMatchist(
\ [
\ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15',
\ ' 3: __init__@main.py:8',
\ ' 4: Main@main.py:23',
\ ' 5: <module>@main.py:29',
\ ],
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#DownFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {->
\ AssertMatchist(
\ [
\ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15',
\ ' 3: __init__@main.py:8',
\ ' 4: Main@main.py:23',
\ ' 5: <module>@main.py:29',
\ ],
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#ClearBreakpoints()
call vimspector#test#setup#Reset()
%bwipe!
endfunction

View file

@ -1,6 +1,7 @@
let s:fn='../support/test/python/simple_python/main.py' let s:fn='../support/test/python/simple_python/main.py'
function! SetUp() function! SetUp()
let g:vimspector_ui_mode = get( s:, 'vimspector_ui_mode', 'horizontal' )
call vimspector#test#setup#SetUpWithMappings( 'HUMAN' ) call vimspector#test#setup#SetUpWithMappings( 'HUMAN' )
endfunction endfunction
@ -16,12 +17,17 @@ function! s:StartDebugging()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 23, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 23, 1 )
endfunction endfunction
function! SetUp_Test_StandardLayout()
call vimspector#test#setup#PushOption( 'columns', 200 )
endfunction
function! Test_StandardLayout() function! Test_StandardLayout()
call s:StartDebugging() call s:StartDebugging()
call vimspector#StepOver() call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
call assert_equal( call assert_equal(
\ [ 'row', [ \ [ 'row', [
\ [ 'col', [ \ [ 'col', [
@ -43,6 +49,247 @@ function! Test_StandardLayout()
%bwipe! %bwipe!
endfunction endfunction
function! TearDown_Test_StandardLayout()
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! SetUp_Test_NarrowLayout()
call vimspector#test#setup#PushOption( 'columns', 100 )
let s:vimspector_ui_mode = 'vertical'
endfunction
function! Test_NarrowLayout()
call s:StartDebugging()
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'vertical', g:vimspector_session_windows.mode )
call assert_equal(
\ [ 'col', [
\ [ 'row', [
\ [ 'leaf', g:vimspector_session_windows.variables ],
\ [ 'leaf', g:vimspector_session_windows.watches ],
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
\ ] ],
\ [ 'leaf', g:vimspector_session_windows.code ],
\ [ 'leaf', g:vimspector_session_windows.terminal ],
\ [ 'leaf', g:vimspector_session_windows.output ],
\ ] ],
\ winlayout( g:vimspector_session_windows.tabpage ) )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! TearDown_Test_NarrowLayout()
unlet s:vimspector_ui_mode
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! SetUp_Test_AutoLayoutTerminalVert()
let s:vimspector_ui_mode = 'auto'
call vimspector#test#setup#PushOption( 'columns', 250 )
call vimspector#test#setup#PushOption( 'lines', 30 )
endfunction
function! Test_AutoLayoutTerminalVert()
call s:StartDebugging()
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
call assert_equal(
\ [ 'row', [
\ [ 'col', [
\ [ 'leaf', g:vimspector_session_windows.variables ],
\ [ 'leaf', g:vimspector_session_windows.watches ],
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
\ ] ],
\ [ 'col', [
\ [ 'row', [
\ [ 'leaf', g:vimspector_session_windows.code ],
\ [ 'leaf', g:vimspector_session_windows.terminal ],
\ ] ],
\ [ 'leaf', g:vimspector_session_windows.output ],
\ ] ]
\ ] ],
\ winlayout( g:vimspector_session_windows.tabpage ) )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! TearDown_Test_AutoLayoutTerminalVert()
unlet s:vimspector_ui_mode
call vimspector#test#setup#PopOption( 'lines' )
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! SetUp_Test_AutoLayoutTerminalHorizVert()
let s:vimspector_ui_mode = 'auto'
" Wide enough to be horizontal layout, but not wide enough to fully fit the
" terminal, with enough rows to fit the max terminal below
call vimspector#test#setup#PushOption( 'columns',
\ 50 + 82 + 3 + 2 + 12 )
call vimspector#test#setup#PushOption( 'lines', 50 )
endfunction
function! Test_AutoLayoutTerminalHorizVert()
call s:StartDebugging()
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
call assert_equal(
\ [ 'row', [
\ [ 'col', [
\ [ 'leaf', g:vimspector_session_windows.variables ],
\ [ 'leaf', g:vimspector_session_windows.watches ],
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
\ ] ],
\ [ 'col', [
\ [ 'leaf', g:vimspector_session_windows.code ],
\ [ 'leaf', g:vimspector_session_windows.terminal ],
\ [ 'leaf', g:vimspector_session_windows.output ],
\ ] ]
\ ] ],
\ winlayout( g:vimspector_session_windows.tabpage ) )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! TearDown_Test_AutoLayoutTerminalHorizVert()
unlet s:vimspector_ui_mode
call vimspector#test#setup#PopOption( 'lines' )
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! SetUp_Test_AutoLayoutTerminalHorizVertButNotEnoughLines()
let s:vimspector_ui_mode = 'auto'
" Wide enough to be horizontal layout, but not wide enough to fully fit the
" terminal, with enough rows to fit the max terminal below, but there are not
" enough lines to do this
call vimspector#test#setup#PushOption( 'columns',
\ 50 + 82 + 3 + 2 + 12 )
call vimspector#test#setup#PushOption( 'lines', 20 )
endfunction
function! Test_AutoLayoutTerminalHorizVertButNotEnoughLines()
call s:StartDebugging()
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
call assert_equal(
\ [ 'row', [
\ [ 'col', [
\ [ 'leaf', g:vimspector_session_windows.variables ],
\ [ 'leaf', g:vimspector_session_windows.watches ],
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
\ ] ],
\ [ 'col', [
\ [ 'row', [
\ [ 'leaf', g:vimspector_session_windows.code ],
\ [ 'leaf', g:vimspector_session_windows.terminal ],
\ ] ],
\ [ 'leaf', g:vimspector_session_windows.output ],
\ ] ],
\ ] ],
\ winlayout( g:vimspector_session_windows.tabpage ) )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! TearDown_Test_AutoLayoutTerminalHorizVertButNotEnoughLines()
unlet s:vimspector_ui_mode
call vimspector#test#setup#PopOption( 'lines' )
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! SetUp_Test_AutoLayoutTerminalHoriz()
let s:vimspector_ui_mode = 'vertical'
" Vertical layout, but we split the terminal horizonally
call vimspector#test#setup#PushOption( 'columns', 200 )
call vimspector#test#setup#PushOption( 'lines', 50 )
endfunction
function! Test_AutoLayoutTerminalHoriz()
call s:StartDebugging()
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'vertical', g:vimspector_session_windows.mode )
call assert_equal(
\ [ 'col', [
\ [ 'row', [
\ [ 'leaf', g:vimspector_session_windows.variables ],
\ [ 'leaf', g:vimspector_session_windows.watches ],
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
\ ] ],
\ [ 'row', [
\ [ 'leaf', g:vimspector_session_windows.code ],
\ [ 'leaf', g:vimspector_session_windows.terminal ],
\ ] ],
\ [ 'leaf', g:vimspector_session_windows.output ],
\ ] ],
\ winlayout( g:vimspector_session_windows.tabpage ) )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! TearDown_Test_AutoLayoutTerminalHoriz()
unlet s:vimspector_ui_mode
call vimspector#test#setup#PopOption( 'lines' )
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! SetUp_Test_AutoLayoutTerminalVertVert()
let s:vimspector_ui_mode = 'auto'
" Not wide enough to go horizontal, but wide enough to put the terminal and
" code vertically split
call vimspector#test#setup#PushOption( 'columns', 80 )
call vimspector#test#setup#PushOption( 'lines', 50 )
endfunction
function! Test_AutoLayoutTerminalVertVert()
call s:StartDebugging()
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
call assert_equal( 'vertical', g:vimspector_session_windows.mode )
call assert_equal(
\ [ 'col', [
\ [ 'row', [
\ [ 'leaf', g:vimspector_session_windows.variables ],
\ [ 'leaf', g:vimspector_session_windows.watches ],
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
\ ] ],
\ [ 'leaf', g:vimspector_session_windows.code ],
\ [ 'leaf', g:vimspector_session_windows.terminal ],
\ [ 'leaf', g:vimspector_session_windows.output ],
\ ] ],
\ winlayout( g:vimspector_session_windows.tabpage ) )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! TearDown_Test_AutoLayoutTerminalVertVert()
unlet s:vimspector_ui_mode
call vimspector#test#setup#PopOption( 'lines' )
call vimspector#test#setup#PopOption( 'columns' )
endfunction
function! Test_CloseVariables() function! Test_CloseVariables()
call s:StartDebugging() call s:StartDebugging()