commit
c1e29be9b8
30 changed files with 1629 additions and 221 deletions
295
README.md
295
README.md
|
|
@ -6,69 +6,74 @@ For a tutorial and usage overview, take a look at the
|
|||
[](https://dev.azure.com/puremouron/Vimspector/_build/latest?definitionId=1&branchName=master) [](https://gitter.im/vimspector/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
|
||||
<!--ts-->
|
||||
* [Features and Usage](#features-and-usage)
|
||||
* [Supported debugging features](#supported-debugging-features)
|
||||
* [Supported languages:](#supported-languages)
|
||||
* [Languages known to work](#languages-known-to-work)
|
||||
* [Languages known not to work](#languages-known-not-to-work)
|
||||
* [Other languages](#other-languages)
|
||||
* [Installation](#installation)
|
||||
* [Dependencies](#dependencies)
|
||||
* [Neovim differences](#neovim-differences)
|
||||
* [Windows differences](#windows-differences)
|
||||
* [Language dependencies](#language-dependencies)
|
||||
* [Clone the plugin](#clone-the-plugin)
|
||||
* [Install some gadgets](#install-some-gadgets)
|
||||
* [Manual gadget installation](#manual-gadget-installation)
|
||||
* [The gadget directory](#the-gadget-directory)
|
||||
* [Trying it out](#trying-it-out)
|
||||
* [About](#about)
|
||||
* [Background](#background)
|
||||
* [Status](#status)
|
||||
* [Experimental](#experimental)
|
||||
* [Mappings](#mappings)
|
||||
* [Visual Studio / VSCode](#visual-studio--vscode)
|
||||
* [Human Mode](#human-mode)
|
||||
* [Usage](#usage)
|
||||
* [Launch and attach by PID:](#launch-and-attach-by-pid)
|
||||
* [Launch with options](#launch-with-options)
|
||||
* [Breakpoints](#breakpoints)
|
||||
* [Exception breakpoints](#exception-breakpoints)
|
||||
* [Clear breakpoints](#clear-breakpoints)
|
||||
* [Stepping](#stepping)
|
||||
* [Variables and scopes](#variables-and-scopes)
|
||||
* [Watches](#watches)
|
||||
* [Stack Traces](#stack-traces)
|
||||
* [Program Output](#program-output)
|
||||
* [Console](#console)
|
||||
* [Closing debugger](#closing-debugger)
|
||||
* [Debug adapter configuration](#debug-adapter-configuration)
|
||||
* [C, C , Rust, etc.](#c-c-rust-etc)
|
||||
* [Remote debugging](#remote-debugging)
|
||||
* [Remote launch and attach](#remote-launch-and-attach)
|
||||
* [Python](#python)
|
||||
* [Remote Debugging](#remote-debugging-1)
|
||||
* [Remote launch and attach](#remote-launch-and-attach-1)
|
||||
* [Legacy: vscode-python](#legacy-vscode-python)
|
||||
* [TCL](#tcl)
|
||||
* [C♯](#c)
|
||||
* [Go](#go)
|
||||
* [PHP](#php)
|
||||
* [Debug web application](#debug-web-application)
|
||||
* [Debug cli application](#debug-cli-application)
|
||||
* [JavaScript, TypeScript, etc.](#javascript-typescript-etc)
|
||||
* [Java](#java)
|
||||
* [Usage with YouCompleteMe](#usage-with-youcompleteme)
|
||||
* [Other LSP clients](#other-lsp-clients)
|
||||
* [Rust](#rust)
|
||||
* [Other servers](#other-servers)
|
||||
* [Customisation](#customisation)
|
||||
* [Changing the default signs](#changing-the-default-signs)
|
||||
* [FAQ](#faq)
|
||||
* [Motivation](#motivation)
|
||||
* [License](#license)
|
||||
* [Features and Usage](#features-and-usage)
|
||||
* [Supported debugging features](#supported-debugging-features)
|
||||
* [Supported languages:](#supported-languages)
|
||||
* [Languages known to work](#languages-known-to-work)
|
||||
* [Languages known not to work](#languages-known-not-to-work)
|
||||
* [Other languages](#other-languages)
|
||||
* [Installation](#installation)
|
||||
* [Dependencies](#dependencies)
|
||||
* [Neovim differences](#neovim-differences)
|
||||
* [Windows differences](#windows-differences)
|
||||
* [Language dependencies](#language-dependencies)
|
||||
* [Clone the plugin](#clone-the-plugin)
|
||||
* [Install some gadgets](#install-some-gadgets)
|
||||
* [Manual gadget installation](#manual-gadget-installation)
|
||||
* [The gadget directory](#the-gadget-directory)
|
||||
* [Trying it out](#trying-it-out)
|
||||
* [About](#about)
|
||||
* [Background](#background)
|
||||
* [Status](#status)
|
||||
* [Experimental](#experimental)
|
||||
* [Mappings](#mappings)
|
||||
* [Visual Studio / VSCode](#visual-studio--vscode)
|
||||
* [Human Mode](#human-mode)
|
||||
* [Usage](#usage)
|
||||
* [Launch and attach by PID:](#launch-and-attach-by-pid)
|
||||
* [Launch with options](#launch-with-options)
|
||||
* [Debug configuration selection](#debug-configuration-selection)
|
||||
* [Breakpoints](#breakpoints)
|
||||
* [Exception breakpoints](#exception-breakpoints)
|
||||
* [Clear breakpoints](#clear-breakpoints)
|
||||
* [Stepping](#stepping)
|
||||
* [Variables and scopes](#variables-and-scopes)
|
||||
* [Watches](#watches)
|
||||
* [Stack Traces](#stack-traces)
|
||||
* [Program Output](#program-output)
|
||||
* [Console](#console)
|
||||
* [Closing debugger](#closing-debugger)
|
||||
* [Debug adapter configuration](#debug-adapter-configuration)
|
||||
* [C, C , Rust, etc.](#c-c-rust-etc)
|
||||
* [Remote debugging](#remote-debugging)
|
||||
* [Remote launch and attach](#remote-launch-and-attach)
|
||||
* [Python](#python)
|
||||
* [Remote Debugging](#remote-debugging-1)
|
||||
* [Remote launch and attach](#remote-launch-and-attach-1)
|
||||
* [Legacy: vscode-python](#legacy-vscode-python)
|
||||
* [TCL](#tcl)
|
||||
* [C♯](#c)
|
||||
* [Go](#go)
|
||||
* [PHP](#php)
|
||||
* [Debug web application](#debug-web-application)
|
||||
* [Debug cli application](#debug-cli-application)
|
||||
* [JavaScript, TypeScript, etc.](#javascript-typescript-etc)
|
||||
* [Java](#java)
|
||||
* [Usage with YouCompleteMe](#usage-with-youcompleteme)
|
||||
* [Other LSP clients](#other-lsp-clients)
|
||||
* [Rust](#rust)
|
||||
* [Other servers](#other-servers)
|
||||
* [Customisation](#customisation)
|
||||
* [Changing the default signs](#changing-the-default-signs)
|
||||
* [Changing the default window sizes](#changing-the-default-window-sizes)
|
||||
* [Changing the terminal size](#changing-the-terminal-size)
|
||||
* [Advanced UI customisation](#advanced-ui-customisation)
|
||||
* [Example](#example)
|
||||
* [FAQ](#faq)
|
||||
* [Motivation](#motivation)
|
||||
* [License](#license)
|
||||
|
||||
<!-- Added by: ben, at: Thu 9 Jul 2020 18:19:20 BST -->
|
||||
<!-- Added by: ben, at: Sat 18 Jul 2020 12:58:35 BST -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
|
|
@ -601,6 +606,19 @@ See [our YouCompleteMe integration guide](#usage-with-youcompleteme) for
|
|||
another example where it can be used to specify the port to connect the [java
|
||||
debugger](#java---partially-supported)
|
||||
|
||||
### Debug configuration selection
|
||||
|
||||
Vimspector uses the following logic to choose a configuration to launch:
|
||||
|
||||
1. If a configuration was specified in the launch options (as above), use that.
|
||||
2. Otherwise if there's only one configuration and it doesn't have `autoselect`
|
||||
set to `false`, use that.
|
||||
3. Otherwise if there's exactly one configuration with `default` set to `true`
|
||||
and without `autoselect` set to `false`, use that.
|
||||
4. Otherwise, prompt the user to select a configuration.
|
||||
|
||||
See [the reference guide][vimspector-ref-config-selection] for details.
|
||||
|
||||
## Breakpoints
|
||||
|
||||
* Use `vimspector#ToggleBreakpoint([ { 'condition': '<condition expr>' } ])`
|
||||
|
|
@ -659,6 +677,8 @@ You can configure your choices in the `.vimspector.json`. See
|
|||
|
||||

|
||||
|
||||
Scopes and variables are represented by the buffer `vimspector.Variables`.
|
||||
|
||||
## Watches
|
||||
|
||||
The watches window is a prompt buffer, where that's available. Enter insert mode
|
||||
|
|
@ -673,6 +693,8 @@ to add a new watch expression.
|
|||
|
||||

|
||||
|
||||
The watches are represented by the buffer `vimspector.StackTrace`.
|
||||
|
||||
## Stack Traces
|
||||
|
||||
* In the threads window, use `<CR>` to expand/collapse.
|
||||
|
|
@ -680,6 +702,8 @@ to add a new watch expression.
|
|||
|
||||

|
||||
|
||||
The stack trace is represented by the buffer `vimspector.StackTrace`.
|
||||
|
||||
## Program Output
|
||||
|
||||
* In the outputs window use the WinBar to select the output channel.
|
||||
|
|
@ -690,6 +714,10 @@ to add a new watch expression.
|
|||
|
||||

|
||||
|
||||
If the output window is closed, a new one can be opened with
|
||||
`:VimspectorShowOutput <category>` (use tab-completion - `wildmenu` to see the
|
||||
options).
|
||||
|
||||
### Console
|
||||
|
||||
The console window is a prompt buffer, where that's available, and can be used
|
||||
|
|
@ -704,6 +732,9 @@ adapters.
|
|||
|
||||
NOTE: See also [Watches](#watches) above.
|
||||
|
||||
If the output window is closed, a new one can be opened with
|
||||
`:VimspectorShowOutput Console`.
|
||||
|
||||
## Closing debugger
|
||||
|
||||
To close the debugger, use:
|
||||
|
|
@ -1284,6 +1315,145 @@ sign define vimspectorBPDisabled text=🔵 texthl=Normal
|
|||
sign define vimspectorPC text=🔶 texthl=SpellBad
|
||||
```
|
||||
|
||||
## Changing the default window sizes
|
||||
|
||||
> ***Please Note***: This cusomiation API is ***unstable***, meaning that it may
|
||||
change at any time. I will endeavour to reduce the impact of this and annouce
|
||||
changes in Gitter.
|
||||
|
||||
The following options control the default sizes of the UI windows (all of them
|
||||
are numbers)
|
||||
|
||||
- `g:vimspector_sidebar_width` (default: 50 columns):
|
||||
The width in columns of the left utility windows (variables, watches, stack
|
||||
trace)
|
||||
- `g:vimspector_bottombar_height` (default 10 lines):
|
||||
The height in rows of the output window below the code window.
|
||||
|
||||
Example:
|
||||
|
||||
```viml
|
||||
let g:vimspector_sidebar_width = 75
|
||||
let g:vimspector_bottombar_height = 15
|
||||
```
|
||||
|
||||
## Changing the terminal size
|
||||
|
||||
The terminal is typically created as a vertical split to the righ of the code
|
||||
window, and that window is re-used for subsequent terminal buffers.
|
||||
The following control the sizing of the terminal window used
|
||||
for debuggee input/output when using Vim's built-in terminal.
|
||||
|
||||
- `g:vimspector_code_minwidth` (default: 82 columns):
|
||||
Minimum number of columns to try and maintain for the code window when
|
||||
splitting to create the terminal window.
|
||||
- `g:vimspector_terminal_maxwidth` (default: 80 columns):
|
||||
Maximum number of columns to use for the terminal.
|
||||
- `g:vimspector_terminal_minwidth` (default: 10 columns):
|
||||
Minimum number of columns to use when it is not possible to fit
|
||||
`g:vimspector_terminal_maxwidth` columns for the terminal.
|
||||
|
||||
That's a lot of options, but essentially we try to make sure that there are at
|
||||
least `g:vimspector_code_minwidth` columns for the main code window and that the
|
||||
terminal is no wider than `g:vimspector_terminal_maxwidth` columns.
|
||||
`g:vimspector_terminal_minwidth` is there to ensure that there's a reasonable
|
||||
number of columns for the terminal even when there isn't enough horizontal space
|
||||
to satisfy the other contraints.
|
||||
|
||||
Example:
|
||||
|
||||
```viml
|
||||
let g:vimspector_code_minwidth = 90
|
||||
let g:vimspector_terminal_maxwidth = 75
|
||||
let g:vimspector_terminal_minwidth = 20
|
||||
```
|
||||
|
||||
## Advanced UI customisation
|
||||
|
||||
> ***Please Note***: This cusomiation API is ***unstable***, meaning that it may
|
||||
change at any time. I will endeavour to reduce the impact of this and annouce
|
||||
changes in Gitter.
|
||||
|
||||
The above customisation of window sizes is limited intentionally to keep things
|
||||
simple. Vimspector also provides a way for you to customise the UI without
|
||||
restrictions, by running a `User` autocommand just after creating the UI or
|
||||
opening the terminal. This requires you to write some vimscript, but allows you
|
||||
to do things like:
|
||||
|
||||
* Hide a particular window or windows
|
||||
* Move a particular window or windows
|
||||
* Resize windows
|
||||
* Have multiple windows for a particular buffer (say, you want 2 watch windows)
|
||||
* etc.
|
||||
|
||||
You can essentially do anything you could do manually by writing a little
|
||||
vimscript code.
|
||||
|
||||
The `User` autocommand is raised with `pattern` set with the following values:
|
||||
|
||||
* `VimspectorUICreated`: Just after setting up the UI for a debug session
|
||||
* `VimspectorTerminalOpened`: Just after opening the terminal window for program
|
||||
input/output.
|
||||
|
||||
The following global variable is set up for you to get access to the UI
|
||||
elements: `g:vimspector_session_windows`. This is a `dict` with the following
|
||||
keys:
|
||||
|
||||
* `g:vimspector_session_windows.tagpage`: The tab page for the session
|
||||
* `g:vimspector_session_windows.variables`: Window ID of the variables window,
|
||||
containing the `vimspector.Variables` buffer.
|
||||
* `g:vimspector_session_windows.watches`: Window ID of the watches window,
|
||||
containng the `vimspector.Watches` buffer.
|
||||
* `g:vimspector_session_windows.stack_trace`: Window ID of the stack trade
|
||||
window containing the `vimspector.StackTrace` buffer.
|
||||
* `g:vimspector_session_windows.code`: Window ID of the code window.
|
||||
* `g:vimspector_session_windows.output`: Window ID of the output window.
|
||||
|
||||
In addition, the following key is added when triggering the
|
||||
`VimspectorTerminalOpened` event:
|
||||
|
||||
* `g:vimspector_session_windows.terminal`: Window ID of the terminal window
|
||||
|
||||
## Example
|
||||
|
||||
There is some example code in `support/custom_ui_vimrc` showing how you can use
|
||||
the window IDs to modify various aspects of the UI using some basic vim
|
||||
commands, primarily `win_gotoid` funciton and the `wincmd` ex command.
|
||||
|
||||
To try this out `vim -Nu support/custom_ui_vimrc <some file>`.
|
||||
|
||||
Here's a rather smaller example. A simple way to use this is to drop it into a
|
||||
file named `my_vimspector_ui.vim` in `~/.vim/plugin` (or paste into your
|
||||
`vimrc`):
|
||||
|
||||
```viml
|
||||
" Set the basic sizes
|
||||
let g:vimspector_sidebar_width = 80
|
||||
let g:vimspector_code_minwidth = 85
|
||||
let g:vimspector_terminal_minwidth = 75
|
||||
|
||||
function! s:CustomiseUI()
|
||||
" Customise the basic UI...
|
||||
|
||||
" Close the output window
|
||||
call win_gotoid( g:vimspector_session_windows.output )
|
||||
q
|
||||
endfunction
|
||||
|
||||
function s:SetUpTerminal()
|
||||
" Customise the terminal window size/position
|
||||
" For some reasons terminal buffers in Neovim have line numbers
|
||||
call win_gotoid( g:vimspector_session_windows.terminal )
|
||||
set norelativenumber nonumber
|
||||
endfunction
|
||||
|
||||
augroup MyVimspectorUICustomistaion
|
||||
autocmd!
|
||||
autocmd User VimspectorUICreated call s:CustomiseUI()
|
||||
autocmd User VimspectorTerminalOpened call s:SetUpTerminal()
|
||||
augroup END
|
||||
```
|
||||
|
||||
# FAQ
|
||||
|
||||
1. Q: Does it work? A: Yeah. It's a bit unpolished.
|
||||
|
|
@ -1366,6 +1536,7 @@ Copyright © 2018 Ben Jackson
|
|||
[vimspector-ref]: https://puremourning.github.io/vimspector/configuration.html
|
||||
[vimspector-ref-var]: https://puremourning.github.io/vimspector/configuration.html#replacements-and-variables
|
||||
[vimspector-ref-exception]: https://puremourning.github.io/vimspector/configuration.html#exception-breakpoints
|
||||
[vimspector-ref-config-selection]: https://puremourning.github.io/vimspector/configuration.html#configuration-selection
|
||||
[debugpy]: https://github.com/microsoft/debugpy
|
||||
[YouCompleteMe]: https://github.com/ycm-core/YouCompleteMe#java-semantic-completion
|
||||
[remote-debugging]: https://puremourning.github.io/vimspector/configuration.html#remote-debugging-support
|
||||
|
|
|
|||
|
|
@ -137,14 +137,16 @@ function! vimspector#ListBreakpoints() abort
|
|||
endfunction
|
||||
|
||||
function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
|
||||
let buffers = py3eval( '_vimspector_session.GetOutputBuffers()' )
|
||||
let buffers = py3eval( '_vimspector_session.GetOutputBuffers() '
|
||||
\ . ' if _vimspector_session else []' )
|
||||
return join( buffers, "\n" )
|
||||
endfunction
|
||||
|
||||
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
||||
return join( py3eval( '_vimspector_session.GetCompletionsSync( '
|
||||
\.' vim.eval( "a:CmdLine" ),'
|
||||
\.' int( vim.eval( "a:CursorPos" ) ) )' ),
|
||||
\.' int( vim.eval( "a:CursorPos" ) ) )'
|
||||
\. ' if _vimspector_session else []' ),
|
||||
\ "\n" )
|
||||
endfunction
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ endfunction
|
|||
function! vimspector#internal#neoterm#Start( cmd, opts ) abort
|
||||
" Prepare current buffer to be turned into a term if curwin is not set
|
||||
if ! get( a:opts, 'curwin', 0 )
|
||||
let mods = ''
|
||||
let mods = 'rightbelow '
|
||||
if get( a:opts, 'vertical', 0 )
|
||||
let mods .= 'vertical '
|
||||
let mods .= get( a:opts, 'term_cols', '' )
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ set cpoptions&vim
|
|||
" }}}
|
||||
|
||||
function! vimspector#internal#term#Start( cmd, opts ) abort
|
||||
return term_start( a:cmd, a:opts )
|
||||
rightbelow return term_start( a:cmd, a:opts )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#term#IsFinished( bufno ) abort
|
||||
|
|
|
|||
|
|
@ -58,11 +58,10 @@ stages:
|
|||
- bash: |
|
||||
eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
|
||||
export GOPATH=$HOME/go
|
||||
./run_tests
|
||||
./run_tests --report messages --quiet
|
||||
displayName: 'Run the tests'
|
||||
env:
|
||||
VIMSPECTOR_MIMODE: gdb
|
||||
VIMSPECTOR_TEST_STDOUT: true
|
||||
|
||||
- bash: ./make_package linux $(Build.SourceVersion)
|
||||
displayName: 'Package'
|
||||
|
|
@ -103,11 +102,10 @@ stages:
|
|||
- bash: vim --version
|
||||
displayName: 'Print vim version information'
|
||||
|
||||
- bash: ./run_tests
|
||||
- bash: ./run_tests --report messages --quiet
|
||||
displayName: 'Run the tests'
|
||||
env:
|
||||
VIMSPECTOR_MIMODE: lldb
|
||||
VIMSPECTOR_TEST_STDOUT: true
|
||||
|
||||
- bash: ./make_package macos $(Build.SourceVersion)
|
||||
displayName: 'Package'
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ function! s:RunTestUnderCursor()
|
|||
let l:cwd = getcwd()
|
||||
execute 'lcd ' . s:root_dir
|
||||
try
|
||||
execute s:make_cmd . ' '
|
||||
execute s:make_cmd . ' --report messages '
|
||||
\ . get( g:, 'vimspector_test_args', '' ) . ' '
|
||||
\ . l:test_arg
|
||||
finally
|
||||
|
|
@ -105,7 +105,7 @@ function! s:RunTest()
|
|||
let l:cwd = getcwd()
|
||||
execute 'lcd ' . s:root_dir
|
||||
try
|
||||
execute s:make_cmd . ' '
|
||||
execute s:make_cmd . ' --report messages '
|
||||
\ . get( g:, 'vimspector_test_args', '' )
|
||||
\ . ' %:p:t'
|
||||
finally
|
||||
|
|
@ -118,7 +118,7 @@ function! s:RunAllTests()
|
|||
let l:cwd = getcwd()
|
||||
execute 'lcd ' . s:root_dir
|
||||
try
|
||||
execute s:make_cmd . ' '
|
||||
execute s:make_cmd . ' --report messages '
|
||||
\ . get( g:, 'vimspector_test_args', '' )
|
||||
finally
|
||||
execute 'lcd ' . l:cwd
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
flake8==3.8.3
|
||||
vim-vint==0.3.21
|
||||
flake8-comprehensions==3.2.3
|
||||
flake8-ycm>= 0.1.0
|
||||
|
||||
# Use fork of vint which is up to date
|
||||
git+https://github.com/puremourning/vint
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ for Vimspector.
|
|||
* [Files and locations](#files-and-locations)
|
||||
* [Adapter configurations](#adapter-configurations)
|
||||
* [Debug configurations](#debug-configurations)
|
||||
* [Configuration selection](#configuration-selection)
|
||||
* [Specifying a default configuration](#specifying-a-default-configuration)
|
||||
* [Preventing automatic selection](#preventing-automatic-selection)
|
||||
* [Exception breakpionts](#exception-breakpionts)
|
||||
* [Predefined Variables](#predefined-variables)
|
||||
* [Remote Debugging Support](#remote-debugging-support)
|
||||
|
|
@ -25,7 +28,7 @@ for Vimspector.
|
|||
* [Appendix: Configuration file format](#appendix-configuration-file-format)
|
||||
* [Appendix: Editor configuration](#appendix-editor-configuration)
|
||||
|
||||
<!-- Added by: ben, at: Thu 9 Jul 2020 18:19:39 BST -->
|
||||
<!-- Added by: ben, at: Sun 12 Jul 2020 16:46:18 BST -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
|
|
@ -321,6 +324,62 @@ typical example looks like this:
|
|||
}
|
||||
```
|
||||
|
||||
### Configuration selection
|
||||
|
||||
When starting debugging, you can specify which debug configuration to launch
|
||||
with `call vimspector#LaunchWithSettings( #{ configuration: 'name here' } )`.
|
||||
|
||||
Otherwise, if there's only one configuration found, Vimspector will use that
|
||||
configuration, unless it contains a key `"autoselect": false`.
|
||||
|
||||
If multiple debug configurations are found, and no explicit configuration was
|
||||
selected on Launch, the user is prompted to select a configuration, unless a
|
||||
single debug configuration is found with a key `"default": true`.
|
||||
|
||||
#### Specifying a default configuration
|
||||
|
||||
As noted, you can specify a default configuration with `"default": true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"configurations": {
|
||||
"use this one": {
|
||||
"default": true,
|
||||
"adapter": " ... ",
|
||||
"configuation": {
|
||||
// ...
|
||||
}
|
||||
},
|
||||
"don't use this one": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If multiple conifigurations are found with `default` set to `true`, then the
|
||||
user is prompted anyway.
|
||||
|
||||
#### Preventing automatic selection
|
||||
|
||||
If you don't want a configuration to be selected automatically, then set
|
||||
`"autoselect": false`. This particularly useful for configurations in the
|
||||
central (as opposed to project-local) directory. For example:
|
||||
|
||||
```json
|
||||
"configurations": {
|
||||
"Don't use this by default!": {
|
||||
"autoselect": false,
|
||||
"adapter": " ... ",
|
||||
"configuation": {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Setting `autoselect` to `false` overrides setting `default` to `true`.
|
||||
|
||||
### Exception breakpionts
|
||||
|
||||
Debug adapters have arbitrary configuration for exception breakpoints. Normally
|
||||
|
|
@ -426,12 +485,12 @@ where the development is done on one host and the runtime is
|
|||
some other host, account, container, etc.
|
||||
|
||||
In order for it to work, you have to set up passwordless SSH between the local
|
||||
and remote machines/accounts. Then just tell Vimsector how to remotely launch
|
||||
and remote machines/accounts. Then just tell Vimspector how to remotely launch
|
||||
and/or attach to the app.
|
||||
|
||||
This is presented as examples with commentary, as it's a fairly advanced/niche
|
||||
case. If you're not already familiar with remote debugging tools (such as
|
||||
gdbserver) or not familar with ssh or such, you might need to independently
|
||||
gdbserver) or not familiar with ssh or such, you might need to independently
|
||||
research that.
|
||||
|
||||
Vimspector's tools are intended to automate your existing process for setting
|
||||
|
|
|
|||
|
|
@ -97,6 +97,13 @@ command! -bar
|
|||
\ VimspectorReset
|
||||
\ call vimspector#Reset()
|
||||
|
||||
" Dummy autocommands so that we can call this whenever
|
||||
augroup VimspectorUserAutoCmds
|
||||
au!
|
||||
au User VimspectorUICreated silent
|
||||
au User VimspectorTerminalOpened silent
|
||||
augroup END
|
||||
|
||||
" boilerplate {{{
|
||||
call s:restore_cpo()
|
||||
" }}}
|
||||
|
|
|
|||
|
|
@ -342,11 +342,14 @@ class ProjectBreakpoints( object ):
|
|||
f"Invalid value for exception breakpoint filter '{f}': "
|
||||
f"'{result}'. Must be boolean, 'Y', 'N' or '' (default)" )
|
||||
else:
|
||||
result = utils.AskForInput(
|
||||
"{}: Break on {} (Y/N/default: {})? ".format( f[ 'filter' ],
|
||||
f[ 'label' ],
|
||||
default_value ),
|
||||
default_value )
|
||||
try:
|
||||
result = utils.AskForInput(
|
||||
"{}: Break on {} (Y/N/default: {})? ".format( f[ 'filter' ],
|
||||
f[ 'label' ],
|
||||
default_value ),
|
||||
default_value )
|
||||
except KeyboardInterrupt:
|
||||
result = ''
|
||||
|
||||
if result == 'Y':
|
||||
exception_filters.append( f[ 'filter' ] )
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import logging
|
|||
import json
|
||||
from collections import defaultdict
|
||||
|
||||
from vimspector import utils
|
||||
from vimspector import utils, settings
|
||||
|
||||
|
||||
class CodeView( object ):
|
||||
|
|
@ -218,7 +218,7 @@ class CodeView( object ):
|
|||
args = params[ 'args' ]
|
||||
env = params.get( 'env', {} )
|
||||
|
||||
options = {
|
||||
term_options = {
|
||||
'vertical': 1,
|
||||
'norestore': 1,
|
||||
'cwd': cwd,
|
||||
|
|
@ -228,35 +228,54 @@ class CodeView( object ):
|
|||
if self._window.valid:
|
||||
window_for_start = self._window
|
||||
else:
|
||||
# TOOD: Where?
|
||||
# TOOD: Where? Maybe we should just use botright vertical ...
|
||||
window_for_start = vim.current.window
|
||||
|
||||
if self._terminal_window is not None and self._terminal_window.valid:
|
||||
assert self._terminal_buffer_number
|
||||
window_for_start = self._terminal_window
|
||||
if ( self._terminal_window.buffer.number == self._terminal_buffer_number
|
||||
and int( utils.Call( 'vimspector#internal#{}term#IsFinished'.format(
|
||||
self._api_prefix ),
|
||||
self._terminal_buffer_number ) ) ):
|
||||
window_for_start = self._terminal_window
|
||||
options[ 'curwin' ] = 1
|
||||
term_options[ 'curwin' ] = 1
|
||||
else:
|
||||
term_options[ 'vertical' ] = 0
|
||||
|
||||
buffer_number = None
|
||||
terminal_window = None
|
||||
with utils.TemporaryVimOptions( { 'splitright': True,
|
||||
'equalalways': False } ):
|
||||
with utils.LetCurrentWindow( window_for_start ):
|
||||
buffer_number = int(
|
||||
utils.Call(
|
||||
'vimspector#internal#{}term#Start'.format( self._api_prefix ),
|
||||
args,
|
||||
options ) )
|
||||
terminal_window = vim.current.window
|
||||
with utils.LetCurrentWindow( window_for_start ):
|
||||
# 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 ):
|
||||
term_options[ 'term_cols' ] = max(
|
||||
min ( int( vim.eval( 'winwidth( 0 )' ) )
|
||||
- settings.Int( 'code_minwidth', 82 ),
|
||||
settings.Int( 'terminal_maxwidth', 80 ) ),
|
||||
settings.Int( 'terminal_minwidth' , 10 )
|
||||
)
|
||||
|
||||
buffer_number = int(
|
||||
utils.Call(
|
||||
'vimspector#internal#{}term#Start'.format( self._api_prefix ),
|
||||
args,
|
||||
term_options ) )
|
||||
terminal_window = vim.current.window
|
||||
|
||||
if buffer_number is None or buffer_number <= 0:
|
||||
# TODO: Do something better like reject the request?
|
||||
raise ValueError( "Unable to start terminal" )
|
||||
else:
|
||||
self._terminal_window = terminal_window
|
||||
self._terminal_buffer_number = buffer_number
|
||||
|
||||
self._terminal_window = terminal_window
|
||||
self._terminal_buffer_number = buffer_number
|
||||
|
||||
vim.vars[ 'vimspector_session_windows' ][ 'terminal' ] = utils.WindowID(
|
||||
self._terminal_window,
|
||||
vim.current.tabpage )
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.RestoreCurrentWindow():
|
||||
with utils.RestoreCurrentBuffer( vim.current.window ):
|
||||
vim.command( 'doautocmd User VimspectorTerminalOpened' )
|
||||
|
||||
return buffer_number
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@ from vimspector import ( breakpoints,
|
|||
output,
|
||||
stack_trace,
|
||||
utils,
|
||||
variables )
|
||||
variables,
|
||||
settings )
|
||||
from vimspector.vendor.json_minify import minify
|
||||
|
||||
# We cache this once, and don't allow it to change (FIXME?)
|
||||
|
|
@ -125,9 +126,17 @@ class DebugSession( object ):
|
|||
next( iter( configurations.values() ) ).get( "autoselect", True ) ):
|
||||
configuration_name = next( iter( configurations.keys() ) )
|
||||
else:
|
||||
configuration_name = utils.SelectFromList(
|
||||
'Which launch configuration?',
|
||||
sorted( configurations.keys() ) )
|
||||
# Find a single configuration with 'default' True and autoselect not False
|
||||
defaults = { n: c for n, c in configurations.items()
|
||||
if c.get( 'default', False ) is True
|
||||
and c.get( 'autoselect', True ) is not False }
|
||||
|
||||
if len( defaults ) == 1:
|
||||
configuration_name = next( iter( defaults.keys() ) )
|
||||
else:
|
||||
configuration_name = utils.SelectFromList(
|
||||
'Which launch configuration?',
|
||||
sorted( configurations.keys() ) )
|
||||
|
||||
if not configuration_name or configuration_name not in configurations:
|
||||
return
|
||||
|
|
@ -206,26 +215,30 @@ class DebugSession( object ):
|
|||
USER_CHOICES.update( launch_variables )
|
||||
variables.update( launch_variables )
|
||||
|
||||
variables.update(
|
||||
utils.ParseVariables( adapter.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
variables.update(
|
||||
utils.ParseVariables( configuration.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
try:
|
||||
variables.update(
|
||||
utils.ParseVariables( adapter.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
variables.update(
|
||||
utils.ParseVariables( configuration.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
|
||||
|
||||
utils.ExpandReferencesInDict( configuration,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
utils.ExpandReferencesInDict( adapter,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
utils.ExpandReferencesInDict( configuration,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
utils.ExpandReferencesInDict( adapter,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
except KeyboardInterrupt:
|
||||
self._Reset()
|
||||
return
|
||||
|
||||
if not adapter:
|
||||
utils.UserMessage( 'No adapter configured for {}'.format(
|
||||
|
|
@ -285,18 +298,35 @@ class DebugSession( object ):
|
|||
|
||||
self._StartWithConfiguration( self._configuration, self._adapter )
|
||||
|
||||
def IfConnected( fct ):
|
||||
def IfConnected( otherwise=None ):
|
||||
def decorator( fct ):
|
||||
"""Decorator, call fct if self._connected else echo warning"""
|
||||
@functools.wraps( fct )
|
||||
def wrapper( self, *args, **kwargs ):
|
||||
if not self._connection:
|
||||
utils.UserMessage(
|
||||
'Vimspector not connected, start a debug session first',
|
||||
persist=False,
|
||||
error=True )
|
||||
return otherwise
|
||||
return fct( self, *args, **kwargs )
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
def RequiresUI( otherwise=None ):
|
||||
"""Decorator, call fct if self._connected else echo warning"""
|
||||
@functools.wraps( fct )
|
||||
def wrapper( self, *args, **kwargs ):
|
||||
if not self._connection:
|
||||
utils.UserMessage(
|
||||
'Vimspector not connected, start a debug session first',
|
||||
persist=True,
|
||||
error=True )
|
||||
return
|
||||
return fct( self, *args, **kwargs )
|
||||
return wrapper
|
||||
def decorator( fct ):
|
||||
@functools.wraps( fct )
|
||||
def wrapper( self, *args, **kwargs ):
|
||||
if not self._uiTab or not self._uiTab.valid:
|
||||
utils.UserMessage(
|
||||
'Vimspector is not active',
|
||||
persist=False,
|
||||
error=True )
|
||||
return otherwise
|
||||
return fct( self, *args, **kwargs )
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
def OnChannelData( self, data ):
|
||||
if self._connection is None:
|
||||
|
|
@ -319,7 +349,7 @@ class DebugSession( object ):
|
|||
# TODO: Not calld
|
||||
self._connection = None
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def Stop( self ):
|
||||
self._logger.debug( "Stop debug adapter with no callback" )
|
||||
self._StopDebugAdapter()
|
||||
|
|
@ -335,6 +365,8 @@ class DebugSession( object ):
|
|||
self._logger.info( "Debugging complete." )
|
||||
if self._uiTab:
|
||||
self._logger.debug( "Clearing down UI" )
|
||||
|
||||
del vim.vars[ 'vimspector_session_windows' ]
|
||||
vim.current.tabpage = self._uiTab
|
||||
|
||||
self._splash_screen = utils.HideSplash( self._api_prefix,
|
||||
|
|
@ -354,7 +386,7 @@ class DebugSession( object ):
|
|||
# make sure that we're displaying signs in any still-open buffers
|
||||
self._breakpoints.UpdateUI()
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def StepOver( self ):
|
||||
if self._stackTraceView.GetCurrentThreadId() is None:
|
||||
return
|
||||
|
|
@ -366,7 +398,7 @@ class DebugSession( object ):
|
|||
},
|
||||
} )
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def StepInto( self ):
|
||||
if self._stackTraceView.GetCurrentThreadId() is None:
|
||||
return
|
||||
|
|
@ -378,7 +410,7 @@ class DebugSession( object ):
|
|||
},
|
||||
} )
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def StepOut( self ):
|
||||
if self._stackTraceView.GetCurrentThreadId() is None:
|
||||
return
|
||||
|
|
@ -396,29 +428,29 @@ class DebugSession( object ):
|
|||
else:
|
||||
self.Start()
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def Pause( self ):
|
||||
self._stackTraceView.Pause()
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def ExpandVariable( self ):
|
||||
self._variablesView.ExpandVariable()
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def AddWatch( self, expression ):
|
||||
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
|
||||
expression )
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def EvaluateConsole( self, expression ):
|
||||
self._outputView.Evaluate( self._stackTraceView.GetCurrentFrame(),
|
||||
expression )
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def DeleteWatch( self ):
|
||||
self._variablesView.DeleteWatch()
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def ShowBalloon( self, winnr, expression ):
|
||||
"""Proxy: ballonexpr -> variables.ShowBallon"""
|
||||
frame = self._stackTraceView.GetCurrentFrame()
|
||||
|
|
@ -437,17 +469,32 @@ class DebugSession( object ):
|
|||
# Return variable aware function
|
||||
return self._variablesView.ShowBalloon( frame, expression )
|
||||
|
||||
@IfConnected
|
||||
@IfConnected()
|
||||
def ExpandFrameOrThread( self ):
|
||||
self._stackTraceView.ExpandFrameOrThread()
|
||||
|
||||
@RequiresUI()
|
||||
def ShowOutput( self, category ):
|
||||
if not self._outputView.WindowIsValid():
|
||||
# TODO: The UI code is too scattered. Re-organise into a UI class that
|
||||
# just deals with these thigns like window layout and custmisattion.
|
||||
# currently, this class and the CodeView share some responsiblity for this
|
||||
# and poking into each View class to check its window is valid also feels
|
||||
# wrong.
|
||||
with utils.LetCurrentTabpage( self._uiTab ):
|
||||
vim.command( f'botright { settings.Int( "bottombar_height", 10 ) }new' )
|
||||
self._outputView.UseWindow( vim.current.window )
|
||||
vim.vars[ 'vimspector_session_windows' ][ 'output' ] = utils.WindowID(
|
||||
vim.current.window,
|
||||
self._uiTab )
|
||||
|
||||
self._outputView.ShowOutput( category )
|
||||
|
||||
@RequiresUI( otherwise=[] )
|
||||
def GetOutputBuffers( self ):
|
||||
return self._outputView.GetCategories()
|
||||
|
||||
@IfConnected
|
||||
@IfConnected( otherwise=[] )
|
||||
def GetCompletionsSync( self, text_line, column_in_bytes ):
|
||||
if not self._server_capabilities.get( 'supportsCompletionsRequest' ):
|
||||
return []
|
||||
|
|
@ -473,49 +520,66 @@ class DebugSession( object ):
|
|||
self._uiTab = vim.current.tabpage
|
||||
|
||||
# Code window
|
||||
self._codeView = code.CodeView( vim.current.window,
|
||||
self._api_prefix )
|
||||
code_window = vim.current.window
|
||||
self._codeView = code.CodeView( code_window, self._api_prefix )
|
||||
|
||||
# Call stack
|
||||
with utils.TemporaryVimOptions( { 'splitright': False,
|
||||
'equalalways': False, } ):
|
||||
vim.command( 'topleft 50vspl' )
|
||||
vim.command( 'enew' )
|
||||
self._stackTraceView = stack_trace.StackTraceView( self,
|
||||
self._connection,
|
||||
vim.current.buffer )
|
||||
vim.command(
|
||||
f'topleft vertical { settings.Int( "sidebar_width", 50 ) }new' )
|
||||
stack_trace_window = vim.current.window
|
||||
one_third = int( vim.eval( 'winheight( 0 )' ) ) / 3
|
||||
self._stackTraceView = stack_trace.StackTraceView( self,
|
||||
self._connection,
|
||||
stack_trace_window )
|
||||
|
||||
with utils.TemporaryVimOptions( { 'splitbelow': False,
|
||||
'eadirection': 'ver',
|
||||
'equalalways': True } ):
|
||||
# Watches
|
||||
vim.command( 'spl' )
|
||||
vim.command( 'enew' )
|
||||
watch_win = vim.current.window
|
||||
# Watches
|
||||
vim.command( 'leftabove new' )
|
||||
watch_window = vim.current.window
|
||||
|
||||
# Variables
|
||||
vim.command( 'spl' )
|
||||
vim.command( 'enew' )
|
||||
vars_win = vim.current.window
|
||||
# Variables
|
||||
vim.command( 'leftabove new' )
|
||||
vars_window = vim.current.window
|
||||
|
||||
self._variablesView = variables.VariablesView( self._connection,
|
||||
vars_win,
|
||||
watch_win )
|
||||
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( self._connection,
|
||||
vars_window,
|
||||
watch_window )
|
||||
|
||||
# Output/logging
|
||||
vim.current.window = code_window
|
||||
vim.command( f'rightbelow { settings.Int( "bottombar_height", 10 ) }new' )
|
||||
output_window = vim.current.window
|
||||
self._outputView = output.OutputView( self._connection,
|
||||
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' ] = {
|
||||
'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 ),
|
||||
}
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.RestoreCurrentWindow():
|
||||
with utils.RestoreCurrentBuffer( vim.current.window ):
|
||||
vim.command( 'doautocmd User VimspectorUICreated' )
|
||||
|
||||
|
||||
with utils.TemporaryVimOption( 'splitbelow', True ):
|
||||
vim.current.window = self._codeView._window
|
||||
|
||||
# Output/logging
|
||||
vim.command( '10spl' )
|
||||
vim.command( 'enew' )
|
||||
self._outputView = output.OutputView( self._connection,
|
||||
vim.current.window,
|
||||
self._api_prefix )
|
||||
|
||||
@RequiresUI()
|
||||
def ClearCurrentFrame( self ):
|
||||
self.SetCurrentFrame( None )
|
||||
|
||||
@RequiresUI()
|
||||
def SetCurrentFrame( self, frame ):
|
||||
if not frame:
|
||||
self._stackTraceView.Clear()
|
||||
|
|
@ -557,6 +621,9 @@ class DebugSession( object ):
|
|||
|
||||
if self._adapter[ 'port' ] == 'ask':
|
||||
port = utils.AskForInput( 'Enter port to connect to: ' )
|
||||
if port is None:
|
||||
self._Reset()
|
||||
return
|
||||
self._adapter[ 'port' ] = port
|
||||
|
||||
self._connection_type = self._api_prefix + self._connection_type
|
||||
|
|
@ -666,6 +733,8 @@ class DebugSession( object ):
|
|||
prop = atttach_config[ 'pidProperty' ]
|
||||
if prop not in launch_config:
|
||||
pid = utils.AskForInput( 'Enter PID to attach to: ' )
|
||||
if pid is None:
|
||||
return
|
||||
launch_config[ prop ] = pid
|
||||
return
|
||||
elif atttach_config[ 'pidSelect' ] == 'none':
|
||||
|
|
|
|||
|
|
@ -102,6 +102,17 @@ class OutputView( object ):
|
|||
# FIXME: nunmenu the WinBar ?
|
||||
self._buffers = {}
|
||||
|
||||
def WindowIsValid( self ):
|
||||
return self._window.valid
|
||||
|
||||
def UseWindow( self, win ):
|
||||
assert not self._window.valid
|
||||
self._window = win
|
||||
# TODO: Sorting of the WinBar ?
|
||||
for category, _ in self._buffers.items():
|
||||
self._RenderWinBar( category )
|
||||
|
||||
|
||||
def _ShowOutput( self, category ):
|
||||
if not self._window.valid:
|
||||
return
|
||||
|
|
@ -157,11 +168,13 @@ class OutputView( object ):
|
|||
|
||||
|
||||
def _CreateBuffer( self, category, file_name = None, cmd = None ):
|
||||
if not self._window.valid:
|
||||
return
|
||||
win = self._window
|
||||
if not win.valid:
|
||||
# We need to borrow the current window
|
||||
win = vim.current.window
|
||||
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
with utils.RestoreCurrentBuffer( self._window ):
|
||||
with utils.LetCurrentWindow( win ):
|
||||
with utils.RestoreCurrentBuffer( win ):
|
||||
|
||||
if file_name is not None:
|
||||
assert cmd is None
|
||||
|
|
|
|||
26
python3/vimspector/settings.py
Normal file
26
python3/vimspector/settings.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# vimspector - A multi-language debugging system for Vim
|
||||
# Copyright 2020 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.
|
||||
|
||||
|
||||
import vim
|
||||
import builtins
|
||||
|
||||
|
||||
def Get( option: str, default=None, cls=str ):
|
||||
return cls( vim.vars.get( f'vimspector_{ option }', default ) )
|
||||
|
||||
|
||||
def Int( option: str, default=0 ):
|
||||
return Get( option, default=default, cls=builtins.int )
|
||||
|
|
@ -21,11 +21,11 @@ from vimspector import utils
|
|||
|
||||
|
||||
class StackTraceView( object ):
|
||||
def __init__( self, session, connection, buf ):
|
||||
def __init__( self, session, connection, win ):
|
||||
self._logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( self._logger )
|
||||
|
||||
self._buf = buf
|
||||
self._buf = win.buffer
|
||||
self._session = session
|
||||
self._connection = connection
|
||||
|
||||
|
|
@ -38,9 +38,7 @@ class StackTraceView( object ):
|
|||
self._scratch_buffers = []
|
||||
|
||||
utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' )
|
||||
|
||||
vim.current.buffer = self._buf
|
||||
utils.SetUpUIWindow( vim.current.window )
|
||||
utils.SetUpUIWindow( win )
|
||||
|
||||
vim.command( 'nnoremap <buffer> <CR> :call vimspector#GoToFrame()<CR>' )
|
||||
|
||||
|
|
|
|||
|
|
@ -184,8 +184,10 @@ def RestoreCurrentWindow():
|
|||
try:
|
||||
yield
|
||||
finally:
|
||||
vim.current.tabpage = old_tabpage
|
||||
vim.current.window = old_window
|
||||
if old_tabpage.valid:
|
||||
vim.current.tabpage = old_tabpage
|
||||
if old_window.valid:
|
||||
vim.current.window = old_window
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -194,9 +196,10 @@ def RestoreCurrentBuffer( window ):
|
|||
try:
|
||||
yield
|
||||
finally:
|
||||
with RestoreCurrentWindow():
|
||||
vim.current.window = window
|
||||
vim.current.buffer = old_buffer
|
||||
if window.valid:
|
||||
with RestoreCurrentWindow():
|
||||
vim.current.window = window
|
||||
vim.current.buffer = old_buffer
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -211,6 +214,13 @@ def AnyWindowForBuffer( buf ):
|
|||
yield
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def LetCurrentTabpage( tabpage ):
|
||||
with RestoreCurrentWindow():
|
||||
vim.current.tabpage = tabpage
|
||||
yield
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def LetCurrentWindow( window ):
|
||||
with RestoreCurrentWindow():
|
||||
|
|
@ -329,7 +339,7 @@ def AskForInput( prompt, default_value = None ):
|
|||
return vim.eval( "input( '{}' {} )".format( Escape( prompt ),
|
||||
default_option ) )
|
||||
except KeyboardInterrupt:
|
||||
return ''
|
||||
return None
|
||||
|
||||
|
||||
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
||||
|
|
@ -437,6 +447,10 @@ def ExpandReferencesInString( orig_s,
|
|||
default_value = user_choices.get( key, None )
|
||||
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
||||
default_value )
|
||||
|
||||
if mapping[ key ] is None:
|
||||
raise KeyboardInterrupt
|
||||
|
||||
user_choices[ key ] = mapping[ key ]
|
||||
_logger.debug( "Value for %s not set in %s (from %s): set to %s",
|
||||
key,
|
||||
|
|
@ -639,3 +653,7 @@ def GetUnusedLocalPort():
|
|||
port = sock.getsockname()[ 1 ]
|
||||
sock.close()
|
||||
return port
|
||||
|
||||
|
||||
def WindowID( window, tab ):
|
||||
return int( Call( 'win_getid', window.number, tab.number ) )
|
||||
|
|
|
|||
83
run_tests
83
run_tests
|
|
@ -1,51 +1,76 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if [ "$1" == "--help" ]; then
|
||||
echo "$(basename $0) [--basedir <basedir>] [--install] <optional list of tests in form file:func>"
|
||||
echo ""
|
||||
echo " --basedir <basedir> path to runtime directory like the optino to install_gadget.py"
|
||||
echo " --install run install_gadget.py, useful with --basedir"
|
||||
echo "e.g.: "
|
||||
echo " - run all tests: $0"
|
||||
echo " - run specific tests script: $0 signature_help.test.vim"
|
||||
echo " - run specific tests fun: $0 signature_help.test.vim:Test_signatures_TopLine\(\)"
|
||||
echo " - run all tests in a clean env: $0 --basedir \$(mktemp -d) --install"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
BASEDIR=$(dirname $0)
|
||||
INSTALL=0
|
||||
RUN_VIM="vim -N --clean --not-a-term"
|
||||
RUN_TEST="${RUN_VIM} -S lib/run_test.vim"
|
||||
BASEDIR_CMD='py3 pass'
|
||||
|
||||
# 1 is stdout
|
||||
out_fd=1
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
"--basedir")
|
||||
BASEDIR=$2
|
||||
shift
|
||||
BASEDIR=$1
|
||||
shift
|
||||
if [[ ! $BASEDIR = /* ]]; then
|
||||
# Relative
|
||||
BASEDIR=$(pwd)/${BASEDIR}
|
||||
fi
|
||||
BASEDIR_CMD="let g:vimspector_base_dir='${BASEDIR}'"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
"--install")
|
||||
INSTALL=1
|
||||
shift
|
||||
;;
|
||||
"--report")
|
||||
shift
|
||||
VIMSPECTOR_TEST_STDOUT=$1
|
||||
shift
|
||||
;;
|
||||
"--quiet")
|
||||
shift
|
||||
# send the output to /dev/null
|
||||
# https://stackoverflow.com/a/47553900
|
||||
# Note we can't use {out_fd} here because the bash version in CI is too
|
||||
# old on macOS
|
||||
out_fd=3
|
||||
exec 3>/dev/null
|
||||
;;
|
||||
"--")
|
||||
shift
|
||||
break
|
||||
;;
|
||||
"--help")
|
||||
shift
|
||||
echo "$(basename $0) [--basedir <basedir>] [--report output] [--quiet] [--install] <optional list of tests in form file:func>"
|
||||
echo ""
|
||||
echo " --basedir <basedir> path to runtime directory like the optino to install_gadget.py"
|
||||
echo " --install run install_gadget.py, useful with --basedir"
|
||||
echo " --report <messages|all> which logs to dump to stdout after a test"
|
||||
echo " --quiet suppress vim's stdout"
|
||||
echo "e.g.: "
|
||||
echo " - run all tests: $0"
|
||||
echo " - run specific tests script: $0 signature_help.test.vim"
|
||||
echo " - run specific tests fun: $0 signature_help.test.vim:Test_signatures_TopLine\(\)"
|
||||
echo " - run all tests in a clean env: $0 --basedir \$(mktemp -d) --install"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# We use fd 3 for vim's output. Send it to stdout if not already redirected
|
||||
# Note: can't use ${out_fd} in a redirect because redirects happen before
|
||||
# variable substitution
|
||||
if [ "${out_fd}" = "1" ]; then
|
||||
exec 3>&1
|
||||
fi
|
||||
|
||||
if [ $INSTALL = 1 ]; then
|
||||
python3 $(dirname $0)/install_gadget.py --basedir ${BASEDIR} --all
|
||||
fi
|
||||
|
|
@ -71,7 +96,7 @@ echo " * BASEDIR_CMD=$BASEDIR_CMD"
|
|||
echo "%SETUP - Building test programs..."
|
||||
set -e
|
||||
pushd tests/testdata/cpp/simple
|
||||
make clean simple
|
||||
make clean all
|
||||
popd
|
||||
set +e
|
||||
echo "%DONE - built test programs"
|
||||
|
|
@ -99,6 +124,7 @@ for t in ${TESTS}; do
|
|||
|
||||
if ${RUN_TEST} --cmd "${BASEDIR_CMD}" \
|
||||
--cmd 'au SwapExists * let v:swapchoice = "e"' $t $T \
|
||||
>&3\
|
||||
&& [ -f $t.res ]; then
|
||||
echo "%PASS: $t PASSED"
|
||||
else
|
||||
|
|
@ -109,10 +135,22 @@ for t in ${TESTS}; do
|
|||
rm -rf $TESTLOGDIR
|
||||
mkdir -p $TESTLOGDIR
|
||||
${RUN_VIM} --version > ${TESTLOGDIR}/vimversion
|
||||
if [ "$VIMSPECTOR_TEST_STDOUT" = "messages" ]; then
|
||||
if [ -f messages ]; then
|
||||
echo "%MESSAGES"
|
||||
cat messages
|
||||
echo "%END"
|
||||
else
|
||||
echo "%MESSAGES"
|
||||
echo "No messages found"
|
||||
echo "%END"
|
||||
fi
|
||||
fi
|
||||
|
||||
for l in messages debuglog test.log *.testlog; do
|
||||
# In CI we can't view the output files, so we just have to cat them
|
||||
if [ -f $l ]; then
|
||||
if [ "$VIMSPECTOR_TEST_STDOUT" ]; then
|
||||
if [ "$VIMSPECTOR_TEST_STDOUT" = "all" ]; then
|
||||
echo ""
|
||||
echo ""
|
||||
echo "*** START: $l ***"
|
||||
|
|
@ -126,11 +164,14 @@ for t in ${TESTS}; do
|
|||
rm -f $t.res
|
||||
done
|
||||
|
||||
# close out_fd if it's not stdout/stderr/
|
||||
(( out_fd > 2 )) && exec 3>&-
|
||||
|
||||
|
||||
echo "Done running tests"
|
||||
popd > /dev/null
|
||||
|
||||
echo ""
|
||||
echo "All done."
|
||||
|
||||
echo "All done. Exit with ${RESULT}"
|
||||
|
||||
exit $RESULT
|
||||
|
|
|
|||
53
support/custom_ui_vimrc
Normal file
53
support/custom_ui_vimrc
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
execute 'source' expand( '<sfile>:p:h' ) . '/minimal_vimrc'
|
||||
set noequalalways
|
||||
|
||||
function! s:CustomiseUI()
|
||||
let wins = g:vimspector_session_windows
|
||||
|
||||
" Close the Variables window
|
||||
if has( 'nvim' )
|
||||
" No win_execute in neovim
|
||||
call win_gotoid( wins.variables )
|
||||
quit
|
||||
else
|
||||
call win_execute( wins.variables, 'q' )
|
||||
endif
|
||||
|
||||
" Put the stack trace at the top of the "left bar" (rotate)
|
||||
call win_gotoid( wins.stack_trace )
|
||||
wincmd r
|
||||
|
||||
" Make the left column at least 70 chars
|
||||
70wincmd |
|
||||
|
||||
" Make the code window at least 80 chars
|
||||
call win_gotoid( wins.code )
|
||||
80wincmd |
|
||||
|
||||
" Make the output window 10 lines high and right at the top of the screen
|
||||
call win_gotoid( wins.output )
|
||||
10wincmd _
|
||||
wincmd K
|
||||
endfunction
|
||||
|
||||
function s:SetUpTerminal()
|
||||
let terminal_win = g:vimspector_session_windows.terminal
|
||||
|
||||
" Make the terminal window at most 80 columns wide, ensuring there is enough
|
||||
" sapce for our code window (80 columns) and the left bar (70 columns)
|
||||
|
||||
" Padding is 2 for the 2 vertical split markers and 2 for the sign column in
|
||||
" the code window.
|
||||
let left_bar = 70
|
||||
let code = 80
|
||||
let padding = 4
|
||||
let cols = max( [ min( [ &columns - left_bar - code - padding, 80 ] ), 10 ] )
|
||||
call win_gotoid( terminal_win )
|
||||
execute cols . 'wincmd |'
|
||||
endfunction
|
||||
|
||||
augroup TestUICustomistaion
|
||||
autocmd!
|
||||
autocmd User VimspectorUICreated call s:CustomiseUI()
|
||||
autocmd User VimspectorTerminalOpened call s:SetUpTerminal()
|
||||
augroup END
|
||||
4
support/minimal_vimrc
Normal file
4
support/minimal_vimrc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
let s:vimspector_path = expand( '<sfile>:p:h:h' )
|
||||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
exe 'source ' . s:vimspector_path . '/tests/vimrc'
|
||||
|
||||
|
|
@ -11,6 +11,12 @@ function! vimspector#test#setup#SetUpWithMappings( mappings ) abort
|
|||
|
||||
" This is a bit of a hack
|
||||
runtime! plugin/**/*.vim
|
||||
|
||||
augroup VimspectorTestSwap
|
||||
au!
|
||||
au SwapExists * let v:swapchoice = 'e'
|
||||
augroup END
|
||||
|
||||
endfunction
|
||||
|
||||
function! vimspector#test#setup#ClearDown() abort
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ function! vimspector#test#signs#AssertCursorIsAtLineInBuffer( buffer,
|
|||
\ line,
|
||||
\ column ) abort
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( a:buffer, bufname( '%' ), 'Current buffer' )
|
||||
\ assert_equal( fnamemodify( a:buffer, ':p' ),
|
||||
\ fnamemodify( bufname( '%' ), ':p' ),
|
||||
\ 'Current buffer' )
|
||||
\ }, 10000 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( a:line, line( '.' ), 'Current line' )
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ func StopVimInTerminal(buf)
|
|||
" In Command-line it's inserted, the CTRL-U removes it again.
|
||||
call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
|
||||
|
||||
call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
|
||||
call WaitForAssert({-> assert_equal('finished', term_getstatus(a:buf))})
|
||||
only!
|
||||
endfunc
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ func s:WaitForCommon(expr, assert, timeout)
|
|||
" Remove the errors added by the assert function.
|
||||
let errors_added = len( v:errors ) - errors_before
|
||||
if errors_added > 0
|
||||
call remove(v:errors, -1 * errors_added )
|
||||
call remove( v:errors, -1 * errors_added, -1 )
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
|||
1
tests/testdata/cpp/simple/.gitignore
vendored
1
tests/testdata/cpp/simple/.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
simple
|
||||
variables
|
||||
struct
|
||||
|
|
|
|||
29
tests/testdata/cpp/simple/.vimspector.json
vendored
29
tests/testdata/cpp/simple/.vimspector.json
vendored
|
|
@ -1,17 +1,38 @@
|
|||
{
|
||||
"configurations": {
|
||||
"cpptools-run": {
|
||||
"run-to-entry": {
|
||||
"adapter": "vscode-cpptools",
|
||||
// This makes this configuration the default. Only one default can be set
|
||||
// (having two is the same as having none)
|
||||
"default": true,
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/${fileBasenameNoExtension}",
|
||||
"externalConsole": false,
|
||||
"stopAtEntry": true,
|
||||
"stopOnEntry": true,
|
||||
"MImode": "${VIMSPECTOR_MIMODE}",
|
||||
"logging": {
|
||||
"engineLogging": true
|
||||
"MImode": "${VIMSPECTOR_MIMODE}"
|
||||
},
|
||||
"breakpoints": {
|
||||
"exception": {
|
||||
"cpp_catch": "",
|
||||
"cpp_throw": "",
|
||||
"objc_catch": "",
|
||||
"objc_throw": "",
|
||||
"swift_catch": "",
|
||||
"swift_throw": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-to-breakpoint": {
|
||||
"adapter": "vscode-cpptools",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/${fileBasenameNoExtension}",
|
||||
"externalConsole": false,
|
||||
"stopAtEntry": false,
|
||||
"stopOnEntry": false,
|
||||
"MImode": "${VIMSPECTOR_MIMODE}"
|
||||
},
|
||||
"breakpoints": {
|
||||
"exception": {
|
||||
|
|
|
|||
2
tests/testdata/cpp/simple/Makefile
vendored
2
tests/testdata/cpp/simple/Makefile
vendored
|
|
@ -2,7 +2,7 @@ CXXFLAGS=-g -O0 -std=c++17
|
|||
|
||||
.PHONY: all
|
||||
|
||||
TARGETS=simple variables
|
||||
TARGETS=simple variables struct
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
|
|
|
|||
33
tests/testdata/cpp/simple/struct.cpp
vendored
Normal file
33
tests/testdata/cpp/simple/struct.cpp
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
struct AnotherTest
|
||||
{
|
||||
char choo;
|
||||
int ints[5];
|
||||
};
|
||||
|
||||
struct Test
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
float fffff;
|
||||
|
||||
AnotherTest another_test;
|
||||
};
|
||||
|
||||
static Test SetUp( Test t )
|
||||
{
|
||||
t.another_test.choo = 'p';
|
||||
t.another_test.ints[ 0 ] = t.i; return t;
|
||||
}
|
||||
|
||||
int main( int , char ** )
|
||||
{
|
||||
Test t = {};
|
||||
|
||||
t.i = 1;
|
||||
t.c = 'c';
|
||||
t.fffff = 3.14;
|
||||
|
||||
t = SetUp( t );
|
||||
|
||||
return t.another_test.ints[ 0 ];
|
||||
}
|
||||
380
tests/ui.test.vim
Normal file
380
tests/ui.test.vim
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
let s:fn='../support/test/python/simple_python/main.py'
|
||||
|
||||
function! SetUp()
|
||||
call vimspector#test#setup#SetUpWithMappings( 'HUMAN' )
|
||||
endfunction
|
||||
|
||||
function! ClearDown()
|
||||
call vimspector#test#setup#ClearDown()
|
||||
endfunction
|
||||
|
||||
function! s:StartDebugging()
|
||||
exe 'edit ' . s:fn
|
||||
call setpos( '.', [ 0, 23, 1 ] )
|
||||
call vimspector#ToggleBreakpoint()
|
||||
call vimspector#LaunchWithSettings( { 'configuration': 'run' } )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 23, 1 )
|
||||
endfunction
|
||||
|
||||
function! Test_StandardLayout()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
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! Test_CloseVariables()
|
||||
call s:StartDebugging()
|
||||
|
||||
call win_execute( g:vimspector_session_windows.variables, 'q' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ '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! Test_CloseWatches()
|
||||
call s:StartDebugging()
|
||||
|
||||
call win_execute( g:vimspector_session_windows.watches, 'q' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
" Add a wtch
|
||||
call vimspector#AddWatch( 't' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 26, 1 )
|
||||
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ '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 ) )
|
||||
|
||||
" Replace the variables view with a watches view!
|
||||
call win_execute( g:vimspector_session_windows.variables,
|
||||
\ 'bu vimspector.Watches' )
|
||||
|
||||
" Delete a watch expression
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<Del>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
|
||||
call vimspector#StepInto()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 13, 1 )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 14, 1 )
|
||||
call vimspector#AddWatch( 'i' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' *- Result: 0',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#AddWatch( 'i+1' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+1',
|
||||
\ ' *- Result: 1',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#AddWatch( 'i+2' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+1',
|
||||
\ ' - Result: 1',
|
||||
\ 'Expression: i+2',
|
||||
\ ' *- Result: 2',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Delete that middle watch
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 4, 1 ] )
|
||||
call vimspector#DeleteWatch()
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+2',
|
||||
\ ' *- Result: 2',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 15, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+2',
|
||||
\ ' - Result: 2',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Delete the top watch
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call vimspector#DeleteWatch()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 13, 1 )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 14, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i+2',
|
||||
\ ' *- Result: 3',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_CloseStackTrace()
|
||||
call s:StartDebugging()
|
||||
|
||||
call win_execute( g:vimspector_session_windows.stack_trace, 'q' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ ] ],
|
||||
\ [ '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! Test_CloseOutput()
|
||||
call s:StartDebugging()
|
||||
|
||||
call win_execute( g:vimspector_session_windows.output, 'q' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ '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 ],
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_CloseOutput_Early()
|
||||
augroup TestCustomUI
|
||||
au!
|
||||
au User VimspectorUICreated
|
||||
\ call win_execute( g:vimspector_session_windows.output, 'q' )
|
||||
augroup END
|
||||
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ '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 ],
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
" Open it again!
|
||||
let g:vimspector_bottombar_height = 5
|
||||
VimspectorShowOutput Console
|
||||
call assert_equal(
|
||||
\ [ 'col', [
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ '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 ) )
|
||||
|
||||
" The actual height reported is the number of lines visible. The WinBar takes
|
||||
" 1 screen row, so g:vimspector_bottombar_height -1
|
||||
call assert_equal( 4, winheight( g:vimspector_session_windows.output ) )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 26, 1 )
|
||||
|
||||
au! TestCustomUI
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
|
||||
function! Test_CustomUI()
|
||||
augroup TestCustomUI
|
||||
au!
|
||||
au User VimspectorUICreated
|
||||
\ call win_execute( g:vimspector_session_windows.watches, 'q' )
|
||||
augroup END
|
||||
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
" Add a watch
|
||||
call vimspector#AddWatch( 't' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 26, 1 )
|
||||
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ '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 ) )
|
||||
|
||||
au! TestCustomUI
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
481
tests/variables.test.vim
Normal file
481
tests/variables.test.vim
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
let s:fn='../support/test/python/simple_python/main.py'
|
||||
|
||||
function! SetUp()
|
||||
call vimspector#test#setup#SetUpWithMappings( 'HUMAN' )
|
||||
endfunction
|
||||
|
||||
function! ClearDown()
|
||||
call vimspector#test#setup#ClearDown()
|
||||
endfunction
|
||||
|
||||
function! s:assert_match_list( expected, actual ) abort
|
||||
let ret = assert_equal( len( a:expected ), len( a:actual ) )
|
||||
let len = min( [ len( a:expected ), len( a:actual ) ] )
|
||||
let idx = 0
|
||||
while idx < len
|
||||
let ret += assert_match( a:expected[ idx ], a:actual[ idx ] )
|
||||
let idx += 1
|
||||
endwhile
|
||||
return ret
|
||||
endfunction
|
||||
|
||||
function! s:StartDebugging( ... )
|
||||
if a:0 == 0
|
||||
let config = #{
|
||||
\ fn: s:fn,
|
||||
\ line: 23,
|
||||
\ col: 1,
|
||||
\ launch: #{ configuration: 'run' }
|
||||
\ }
|
||||
else
|
||||
let config = a:1
|
||||
endif
|
||||
|
||||
execute 'edit' config.fn
|
||||
call setpos( '.', [ 0, config.line, config.col ] )
|
||||
call vimspector#ToggleBreakpoint()
|
||||
call vimspector#LaunchWithSettings( config.launch )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer(
|
||||
\ config.fn,
|
||||
\ config.line,
|
||||
\ config.col )
|
||||
endfunction
|
||||
|
||||
function! Test_SimpleWatches()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
" Add a wtch
|
||||
call vimspector#AddWatch( 't' )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 26, 1 )
|
||||
|
||||
" Delete a watch expression
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<Del>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call assert_equal( 'python',
|
||||
\ getbufvar(
|
||||
\ winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ '&syntax' ) )
|
||||
|
||||
call vimspector#StepInto()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 13, 1 )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 14, 1 )
|
||||
call vimspector#AddWatch( 'i' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' *- Result: 0',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#AddWatch( 'i+1' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+1',
|
||||
\ ' *- Result: 1',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#AddWatch( 'i+2' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+1',
|
||||
\ ' - Result: 1',
|
||||
\ 'Expression: i+2',
|
||||
\ ' *- Result: 2',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Delete that middle watch
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 4, 1 ] )
|
||||
call vimspector#DeleteWatch()
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+2',
|
||||
\ ' *- Result: 2',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 15, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i',
|
||||
\ ' - Result: 0',
|
||||
\ 'Expression: i+2',
|
||||
\ ' - Result: 2',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Delete the top watch
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call vimspector#DeleteWatch()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 13, 1 )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 14, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: i+2',
|
||||
\ ' *- Result: 3',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_ExpandVariables()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
" Make sure the Test t is initialised
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' *+ t (Test): {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call assert_equal( 'cpp',
|
||||
\ getbufvar(
|
||||
\ winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ '&syntax' ) )
|
||||
|
||||
" Expand
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 2, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
\ ' \*- i (int): 0',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Step - stays expanded
|
||||
call vimspector#StepOver()
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' - t (Test): {...}',
|
||||
\ ' \*- i (int): 1',
|
||||
\ ' - c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff (float): 0',
|
||||
\ ' + another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Collapse
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 2, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' + t (Test): {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 28, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' + t (Test): {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 2, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' - t (Test): {...}',
|
||||
\ ' \*- i (int): 1',
|
||||
\ ' \*- c (char): 99 ''c''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Collapse the 'inexpensive' scope and see that it stays collapsed
|
||||
" Exapand - see that the changed value is highlighted
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 1, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '+ Scope: Locals',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Stays collpased through step
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 30, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '+ Scope: Locals',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Cpptools keeps the same "Locals" scope, so it stays collapsed even throught
|
||||
" step-in
|
||||
call vimspector#StepInto()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 18, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '+ Scope: Locals',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_ExpandWatch()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
" Make sure the Test t is initialised
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call feedkeys( "it\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' *+ Result: {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call assert_equal( 'cpp',
|
||||
\ getbufvar(
|
||||
\ winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ '&syntax' ) )
|
||||
|
||||
" Expand
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' \*- Result: {...}',
|
||||
\ ' \*- i (int): 0',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Step - stays expanded
|
||||
call vimspector#StepOver()
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' - Result: {...}',
|
||||
\ ' \*- i (int): 1',
|
||||
\ ' - c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff (float): 0',
|
||||
\ ' + another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Collapse
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' + Result: {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 28, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' + Result: {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ s:assert_match_list(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' - Result: {...}',
|
||||
\ ' - i (int): 1',
|
||||
\ ' - c (char): 99 ''c''',
|
||||
\ ' - fffff (float): 0',
|
||||
\ ' + another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
let g:vimspector_test_plugin_path = expand( '<sfile>:p:h:h' )
|
||||
set mouse=a
|
||||
set noequalalways
|
||||
|
||||
let &rtp = &rtp . ',' . g:vimspector_test_plugin_path
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue