Compare commits

...

132 commits

Author SHA1 Message Date
Joey Yakimowich-Payne
7c12519b9d Modify for mac m1 2021-09-10 10:30:44 -06:00
mergify[bot]
2bb8561eb6
Merge pull request #452 from seezer/readme-gdb-prettyprinter
Readme: pretty printing with vscode-cpptools / gdb
2021-09-09 16:19:52 +00:00
mergify[bot]
a868102b5e
Merge branch 'master' into readme-gdb-prettyprinter 2021-09-09 16:05:28 +00:00
Sebastian Goth
dc862fe565 Readme: pretty printing with vscode-cpptools / gdb 2021-09-09 16:59:01 +02:00
Ben Jackson
b4bcfca932
Merge pull request #450 from puremourning/gha-ubuntu-18.04
Update to ubuntu 18.04 as 16.04 is deprecated
2021-09-08 22:49:22 +01:00
Ben Jackson
3df0602a69
Merge branch 'master' into gha-ubuntu-18.04 2021-09-08 22:30:49 +01:00
mergify[bot]
1c2dda4a6a
Merge pull request #449 from seezer/vscode-cpptools-1.6.0
Update vscode-cpptools from 0.27.0 to 1.6.0
2021-09-08 21:30:08 +00:00
Ben Jackson
db5ed8e802 Update to ubuntu 18.04 as 16.04 is deprecated 2021-09-08 22:20:33 +01:00
Sebastian Goth
17ca1522f8 Use correct spelling of MIMode in tests 2021-09-08 23:16:47 +02:00
Sebastian Goth
561a5b9aa2 Update variables tests to expect register scope
vscode-cpptools 1.6.0 now reports an additional scope 'Registers' after
'Locals'.
2021-09-08 21:58:32 +02:00
Sebastian Goth
46cfdc678d Update vscode-cpptools from 0.27.0 to 1.6.0 2021-09-08 21:58:32 +02:00
Ben Jackson
51d78fce5f
Note on using legacy vscode-dap 2021-09-07 17:00:04 +01:00
mergify[bot]
14f34ea6d1
Merge pull request #442 from roachsinai/master
Fix error: E806: using Float as a String.
2021-08-20 18:09:07 +00:00
roachsinai
a720d0e1d5 Fix error: E806: using Float as a String. 2021-08-21 00:57:27 +08:00
Ben Jackson
7c7e3f9c3f Add config for bash to tests 2021-08-20 11:17:05 +01:00
Ben Jackson
57ce099280 SHow the output in the console, as this is where codelldb puts it 2021-08-03 17:30:42 +01:00
mergify[bot]
27eb464b8e
Merge pull request #436 from puremourning/update-codelldb
Update codelldb
2021-08-02 16:37:04 +00:00
Ben Jackson
f1e2c12e5b Update codelldb
Add a way to checksum downloads and a little guide to updating gadgets
2021-08-02 17:23:32 +01:00
mergify[bot]
26cd7c5c7e
Merge pull request #435 from przepompownia/upgrade-vscode-php-debug-1.17.0
Upgrade vscode-php-debug to 1.17.0
2021-08-02 14:51:01 +00:00
przepompownia
59c9cd10ab Upgrade vscode-php-debug to 1.17.0 2021-08-02 16:11:04 +02:00
mergify[bot]
9c806d2a01
Merge pull request #429 from puremourning/dependabot/bundler/docs/addressable-2.8.0
Bump addressable from 2.7.0 to 2.8.0 in /docs
2021-07-13 15:07:15 +00:00
dependabot[bot]
3af97f1928
Bump addressable from 2.7.0 to 2.8.0 in /docs
Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.7.0 to 2.8.0.
- [Release notes](https://github.com/sporkmonger/addressable/releases)
- [Changelog](https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.7.0...addressable-2.8.0)

---
updated-dependencies:
- dependency-name: addressable
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-13 05:43:17 +00:00
mergify[bot]
da39c4955c
Merge pull request #422 from przepompownia/upgrade-vscode-php-debug-1.16.1
Upgrade vscode-php-debug to 1.16.1
2021-07-04 21:17:05 +00:00
przepompownia
21ebb22fd4 Upgrade vscode-php-debug to 1.16.1 2021-07-04 23:00:32 +02:00
mergify[bot]
aa0cddc0da
Merge pull request #420 from simondrake/master
Add a runnable Go example
2021-06-24 16:05:30 +00:00
Simon Drake
5075f3a11a Add a runnable Go example 2021-06-24 15:12:20 +01:00
mergify[bot]
bab81953d7
Merge pull request #414 from BaskovicP/patch-1
FIx typo in configuration.md
2021-06-09 18:24:31 +00:00
Paulo
0500e41429
FIx typo in configuration.md
A small typo that wastes time for people that copy and modify the config file
2021-06-09 19:24:37 +02:00
mergify[bot]
1cbb400d42
Merge pull request #413 from przepompownia/vscode-php-debug-1.16.0
Upgrade vscode-php-debug to 1.16.0
2021-06-07 12:27:55 +00:00
przepompownia
5ea1f0d9d4 Upgrade vscode-php-debug to 1.16.0 2021-06-07 14:10:44 +02:00
Ben Jackson
a51b8b23c9 Fix traceback if the current frame isn't set 2021-05-25 14:53:29 +01:00
mergify[bot]
99c0c4f763
Merge pull request #409 from puremourning/dependabot/bundler/docs/nokogiri-1.11.5
Bump nokogiri from 1.11.3 to 1.11.5 in /docs
2021-05-20 11:10:01 +00:00
dependabot[bot]
daa8865fea
Bump nokogiri from 1.11.3 to 1.11.5 in /docs
Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.11.3 to 1.11.5.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.11.3...v1.11.5)

Signed-off-by: dependabot[bot] <support@github.com>
2021-05-20 10:56:04 +00:00
mergify[bot]
f4d756fe86
Merge pull request #406 from puremourning/debuginfo
Add basic VimspectorDebugInfo command
2021-05-18 19:13:33 +00:00
Ben Jackson
d43904eb57 Add basic VimspectorDebugInfo command 2021-05-15 17:55:01 +01:00
Ben Jackson
aacd62f09f Rename AssertMatchist -> AssertMatchList 2021-05-15 16:06:16 +01:00
Ben Jackson
0e9497ce8f Add cpptools to cpp test proj 2021-05-15 15:55:17 +01:00
mergify[bot]
2708e8e6ec
Merge pull request #398 from przepompownia/php-debug-1.15.1
Upgrade php-debug to v1.15.1
2021-05-11 19:16:29 +00:00
Ben Jackson
adf6163653
Merge branch 'master' into php-debug-1.15.1 2021-05-11 20:05:48 +01:00
mergify[bot]
0af9d70b0d
Merge pull request #394 from puremourning/highlight-current-frame
Add cursorline highlight for current frame
2021-05-11 18:56:14 +00:00
Ben Jackson
9113dbb698 stack_trace: Add cursorline highlight and sign for current frame 2021-05-11 19:44:42 +01:00
przepompownia
08679d1c3e Upgrade php-debug to v1.15.1 2021-05-11 00:55:35 +02:00
Ben Jackson
4e04a862cb Add note about existing github issues 2021-05-03 15:02:50 +01:00
Ben Jackson
a7e8e93920 Allow manual running of locker 2021-05-03 14:09:56 +01:00
Ben Jackson
2b84439413 Lock closed issues after 60 days 2021-05-03 14:09:14 +01:00
Ben Jackson
0c88cc8bad Fix traceback when opening popup in neovim with log visible
* We enter the popup window
* some log data is received, so we update the log buffer and jump to the
  log window to scroll it
* meanwhile, the WinLeave auto command on the popup window fires and
  closes the popup window
* Having scrolled the log window, we try to jump back to the popup
  window, which by now has been closed.

Fixes #390
2021-04-29 10:02:23 +01:00
mergify[bot]
a47d0b921c
Merge pull request #387 from lf-/typos
Fix some typos in the readme
2021-04-22 12:19:58 +00:00
Jade
026ac22280 Fix some typos in the readme 2021-04-22 03:33:02 -07:00
Ben Jackson
297c0bea56 Ensure linux tests pass on PR 2021-04-20 20:52:53 +01:00
Ben Jackson
a9a26a5a60
Merge pull request #386 from puremourning/csharp-test
Add tests for c# using netcoredbg
2021-04-15 23:23:19 +01:00
Ben Jackson
1e25313cb5 Switch to xcode 11 which apparently works with coreclr debugging
https://github.com/dotnet/runtime/issues/42311#issuecomment-700718025
2021-04-15 23:04:31 +01:00
Ben Jackson
bc15c94513 Retire mono debug - never worked and seems abandoned, and vscode-python as it is serious legacy now 2021-04-15 21:39:38 +01:00
Ben Jackson
f389d65a24 Add a test for csharp, run in CI 2021-04-15 21:09:09 +01:00
Ben Jackson
b4195eee93 Upgrade to netcoredbg v1.2.0-782
Also upgrade the test project to LTS 3.1 dotnet framework, as MS is
making it very difficult to get framework 2.2 anymore.

Also remove some object files which apparently were included in the
repo.
2021-04-15 18:02:55 +01:00
Ben Jackson
6ad9101cf2
Add FAQ about json files in each project. 2021-04-15 15:02:46 +01:00
Ben Jackson
a41db89523 Fix get_configurations test 2021-04-13 18:01:10 +01:00
Ben Jackson
dd88e051a4 Attempt to recover from broken messages 2021-04-13 17:35:04 +01:00
Ben Jackson
fa92c2a8d5 Add a mode for debugging the extremely flaky netcoredbg 2021-04-11 19:23:47 +01:00
mergify[bot]
6709b45c77
Merge pull request #382 from aqez/master
Update sha256sum of netcoredbg for macos
2021-04-09 16:45:58 +00:00
Tony Dwire
278fc3cd8c Update sha256sum of netcoredbg 2021-04-09 11:29:17 -05:00
Ben Jackson
13a5a1b947 Fix traceback when +python3 is not availble 2021-04-09 16:54:49 +01:00
Ben Jackson
7d83419a4f Update docs bundles 2021-04-07 22:45:58 +01:00
mergify[bot]
7b3016aa90
Merge pull request #381 from aqez/master
Updated netcoredbg to 1.2.0-761 to enable mac support of async/await
2021-04-07 17:33:27 +00:00
Tony Dwire
d70d51a614 Updated netcoredbg to 1.2.0-761 to enable mac support of async/await 2021-04-07 11:50:26 -05:00
mergify[bot]
caeb6610ed
Merge pull request #379 from puuuuh/master
Update CodeLLDB
2021-03-30 18:13:03 +00:00
puh
0d9e7835a8 Update CodeLLDB 2021-03-30 00:16:58 +03:00
Ben Jackson
054ea35428 Add a way to test with dlv directly. Currrently not ready for the big time 2021-03-22 15:13:58 +00:00
Ben Jackson
244d7d8fdf Add the reference material to the vim doc too 2021-03-22 14:45:21 +00:00
Ben Jackson
35e5b3d56e Add vim doc based on README
Use the following to recrate the doc:

* clone https://github.com/ycm-core/vim-tools
* create a venv and pip install the requierments
* cd to vimspector dir
* /path/to/vim-tools/html2vimdoc.py -f vimspector README.md > doc/vimspector.txt
2021-03-20 15:56:41 +00:00
Ben Jackson
842d9fbc2d Config for pyright language server 2021-03-20 15:56:41 +00:00
mergify[bot]
6a24a17f2e
Merge pull request #371 from aqez/master
Update netcoredbg to 1.2.0-738 to support async/await
2021-03-19 23:33:58 +00:00
Ben Jackson
91e0426e88
Merge branch 'master' into master 2021-03-19 23:20:41 +00:00
mergify[bot]
bf24b37190
Merge pull request #372 from puremourning/hot-code-replace
Hot code replace for java
2021-03-19 23:15:34 +00:00
Ben Jackson
2d589475eb
Merge branch 'master' into master 2021-03-19 23:05:19 +00:00
Ben Jackson
1414f261a1 Documentation for hot code replace 2021-03-19 22:59:27 +00:00
Ben Jackson
a39017dd06 Fix actually sending terminateDebugee, and fix neovim 1-based index reporting 2021-03-19 18:43:45 +00:00
Ben Jackson
c05335c799 Make default option work for terminate debugee 2021-03-19 17:51:59 +00:00
Ben Jackson
efc5c76866 Fix lints 2021-03-19 17:51:59 +00:00
Ben Jackson
154e727b96 Make confirm dialog take arbitrary keys
Confirm now takes the list of options, list of keys to select them and
the default value. Returned values are always a 1-based index into the
list (like SelectFromList) or -1 to mean esc/ctrl-c.

This uses a nice popup dialog in vim and a crappy input on neovim.
2021-03-19 17:51:59 +00:00
Ben Jackson
6b74e584d5 Create a messagebox-like interface in vim 2021-03-19 17:51:59 +00:00
Ben Jackson
85bb8594ab Allow forcing selection from the menu with <leader>F5 2021-03-19 17:51:59 +00:00
Ben Jackson
63fd3165fb Use popup for confirmations (note these have to be async) 2021-03-19 17:51:59 +00:00
Ben Jackson
afb912dd08 Print hotcodereplace messages 2021-03-19 17:51:59 +00:00
Ben Jackson
b92a89f0d4 Add a way to have adapter specific message handlers 2021-03-19 17:51:59 +00:00
Ben Jackson
6f88b400e1 Only disable mappings in the keyboard-version of the popup 2021-03-18 13:51:32 +00:00
mergify[bot]
af2670ef9a
Merge pull request #373 from puremourning/fix-calculus
Fix default variable values having substitutions from the calculus
2021-03-12 22:22:51 +00:00
mergify[bot]
2b24611036
Merge branch 'master' into fix-calculus 2021-03-12 22:08:52 +00:00
mergify[bot]
d84ebdd0ee
Merge pull request #375 from puremourning/up-down-stack
Add commands to navigate up/down the stack in focussed thread.
2021-03-12 22:08:46 +00:00
Ben Jackson
6b67d165b9 Update docs for new mappings 2021-03-12 21:50:37 +00:00
Ben Jackson
a53d68f043 Add up and down frame mappings 2021-03-12 21:27:56 +00:00
Ben Jackson
6d3f3e207b Fix default variable values having substitutions from the calculus 2021-03-12 20:15:45 +00:00
mergify[bot]
5716bbefa9
Merge pull request #369 from puremourning/narrow-mode
Narrow UI mode
2021-03-11 21:38:40 +00:00
Ben Jackson
2615cff97a If there isn't enough vertical space, we get vim errors (not enough room), so don't do that 2021-03-11 21:14:30 +00:00
Ben Jackson
01ea50cb70 use --clean for minimal vimrc 2021-03-11 21:13:58 +00:00
Ben Jackson
7d2770f3c4 Add vertical (i.e. narrow) layout
This puts the 3 utility windows at the top, horizontally split, with the
code view below.  The terminal window is drawn either vertically split
(if there's room) or horizontally split otherwise.  The output window
remains at tht bottom.

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

We try to guess the best layout to use. In particular we go into
'narrow' mode if there are not enough horizonal columns to fit the
sidebar, code and at least the minimum terminal size. We also try to
move the terminal to be horizontally spit (i.e. vertically stacked) if
we can fit the max number of lines, but only the min number of columns.

This is all a little heuristic, but when testing it myself, it feels
good and tends to pick a good option by default. Users can always
customise the ui mode (g:vimspector_ui_mode and all the various specific
width options)
2021-03-10 23:44:45 +00:00
Tony Dwire
2a635294d0 Fix wrong version number for macos version. 2021-03-09 20:11:58 -06:00
Tony Dwire
38c843219e Updated file name for netcoredbg to reflect new filename. Overrode
version for macos since there is no new build for it yet.
2021-03-09 19:55:38 -06:00
Tony Dwire
c012f9520e Updated netcoredbg to 1.2.0-738 2021-03-09 19:45:27 -06:00
Ben Jackson
943ae6c7c9 Fix error when nothing to expand 2021-03-05 19:05:42 +00:00
Ben Jackson
82db32780b Add example of ssh to remote host 2021-03-04 13:28:04 +00:00
mergify[bot]
4cb4b814a1
Merge pull request #366 from puremourning/fix-stop
Fix crash using Stop function
2021-03-02 11:28:07 +00:00
Ben Jackson
d2b92b7ce5 Fix crash using STop function 2021-03-02 11:12:01 +00:00
Ben Jackson
5bd83d3e37 Add debugging instruction 2021-02-27 21:02:21 +00:00
mergify[bot]
f6517892c1
Merge pull request #357 from puremourning/set-variable-value
Set variable value
2021-02-25 22:39:45 +00:00
Ben Jackson
edcb057ead Add <leader><CR> to docs 2021-02-25 22:23:30 +00:00
Ben Jackson
06f9bfc057 Add basic tests for set variable value 2021-02-25 22:15:09 +00:00
Ben Jackson
804b499286 Allow setting the value via the api 2021-02-25 22:15:09 +00:00
Ben Jackson
49a9a4b367 Allow mappings which aren't special chars 2021-02-25 22:15:09 +00:00
Ben Jackson
f2d407256e Use expression completion for watch and set 2021-02-25 22:15:09 +00:00
Ben Jackson
94242fa532 CustomUI: Make buffers non-modifiable when opened for debugging 2021-02-25 22:15:09 +00:00
Ben Jackson
ba83a59e88 TEst overriding the mappings 2021-02-25 22:15:09 +00:00
Ben Jackson
675a68c601 Make it work in neovim too 2021-02-25 22:15:09 +00:00
Ben Jackson
e1078375fe Also allow <leader><CR> in case modifyOtherKeys mode doesn't work 2021-02-25 22:15:09 +00:00
Ben Jackson
26452289a8 Allow overriding the variables/stack trace mappings in config 2021-02-25 22:15:09 +00:00
Ben Jackson
ec9122284e Add some notes on setting values to the readme 2021-02-25 22:15:09 +00:00
Ben Jackson
131cfcdd33 Don't try and set a value if not supported 2021-02-25 22:15:09 +00:00
Ben Jackson
c2082cffae Support setting from the balloon 2021-02-25 22:15:09 +00:00
Ben Jackson
9e1a1ab4b5 Report failures 2021-02-25 22:15:09 +00:00
Ben Jackson
32f9a6ec43 Use silent for winbar menus 2021-02-25 22:15:09 +00:00
Ben Jackson
d8d6eb2286 Add ability to set a variable value
This works only for things which have known variablesReference, so
particularly currently only for scopes and theoretically for members.

I think this can work for watches too. will need to check.
2021-02-25 22:15:09 +00:00
mergify[bot]
1d38b8198f
Merge pull request #362 from puremourning/expr-completions-startup
Delay launching the python interpreter until needed
2021-02-25 22:14:59 +00:00
Ben Jackson
f40ac5db23 Delay launching the python interpreter until needed 2021-02-25 21:24:40 +00:00
Jake Zimmerman
11edcddd9c
Fix using double-quotes in VimspectorEval
The VimspectorEval command used `-bar` but this prevented the use of double quotes. This seems much more useful than a vim comment in this scenario, so remove the `-bar`.

This is _techncially_ breaking change, but I don't think it's likely anyone will be relying on doing `VimspectorEval x | something else`. If they are, sorry.
2021-02-25 11:04:12 +00:00
mergify[bot]
f9c5a33301
Merge pull request #355 from puremourning/terminate-debugee
Ask the user about terminating the debuggee
2021-02-24 18:27:16 +00:00
mergify[bot]
fdfa8b265b
Merge branch 'master' into terminate-debugee 2021-02-24 18:14:04 +00:00
mergify[bot]
a8651e257b
Merge pull request #356 from puremourning/telemetry-hide
hide the pointless telemetry data;
2021-02-24 18:09:48 +00:00
Ben Jackson
d8eb6a0463 Only prompt in 'interactive' contexts to avoid annoying questions 2021-02-24 18:00:08 +00:00
Ben Jackson
09efcf5e50 hide the controvertial telemetry data; it's not like anyone will ever look at it 2021-02-24 16:49:56 +00:00
Ben Jackson
5201995279 Ask the user about terminating the debuggee
CodeLLDB seems to actually support the terminateDebugee flag, so rather
than just forcefully killing things, ask the user if they want to.
2021-02-24 16:49:03 +00:00
mergify[bot]
fd03e074f3
Merge pull request #354 from YgorSouza/fix-readme-typos
Fix typos in README
2021-02-23 19:57:14 +00:00
Ygor Oliveira
fd0c6e7675 Fix typos in README 2021-02-23 19:51:52 +01:00
Ben Jackson
6fac220ee5 Disable mappings in the popup to ensure navigaion works 2021-02-23 09:42:57 +00:00
64 changed files with 6196 additions and 1329 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_
@ -57,6 +57,12 @@ discussing on Gitter rather than raising an issue.
* Version of Vimspector: (e.g. output of `git rev-parse HEAD` if cloned or the * Version of Vimspector: (e.g. output of `git rev-parse HEAD` if cloned or the
name of the tarball used to install otherwise) name of the tarball used to install otherwise)
* Output of `:VimspectorDebugInfo`
```
paste here
```
* Output of `vim --version` or `nvim --version` * Output of `vim --version` or `nvim --version`
``` ```

View file

@ -13,7 +13,7 @@ defaults:
jobs: jobs:
PythonLint: PythonLint:
runs-on: ubuntu-16.04 runs-on: ubuntu-18.04
container: 'puremourning/vimspector:test' container: 'puremourning/vimspector:test'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -22,7 +22,7 @@ jobs:
- name: 'Run flake8' - name: 'Run flake8'
run: '$HOME/.local/bin/flake8 python3/ *.py' run: '$HOME/.local/bin/flake8 python3/ *.py'
VimscriptLint: VimscriptLint:
runs-on: 'ubuntu-16.04' runs-on: 'ubuntu-18.04'
container: 'puremourning/vimspector:test' container: 'puremourning/vimspector:test'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
@ -32,7 +32,7 @@ jobs:
run: $HOME/.local/bin/vint autoload/ compiler/ plugin/ tests/ syntax/ run: $HOME/.local/bin/vint autoload/ compiler/ plugin/ tests/ syntax/
Linux: Linux:
runs-on: 'ubuntu-16.04' runs-on: 'ubuntu-18.04'
container: container:
image: 'puremourning/vimspector:test' image: 'puremourning/vimspector:test'
options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
@ -111,6 +111,16 @@ jobs:
path: gadgets/macos/download path: gadgets/macos/download
name: Cache gadgets name: Cache gadgets
- name: 'Install .NET Core SDK 3.1'
uses: actions/setup-dotnet@v1.7.2
with:
dotnet-version: 3.1
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: ^11
name: "Switch to xcode 11 because of .NET debugging bug"
- run: vim --version - run: vim --version
name: 'Print vim version information' name: 'Print vim version information'
@ -143,10 +153,10 @@ jobs:
# if: failure() # if: failure()
# with: # with:
# NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }} # NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }}
# SSH_PASS: ${{ secrets.SSH_PASS }} # SSH_PASS: ${{ secrets.SSH_PASS }} # [V]imspector
PublishRelease: PublishRelease:
runs-on: 'ubuntu-16.04' runs-on: 'ubuntu-18.04'
needs: needs:
- Linux - Linux
- MacOS - MacOS

27
.github/workflows/lock_old_issues.yaml vendored Normal file
View file

@ -0,0 +1,27 @@
name: "Lock Old Issues"
on:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '60'
# issue-exclude-created-before: ''
# issue-exclude-labels: ''
# issue-lock-labels: ''
# issue-lock-comment: ''
# issue-lock-reason: 'resolved'
# pr-lock-inactive-days: '365'
# pr-exclude-created-before: ''
# pr-exclude-labels: ''
# pr-lock-labels: ''
# pr-lock-comment: ''
# pr-lock-reason: 'resolved'
process-only: 'issues'

1
.gitignore vendored
View file

@ -20,3 +20,4 @@ support/test/csharp/*.exe*
configurations/ configurations/
venv/ venv/
test-base/ test-base/
tags

View file

@ -9,9 +9,8 @@ pull_request_rules:
# CI https://doc.mergify.io/conditions.html#github-actions # CI https://doc.mergify.io/conditions.html#github-actions
- status-success=PythonLint - status-success=PythonLint
- status-success=VimscriptLint - status-success=VimscriptLint
- status-success=Linux
- status-success=MacOS - status-success=MacOS
actions: &merge-actions actions: &merge-actions
merge: merge:
method: merge method: merge

View file

@ -42,7 +42,17 @@ def Settings( **kwargs ):
return { return {
'sys_path': [ 'sys_path': [
p.join( PATH_TO_THIS_DIR, 'python3' ) p.join( PATH_TO_THIS_DIR, 'python3' )
] ],
'ls': {
'python': {
'analysis': {
'extraPaths': [
p.join( PATH_TO_THIS_DIR, 'python3' ),
],
'useLibraryCodeForTypes': True
}
}
}
} }
if IgnoreExtraConf: if IgnoreExtraConf:

View file

@ -46,6 +46,23 @@ The GitHub issue tracker is for *bug reports* and *features requests* for the
Vimspector project, and on-topic comments and follow-ups to them. It is not for Vimspector project, and on-topic comments and follow-ups to them. It is not for
general discussion, general support or for any other purpose. general discussion, general support or for any other purpose.
Please **search the issue tracker for similar issues** before creating a new
one. There's no point in duplication; if an existing open issue addresses your
problem, please comment there instead of creating a duplicate. However, if the
issue you found is **closed as resolved** (e.g. with a PR or the original user's
problem was resolved), raise a **new issue**, because you've found a new
problem. Reference the original issue if you think that's useful information.
Closed issues which have been inactive for 60 days will be locked, this helps to
keep discussions focussed. If you believe you are still experiencing an issue
which has been closed, please raise a new issue, completing the issue template.
If you do find a similar _open_ issue, **don't just post 'me too' or similar**
responses. This almost never helps resolve the issue, and just causes noise for
the maintainers. Only post if it will aid the maintainers in solving the issue;
if there are existing diagnostics requested in the thread, perform
them and post the results.
Please do not be offended if your Issue or comment is closed or hidden, for any Please do not be offended if your Issue or comment is closed or hidden, for any
of the following reasons: of the following reasons:
@ -53,6 +70,7 @@ of the following reasons:
* The issue or comment is off-topic * The issue or comment is off-topic
* The issue does not represent a Vimspector bug or feature request * The issue does not represent a Vimspector bug or feature request
* The issue cannot be reasonably reproduced using the minimal vimrc * The issue cannot be reasonably reproduced using the minimal vimrc
* The issue is a duplicate of an existing issue
* etc. * etc.
Issue titles are important. It's not usually helpful to write a title like Issue titles are important. It's not usually helpful to write a title like
@ -83,7 +101,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
@ -184,6 +202,30 @@ They're also run by CI, so please check for lint failures. The canonical
definition of the command to run is the command run in CI, i.e. in definition of the command to run is the command run in CI, i.e. in
`.git/workflows/build.yml`. `.git/workflows/build.yml`.
### Debugging Vimspector
You can debug vimspector's python code using vimspector! We can use debugpy,
from within Vim's embedded python and connect to it. Here's how:
1. In one instance of vim, run the following to get debugpy to start listening
for us to connect: `:py3 __import__( 'vimspector', fromlist=[ 'developer' ]
).developer.SetUpDebugpy()`
2. In another instance of Vim, set a breakpoint in the vimspector python code
you want to debug and launch vimspector (e.g. `<F5>`). Select the `Python:
attach to vim` profile. This will attach to the debugpy running in the other
vim.
3. Back in the first vim (the debuggee), trigger the vimspector code in
question, e.g. by starting to debug something else.
4. You'll see it pause, and the 2nd vim (the debugger), you should be able to
step through and inspect as with any other python remote debugging.
NB. It's also possible to debug the vimscript code using vimspector, but this
requires unreleased vim patches and a fair amount of faff. You can always use
`:debug` (see the help) for this though.
# Code of conduct # Code of conduct
Please see [code of conduct](CODE_OF_CONDUCT.md). Please see [code of conduct](CODE_OF_CONDUCT.md).

321
README.md
View file

@ -3,7 +3,7 @@
For a tutorial and usage overview, take a look at the For a tutorial and usage overview, take a look at the
[Vimspector website][website]. [Vimspector website][website].
For detailed explanatin of the `.vimspector.json` format, see the For detailed explanation of the `.vimspector.json` format, see the
[reference guide][vimspector-ref]. [reference guide][vimspector-ref].
![Build](https://github.com/puremourning/vimspector/workflows/Build/badge.svg?branch=master) [![Gitter](https://badges.gitter.im/vimspector/Lobby.svg)](https://gitter.im/vimspector/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) ![Build](https://github.com/puremourning/vimspector/workflows/Build/badge.svg?branch=master) [![Gitter](https://badges.gitter.im/vimspector/Lobby.svg)](https://gitter.im/vimspector/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
@ -59,15 +59,16 @@ For detailed explanatin of the `.vimspector.json` format, see the
* [Console autocompletion](#console-autocompletion) * [Console autocompletion](#console-autocompletion)
* [Log View](#log-view) * [Log View](#log-view)
* [Closing debugger](#closing-debugger) * [Closing debugger](#closing-debugger)
* [Terminate debuggee](#terminate-debuggee)
* [Debug profile configuration](#debug-profile-configuration) * [Debug profile configuration](#debug-profile-configuration)
* [C, C , Rust, etc.](#c-c-rust-etc) * [C, C++, Rust, etc.](#c-c-rust-etc)
* [C Remote debugging](#c-remote-debugging) * [Data visualization / pretty printing](#data-visualization--pretty-printing)
* [C Remote launch and attach](#c-remote-launch-and-attach) * [C++ Remote debugging](#c-remote-debugging)
* [C++ Remote launch and attach](#c-remote-launch-and-attach)
* [Rust](#rust) * [Rust](#rust)
* [Python](#python) * [Python](#python)
* [Python Remote Debugging](#python-remote-debugging) * [Python Remote Debugging](#python-remote-debugging)
* [Python Remote launch and attach](#python-remote-launch-and-attach) * [Python Remote launch and attach](#python-remote-launch-and-attach)
* [Legacy: vscode-python](#legacy-vscode-python)
* [TCL](#tcl) * [TCL](#tcl)
* [C♯](#c) * [C♯](#c)
* [Go](#go) * [Go](#go)
@ -76,6 +77,7 @@ For detailed explanatin of the `.vimspector.json` format, see the
* [Debug cli application](#debug-cli-application) * [Debug cli application](#debug-cli-application)
* [JavaScript, TypeScript, etc.](#javascript-typescript-etc) * [JavaScript, TypeScript, etc.](#javascript-typescript-etc)
* [Java](#java) * [Java](#java)
* [Hot code replace](#hot-code-replace)
* [Usage with YouCompleteMe](#usage-with-youcompleteme) * [Usage with YouCompleteMe](#usage-with-youcompleteme)
* [Other LSP clients](#other-lsp-clients) * [Other LSP clients](#other-lsp-clients)
* [Lua](#lua) * [Lua](#lua)
@ -91,14 +93,14 @@ For detailed explanatin of the `.vimspector.json` format, see the
* [Example](#example) * [Example](#example)
* [FAQ](#faq) * [FAQ](#faq)
<!-- Added by: ben, at: Sun 21 Feb 2021 21:15:32 GMT --> <!-- Added by: ben, at: Fri 19 Mar 2021 22:57:28 GMT -->
<!--te--> <!--te-->
# Features and Usage # Features and Usage
The plugin is a capable Vim graphical debugger for multiple languages. The plugin is a capable Vim graphical debugger for multiple languages.
It's mostly tested for c++, python and TCL, but in theory supports any It's mostly tested for C++, Python and TCL, but in theory supports any
language that Visual Studio Code supports (but see caveats). language that Visual Studio Code supports (but see caveats).
The [Vimspector website][website] has an overview of the UI, along with basic The [Vimspector website][website] has an overview of the UI, along with basic
@ -125,10 +127,12 @@ And a couple of brief demos:
- remote launch, remote attach - remote launch, remote attach
- locals and globals display - locals and globals display
- watch expressions with autocompletion - watch expressions with autocompletion
- variable inspection tooltip on hover
- set variable value in locals, watch and hover windows
- call stack display and navigation - call stack display and navigation
- hierarchical variable value display popup (see `<Plug>VimspectorBalloonEval`) - hierarchical variable value display popup (see `<Plug>VimspectorBalloonEval`)
- interactive debug console with autocompletion - interactive debug console with autocompletion
- launch debugee within Vim's embedded terminal - launch debuggee within Vim's embedded terminal
- logging/stdout display - logging/stdout display
- simple stable API for custom tooling (e.g. integrate with language server) - simple stable API for custom tooling (e.g. integrate with language server)
@ -141,23 +145,24 @@ runtime dependencies). They are categorised by their level of support:
* `Supported` : Fully supported, frequently used and manually tested * `Supported` : Fully supported, frequently used and manually tested
* `Experimental`: Working, but not frequently used and rarely tested * `Experimental`: Working, but not frequently used and rarely tested
* `Legacy`: No longer supported, please migrate your config * `Legacy`: No longer supported, please migrate your config
* `Retired`: No longer included or supported.
| Language | Status | Switch (for `install_gadget.py`) | Adapter (for `:VimspectorInstall`) | Dependencies | | Language | Status | Switch (for `install_gadget.py`) | Adapter (for `:VimspectorInstall`) | Dependencies |
|--------------------|--------------|------------------------------------|------------------------------------|--------------------------------------------| |--------------------|-----------|----------------------------------|------------------------------------|--------------------------------------------|
| C, C++, Rust etc. | Tested | `--all` or `--enable-c` (or cpp) | vscode-cpptools | mono-core | | C, C++, Rust etc. | Tested | `--all` or `--enable-c` (or cpp) | vscode-cpptools | mono-core |
| Rust, C, C++, etc. | Supported | `--force-enable-rust` | CodeLLDB | Python 3 | | Rust, C, C++, etc. | Supported | `--force-enable-rust` | CodeLLDB | Python 3 |
| Python | Tested | `--all` or `--enable-python` | debugpy | Python 2.7 or Python 3 | | Python | Tested | `--all` or `--enable-python` | debugpy | Python 2.7 or Python 3 |
| Go | Tested | `--enable-go` | vscode-go | Go, [Delve][] | | Go | Tested | `--enable-go` | vscode-go | Node, Go, [Delve][] |
| TCL | Supported | `--all` or `--enable-tcl` | tclpro | TCL 8.5 | | TCL | Supported | `--all` or `--enable-tcl` | tclpro | TCL 8.5 |
| Bourne Shell | Supported | `--all` or `--enable-bash` | vscode-bash-debug | Bash v?? | | Bourne Shell | Supported | `--all` or `--enable-bash` | vscode-bash-debug | Bash v?? |
| Lua | Supported | `--all` or `--enable-lua` | local-lua-debugger-vscode | Node >=12.13.0, Npm, Lua interpreter | | Lua | Supported | `--all` or `--enable-lua` | local-lua-debugger-vscode | Node >=12.13.0, Npm, Lua interpreter |
| Node.js | Supported | `--force-enable-node` | vscode-node-debug2 | 6 < Node < 12, Npm | | Node.js | Supported | `--force-enable-node` | vscode-node-debug2 | 6 < Node < 12, Npm |
| Javascript | Supported | `--force-enable-chrome` | debugger-for-chrome | Chrome | | Javascript | Supported | `--force-enable-chrome` | debugger-for-chrome | Chrome |
| Java | Supported | `--force-enable-java ` | vscode-java-debug | Compatible LSP plugin (see [later](#java)) | | Java | Supported | `--force-enable-java ` | vscode-java-debug | Compatible LSP plugin (see [later](#java)) |
| C# (dotnet core) | Experimental | `--force-enable-csharp` | netcoredbg | DotNet core | | C# (dotnet core) | Tested | `--force-enable-csharp` | netcoredbg | DotNet core |
| C# (mono) | Experimental | `--force-enable-csharp` | vscode-mono-debug | Mono | | F#, VB, etc. | Supported | `--force-enable-[fsharp,vbnet]` | `, `--force-enable-vbnet` | netcoredbg | DotNet core |
| F#, VB, etc. | Experimental | `--force-enable-fsharp` (or vbnet) | netcoredbg | DotNet core | | C# (mono) | _Retired_ | N/A | N/A | N/A |
| Python.legacy | Legacy | `--force-enable-python.legacy` | vscode-python | Node 10, Python 2.7 or Python 3 | | Python.legacy | _Retired_ | N/A | N/A | N/A |
## Other languages ## Other languages
@ -286,7 +291,7 @@ If you just want to try out vimspector without changing your vim config, there
are example projects for a number of languages in `support/test`, including: are example projects for a number of languages in `support/test`, including:
* Python (`support/test/python/simple_python`) * Python (`support/test/python/simple_python`)
* Go (`support/test/go/hello_world`) * Go (`support/test/go/hello_world` and `support/test/go/name-starts-with-vowel`)
* Nodejs (`support/test/node/simple`) * Nodejs (`support/test/node/simple`)
* Chrome (`support/test/chrome/`) * Chrome (`support/test/chrome/`)
* etc. * etc.
@ -346,7 +351,7 @@ See support/doc/example_vimrc.vim for a minimal example.
Vimspector is a generic client for Debug Adapters. Debug Adapters (referred to Vimspector is a generic client for Debug Adapters. Debug Adapters (referred to
as 'gadgets' or 'adapters') are what actually do the work of talking to the real as 'gadgets' or 'adapters') are what actually do the work of talking to the real
debugers. debuggers.
In order for Vimspector to be useful, you need to have some adapters installed. In order for Vimspector to be useful, you need to have some adapters installed.
@ -464,7 +469,7 @@ You essentially need to get a working installation of the debug adapter, find
out how to start it, and configure that in an `adapters` entry in either your out how to start it, and configure that in an `adapters` entry in either your
`.vimspector.json` or in `.gadgets.json`. `.vimspector.json` or in `.gadgets.json`.
The simplest way in practice is to install or start Visusal Studio Code and use The simplest way in practice is to install or start Visual Studio Code and use
its extension manager to install the relevant extension. You can then configure its extension manager to install the relevant extension. You can then configure
the adapter manually in the `adapters` section of your `.vimspector.json` or in the adapter manually in the `adapters` section of your `.vimspector.json` or in
a `gadgets.json`. a `gadgets.json`.
@ -522,13 +527,6 @@ Example:
"${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7" "${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7"
], ],
"name": "cppdbg" "name": "cppdbg"
},
"vscode-python": {
"command": [
"node",
"${gadgetDir}/vscode-python/out/client/debugger/debugAdapter/main.js"
],
"name": "vscode-python"
} }
} }
} }
@ -545,7 +543,7 @@ format as `.gadgets.json` but are not overwritten when running
## Upgrade ## Upgrade
After updating the Vimspector code (either via `git pull` or whatever package After updating the Vimspector code (either via `git pull` or whatever package
manager), run `:VimspectorUpdate` to update any already-installed gadets. manager), run `:VimspectorUpdate` to update any already-installed gadgets.
# About # About
@ -654,18 +652,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.
@ -693,17 +696,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 debugee. | `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
@ -718,19 +721,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 debugee. | `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:
@ -744,6 +747,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
@ -770,7 +780,7 @@ The argument is a `dict` with the following keys:
* `configuration`: (optional) Name of the debug configuration to launch * `configuration`: (optional) Name of the debug configuration to launch
* `<anything else>`: (optional) Name of a variable to set * `<anything else>`: (optional) Name of a variable to set
This allows for some intergration and automation. For example, if you have a This allows for some integration and automation. For example, if you have a
configuration named `Run Test` that contains a [replacement configuration named `Run Test` that contains a [replacement
variable][vimspector-ref-var] named `${Test}` you could write a mapping which variable][vimspector-ref-var] named `${Test}` you could write a mapping which
ultimately executes: ultimately executes:
@ -854,9 +864,9 @@ breakpoint on the current line and `<F5>` to launch the application.
### Conditional breakpoints ### Conditional breakpoints
Some debug adapters support conditional breakpionts. Note that vimspector does Some debug adapters support conditional breakpoints. Note that vimspector does
not tell you if the debugger doesn't support conditional breakpoints (yet). A not tell you if the debugger doesn't support conditional breakpoints (yet). A
conditional breakpiont is a breakpiont which only triggers if some expression conditional breakpoint is a breakpoint which only triggers if some expression
evaluates to true, or has some other constraints met. evaluates to true, or has some other constraints met.
Some of these functions above take a single optional argument which is a Some of these functions above take a single optional argument which is a
@ -912,6 +922,8 @@ breakpoint when it is hit.
* Current scope shows values of locals. * Current scope shows values of locals.
* Use `<CR>`, or double-click with left mouse to expand/collapse (+, -). * Use `<CR>`, or double-click with left mouse to expand/collapse (+, -).
* Set the value of the variable with `<C-CR>` (control + `<CR>`) or
`<leader><CR>` (if `modifyOtherKeys` doesn't work for you)
* When changing the stack frame the locals window updates. * When changing the stack frame the locals window updates.
* While paused, hover to see values * While paused, hover to see values
@ -928,7 +940,9 @@ All rules for `Variables and scopes` apply plus the following:
and get its result. and get its result.
* Make a normal mode (`nmap`) and visual mode (`xmap`) mapping to * Make a normal mode (`nmap`) and visual mode (`xmap`) mapping to
`<Plug>VimspectorBalloonEval` to manually trigger the popup. `<Plug>VimspectorBalloonEval` to manually trigger the popup.
* Use regular nagivation keys (`j`, `k`) to chose the current selection; `<Esc>` * Set the value of the variable with `<C-CR>` (control + `<CR>`) or
`<leader><CR>` (if `modifyOtherKeys` doesn't work for you)
* Use regular nagivation keys (`j`, `k`) to choose the current selection; `<Esc>`
(or leave the tooltip window) to close the tooltip. (or leave the tooltip window) to close the tooltip.
![variable eval hover](https://puremourning.github.io/vimspector-web/img/vimspector-variable-eval-hover.png) ![variable eval hover](https://puremourning.github.io/vimspector-web/img/vimspector-variable-eval-hover.png)
@ -946,6 +960,8 @@ to add a new watch expression.
* Alternatively, use `:VimspectorWatch <expression>`. Tab-completion for * Alternatively, use `:VimspectorWatch <expression>`. Tab-completion for
expression is available in some debug adapters. expression is available in some debug adapters.
* Expand result with `<CR>`, or double-click with left mouse. * Expand result with `<CR>`, or double-click with left mouse.
* Set the value of the variable with `<C-CR>` (control + `<CR>`) or
`<leader><CR>` (if `modifyOtherKeys` doesn't work for you)
* Delete with `<DEL>`. * Delete with `<DEL>`.
![watch window](https://puremourning.github.io/vimspector-web/img/vimspector-watch-window.png) ![watch window](https://puremourning.github.io/vimspector-web/img/vimspector-watch-window.png)
@ -992,6 +1008,8 @@ be changed manually to "switch to" that thread.
to set the "focussed" thread to the currently selected one. If the selected to set the "focussed" thread to the currently selected one. If the selected
line is a stack frame, set the focussed thread to the thread of that frame and line is a stack frame, set the focussed thread to the thread of that frame and
jump to that frame in the code window. jump to that frame in the code window.
* The current frame when a breakpoint is hit or if manuall jumping is also
highlighted.
![stack trace](https://puremourning.github.io/vimspector-web/img/vimspector-callstack-window.png) ![stack trace](https://puremourning.github.io/vimspector-web/img/vimspector-callstack-window.png)
@ -1002,7 +1020,7 @@ The stack trace is represented by the buffer `vimspector.StackTrace`.
* In the outputs window, use the WinBar to select the output channel. * In the outputs window, use the WinBar to select the output channel.
* Alternatively, use `:VimspectorShowOutput <category>`. Use command-line * Alternatively, use `:VimspectorShowOutput <category>`. Use command-line
completion to see the categories. completion to see the categories.
* The debugee prints to the stdout channel. * The debuggee prints to the stdout channel.
* Other channels may be useful for debugging. * Other channels may be useful for debugging.
![output window](https://puremourning.github.io/vimspector-web/img/vimspector-output-window.png) ![output window](https://puremourning.github.io/vimspector-web/img/vimspector-output-window.png)
@ -1053,14 +1071,35 @@ information when something goes wrong that's not a Vim traceback.
If you just want to see the Vimspector log file, use `:VimspectorToggleLog`, If you just want to see the Vimspector log file, use `:VimspectorToggleLog`,
which will tail it in a little window (doesn't work on Windows). which will tail it in a little window (doesn't work on Windows).
You can see some debugging info with `:VimspectorDebugInfo`
## Closing debugger ## Closing debugger
To close the debugger, use: To close the debugger, use:
* `Reset` WinBar button (`set mouse=a`) * `Reset` WinBar button
* `:VimspectorReset` when the WinBar is not available. * `:VimspectorReset` when the WinBar is not available.
* `call vimspector#Reset()` * `call vimspector#Reset()`
## Terminate debuggee
If the debuggee is still running when stopping or resetting, then some debug
adapters allow you to specify what should happen to it when finishing debugging.
Typically, the default behaviour is sensible, and this is what happens most of
the time. These are the defaults according to DAP:
* If the request was 'launch': terminate the debuggee
* If the request was 'attach': don't terminate the debuggee
Some debug adapters allow you to choose what to do when disconnecting. If you
wish to control this behaviour, use `:VimspectorReset` or call
`vimspector#Reset( { 'interactive': v:true } )`. If the debug adapter offers a
choice as to whether or not to terminate the debuggee, you will be prompted to
choose. The same applies for `vimspector#Stop()` which can take an argument:
`vimspector#Stop( { 'interactive': v:true } )`.
# Debug profile configuration # Debug profile configuration
For an introduction to the configuration of `.vimspector.json`, take a look at For an introduction to the configuration of `.vimspector.json`, take a look at
@ -1138,6 +1177,38 @@ licensing.
} }
``` ```
### Data visualization / pretty printing
Depending on the backend you need to enable pretty printing of complex types manually.
* LLDB: Pretty printing is enabled by default
* GDB: To enable gdb pretty printers, consider the snippet below.
It is not enough to have `set print pretty on` in your .gdbinit!
```
{
"configurations": {
"Launch": {
"adapter": "vscode-cpptools",
"configuration": {
"request": "launch",
"program": "<path to binary>",
...
"MIMode": "gdb"
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
}
}
}
}
```
### C++ Remote debugging ### C++ Remote debugging
The cpptools documentation describes how to attach cpptools to gdbserver using The cpptools documentation describes how to attach cpptools to gdbserver using
@ -1223,10 +1294,6 @@ Rust is supported with any gdb/lldb-based debugger. So it works fine with
headers/libs to build a C python extension for performance. headers/libs to build a C python extension for performance.
* Full options: https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings * Full options: https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings
**Migrating from `vscode-python`**: change `"adapter": "vscode-python"` to
`"adapter": "debugpy"`.
```json ```json
{ {
"configurations": { "configurations": {
@ -1293,34 +1360,6 @@ debugpy](https://github.com/microsoft/debugpy/wiki/Debugging-over-SSH).
If you're feeling fancy, checkout the [reference guide][remote-debugging] for If you're feeling fancy, checkout the [reference guide][remote-debugging] for
an example of getting Vimspector to remotely launch and attach. an example of getting Vimspector to remotely launch and attach.
### Legacy: vscode-python
* No longer installed by default - please pass `--force-enable-python.legacy` if
you just want to continue using your working setup.
* [vscode-python](https://github.com/Microsoft/vscode-python)
* NOTE: You must be running `node` 10. See [this issue](https://github.com/puremourning/vimspector/issues/105)
```json
{
"configurations": {
"<name>: Launch": {
"adapter": "vscode-python",
"configuration": {
"name": "<name>: Launch",
"type": "python",
"request": "launch",
"cwd": "<working directory>",
"stopOnEntry": true,
"console": "externalTerminal",
"debugOptions": [],
"program": "<path to main python file>"
}
}
...
}
}
```
## TCL ## TCL
* TCL (TclProDebug) * TCL (TclProDebug)
@ -1344,35 +1383,8 @@ netcoredbg`
"program": "${workspaceRoot}/bin/Debug/netcoreapp2.2/csharp.dll", "program": "${workspaceRoot}/bin/Debug/netcoreapp2.2/csharp.dll",
"args": [], "args": [],
"stopAtEntry": true, "stopAtEntry": true,
"cwd": "${workspaceRoot}"
}
}
}
}
```
* C# - mono
Install with `install_gadget.py --force-enable-csharp` or `:VimspectorInstall
vscode-mono-debug`.
***Known not to work.***
```json
{
"configurations": {
"launch - mono": {
"adapter": "vscode-mono-debug",
"configuration": {
"request": "launch",
"program": "${workspaceRoot}/bin/Debug/netcoreapp2.2/csharp.dll",
"args": [],
"cwd": "${workspaceRoot}", "cwd": "${workspaceRoot}",
"runtimeExecutable": "mono", "env": {}
"runtimeArgs": [],
"env": [],
"externalConsole": false,
"console": "integratedTerminal"
} }
} }
} }
@ -1389,6 +1401,8 @@ Requires:
* [Delve][delve-install] installed, e.g. `go get -u github.com/go-delve/delve/cmd/dlv` * [Delve][delve-install] installed, e.g. `go get -u github.com/go-delve/delve/cmd/dlv`
* Delve to be in your PATH, or specify the `dlvToolPath` launch option * Delve to be in your PATH, or specify the `dlvToolPath` launch option
NOTE: Vimspector uses the ["legacy" vscode-go debug adapter](https://github.com/golang/vscode-go/blob/master/docs/debugging-legacy.md) rather than the "built-in" DAP support in Delve. You can track https://github.com/puremourning/vimspector/issues/186 for that.
```json ```json
{ {
"configurations": { "configurations": {
@ -1406,7 +1420,7 @@ Requires:
``` ```
See the vscode-go docs for See the vscode-go docs for
[troubleshooting information](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#troubleshooting) [troubleshooting information](https://github.com/golang/vscode-go/blob/master/docs/debugging-legacy.md#troubleshooting)
## PHP ## PHP
@ -1552,6 +1566,20 @@ editor plugin to use Java. I recommend [YouCompleteMe][], which has full support
for jdt.ls, and most importantly a trivial way to load the debug adapter and to for jdt.ls, and most importantly a trivial way to load the debug adapter and to
use it with Vimspector. use it with Vimspector.
### Hot code replace
When using the [java debug server][java-debug-server], Vimspector supports the
hot code replace custom feature. By default, when the underlying class files
change, vimspector asks the user if they wish to reload these classes at
runtime.
This behaviour can be customised:
* `let g:ycm_java_hotcodereplace_mode = 'ask'` - the default, ask the user for
each reload.
* `let g:ycm_java_hotcodereplace_mode = 'always'` - don't ask, always reload
* `let g:ycm_java_hotcodereplace_mode = 'never'` - don't ask, never reload
### Usage with YouCompleteMe ### Usage with YouCompleteMe
* Set up [YCM for java][YcmJava]. * Set up [YCM for java][YcmJava].
@ -1712,12 +1740,14 @@ define them in your `vimrc`.
| Sign | Description | Priority | | Sign | Description | Priority |
|------------------------|-------------------------------------|----------| |---------------------------|-----------------------------------------|----------|
| `vimspectorBP` | Line breakpoint | 9 | | `vimspectorBP` | Line breakpoint | 9 |
| `vimspectorBPCond` | Conditional line breakpoint | 9 | | `vimspectorBPCond` | Conditional line breakpoint | 9 |
| `vimspectorBPDisabled` | Disabled breakpoint | 9 | | `vimspectorBPDisabled` | Disabled breakpoint | 9 |
| `vimspectorPC` | Program counter (i.e. current line) | 200 | | `vimspectorPC` | Program counter (i.e. current line) | 200 |
| `vimspectorPCBP` | Program counter and breakpoint | 200 | | `vimspectorPCBP` | Program counter and breakpoint | 200 |
| `vimspectorCurrentThread` | Focussed thread in stack trace view | 200 |
| `vimspectorCurrentFrame` | Current stack frame in stack trace view | 200 |
The default symbols are the equivalent of something like the following: The default symbols are the equivalent of something like the following:
@ -1727,6 +1757,8 @@ sign define vimspectorBPCond text=\ ◆ texthl=WarningMsg
sign define vimspectorBPDisabled text=\ ● texthl=LineNr sign define vimspectorBPDisabled text=\ ● texthl=LineNr
sign define vimspectorPC text=\ ▶ texthl=MatchParen linehl=CursorLine sign define vimspectorPC text=\ ▶ texthl=MatchParen linehl=CursorLine
sign define vimspectorPCBP text=●▶ texthl=MatchParen linehl=CursorLine sign define vimspectorPCBP text=●▶ texthl=MatchParen linehl=CursorLine
sign define vimspectorCurrentThread text=▶ texthl=MatchParen linehl=CursorLine
sign define vimspectorCurrentFrame text=▶ texthl=Special linehl=CursorLine
``` ```
If the signs don't display properly, your font probably doesn't contain these If the signs don't display properly, your font probably doesn't contain these
@ -1739,6 +1771,8 @@ sign define vimspectorBPCond text=o? texthl=WarningMsg
sign define vimspectorBPDisabled text=o! texthl=LineNr sign define vimspectorBPDisabled text=o! texthl=LineNr
sign define vimspectorPC text=\ > texthl=MatchParen sign define vimspectorPC text=\ > texthl=MatchParen
sign define vimspectorPCBP text=o> texthl=MatchParen sign define vimspectorPCBP text=o> texthl=MatchParen
sign define vimspectorCurrentThread text=> texthl=MatchParen
sign define vimspectorCurrentFrame text=> texthl=Special
``` ```
## Sign priority ## Sign priority
@ -1775,7 +1809,7 @@ smaller ones.
## Changing the default window sizes ## Changing the default window sizes
> ***Please Note***: This cusomiation API is ***unstable***, meaning that it may > ***Please Note***: This customisation API is ***unstable***, meaning that it may
change at any time. I will endeavour to reduce the impact of this and announce change at any time. I will endeavour to reduce the impact of this and announce
changes in Gitter. changes in Gitter.
@ -1797,7 +1831,7 @@ let g:vimspector_bottombar_height = 15
## Changing the terminal size ## Changing the terminal size
The terminal is typically created as a vertical split to the righ of the code The terminal is typically created as a vertical split to the right of the code
window, and that window is re-used for subsequent terminal buffers. window, and that window is re-used for subsequent terminal buffers.
The following control the sizing of the terminal window used The following control the sizing of the terminal window used
for debuggee input/output when using Vim's built-in terminal. for debuggee input/output when using Vim's built-in terminal.
@ -1816,7 +1850,7 @@ least `g:vimspector_code_minwidth` columns for the main code window and that the
terminal is no wider than `g:vimspector_terminal_maxwidth` columns. terminal is no wider than `g:vimspector_terminal_maxwidth` columns.
`g:vimspector_terminal_minwidth` is there to ensure that there's a reasonable `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 number of columns for the terminal even when there isn't enough horizontal space
to satisfy the other contraints. to satisfy the other constraints.
Example: Example:
@ -1830,7 +1864,7 @@ let g:vimspector_terminal_minwidth = 20
It's useful to be able to define mappings only while debugging and remove those It's useful to be able to define mappings only while debugging and remove those
mappings when debugging is complete. For this purpose, Vimspector provides 2 mappings when debugging is complete. For this purpose, Vimspector provides 2
`User` autocommds: `User` autocommands:
* `VimspectorJumpedToFrame` - triggered whenever a 'break' event happens, or * `VimspectorJumpedToFrame` - triggered whenever a 'break' event happens, or
when selecting a stack from to jump to. This can be used to create (for when selecting a stack from to jump to. This can be used to create (for
@ -1841,7 +1875,7 @@ mappings when debugging is complete. For this purpose, Vimspector provides 2
An example way to use this is included in `support/custom_ui_vimrc`. In there, An example way to use this is included in `support/custom_ui_vimrc`. In there,
these autocommands are used to create buffer-local mappings for any files these autocommands are used to create buffer-local mappings for any files
visited while debugging and to clear them when completing debugging. This is visited while debugging and to clear them when completing debugging. This is
particularly useful for commadns like `<Plug>VimspectorBalloonEval` which only particularly useful for commands like `<Plug>VimspectorBalloonEval` which only
make sense while debugging (and only in the code window). Check the commented make sense while debugging (and only in the code window). Check the commented
section `Custom mappings while debugging`. section `Custom mappings while debugging`.
@ -1851,7 +1885,7 @@ as it is a common requirement.
## Advanced UI customisation ## Advanced UI customisation
> ***Please Note***: This cusomiation API is ***unstable***, meaning that it may > ***Please Note***: This customisation API is ***unstable***, meaning that it may
change at any time. I will endeavour to reduce the impact of this and announce change at any time. I will endeavour to reduce the impact of this and announce
changes in Gitter. changes in Gitter.
@ -1898,19 +1932,19 @@ In addition, the following key is added when triggering the
## Customising the WinBar ## Customising the WinBar
You can even customise the WinBar buttons by simply running the usual `menu` You can even customise the WinBar buttons by simply running the usual `menu`
(and `unmanu`) commands. (and `unmenu`) commands.
By default, Vimspector uses something a bit like this: By default, Vimspector uses something a bit like this:
```viml ```viml
nnoremenu WinBar.■\ Stop :call vimspector#Stop()<CR> nnoremenu WinBar.■\ Stop :call vimspector#Stop( { 'interactive': v:false } )<CR>
nnoremenu WinBar.▶\ Cont :call vimspector#Continue()<CR> nnoremenu WinBar.▶\ Cont :call vimspector#Continue()<CR>
nnoremenu WinBar.▷\ Pause :call vimspector#Pause()<CR> nnoremenu WinBar.▷\ Pause :call vimspector#Pause()<CR>
nnoremenu WinBar.↷\ Next :call vimspector#StepOver()<CR> nnoremenu WinBar.↷\ Next :call vimspector#StepOver()<CR>
nnoremenu WinBar.→\ Step :call vimspector#StepInto()<CR> nnoremenu WinBar.→\ Step :call vimspector#StepInto()<CR>
nnoremenu WinBar.←\ Out :call vimspector#StepOut()<CR> nnoremenu WinBar.←\ Out :call vimspector#StepOut()<CR>
nnoremenu WinBar.⟲: :call vimspector#Restart()<CR> nnoremenu WinBar.⟲: :call vimspector#Restart()<CR>
nnoremenu WinBar.✕ :call vimspector#Reset()<CR> nnoremenu WinBar.✕ :call vimspector#Reset( { 'interactive': v:false } )<CR>
``` ```
If you prefer a different layout or if the unicode symbols don't render If you prefer a different layout or if the unicode symbols don't render
@ -1923,7 +1957,7 @@ func! CustomiseUI()
" Clear the existing WinBar created by Vimspector " Clear the existing WinBar created by Vimspector
nunmenu WinBar nunmenu WinBar
" Cretae our own WinBar " Cretae our own WinBar
nnoremenu WinBar.Kill :call vimspector#Stop()<CR> nnoremenu WinBar.Kill :call vimspector#Stop( { 'interactive': v:true } )<CR>
nnoremenu WinBar.Continue :call vimspector#Continue()<CR> nnoremenu WinBar.Continue :call vimspector#Continue()<CR>
nnoremenu WinBar.Pause :call vimspector#Pause()<CR> nnoremenu WinBar.Pause :call vimspector#Pause()<CR>
nnoremenu WinBar.Step\ Over :call vimspector#StepOver()<CR> nnoremenu WinBar.Step\ Over :call vimspector#StepOver()<CR>
@ -2009,12 +2043,16 @@ hi link jsonComment Comment
but in theory a single gadget can supply multiple `adapter` configs. but in theory a single gadget can supply multiple `adapter` configs.
Typically this happens when a `gadget` supplies different `adapter` config Typically this happens when a `gadget` supplies different `adapter` config
for, say remote debugging, or debugging in a container, etc. for, say remote debugging, or debugging in a container, etc.
8. The signs and winbar display funny symbols. How do i fix them? See 8. The signs and winbar display funny symbols. How do I fix them? See
[this](#changing-the-default-signs) and [this](#customising-the-winbar) [this](#changing-the-default-signs) and [this](#customising-the-winbar)
9. What's thie telemetry stuff all about? Are you sending my data to evil companies? 9. What's this telemetry stuff all about? Are you sending my data to evil companies?
Debug adapters (for some reason) send telemetry data to clients. Vimspector simply Debug adapters (for some reason) send telemetry data to clients. Vimspector simply
displays this information in the output window. It *does not* and *will not ever* displays this information in the output window. It *does not* and *will not ever*
collect, use, forward or otherwise share any data with any third parties. collect, use, forward or otherwise share any data with any third parties.
10. Do I _have_ to put a `.vimspector.json` in the root of every project? No, you
can put all of your adapter and debug configs in a [single directory](https://puremourning.github.io/vimspector/configuration.html#debug-configurations) if you want to, but note
the caveat that `${workspaceRoot}` won't be calculated correctly in that case.
The vimsepctor author uses this [a lot](https://github.com/puremourning/.vim-mac/tree/master/vimspector-conf).
[ycmd]: https://github.com/Valloric/ycmd [ycmd]: https://github.com/Valloric/ycmd
@ -2030,3 +2068,4 @@ hi link jsonComment Comment
[debugpy]: https://github.com/microsoft/debugpy [debugpy]: https://github.com/microsoft/debugpy
[YouCompleteMe]: https://github.com/ycm-core/YouCompleteMe#java-semantic-completion [YouCompleteMe]: https://github.com/ycm-core/YouCompleteMe#java-semantic-completion
[remote-debugging]: https://puremourning.github.io/vimspector/configuration.html#remote-debugging-support [remote-debugging]: https://puremourning.github.io/vimspector/configuration.html#remote-debugging-support
[YcmJava]: https://github.com/ycm-core/YouCompleteMe#java-semantic-completion

View file

@ -13,6 +13,9 @@
" See the License for the specific language governing permissions and " See the License for the specific language governing permissions and
" limitations under the License. " limitations under the License.
if !has( 'python3' )
finish
endif
" Boilerplate {{{ " Boilerplate {{{
let s:save_cpo = &cpoptions let s:save_cpo = &cpoptions
@ -41,11 +44,11 @@ function! s:Enabled() abort
return s:enabled return s:enabled
endfunction endfunction
function! vimspector#Launch() abort function! vimspector#Launch( ... ) abort
if !s:Enabled() if !s:Enabled()
return return
endif endif
py3 _vimspector_session.Start() py3 _vimspector_session.Start( *vim.eval( 'a:000' ) )
endfunction endfunction
function! vimspector#LaunchWithSettings( settings ) abort function! vimspector#LaunchWithSettings( settings ) abort
@ -55,11 +58,16 @@ function! vimspector#LaunchWithSettings( settings ) abort
py3 _vimspector_session.Start( launch_variables = vim.eval( 'a:settings' ) ) py3 _vimspector_session.Start( launch_variables = vim.eval( 'a:settings' ) )
endfunction endfunction
function! vimspector#Reset() abort function! vimspector#Reset( ... ) abort
if !s:Enabled() if !s:Enabled()
return return
endif endif
py3 _vimspector_session.Reset() if a:0 == 0
let options = {}
else
let options = a:1
endif
py3 _vimspector_session.Reset( **vim.eval( 'options' ) )
endfunction endfunction
function! vimspector#Restart() abort function! vimspector#Restart() abort
@ -185,11 +193,16 @@ function! vimspector#SetCurrentThread() abort
py3 _vimspector_session.SetCurrentThread() py3 _vimspector_session.SetCurrentThread()
endfunction endfunction
function! vimspector#Stop() abort function! vimspector#Stop( ... ) abort
if !s:Enabled() if !s:Enabled()
return return
endif endif
py3 _vimspector_session.Stop() if a:0 == 0
let options = {}
else
let options = a:1
endif
py3 _vimspector_session.Stop( **vim.eval( 'options' ) )
endfunction endfunction
function! vimspector#ExpandVariable() abort function! vimspector#ExpandVariable() abort
@ -199,6 +212,17 @@ function! vimspector#ExpandVariable() abort
py3 _vimspector_session.ExpandVariable() py3 _vimspector_session.ExpandVariable()
endfunction endfunction
function! vimspector#SetVariableValue( ... ) abort
if !s:Enabled()
return
endif
if a:0 == 0
py3 _vimspector_session.SetVariableValue()
else
py3 _vimspector_session.SetVariableValue( new_value = vim.eval( 'a:1' ) )
endif
endfunction
function! vimspector#DeleteWatch() abort function! vimspector#DeleteWatch() abort
if !s:Enabled() if !s:Enabled()
return return
@ -213,12 +237,28 @@ 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
endif endif
if a:0 == 0 if a:0 == 0
let expr = input( 'Enter watch expression: ' ) let expr = input( 'Enter watch expression: ',
\ '',
\ 'custom,vimspector#CompleteExpr' )
else else
let expr = a:1 let expr = a:1
endif endif
@ -310,28 +350,6 @@ function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
return join( buffers, "\n" ) return join( buffers, "\n" )
endfunction endfunction
py3 <<EOF
def _vimspector_GetExprCompletions( ArgLead, prev_non_keyword_char ):
if not _vimspector_session:
return []
items = []
for candidate in _vimspector_session.GetCompletionsSync(
ArgLead,
prev_non_keyword_char ):
label = candidate.get( 'text', candidate[ 'label' ] )
start = prev_non_keyword_char - 1
if 'start' in candidate and 'length' in candidate:
start = candidate[ 'start' ]
items.append( ArgLead[ 0 : start ] + label )
return items
EOF
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
if !s:Enabled() if !s:Enabled()
return return
@ -340,7 +358,7 @@ function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
let col = len( a:ArgLead ) let col = len( a:ArgLead )
let prev_non_keyword_char = match( a:ArgLead[ 0 : col - 1 ], '\k*$' ) + 1 let prev_non_keyword_char = match( a:ArgLead[ 0 : col - 1 ], '\k*$' ) + 1
return join( py3eval( '_vimspector_GetExprCompletions( ' return join( py3eval( '_vimspector_session.GetCommandLineCompletions( '
\ . 'vim.eval( "a:ArgLead" ), ' \ . 'vim.eval( "a:ArgLead" ), '
\ . 'int( vim.eval( "prev_non_keyword_char" ) ) )' ), \ . 'int( vim.eval( "prev_non_keyword_char" ) ) )' ),
\ "\n" ) \ "\n" )
@ -539,6 +557,14 @@ function! vimspector#ShowEvalBalloon( is_visual ) abort
\ . '", 0 )' ) \ . '", 0 )' )
endfunction endfunction
function! vimspector#PrintDebugInfo() abort
if !s:Enabled()
return
endif
py3 _vimspector_session.PrintDebugInfo()
endfunction
" Boilerplate {{{ " Boilerplate {{{
let &cpoptions=s:save_cpo let &cpoptions=s:save_cpo

View file

@ -68,14 +68,10 @@ function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
\ 'drag': 1, \ 'drag': 1,
\ 'resize': 1, \ 'resize': 1,
\ 'close': 'button', \ 'close': 'button',
\ 'callback': 'vimspector#internal#balloon#CloseCallback' \ 'callback': 'vimspector#internal#balloon#CloseCallback',
\ } \ }
" When ambiwidth is single, use prettier characters for the border. This let config = vimspector#internal#popup#SetBorderChars( config )
" would look silly when ambiwidth is double.
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
let config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
endif
if a:is_hover if a:is_hover
let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter' let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter'
@ -85,6 +81,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
@ -123,8 +120,6 @@ function! vimspector#internal#balloon#MouseFilter( winid, key ) abort
" expand the variable if we got double click " expand the variable if we got double click
if a:key ==? "\<2-leftmouse>" if a:key ==? "\<2-leftmouse>"
" forward line number to python, since vim does not allow us to focus
" the correct window
call py3eval( '_vimspector_session.ExpandVariable(' call py3eval( '_vimspector_session.ExpandVariable('
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],' \ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
\ . 'line_num = ' . line( '.', a:winid ) \ . 'line_num = ' . line( '.', a:winid )
@ -135,17 +130,49 @@ function! vimspector#internal#balloon#MouseFilter( winid, key ) abort
return handled return handled
endfunction endfunction
function! s:MatchKey( key, candidates ) abort
for candidate in a:candidates
" If the mapping string looks like a special character, then try and
" expand it. This is... a hack. The whole thing only works if the mapping
" is a single key (anyway), and so we assume any string starting with < is a
" special key (which will be the common case) and try and map it. If it
" fails... it fails.
if candidate[ 0 ] == '<'
try
execute 'let candidate = "\' . candidate . '"'
endtry
endif
if candidate ==# a:key
return v:true
endif
endfor
return v:false
endfunction
function! vimspector#internal#balloon#CursorFilter( winid, key ) abort function! vimspector#internal#balloon#CursorFilter( winid, key ) abort
if a:key ==? "\<CR>" let mappings = py3eval(
" forward line number to python, since vim does not allow us to focus \ "__import__( 'vimspector',"
" the correct window \." fromlist = [ 'settings' ] ).settings.Dict("
\." 'mappings' )[ 'variables' ]" )
if index( [ "\<LeftMouse>", "\<2-LeftMouse>" ], a:key ) >= 0
return vimspector#internal#balloon#MouseFilter( a:winid, a:key )
endif
if s:MatchKey( a:key, mappings.expand_collapse )
call py3eval( '_vimspector_session.ExpandVariable(' call py3eval( '_vimspector_session.ExpandVariable('
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],' \ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
\ . 'line_num = ' . line( '.', a:winid ) \ . 'line_num = ' . line( '.', a:winid )
\ . ')' ) \ . ')' )
return 1 return 1
elseif index( [ "\<LeftMouse>", "\<2-LeftMouse>" ], a:key ) >= 0 elseif s:MatchKey( a:key, mappings.set_value )
return vimspector#internal#balloon#MouseFilter( a:winid, a:key ) call py3eval( '_vimspector_session.SetVariableValue('
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
\ . 'line_num = ' . line( '.', a:winid )
\ . ')' )
return 1
endif endif
return popup_filter_menu( a:winid, a:key ) return popup_filter_menu( a:winid, a:key )
@ -290,12 +317,10 @@ function! s:CreateNeovimTooltip( body ) abort
" interract with the popup in neovim " interract with the popup in neovim
noautocmd call win_gotoid( s:popup_win_id ) noautocmd call win_gotoid( s:popup_win_id )
nnoremap <silent> <buffer> <CR> nnoremap <silent> <buffer> <Esc> <cmd>quit<CR>
\ <cmd>call vimspector#ExpandVariable()<CR> call py3eval( "__import__( 'vimspector', "
nnoremap <silent> <buffer> <Esc> \." fromlist = [ 'variables' ] )."
\ <cmd>quit<CR> \.' variables.AddExpandMappings()' )
nnoremap <silent> <buffer> <2-LeftMouse>
\ <cmd>call vimspector#ExpandVariable()<CR>
" Close the popup whenever we leave this window " Close the popup whenever we leave this window
augroup vimspector#internal#balloon#nvim_float augroup vimspector#internal#balloon#nvim_float

View file

@ -159,15 +159,16 @@ function! s:_OnCommandEvent( category, id, data, event ) abort
call setbufvar( buffer, '&modified', 0 ) call setbufvar( buffer, '&modified', 0 )
endtry endtry
" if the buffer is visible, scroll it " if the buffer is visible, scroll it, but don't allow autocommands to fire,
" as this may close the current window!
let w = bufwinnr( buffer ) let w = bufwinnr( buffer )
if w > 0 if w > 0
let cw = winnr() let cw = winnr()
try try
execute w . 'wincmd w' noautocmd execute w . 'wincmd w'
normal! Gz- noautocmd normal! Gz-
finally finally
execute cw . 'wincmd w' noautocmd execute cw . 'wincmd w'
endtry endtry
endif endif
elseif a:event ==# 'exit' elseif a:event ==# 'exit'

View file

@ -80,6 +80,56 @@ function! vimspector#internal#neopopup#HideSplash( id ) abort
unlet s:db[ a:id ] unlet s:db[ a:id ]
endfunction endfunction
function! vimspector#internal#neopopup#Confirm( confirm_id,
\ text,
\ options,
\ default_value,
\ keys ) abort
" Neovim doesn't have an equivalent of popup_dialog, and it's way too much
" effort to write one, so we just use confirm()...
" Annoyingly we can't use confirm() here because for some reason it doesn't
" render properly in a channel callback. So we use input() and mimic dialog
" behaviour.
let prompt = a:text
for opt in a:options
let prompt .= ' ' . opt
endfor
let prompt .= ': '
try
let result = input( prompt, a:keys[ a:default_value - 1 ] )
catch /.*/
let result = -1
endtry
" Map the results to what the vim popup stuff would return (s:ConfirmCallback
" in popup.vim), i.e.:
" - 1-based index of selected item, or
" - -1 or 0 for cancellation
if result == ''
" User pressed ESC/ctrl-c
let result = -1
else
let index = 1
for k in a:keys
if k ==? result
let result = index
break
endif
let index += 1
endfor
if index > len( a:keys )
let result = -1
endif
endif
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
\ int( vim.eval( 'a:confirm_id' ) ),
\ int( vim.eval( 'result' ) ) )
endfunction
" Boilerplate {{{ " Boilerplate {{{
let &cpoptions=s:save_cpo let &cpoptions=s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -12,6 +12,7 @@
" WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. " WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
" See the License for the specific language governing permissions and " See the License for the specific language governing permissions and
" limitations under the License. " limitations under the License.
scriptencoding utf-8
" Boilerplate {{{ " Boilerplate {{{
@ -32,6 +33,113 @@ function! vimspector#internal#popup#HideSplash( id ) abort
call popup_hide( a:id ) call popup_hide( a:id )
endfunction endfunction
let s:current_selection = 0
let s:selections = []
let s:text = []
function! s:UpdatePopup( id ) abort
let buf = copy( s:text )
call extend( buf, s:DrawButtons() )
call popup_settext( a:id, buf )
endfunction
function! s:ConfirmKeyFilter( keys, id, key ) abort
if a:key ==# "\<CR>"
call popup_close( a:id, s:current_selection + 1 )
return 1
elseif index( [ "\<Tab>", "\<Right>" ], a:key ) >= 0
let s:current_selection = ( s:current_selection + 1 ) % len( s:selections )
call s:UpdatePopup( a:id )
return 1
elseif index( [ "\<S-Tab>", "\<Left>" ], a:key ) >= 0
let s:current_selection = s:current_selection == 0
\ ? len( s:selections ) - 1: s:current_selection - 1
call s:UpdatePopup( a:id )
return 1
elseif a:key ==# "\<Esc>" || a:key ==# "\<C-c>"
call popup_close( a:id, -1 )
return 1
endif
let index = 1
for key in a:keys
if a:key ==? key
call popup_close( a:id, index )
return 1
endif
let index += 1
endfor
endfunction
function! s:ConfirmCallback( confirm_id, id, result ) abort
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
\ int( vim.eval( 'a:confirm_id' ) ),
\ int( vim.eval( 'a:result' ) ) )
endfunction
function! s:SelectionPosition( idx ) abort
return a:idx == 0 ? 0 : len( join( s:selections[ : a:idx - 1 ], ' ' ) ) + 1
endfunction
function! s:DrawButtons() abort
return [ {
\ 'text': join( s:selections, ' ' ),
\ 'props': [
\ {
\ 'col': s:SelectionPosition( s:current_selection ) + 1,
\ 'length': len( s:selections[ s:current_selection ] ),
\ 'type': 'VimspectorSelectedItem'
\ },
\ ]
\ } ]
endfunction
function! vimspector#internal#popup#Confirm(
\ confirm_id,
\ text,
\ options,
\ default_value,
\ keys ) abort
silent! call prop_type_add( 'VimspectorSelectedItem', {
\ 'highlight': 'PMenuSel'
\ } )
let lines = split( a:text, "\n", v:true )
let buf = []
for line in lines
call add( buf, { 'text': line, 'props': [] } )
endfor
call add( buf, { 'text': '', 'props': [] } )
let s:selections = a:options
let s:current_selection = ( a:default_value - 1 )
let s:text = copy( buf )
call extend( buf, s:DrawButtons() )
let config = {
\ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ),
\ 'filter': function( 's:ConfirmKeyFilter', [ a:keys ] ),
\ 'mapping': v:false,
\ }
let config = vimspector#internal#popup#SetBorderChars( config )
return popup_dialog( buf, config )
endfunction
function! vimspector#internal#popup#SetBorderChars( config ) abort
" When ambiwidth is single, use prettier characters for the border. This
" would look silly when ambiwidth is double.
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
let a:config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
endif
return a:config
endfunction
" Boilerplate {{{ " Boilerplate {{{
let &cpoptions=s:save_cpo let &cpoptions=s:save_cpo
unlet s:save_cpo unlet s:save_cpo

1085
doc/vimspector-ref.txt Normal file

File diff suppressed because it is too large Load diff

2394
doc/vimspector.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
activesupport (6.0.3.4) activesupport (6.0.3.6)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2) i18n (>= 0.7, < 2)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2) zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0) addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1) coffee-script (2.4.1)
coffee-script-source coffee-script-source
@ -16,7 +16,7 @@ GEM
colorator (1.1.0) colorator (1.1.0)
commonmarker (0.17.13) commonmarker (0.17.13)
ruby-enum (~> 0.5) ruby-enum (~> 0.5)
concurrent-ruby (1.1.7) concurrent-ruby (1.1.8)
dnsruby (1.61.5) dnsruby (1.61.5)
simpleidn (~> 0.1) simpleidn (~> 0.1)
em-websocket (0.5.2) em-websocket (0.5.2)
@ -30,12 +30,12 @@ GEM
faraday-net_http (~> 1.0) faraday-net_http (~> 1.0)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
ruby2_keywords ruby2_keywords
faraday-net_http (1.0.0) faraday-net_http (1.0.1)
ffi (1.14.2) ffi (1.15.0)
forwardable-extended (2.6.0) forwardable-extended (2.6.0)
gemoji (3.0.1) gemoji (3.0.1)
github-pages (209) github-pages (214)
github-pages-health-check (= 1.16.1) github-pages-health-check (= 1.17.0)
jekyll (= 3.9.0) jekyll (= 3.9.0)
jekyll-avatar (= 0.7.0) jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1) jekyll-coffeescript (= 1.1.1)
@ -50,9 +50,9 @@ GEM
jekyll-readme-index (= 0.3.0) jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.16.0) jekyll-redirect-from (= 0.16.0)
jekyll-relative-links (= 0.6.1) jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.2) jekyll-remote-theme (= 0.4.3)
jekyll-sass-converter (= 1.5.2) jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.6.1) jekyll-seo-tag (= 2.7.1)
jekyll-sitemap (= 1.4.0) jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0) jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.1.1) jekyll-theme-architect (= 0.1.1)
@ -70,19 +70,19 @@ GEM
jekyll-theme-time-machine (= 0.1.1) jekyll-theme-time-machine (= 0.1.1)
jekyll-titles-from-headings (= 0.5.3) jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.12.0) jemoji (= 0.12.0)
kramdown (= 2.3.0) kramdown (= 2.3.1)
kramdown-parser-gfm (= 1.1.0) kramdown-parser-gfm (= 1.1.0)
liquid (= 4.0.3) liquid (= 4.0.3)
mercenary (~> 0.3) mercenary (~> 0.3)
minima (= 2.5.1) minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0) nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.23.0) rouge (= 3.26.0)
terminal-table (~> 1.4) terminal-table (~> 1.4)
github-pages-health-check (1.16.1) github-pages-health-check (1.17.0)
addressable (~> 2.3) addressable (~> 2.3)
dnsruby (~> 1.60) dnsruby (~> 1.60)
octokit (~> 4.0) octokit (~> 4.0)
public_suffix (~> 3.0) public_suffix (>= 2.0.2, < 5.0)
typhoeus (~> 1.3) typhoeus (~> 1.3)
html-pipeline (2.14.0) html-pipeline (2.14.0)
activesupport (>= 2) activesupport (>= 2)
@ -136,15 +136,15 @@ GEM
jekyll (>= 3.3, < 5.0) jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1) jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0) jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.2) jekyll-remote-theme (0.4.3)
addressable (~> 2.0) addressable (~> 2.0)
jekyll (>= 3.5, < 5.0) jekyll (>= 3.5, < 5.0)
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0) jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
rubyzip (>= 1.3.0, < 3.0) rubyzip (>= 1.3.0, < 3.0)
jekyll-sass-converter (1.5.2) jekyll-sass-converter (1.5.2)
sass (~> 3.4) sass (~> 3.4)
jekyll-seo-tag (2.6.1) jekyll-seo-tag (2.7.1)
jekyll (>= 3.3, < 5.0) jekyll (>= 3.8, < 5.0)
jekyll-sitemap (1.4.0) jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0) jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0) jekyll-swiss (1.0.0)
@ -196,23 +196,23 @@ GEM
gemoji (~> 3.0) gemoji (~> 3.0)
html-pipeline (~> 2.2) html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0) jekyll (>= 3.0, < 5.0)
kramdown (2.3.0) kramdown (2.3.1)
rexml rexml
kramdown-parser-gfm (1.1.0) kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0) kramdown (~> 2.0)
liquid (4.0.3) liquid (4.0.3)
listen (3.4.0) listen (3.5.1)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6) mercenary (0.3.6)
mini_portile2 (2.5.0) mini_portile2 (2.5.1)
minima (2.5.1) minima (2.5.1)
jekyll (>= 3.5, < 5.0) jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9) jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1) jekyll-seo-tag (~> 2.1)
minitest (5.14.3) minitest (5.14.4)
multipart-post (2.1.1) multipart-post (2.1.1)
nokogiri (1.11.1) nokogiri (1.11.5)
mini_portile2 (~> 2.5.0) mini_portile2 (~> 2.5.0)
racc (~> 1.4) racc (~> 1.4)
octokit (4.20.0) octokit (4.20.0)
@ -220,16 +220,16 @@ GEM
sawyer (~> 0.8.0, >= 0.5.3) sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2) pathutil (0.16.2)
forwardable-extended (~> 2.6) forwardable-extended (~> 2.6)
public_suffix (3.1.1) public_suffix (4.0.6)
racc (1.5.2) racc (1.5.2)
rb-fsevent (0.10.4) rb-fsevent (0.10.4)
rb-inotify (0.10.1) rb-inotify (0.10.1)
ffi (~> 1.0) ffi (~> 1.0)
rexml (3.2.4) rexml (3.2.5)
rouge (3.23.0) rouge (3.26.0)
ruby-enum (0.8.0) ruby-enum (0.9.0)
i18n i18n
ruby2_keywords (0.0.2) ruby2_keywords (0.0.4)
rubyzip (2.3.0) rubyzip (2.3.0)
safe_yaml (1.0.5) safe_yaml (1.0.5)
sass (3.7.4) sass (3.7.4)
@ -240,7 +240,7 @@ GEM
sawyer (0.8.2) sawyer (0.8.2)
addressable (>= 2.3.5) addressable (>= 2.3.5)
faraday (> 0.8, < 2.0) faraday (> 0.8, < 2.0)
simpleidn (0.1.1) simpleidn (0.2.1)
unf (~> 0.1.4) unf (~> 0.1.4)
terminal-table (1.8.0) terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1) unicode-display_width (~> 1.1, >= 1.1.1)

View file

@ -271,7 +271,7 @@ JSON value `true`, and the suffix is stripped fom the key, resulting in the
following: following:
```json ```json
"stopOnEntry#json": true "stopOnEntry": true
``` ```
Which is what we need. Which is what we need.
@ -634,7 +634,9 @@ Vimspector then orchestrates the various tools to set you up.
// %CMD% replaced with the remote-cmdLine configured in the launch // %CMD% replaced with the remote-cmdLine configured in the launch
// configuration. (mandatory) // configuration. (mandatory)
"runCommand": [ "runCommand": [
"python", "-m", "debugpy", "--listen", "0.0.0.0:${port}", "python", "-m", "debugpy",
"--listen", "0.0.0.0:${port}",
"--wait-for-client",
"%CMD%" "%CMD%"
] ]
@ -720,7 +722,7 @@ Vimspector then orchestrates the various tools to set you up.
"variables": { "variables": {
// Just an example of how to specify a variable manually rather than // Just an example of how to specify a variable manually rather than
// vimspector asking for input from the user // vimspector asking for input from the user
"ServiceName": "${fileBasenameNoExtention}" "ServiceName": "${fileBasenameNoExtension}"
}, },
"adapter": "python-remote", "adapter": "python-remote",
@ -848,7 +850,9 @@ port.
// %CMD% replaced with the remote-cmdLine configured in the launch // %CMD% replaced with the remote-cmdLine configured in the launch
// configuration. (mandatory) // configuration. (mandatory)
"runCommand": [ "runCommand": [
"python", "-m", "debugpy", "--listen", "0.0.0.0:${port}", "python", "-m", "debugpy",
"--listen", "0.0.0.0:${port}",
"--wait-for-client",
"%CMD%" "%CMD%"
] ]

View file

@ -13,6 +13,13 @@
" See the License for the specific language governing permissions and " See the License for the specific language governing permissions and
" limitations under the License. " limitations under the License.
if !has( 'python3' )
echohl WarningMsg
echom 'Vimspector unavailable: Requires Vim compiled with +python3'
echohl None
finish
endif
" Boilerplate {{{ " Boilerplate {{{
let s:save_cpo = &cpoptions let s:save_cpo = &cpoptions
set cpoptions&vim set cpoptions&vim
@ -35,6 +42,8 @@ let s:mappings = get( g:, 'vimspector_enable_mappings', '' )
nnoremap <silent> <Plug>VimspectorContinue nnoremap <silent> <Plug>VimspectorContinue
\ :<c-u>call vimspector#Continue()<CR> \ :<c-u>call vimspector#Continue()<CR>
nnoremap <silent> <Plug>VimspectorLaunch
\ :<c-u>call vimspector#Launch( v:true )<CR>
nnoremap <silent> <Plug>VimspectorStop nnoremap <silent> <Plug>VimspectorStop
\ :<c-u>call vimspector#Stop()<CR> \ :<c-u>call vimspector#Stop()<CR>
nnoremap <silent> <Plug>VimspectorRestart nnoremap <silent> <Plug>VimspectorRestart
@ -67,6 +76,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
@ -79,6 +93,7 @@ if s:mappings ==# 'VISUAL_STUDIO'
nmap <S-F11> <Plug>VimspectorStepOut nmap <S-F11> <Plug>VimspectorStepOut
elseif s:mappings ==# 'HUMAN' elseif s:mappings ==# 'HUMAN'
nmap <F5> <Plug>VimspectorContinue nmap <F5> <Plug>VimspectorContinue
nmap <leader><F5> <Plug>VimspectorLaunch
nmap <F3> <Plug>VimspectorStop nmap <F3> <Plug>VimspectorStop
nmap <F4> <Plug>VimspectorRestart nmap <F4> <Plug>VimspectorRestart
nmap <F6> <Plug>VimspectorPause nmap <F6> <Plug>VimspectorPause
@ -100,12 +115,15 @@ command! -bar -nargs=? -complete=custom,vimspector#CompleteOutput
command! -bar command! -bar
\ VimspectorToggleLog \ VimspectorToggleLog
\ call vimspector#ToggleLog() \ call vimspector#ToggleLog()
command! -bar -nargs=1 -complete=custom,vimspector#CompleteExpr command! -bar
\ VimspectorDebugInfo
\ call vimspector#PrintDebugInfo()
command! -nargs=1 -complete=custom,vimspector#CompleteExpr
\ VimspectorEval \ VimspectorEval
\ call vimspector#Evaluate( <f-args> ) \ call vimspector#Evaluate( <f-args> )
command! -bar command! -bar
\ VimspectorReset \ VimspectorReset
\ call vimspector#Reset() \ call vimspector#Reset( { 'interactive': v:true } )
" Installer commands " Installer commands
command! -bar -bang -nargs=* -complete=custom,vimspector#CompleteInstall command! -bar -bang -nargs=* -complete=custom,vimspector#CompleteInstall
@ -129,6 +147,7 @@ augroup VimspectorUserAutoCmds
autocmd user VimspectorDebugEnded silent autocmd user VimspectorDebugEnded silent
augroup END augroup END
" FIXME: Only register this _while_ debugging is active
augroup Vimspector augroup Vimspector
autocmd! autocmd!
autocmd BufNew * call vimspector#OnBufferCreated( expand( '<afile>' ) ) autocmd BufNew * call vimspector#OnBufferCreated( expand( '<afile>' ) )

View file

@ -0,0 +1,51 @@
# vimspector - A multi-language debugging system for Vim
# Copyright 2021 Ben Jackson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from vimspector.debug_session import DebugSession
from vimspector import utils, settings
class JavaDebugAdapter( object ):
def __init__( self, debug_session: DebugSession ):
self.debug_session = debug_session
def OnEvent_hotcodereplace( self, message ):
# Hack for java debug server hot-code-replace
body = message.get( 'body' ) or {}
if body.get( 'type' ) != 'hotcodereplace':
return
if body.get( 'changeType' ) == 'BUILD_COMPLETE':
def handler( result ):
if result == 1:
self.debug_session._connection.DoRequest( None, {
'command': 'redefineClasses',
'arguments': {},
} )
mode = settings.Get( 'java_hotcodereplace_mode' )
if mode == 'ask':
utils.Confirm( self.debug_session._api_prefix,
'Code has changed, hot reload?',
handler,
default_value = 1 )
elif mode == 'always':
self.debug_session._connection.DoRequest( None, {
'command': 'redefineClasses',
'arguments': {},
} )
elif body.get( 'message' ):
utils.UserMessage( 'Hot code replace: ' + body[ 'message' ] )

View file

@ -29,14 +29,14 @@ class PendingRequest( object ):
class DebugAdapterConnection( object ): class DebugAdapterConnection( object ):
def __init__( self, handler, send_func ): def __init__( self, handlers, send_func ):
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger )
self._Write = send_func self._Write = send_func
self._SetState( 'READ_HEADER' ) self._SetState( 'READ_HEADER' )
self._buffer = bytes() self._buffer = bytes()
self._handler = handler self._handlers = handlers
self._next_message_id = 0 self._next_message_id = 0
self._outstanding_requests = {} self._outstanding_requests = {}
@ -124,7 +124,7 @@ class DebugAdapterConnection( object ):
def Reset( self ): def Reset( self ):
self._Write = None self._Write = None
self._handler = None self._handlers = None
while self._outstanding_requests: while self._outstanding_requests:
_, request = self._outstanding_requests.popitem() _, request = self._outstanding_requests.popitem()
@ -226,7 +226,12 @@ class DebugAdapterConnection( object ):
# self._logger.debug( 'Message received (raw): %s', payload ) # self._logger.debug( 'Message received (raw): %s', payload )
message = json.loads( payload ) try:
message = json.loads( payload, strict = False )
except Exception:
self._logger.exception( "Invalid message received: %s", payload )
self._SetState( 'READ_HEADER' )
raise
self._logger.debug( 'Message received: {0}'.format( message ) ) self._logger.debug( 'Message received: {0}'.format( message ) )
@ -237,7 +242,7 @@ class DebugAdapterConnection( object ):
def _OnMessageReceived( self, message ): def _OnMessageReceived( self, message ):
if not self._handler: if not self._handlers:
return return
if message[ 'type' ] == 'response': if message[ 'type' ] == 'response':
@ -270,25 +275,21 @@ class DebugAdapterConnection( object ):
self._logger.error( 'Request failed: {0}'.format( reason ) ) self._logger.error( 'Request failed: {0}'.format( reason ) )
if request.failure_handler: if request.failure_handler:
request.failure_handler( reason, message ) request.failure_handler( reason, message )
elif 'OnFailure' in dir( self._handler ):
self._handler.OnFailure( reason, request.msg, message )
else: else:
utils.UserMessage( 'Request failed: {0}'.format( reason ) ) for h in self._handlers:
if 'OnFailure' in dir( h ):
h.OnFailure( reason, request.msg, message )
elif message[ 'type' ] == 'event': elif message[ 'type' ] == 'event':
method = 'OnEvent_' + message[ 'event' ] method = 'OnEvent_' + message[ 'event' ]
if method in dir( self._handler ): for h in self._handlers:
getattr( self._handler, method )( message ) if method in dir( h ):
else: getattr( h, method )( message )
utils.UserMessage( 'Unhandled event: {0}'.format( message[ 'event' ] ),
persist = True )
elif message[ 'type' ] == 'request': elif message[ 'type' ] == 'request':
method = 'OnRequest_' + message[ 'command' ] method = 'OnRequest_' + message[ 'command' ]
if method in dir( self._handler ): for h in self._handlers:
getattr( self._handler, method )( message ) if method in dir( h ):
else: getattr( h, method )( message )
utils.UserMessage(
'Unhandled request: {0}'.format( message[ 'command' ] ),
persist = True )
def _KillTimer( request ): def _KillTimer( request ):

View file

@ -21,6 +21,7 @@ import shlex
import subprocess import subprocess
import functools import functools
import vim import vim
import importlib
from vimspector import ( breakpoints, from vimspector import ( breakpoints,
code, code,
@ -99,7 +100,7 @@ class DebugSession( object ):
return launch_config_file, configurations return launch_config_file, configurations
def Start( self, launch_variables = None ): def Start( self, force_choose=False, launch_variables = None ):
# We mutate launch_variables, so don't mutate the default argument. # We mutate launch_variables, so don't mutate the default argument.
# https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments # https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
if launch_variables is None: if launch_variables is None:
@ -134,6 +135,11 @@ class DebugSession( object ):
if 'configuration' in launch_variables: if 'configuration' in launch_variables:
configuration_name = launch_variables.pop( 'configuration' ) configuration_name = launch_variables.pop( 'configuration' )
elif force_choose:
# Always display the menu
configuration_name = utils.SelectFromList(
'Which launch configuration?',
sorted( configurations.keys() ) )
elif ( len( configurations ) == 1 and elif ( len( configurations ) == 1 and
next( iter( configurations.values() ) ).get( "autoselect", True ) ): next( iter( configurations.values() ) ).get( "autoselect", True ) ):
configuration_name = next( iter( configurations.keys() ) ) configuration_name = next( iter( configurations.keys() ) )
@ -320,7 +326,7 @@ class DebugSession( object ):
if self._connection: if self._connection:
self._logger.debug( "_StopDebugAdapter with callback: start" ) self._logger.debug( "_StopDebugAdapter with callback: start" )
self._StopDebugAdapter( start ) self._StopDebugAdapter( interactive = False, callback = start )
return return
start() start()
@ -385,14 +391,15 @@ class DebugSession( object ):
self._connection = None self._connection = None
@IfConnected() @IfConnected()
def Stop( self ): def Stop( self, interactive = False ):
self._logger.debug( "Stop debug adapter with no callback" ) self._logger.debug( "Stop debug adapter with no callback" )
self._StopDebugAdapter() self._StopDebugAdapter( interactive = interactive )
def Reset( self ): def Reset( self, interactive = False ):
if self._connection: if self._connection:
self._logger.debug( "Stop debug adapter with callback : self._Reset()" ) self._logger.debug( "Stop debug adapter with callback : self._Reset()" )
self._StopDebugAdapter( lambda: self._Reset() ) self._StopDebugAdapter( interactive = interactive,
callback = lambda: self._Reset() )
else: else:
self._Reset() self._Reset()
@ -524,6 +531,10 @@ class DebugSession( object ):
def ExpandVariable( self, buf = None, line_num = None ): def ExpandVariable( self, buf = None, line_num = None ):
self._variablesView.ExpandVariable( buf, line_num ) self._variablesView.ExpandVariable( buf, line_num )
@IfConnected()
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
self._variablesView.SetVariableValue( new_value, buf, line_num )
@IfConnected() @IfConnected()
def AddWatch( self, expression ): def AddWatch( self, expression ):
self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(), self._variablesView.AddWatch( self._stackTraceView.GetCurrentFrame(),
@ -566,6 +577,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' )
@ -627,6 +646,18 @@ class DebugSession( object ):
return response[ 'body' ][ 'targets' ] return response[ 'body' ][ 'targets' ]
@IfConnected( otherwise=[] )
def GetCommandLineCompletions( self, ArgLead, prev_non_keyword_char ):
items = []
for candidate in self.GetCompletionsSync( ArgLead, prev_non_keyword_char ):
label = candidate.get( 'text', candidate[ 'label' ] )
start = prev_non_keyword_char - 1
if 'start' in candidate and 'length' in candidate:
start = candidate[ 'start' ]
items.append( ArgLead[ 0 : start ] + label )
return items
def RefreshSigns( self, file_name ): def RefreshSigns( self, file_name ):
if self._connection: if self._connection:
self._codeView.Refresh( file_name ) self._codeView.Refresh( file_name )
@ -638,6 +669,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 )
@ -678,6 +748,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 ),
@ -764,15 +894,31 @@ class DebugSession( object ):
self._splash_screen, self._splash_screen,
"Unable to start adapter" ) "Unable to start adapter" )
else: else:
if 'custom_handler' in self._adapter:
spec = self._adapter[ 'custom_handler' ]
if isinstance( spec, dict ):
module = spec[ 'module' ]
cls = spec[ 'class' ]
else:
module, cls = spec.rsplit( '.', 1 )
CustomHandler = getattr( importlib.import_module( module ), cls )
handlers = [ CustomHandler( self ), self ]
else:
handlers = [ self ]
self._connection = debug_adapter_connection.DebugAdapterConnection( self._connection = debug_adapter_connection.DebugAdapterConnection(
self, handlers,
lambda msg: utils.Call( lambda msg: utils.Call(
"vimspector#internal#{}#Send".format( self._connection_type ), "vimspector#internal#{}#Send".format( self._connection_type ),
msg ) ) msg ) )
self._logger.info( 'Debug Adapter Started' ) self._logger.info( 'Debug Adapter Started' )
def _StopDebugAdapter( self, callback = None ): def _StopDebugAdapter( self, interactive = False, callback = None ):
arguments = {}
def disconnect():
self._splash_screen = utils.DisplaySplash( self._splash_screen = utils.DisplaySplash(
self._api_prefix, self._api_prefix,
self._splash_screen, self._splash_screen,
@ -790,17 +936,38 @@ class DebugSession( object ):
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format( vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
self._connection_type ) ) self._connection_type ) )
arguments = {}
if self._server_capabilities.get( 'supportTerminateDebuggee' ):
# If we attached, we should _not_ terminate the debuggee
arguments[ 'terminateDebuggee' ] = False
self._connection.DoRequest( handler, { self._connection.DoRequest( handler, {
'command': 'disconnect', 'command': 'disconnect',
'arguments': arguments, 'arguments': arguments,
}, failure_handler = handler, timeout = 5000 ) }, failure_handler = handler, timeout = 5000 )
# TODO: Use the 'tarminate' request if supportsTerminateRequest set if not interactive:
disconnect()
elif not self._server_capabilities.get( 'supportTerminateDebuggee' ):
disconnect()
elif not self._stackTraceView.AnyThreadsRunning():
disconnect()
else:
def handle_choice( choice ):
if choice == 1:
# yes
arguments[ 'terminateDebuggee' ] = True
elif choice == 2:
# no
arguments[ 'terminateDebuggee' ] = False
elif choice <= 0:
# Abort
return
# Else, use server default
disconnect()
utils.Confirm( self._api_prefix,
"Terminate debuggee?",
handle_choice,
default_value = 3,
options = [ '(Y)es', '(N)o', '(D)efault' ],
keys = [ 'y', 'n', 'd' ] )
def _PrepareAttach( self, adapter_config, launch_config ): def _PrepareAttach( self, adapter_config, launch_config ):
@ -981,6 +1148,7 @@ class DebugSession( object ):
def handle_initialize_response( msg ): def handle_initialize_response( msg ):
self._server_capabilities = msg.get( 'body' ) or {} self._server_capabilities = msg.get( 'body' ) or {}
self._breakpoints.SetServerCapabilities( self._server_capabilities ) self._breakpoints.SetServerCapabilities( self._server_capabilities )
self._variablesView.SetServerCapabilities( self._server_capabilities )
self._Launch() self._Launch()
self._connection.DoRequest( handle_initialize_response, { self._connection.DoRequest( handle_initialize_response, {
@ -1023,14 +1191,14 @@ class DebugSession( object ):
self._splash_screen = utils.DisplaySplash( self._splash_screen = utils.DisplaySplash(
self._api_prefix, self._api_prefix,
self._splash_screen, self._splash_screen,
"Attaching to debugee..." ) "Attaching to debuggee..." )
self._PrepareAttach( self._adapter, self._launch_config ) self._PrepareAttach( self._adapter, self._launch_config )
elif request == "launch": elif request == "launch":
self._splash_screen = utils.DisplaySplash( self._splash_screen = utils.DisplaySplash(
self._api_prefix, self._api_prefix,
self._splash_screen, self._splash_screen,
"Launching debugee..." ) "Launching debuggee..." )
# FIXME: This cmdLine hack is not fun. # FIXME: This cmdLine hack is not fun.
self._PrepareLaunch( self._configuration.get( 'remote-cmdLine', [] ), self._PrepareLaunch( self._configuration.get( 'remote-cmdLine', [] ),
@ -1102,6 +1270,37 @@ class DebugSession( object ):
self._stackTraceView.LoadThreads( True ) self._stackTraceView.LoadThreads( True )
@IfConnected()
@RequiresUI()
def PrintDebugInfo( self ):
def Line():
return ( "--------------------------------------------------------------"
"------------------" )
def Pretty( obj ):
if obj is None:
return [ "None" ]
return [ Line() ] + json.dumps( obj, indent=2 ).splitlines() + [ Line() ]
debugInfo = [
"Vimspector Debug Info",
Line(),
f"ConnectionType: { self._connection_type }",
"Adapter: " ] + Pretty( self._adapter ) + [
"Configuration: " ] + Pretty( self._configuration ) + [
f"API Prefix: { self._api_prefix }",
f"Launch/Init: { self._launch_complete } / { self._init_complete }",
f"Workspace Root: { self._workspace_root }",
"Launch Config: " ] + Pretty( self._launch_config ) + [
"Server Capabilities: " ] + Pretty( self._server_capabilities ) + [
]
self._outputView.ClearCategory( 'DebugInfo' )
self._outputView.Print( "DebugInfo", debugInfo )
self.ShowOutput( "DebugInfo" )
def OnEvent_loadedSource( self, msg ): def OnEvent_loadedSource( self, msg ):
pass pass
@ -1164,13 +1363,25 @@ class DebugSession( object ):
self._connection.DoResponse( message, None, response ) self._connection.DoResponse( message, None, response )
def OnEvent_exited( self, message ): def OnEvent_terminated( self, message ):
utils.UserMessage( 'The debugee exited with status code: {}'.format( # The debugging _session_ has terminated. This does not mean that the
message[ 'body' ][ 'exitCode' ] ) ) # debuggee has terminated (that's the exited event).
#
# We will handle this when the server actually exists.
#
# FIXME we should always wait for this event before disconnecting closing
# any socket connection
self.SetCurrentFrame( None ) self.SetCurrentFrame( None )
def OnEvent_exited( self, message ):
utils.UserMessage( 'The debuggee exited with status code: {}'.format(
message[ 'body' ][ 'exitCode' ] ) )
self._stackTraceView.OnExited( message )
self._codeView.SetCurrentFrame( None )
def OnEvent_process( self, message ): def OnEvent_process( self, message ):
utils.UserMessage( 'The debugee was started: {}'.format( utils.UserMessage( 'The debuggee was started: {}'.format(
message[ 'body' ][ 'name' ] ) ) message[ 'body' ][ 'name' ] ) )
def OnEvent_module( self, message ): def OnEvent_module( self, message ):
@ -1210,11 +1421,6 @@ class DebugSession( object ):
else: else:
self._logger.debug( "No server exit handler" ) self._logger.debug( "No server exit handler" )
def OnEvent_terminated( self, message ):
# We will handle this when the server actually exists
utils.UserMessage( "Debugging was terminated by the server." )
self.SetCurrentFrame( None )
def OnEvent_output( self, message ): def OnEvent_output( self, message ):
if self._outputView: if self._outputView:
self._outputView.OnOutput( message[ 'body' ] ) self._outputView.OnOutput( message[ 'body' ] )

View file

@ -30,12 +30,12 @@ GADGETS = {
root, root,
gadget ), gadget ),
'all': { 'all': {
'version': '0.27.0', 'version': '1.6.0',
"adapters": { "adapters": {
"vscode-cpptools": { "vscode-cpptools": {
"name": "cppdbg", "name": "cppdbg",
"command": [ "command": [
"${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7" "${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7"
], ],
"attach": { "attach": {
"pidProperty": "processId", "pidProperty": "processId",
@ -53,17 +53,17 @@ GADGETS = {
'linux': { 'linux': {
'file_name': 'cpptools-linux.vsix', 'file_name': 'cpptools-linux.vsix',
'checksum': 'checksum':
'3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435', 'c25299bcfb46b22d41aa3f125df7184e6282a35ff9fb69c47def744cb4778f55',
}, },
'macos': { 'macos': {
'file_name': 'cpptools-osx.vsix', 'file_name': 'cpptools-osx-arm64.vsix',
'checksum': 'checksum':
'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c', 'ceb3e8cdaa2b5bb45af50913ddd8402089969748af8d70f5d46480408287ba6f',
}, },
'windows': { 'windows': {
'file_name': 'cpptools-win32.vsix', 'file_name': 'cpptools-win32.vsix',
'checksum': 'checksum':
'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e', 'ef7ac5831874a3c7dbf0feb826bfda2be579aff9b6d990622fff1d0d4ede00d1',
"adapters": { "adapters": {
"vscode-cpptools": { "vscode-cpptools": {
"name": "cppdbg", "name": "cppdbg",
@ -86,29 +86,6 @@ GADGETS = {
}, },
}, },
}, },
'vscode-python': {
'language': 'python.legacy',
'enabled': False,
'download': {
'url': 'https://github.com/Microsoft/vscode-python/releases/download/'
'${version}/${file_name}',
},
'all': {
'version': '2019.11.50794',
'file_name': 'ms-python-release.vsix',
'checksum':
'6a9edf9ecabed14aac424e6007858068204a3638bf3bb4f235bd6035d823acc6',
},
'adapters': {
"vscode-python": {
"name": "vscode-python",
"command": [
"node",
"${gadgetDir}/vscode-python/out/client/debugger/debugAdapter/main.js",
],
}
},
},
'debugpy': { 'debugpy': {
'language': 'python', 'language': 'python',
'download': { 'download': {
@ -159,7 +136,8 @@ GADGETS = {
"port": "${DAPPort}", "port": "${DAPPort}",
"configuration": { "configuration": {
"cwd": "${workspaceRoot}" "cwd": "${workspaceRoot}"
} },
'custom_handler': 'vimspector.custom.java.JavaDebugAdapter'
} }
}, },
}, },
@ -233,15 +211,15 @@ GADGETS = {
'format': 'tar', 'format': 'tar',
}, },
'all': { 'all': {
'version': '1.2.0-635' 'version': '1.2.0-782'
}, },
'macos': { 'macos': {
'file_name': 'netcoredbg-osx.tar.gz', 'file_name': 'netcoredbg-osx.tar.gz',
'checksum': 'checksum':
'71c773e34d358950f25119bade7e3081c4c2f9d71847bd49027ca5792e918beb', '',
}, },
'linux': { 'linux': {
'file_name': 'netcoredbg-linux-bionic.tar.gz', 'file_name': 'netcoredbg-linux-bionic-amd64.tar.gz',
'checksum': '', 'checksum': '',
}, },
'windows': { 'windows': {
@ -268,41 +246,6 @@ GADGETS = {
}, },
} }
}, },
'vscode-mono-debug': {
'language': 'csharp',
'enabled': False,
'download': {
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
'publishers/ms-vscode/vsextensions/mono-debug/${version}/'
'vspackage',
'target': 'vscode-mono-debug.vsix.gz',
'format': 'zip.gz',
},
'all': {
'file_name': 'vscode-mono-debug.vsix',
'version': '0.16.2',
'checksum':
'121eca297d83daeeb1e6e1d791305d1827998dbd595c330086b3b94d33dba3b9',
},
'adapters': {
'vscode-mono-debug': {
"name": "mono-debug",
"command": [
"mono",
"${gadgetDir}/vscode-mono-debug/bin/Release/mono-debug.exe"
],
"attach": {
"pidSelect": "none"
},
"configuration": {
"cwd": "${workspaceRoot}",
"console": "integratedTerminal",
"args": [],
"env": {}
}
},
}
},
'vscode-bash-debug': { 'vscode-bash-debug': {
'language': 'bash', 'language': 'bash',
'download': { 'download': {
@ -380,10 +323,10 @@ GADGETS = {
'${version}/${file_name}', '${version}/${file_name}',
}, },
'all': { 'all': {
'version': 'v1.14.9', 'version': 'v1.17.0',
'file_name': 'php-debug.vsix', 'file_name': 'php-debug-1.17.0.vsix',
'checksum': 'checksum':
'0c5709cbbffe26b12aa63a88142195a9a045a5d8fca7fe63d62c789fe601630d', 'd0fff272503414b6696cc737bc2e18e060fdd5e5dc4bcaf38ae7373afd8d8bc9',
}, },
'adapters': { 'adapters': {
'vscode-php-debug': { 'vscode-php-debug': {
@ -451,12 +394,12 @@ GADGETS = {
'${version}/${file_name}', '${version}/${file_name}',
}, },
'all': { 'all': {
'version': 'v1.5.3', 'version': 'v1.6.6',
}, },
'macos': { 'macos': {
'file_name': 'codelldb-x86_64-darwin.vsix', 'file_name': 'codelldb-aarch64-darwin.vsix',
'checksum': 'checksum':
'7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a', '5adc3b9139eabdafd825bd5efc55df4424a203fb2b6087b425cd434956e7ec58',
'make_executable': [ 'make_executable': [
'adapter/codelldb', 'adapter/codelldb',
'lldb/bin/debugserver', 'lldb/bin/debugserver',
@ -467,7 +410,7 @@ GADGETS = {
'linux': { 'linux': {
'file_name': 'codelldb-x86_64-linux.vsix', 'file_name': 'codelldb-x86_64-linux.vsix',
'checksum': 'checksum':
'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139', 'eda2cd9b3089dcc0524c273e91ffb5875fe08c930bf643739a2cd1846e1f98d6',
'make_executable': [ 'make_executable': [
'adapter/codelldb', 'adapter/codelldb',
'lldb/bin/lldb', 'lldb/bin/lldb',
@ -478,7 +421,7 @@ GADGETS = {
'windows': { 'windows': {
'file_name': 'codelldb-x86_64-windows.vsix', 'file_name': 'codelldb-x86_64-windows.vsix',
'checksum': 'checksum':
'', '8ddebe8381a3d22dc3d95139c3797fda06b5cc34aadf300e13b1c516b9da95fe',
'make_executable': [] 'make_executable': []
}, },
'adapters': { 'adapters': {

View file

@ -358,7 +358,8 @@ def InstallCppTools( name, root, gadget ):
# It's hilarious, but the execute bits aren't set in the vsix. So they # It's hilarious, but the execute bits aren't set in the vsix. So they
# actually have javascript code which does this. It's just a horrible horrible # actually have javascript code which does this. It's just a horrible horrible
# hack that really is not funny. # hack that really is not funny.
MakeExecutable( os.path.join( extension, 'debugAdapters', 'OpenDebugAD7' ) ) MakeExecutable(
os.path.join( extension, 'debugAdapters', 'bin', 'OpenDebugAD7' ) )
with open( os.path.join( extension, 'package.json' ) ) as f: with open( os.path.join( extension, 'package.json' ) ) as f:
package = json.load( f ) package = json.load( f )
runtime_dependencies = package[ 'runtimeDependencies' ] runtime_dependencies = package[ 'runtimeDependencies' ]

View file

@ -32,8 +32,9 @@ class TabBuffer( object ):
BUFFER_MAP = { BUFFER_MAP = {
'console': 'Console', 'console': 'Console',
'stdout': 'Console', 'stdout': 'Console',
'output': 'Console',
'stderr': 'stderr', 'stderr': 'stderr',
'telemetry': 'Telemetry', 'telemetry': None,
} }
@ -64,8 +65,11 @@ class OutputView( object ):
self._api_prefix = api_prefix self._api_prefix = api_prefix
VIEWS.add( self ) VIEWS.add( self )
def Print( self, categroy, text ): def Print( self, category, text: typing.Union[ str, list ] ):
self._Print( 'server', text.splitlines() ) if not isinstance( text, list ):
text = text.splitlines()
self._Print( category, text )
def OnOutput( self, event ): def OnOutput( self, event ):
category = CategoryToBuffer( event.get( 'category' ) or 'output' ) category = CategoryToBuffer( event.get( 'category' ) or 'output' )
@ -77,6 +81,10 @@ class OutputView( object ):
self._Print( category, text_lines ) self._Print( category, text_lines )
def _Print( self, category, text_lines ): def _Print( self, category, text_lines ):
if category is None:
# This category is supressed
return
if category not in self._buffers: if category not in self._buffers:
self._CreateBuffer( category ) self._CreateBuffer( category )
@ -100,13 +108,26 @@ class OutputView( object ):
def Clear( self ): def Clear( self ):
for category, tab_buffer in self._buffers.items(): for category, tab_buffer in self._buffers.items():
if tab_buffer.is_job: self._CleanUpBuffer( category, tab_buffer )
utils.CleanUpCommand( category, self._api_prefix )
utils.CleanUpHiddenBuffer( tab_buffer.buf )
# FIXME: nunmenu the WinBar ? # FIXME: nunmenu the WinBar ?
self._buffers = {} self._buffers = {}
def ClearCategory( self, category: str ):
if category not in self._buffers:
return
self._CleanUpBuffer( category, self._buffers[ category ] )
def _CleanUpBuffer( self, category: str, tab_buffer: TabBuffer ):
if tab_buffer.is_job:
utils.CleanUpCommand( category, self._api_prefix )
utils.CleanUpHiddenBuffer( tab_buffer.buf )
def WindowIsValid( self ): def WindowIsValid( self ):
return self._window.valid return self._window.valid
@ -230,7 +251,7 @@ class OutputView( object ):
raise raise
vim.command( vim.command(
"nnoremenu 1.{0} WinBar.{1}{2} " "nnoremenu <silent> 1.{0} WinBar.{1}{2} "
":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format( ":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format(
tab_buffer.index, tab_buffer.index,
utils.Escape( category ), utils.Escape( category ),
@ -251,6 +272,7 @@ class DAPOutputView( OutputView ):
self._connection = None self._connection = None
for b in set( BUFFER_MAP.values() ): for b in set( BUFFER_MAP.values() ):
if b is not None:
self._CreateBuffer( b ) self._CreateBuffer( b )
self.AddLogFileView() self.AddLogFileView()

View file

@ -20,12 +20,21 @@ from vimspector import utils
DEFAULTS = { DEFAULTS = {
# UI # UI
'ui_mode': 'auto',
'bottombar_height': 10, 'bottombar_height': 10,
# For ui_mode = 'horizontal':
'sidebar_width': 50, 'sidebar_width': 50,
'code_minwidth': 82, 'code_minwidth': 82,
'terminal_maxwidth': 80, 'terminal_maxwidth': 80,
'terminal_minwidth': 10, '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': {
'vimspectorPC': 200, 'vimspectorPC': 200,
@ -33,11 +42,28 @@ DEFAULTS = {
'vimspectorBP': 9, 'vimspectorBP': 9,
'vimspectorBPCond': 9, 'vimspectorBPCond': 9,
'vimspectorBPDisabled': 9, 'vimspectorBPDisabled': 9,
'vimspectorCurrentThread': 200 'vimspectorCurrentThread': 200,
'vimspectorCurrentFrame': 200,
}, },
# Installer # Installer
'install_gadgets': [], 'install_gadgets': [],
# Mappings
'mappings': {
'variables': {
'expand_collapse': [ '<CR>', '<2-LeftMouse>' ],
'delete': [ '<Del>' ],
'set_value': [ '<C-CR>', '<leader><CR>' ]
},
'stack_trace': {
'expand_or_jump': [ '<CR>', '<2-LeftMouse>' ],
'focus_thread': [ '<leader><CR>' ],
}
},
# Custom
'java_hotcodereplace_mode': 'ask',
} }
@ -69,9 +95,44 @@ if hasattr( vim, 'Dictionary' ):
DICT_TYPE = vim.Dictionary DICT_TYPE = vim.Dictionary
def Dict( option: str ): def Dict( option ):
d = DICT_TYPE( DEFAULTS.get( option, {} ) ) return _UpdateDict( DICT_TYPE( DEFAULTS.get( option, {} ) ),
d.update( utils.GetVimValue( vim.vars, vim.vars.get( f'vimspector_{ option }', DICT_TYPE() ) )
f'vimspector_{ option }',
{} ) )
return d def _UpdateDict( target, override ):
"""Apply the updates in |override| to the dict |target|. This is like
dict.update, but recursive. i.e. if the existing element is a dict, then
override elements of the sub-dict rather than wholesale replacing.
e.g.
UpdateDict(
{
'outer': { 'inner': { 'key': 'oldValue', 'existingKey': True } }
},
{
'outer': { 'inner': { 'key': 'newValue' } },
'newKey': { 'newDict': True },
}
)
yields:
{
'outer': {
'inner': {
'key': 'newValue',
'existingKey': True
}
},
'newKey': { newDict: True }
}
"""
for key, value in override.items():
current_value = target.get( key )
if not isinstance( current_value, DICT_TYPE ):
target[ key ] = value
elif isinstance( value, DICT_TYPE ):
target[ key ] = _UpdateDict( current_value, value )
else:
target[ key ] = value
return target

View file

@ -18,7 +18,7 @@ import os
import logging import logging
import typing import typing
from vimspector import utils, signs from vimspector import utils, signs, settings
class Thread: class Thread:
@ -102,28 +102,33 @@ class StackTraceView( object ):
self._scratch_buffers = [] self._scratch_buffers = []
# FIXME: This ID is by group, so should be module scope # FIXME: This ID is by group, so should be module scope
self._next_sign_id = 1 self._current_thread_sign_id = 0 # 1 when used
self._current_frame_sign_id = 0 # 2 when used
utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' ) utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' )
utils.SetUpUIWindow( win ) utils.SetUpUIWindow( win )
mappings = settings.Dict( 'mappings' )[ 'stack_trace' ]
with utils.LetCurrentWindow( win ): with utils.LetCurrentWindow( win ):
vim.command( 'nnoremap <silent> <buffer> <CR> ' for mapping in utils.GetVimList( mappings, 'expand_or_jump' ):
':<C-U>call vimspector#GoToFrame()<CR>' ) vim.command( f'nnoremap <silent> <buffer> { mapping } '
vim.command( 'nnoremap <silent> <buffer> <leader><CR> '
':<C-U>call vimspector#SetCurrentThread()<CR>' )
vim.command( 'nnoremap <silent> <buffer> <2-LeftMouse> '
':<C-U>call vimspector#GoToFrame()<CR>' ) ':<C-U>call vimspector#GoToFrame()<CR>' )
for mapping in utils.GetVimList( mappings, 'focus_thread' ):
vim.command( f'nnoremap <silent> <buffer> { mapping } '
':<C-U>call vimspector#SetCurrentThread()<CR>' )
if utils.UseWinBar(): if utils.UseWinBar():
vim.command( 'nnoremenu 1.1 WinBar.Pause/Continue ' vim.command( 'nnoremenu <silent> 1.1 WinBar.Pause/Continue '
':call vimspector#PauseContinueThread()<CR>' ) ':call vimspector#PauseContinueThread()<CR>' )
vim.command( 'nnoremenu 1.2 WinBar.Expand/Collapse ' vim.command( 'nnoremenu <silent> 1.2 WinBar.Expand/Collapse '
':call vimspector#GoToFrame()<CR>' ) ':call vimspector#GoToFrame()<CR>' )
vim.command( 'nnoremenu 1.3 WinBar.Focus ' vim.command( 'nnoremenu <silent> 1.3 WinBar.Focus '
':call vimspector#SetCurrentThread()<CR>' ) ':call vimspector#SetCurrentThread()<CR>' )
win.options[ 'cursorline' ] = False win.options[ 'cursorline' ] = False
win.options[ 'signcolumn' ] = 'auto'
if not signs.SignDefined( 'vimspectorCurrentThread' ): if not signs.SignDefined( 'vimspectorCurrentThread' ):
@ -133,6 +138,13 @@ class StackTraceView( object ):
texthl = 'MatchParen', texthl = 'MatchParen',
linehl = 'CursorLine' ) linehl = 'CursorLine' )
if not signs.SignDefined( 'vimspectorCurrentFrame' ):
signs.DefineSign( 'vimspectorCurrentFrame',
text = '▶ ',
double_text = '▶',
texthl = 'Special',
linehl = 'CursorLine' )
self._line_to_frame = {} self._line_to_frame = {}
self._line_to_thread = {} self._line_to_thread = {}
@ -154,9 +166,12 @@ class StackTraceView( object ):
self._sources = {} self._sources = {}
self._requesting_threads = StackTraceView.ThreadRequestState.NO self._requesting_threads = StackTraceView.ThreadRequestState.NO
self._pending_thread_request = None self._pending_thread_request = None
if self._next_sign_id: if self._current_thread_sign_id:
signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' ) signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' )
self._next_sign_id = 0 self._current_thread_sign_id = 0
if self._current_frame_sign_id:
signs.UnplaceSign( self._current_frame_sign_id, 'VimspectorStackTrace' )
self._current_frame_sign_id = 0
with utils.ModifiableScratchBuffer( self._buf ): with utils.ModifiableScratchBuffer( self._buf ):
utils.ClearBuffer( self._buf ) utils.ClearBuffer( self._buf )
@ -270,10 +285,10 @@ class StackTraceView( object ):
self._line_to_frame.clear() self._line_to_frame.clear()
self._line_to_thread.clear() self._line_to_thread.clear()
if self._next_sign_id: if self._current_thread_sign_id:
signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' ) signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' )
else: else:
self._next_sign_id = 1 self._current_thread_sign_id = 1
with utils.ModifiableScratchBuffer( self._buf ): with utils.ModifiableScratchBuffer( self._buf ):
with utils.RestoreCursorPosition(): with utils.RestoreCursorPosition():
@ -287,7 +302,7 @@ class StackTraceView( object ):
f'({thread.State()})' ) f'({thread.State()})' )
if self._current_thread == thread.id: if self._current_thread == thread.id:
signs.PlaceSign( self._next_sign_id, signs.PlaceSign( self._current_thread_sign_id,
'VimspectorStackTrace', 'VimspectorStackTrace',
'vimspectorCurrentThread', 'vimspectorCurrentThread',
self._buf.name, self._buf.name,
@ -364,12 +379,61 @@ 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 ):
for thread in self._threads:
if thread.state != Thread.TERMINATED:
return True
return False
def _JumpToFrame( self, frame, reason = '' ): def _JumpToFrame( self, frame, reason = '' ):
def do_jump(): def do_jump():
if 'line' in frame and frame[ 'line' ] > 0: if 'line' in frame and frame[ 'line' ] > 0:
# Should this set the current _Thread_ too ? If i jump to a frame in # Should this set the current _Thread_ too ? If i jump to a frame in
# Thread 2, should that become the focussed thread ? # Thread 2, should that become the focussed thread ?
self._current_frame = frame self._current_frame = frame
self._DrawThreads()
return self._session.SetCurrentFrame( self._current_frame, reason ) return self._session.SetCurrentFrame( self._current_frame, reason )
return False return False
@ -459,10 +523,19 @@ class StackTraceView( object ):
self.LoadThreads( infer_current_frame ) self.LoadThreads( infer_current_frame )
def OnExited( self, event ):
for thread in self._threads:
thread.Exited()
def _DrawStackTrace( self, thread: Thread ): def _DrawStackTrace( self, thread: Thread ):
if not thread.IsExpanded(): if not thread.IsExpanded():
return return
if self._current_frame_sign_id:
signs.UnplaceSign( self._current_frame_sign_id, 'VimspectorStackTrace' )
else:
self._current_frame_sign_id = 2
for frame in thread.stacktrace: for frame in thread.stacktrace:
if frame.get( 'source' ): if frame.get( 'source' ):
source = frame[ 'source' ] source = frame[ 'source' ]
@ -487,6 +560,14 @@ class StackTraceView( object ):
source[ 'name' ], source[ 'name' ],
frame[ 'line' ] ) ) frame[ 'line' ] ) )
if ( self._current_frame is not None and
self._current_frame[ 'id' ] == frame[ 'id' ] ):
signs.PlaceSign( self._current_frame_sign_id,
'VimspectorStackTrace',
'vimspectorCurrentFrame',
self._buf.name,
line )
self._line_to_frame[ line ] = ( thread, frame ) self._line_to_frame[ line ] = ( thread, frame )
def _ResolveSource( self, source, and_then ): def _ResolveSource( self, source, and_then ):

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

@ -356,20 +356,63 @@ def SelectFromList( prompt, options ):
return None return None
def AskForInput( prompt, default_value = None ): def AskForInput( prompt, default_value = None, completion = None ):
if default_value is None: if default_value is None:
default_option = '' default_value = ''
args = [ prompt, default_value ]
if completion is not None:
if completion == 'expr':
args.append( 'custom,vimspector#CompleteExpr' )
else: else:
default_option = ", '{}'".format( Escape( default_value ) ) args.append( completion )
with InputSave(): with InputSave():
try: try:
return vim.eval( "input( '{}' {} )".format( Escape( prompt ), return Call( 'input', *args )
default_option ) )
except ( KeyboardInterrupt, vim.error ): except ( KeyboardInterrupt, vim.error ):
return None return None
CONFIRM = {}
CONFIRM_ID = 0
def ConfirmCallback( confirm_id, result ):
try:
handler = CONFIRM.pop( confirm_id )
except KeyError:
UserMessage( f"Internal error: unexpected callback id { confirm_id }",
persist = True,
error = True )
return
handler( result )
def Confirm( api_prefix,
prompt,
handler,
default_value = 2,
options: list = None,
keys: list = None ):
if not options:
options = [ '(Y)es', '(N)o' ]
if not keys:
keys = [ 'y', 'n' ]
global CONFIRM_ID
CONFIRM_ID += 1
CONFIRM[ CONFIRM_ID ] = handler
Call( f'vimspector#internal#{ api_prefix }popup#Confirm',
CONFIRM_ID,
prompt,
options,
default_value,
keys )
def AppendToBuffer( buf, line_or_lines, modified=False ): def AppendToBuffer( buf, line_or_lines, modified=False ):
line = 1 line = 1
try: try:
@ -398,8 +441,10 @@ def AppendToBuffer( buf, line_or_lines, modified=False ):
def ClearBuffer( buf ): def ClearBuffer( buf, modified = False ):
buf[ : ] = None buf[ : ] = None
if not modified:
buf.options[ 'modified' ] = False
def SetBufferContents( buf, lines, modified=False ): def SetBufferContents( buf, lines, modified=False ):
@ -489,7 +534,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( '\\}', '}' ) )
@ -531,7 +575,10 @@ 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:
if e2.name in calculus:
default_value = calculus[ e2.name ]()
else:
default_value = e.default_value default_value = e.default_value
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ), mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),

View file

@ -19,7 +19,7 @@ import logging
from functools import partial from functools import partial
import typing import typing
from vimspector import utils from vimspector import utils, settings
class Expandable: class Expandable:
@ -32,8 +32,9 @@ class Expandable:
a 'variablesReference' to be resolved by the 'variables' request. Records the a 'variablesReference' to be resolved by the 'variables' request. Records the
current state expanded/collapsed. Implementations just implement current state expanded/collapsed. Implementations just implement
VariablesReference to get the variables.""" VariablesReference to get the variables."""
def __init__( self ): def __init__( self, container: 'Expandable' = None ):
self.variables: typing.List[ 'Variable' ] = None self.variables: typing.List[ 'Variable' ] = None
self.container: Expandable = container
# None is Falsy and represents collapsed _by default_. WHen set to False, # None is Falsy and represents collapsed _by default_. WHen set to False,
# this means the user explicitly collapsed it. When True, the user expanded # this means the user explicitly collapsed it. When True, the user expanded
# it (or we expanded it by default). # it (or we expanded it by default).
@ -48,6 +49,9 @@ class Expandable:
def IsExpandable( self ): def IsExpandable( self ):
return self.VariablesReference() > 0 return self.VariablesReference() > 0
def IsContained( self ):
return self.container is not None
@abc.abstractmethod @abc.abstractmethod
def VariablesReference( self ): def VariablesReference( self ):
assert False assert False
@ -92,8 +96,8 @@ class WatchFailure( WatchResult ):
class Variable( Expandable ): class Variable( Expandable ):
"""Holds one level of an expanded value tree. Also itself expandable.""" """Holds one level of an expanded value tree. Also itself expandable."""
def __init__( self, variable: dict ): def __init__( self, container: Expandable, variable: dict ):
super().__init__() super().__init__( container = container )
self.variable = variable self.variable = variable
# A new variable appearing is marked as changed # A new variable appearing is marked as changed
self.changed = True self.changed = True
@ -149,6 +153,18 @@ class BufView( View ):
self.buf = buf self.buf = buf
def AddExpandMappings( mappings = None ):
if mappings is None:
mappings = settings.Dict( 'mappings' )[ 'variables' ]
for mapping in utils.GetVimList( mappings, 'expand_collapse' ):
vim.command( f'nnoremap <silent> <buffer> { mapping } '
':<C-u>call vimspector#ExpandVariable()<CR>' )
for mapping in utils.GetVimList( mappings, 'set_value' ):
vim.command( f'nnoremap <silent> <buffer> { mapping } '
':<C-u>call vimspector#SetVariableValue()<CR>' )
class VariablesView( object ): class VariablesView( object ):
def __init__( self, variables_win, watches_win ): def __init__( self, variables_win, watches_win ):
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ )
@ -156,22 +172,22 @@ class VariablesView( object ):
self._connection = None self._connection = None
self._current_syntax = '' self._current_syntax = ''
self._server_capabilities = None
self._variable_eval: Scope = None self._variable_eval: Scope = None
self._variable_eval_view: View = None self._variable_eval_view: View = None
def AddExpandMappings(): mappings = settings.Dict( 'mappings' )[ 'variables' ]
vim.command( 'nnoremap <silent> <buffer> <CR> '
':<C-u>call vimspector#ExpandVariable()<CR>' )
vim.command( 'nnoremap <silent> <buffer> <2-LeftMouse> '
':<C-u>call vimspector#ExpandVariable()<CR>' )
# Set up the "Variables" buffer in the variables_win # Set up the "Variables" buffer in the variables_win
self._scopes: typing.List[ Scope ] = [] self._scopes: typing.List[ Scope ] = []
self._vars = View( variables_win, {}, self._DrawScopes ) self._vars = View( variables_win, {}, self._DrawScopes )
utils.SetUpHiddenBuffer( self._vars.buf, 'vimspector.Variables' ) utils.SetUpHiddenBuffer( self._vars.buf, 'vimspector.Variables' )
with utils.LetCurrentWindow( variables_win ): with utils.LetCurrentWindow( variables_win ):
AddExpandMappings() if utils.UseWinBar():
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
':call vimspector#SetVariableValue()<CR>' )
AddExpandMappings( mappings )
# Set up the "Watches" buffer in the watches_win (and create a WinBar in # Set up the "Watches" buffer in the watches_win (and create a WinBar in
# there) # there)
@ -183,17 +199,20 @@ class VariablesView( object ):
'vimspector#AddWatchPrompt', 'vimspector#AddWatchPrompt',
'vimspector#OmniFuncWatch' ) 'vimspector#OmniFuncWatch' )
with utils.LetCurrentWindow( watches_win ): with utils.LetCurrentWindow( watches_win ):
AddExpandMappings() AddExpandMappings( mappings )
for mapping in utils.GetVimList( mappings, 'delete' ):
vim.command( vim.command(
'nnoremap <buffer> <DEL> :call vimspector#DeleteWatch()<CR>' ) f'nnoremap <buffer> { mapping } :call vimspector#DeleteWatch()<CR>' )
if utils.UseWinBar(): if utils.UseWinBar():
vim.command( 'nnoremenu 1.1 WinBar.New ' vim.command( 'nnoremenu <silent> 1.1 WinBar.New '
':call vimspector#AddWatch()<CR>' ) ':call vimspector#AddWatch()<CR>' )
vim.command( 'nnoremenu 1.2 WinBar.Expand/Collapse ' vim.command( 'nnoremenu <silent> 1.2 WinBar.Expand/Collapse '
':call vimspector#ExpandVariable()<CR>' ) ':call vimspector#ExpandVariable()<CR>' )
vim.command( 'nnoremenu 1.3 WinBar.Delete ' vim.command( 'nnoremenu <silent> 1.3 WinBar.Delete '
':call vimspector#DeleteWatch()<CR>' ) ':call vimspector#DeleteWatch()<CR>' )
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
':call vimspector#SetVariableValue()<CR>' )
# Set the (global!) balloon expr if supported # Set the (global!) balloon expr if supported
has_balloon = int( vim.eval( "has( 'balloon_eval' )" ) ) has_balloon = int( vim.eval( "has( 'balloon_eval' )" ) )
@ -231,11 +250,17 @@ class VariablesView( object ):
def ConnectionUp( self, connection ): def ConnectionUp( self, connection ):
self._connection = connection self._connection = connection
def SetServerCapabilities( self, capabilities ):
self._server_capabilities = capabilities
def ConnectionClosed( self ): def ConnectionClosed( self ):
self.Clear() self.Clear()
self._connection = None self._connection = None
self._server_capabilities = None
def Reset( self ): def Reset( self ):
self._server_capabilities = None
for k, v in self._oldoptions.items(): for k, v in self._oldoptions.items():
vim.options[ k ] = v vim.options[ k ] = v
@ -447,7 +472,9 @@ class VariablesView( object ):
watch.result = WatchFailure( reason ) watch.result = WatchFailure( reason )
self._DrawWatches() self._DrawWatches()
def ExpandVariable( self, buf = None, line_num = None ): def _GetVariable( self, buf = None, line_num = None ):
none = ( None, None )
if buf is None: if buf is None:
buf = vim.current.buffer buf = vim.current.buffer
@ -462,12 +489,17 @@ class VariablesView( object ):
and buf == self._variable_eval_view.buf ): and buf == self._variable_eval_view.buf ):
view = self._variable_eval_view view = self._variable_eval_view
else: else:
return return none
if line_num not in view.lines: if line_num not in view.lines:
return return none
variable = view.lines[ line_num ] return view.lines[ line_num ], view
def ExpandVariable( self, buf = None, line_num = None ):
variable, view = self._GetVariable( buf, line_num )
if variable is None:
return
if variable.IsExpanded(): if variable.IsExpanded():
# Collapse # Collapse
@ -488,6 +520,67 @@ class VariablesView( object ):
}, },
} ) } )
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
variable: Variable
view: View
if not self._server_capabilities.get( 'supportsSetVariable' ):
return
variable, view = self._GetVariable( buf, line_num )
if variable is None:
return
if not variable.IsContained():
return
if new_value is None:
new_value = utils.AskForInput( 'New Value: ',
variable.variable.get( 'value', '' ),
completion = 'expr' )
if new_value is None:
return
def handler( message ):
# Annoyingly the response to setVariable request doesn't return a
# Variable, but some part of it, so take a copy of the existing Variable
# dict and update it, then call its update method with the updated copy.
new_variable = dict( variable.variable )
new_variable.update( message[ 'body' ] )
# Clear any existing known children (FIXME: Is this the right thing to do)
variable.variables = None
# If the variable is expanded, re-request its children
if variable.IsExpanded():
self._connection.DoRequest( partial( self._ConsumeVariables,
view.draw,
variable ), {
'command': 'variables',
'arguments': {
'variablesReference': variable.VariablesReference()
},
} )
variable.Update( new_variable )
view.draw()
def failure_handler( reason, message ):
utils.UserMessage( f'Cannot set value: { reason }', error = True )
self._connection.DoRequest( handler, {
'command': 'setVariable',
'arguments': {
'variablesReference': variable.container.VariablesReference(),
'name': variable.variable[ 'name' ],
'value': new_value
},
}, failure_handler = failure_handler )
def _DrawVariables( self, view, variables, indent, is_short = False ): def _DrawVariables( self, view, variables, indent, is_short = False ):
assert indent > 0 assert indent > 0
for variable in variables: for variable in variables:
@ -609,7 +702,7 @@ class VariablesView( object ):
found = True found = True
break break
if not found: if not found:
variable = Variable( variable_body ) variable = Variable( parent, variable_body )
else: else:
variable.Update( variable_body ) variable.Update( variable_body )

View file

@ -21,7 +21,7 @@ out_fd=1
while [ -n "$1" ]; do while [ -n "$1" ]; do
case "$1" in case "$1" in
"--basedir") "--basedir"|"--base-dir"|"--test-base")
shift shift
SetBaseDir $1 SetBaseDir $1
shift shift
@ -36,7 +36,7 @@ while [ -n "$1" ]; do
INSTALL=$1 INSTALL=$1
shift shift
;; ;;
"--update") "--update"|"--upgrade")
UPDATE=1 UPDATE=1
shift shift
;; ;;
@ -91,7 +91,8 @@ if [ "$INSTALL" = "1" ] || [ "$INSTALL" = "script" ]; then
if ! python3 $(dirname $0)/install_gadget.py \ if ! python3 $(dirname $0)/install_gadget.py \
--basedir ${BASEDIR} \ --basedir ${BASEDIR} \
${INSTALLER_ARGS} \ ${INSTALLER_ARGS} \
--all; then --all \
--force-enable-csharp; then
echo "Script installation reported errors" >&2 echo "Script installation reported errors" >&2
exit 1 exit 1
fi fi
@ -102,7 +103,7 @@ if [ "$INSTALL" = "1" ] || [ "$INSTALL" = "vim" ]; then
--cmd "${BASEDIR_CMD}" \ --cmd "${BASEDIR_CMD}" \
-c 'autocmd User VimspectorInstallSuccess qa!' \ -c 'autocmd User VimspectorInstallSuccess qa!' \
-c 'autocmd User VimspectorInstallFailed cquit!' \ -c 'autocmd User VimspectorInstallFailed cquit!' \
-c "VimspectorInstall --all"; then -c "VimspectorInstall --all netcoredbg"; then
echo "Vim installation reported errors" >&2 echo "Vim installation reported errors" >&2
exit 1 exit 1
fi fi
@ -144,6 +145,9 @@ set -e
pushd tests/testdata/cpp/simple pushd tests/testdata/cpp/simple
make clean all make clean all
popd popd
pushd support/test/csharp
dotnet build
popd
set +e set +e
echo "%DONE - built test programs" echo "%DONE - built test programs"

View file

@ -54,7 +54,7 @@ function s:SetUpTerminal()
let padding = 4 let padding = 4
let cols = max( [ min( [ &columns - left_bar - code - padding, 80 ] ), 10 ] ) let cols = max( [ min( [ &columns - left_bar - code - padding, 80 ] ), 10 ] )
call win_gotoid( terminal_win ) call win_gotoid( terminal_win )
execute cols . 'wincmd |' execute string(cols) . 'wincmd |'
endfunction endfunction
function! s:CustomiseWinBar() function! s:CustomiseWinBar()
@ -105,7 +105,10 @@ function! s:OnJumpToFrame() abort
nmap <silent> <buffer> <LocalLeader>di <Plug>VimspectorBalloonEval nmap <silent> <buffer> <LocalLeader>di <Plug>VimspectorBalloonEval
xmap <silent> <buffer> <LocalLeader>di <Plug>VimspectorBalloonEval xmap <silent> <buffer> <LocalLeader>di <Plug>VimspectorBalloonEval
let s:mapped[ string( bufnr() ) ] = 1 let s:mapped[ string( bufnr() ) ] = { 'modifiable': &modifiable }
setlocal nomodifiable
endfunction endfunction
function! s:OnDebugEnd() abort function! s:OnDebugEnd() abort
@ -124,6 +127,8 @@ function! s:OnDebugEnd() abort
silent! nunmap <buffer> <LocalLeader>dc silent! nunmap <buffer> <LocalLeader>dc
silent! nunmap <buffer> <LocalLeader>di silent! nunmap <buffer> <LocalLeader>di
silent! xunmap <buffer> <LocalLeader>di silent! xunmap <buffer> <LocalLeader>di
let &l:modifiable = s:mapped[ bufnr ][ 'modifiable' ]
endtry endtry
endfor endfor
finally finally
@ -142,4 +147,15 @@ augroup END
" }}} " }}}
" Custom mappings for special buffers {{{
let g:vimspector_mappings = {
\ 'stack_trace': {},
\ 'variables': {
\ 'set_value': [ '<Tab>', '<C-CR>', 'C' ],
\ }
\ }
" }}}
" vim: foldmethod=marker " vim: foldmethod=marker

View file

@ -0,0 +1,8 @@
# Manually updating shipped gadgets
Download the gadget files manuall from their official source into this dir.
Run `./checksum.py <list of files>` to get the checksums.
Update ../../python3/vimspector/gadgets.py with the new version and the
checksums.

View file

@ -0,0 +1,13 @@
#!/usr/bin/env python3
import hashlib
import sys
def GetChecksumSHA254( file_path ):
with open( file_path, 'rb' ) as existing_file:
return hashlib.sha256( existing_file.read() ).hexdigest()
for arg in sys.argv[ 1: ]:
print( f"{ arg } = { GetChecksumSHA254( arg ) }" )

View file

@ -0,0 +1,15 @@
{
"$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json",
"configurations": {
"Run Current Script": {
"adapter": "vscode-bash",
"autoselect": false,
"configuration": {
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"args": [ "*${args}" ]
}
}
}
}

View file

@ -15,6 +15,15 @@
"program": "${workspaceRoot}/test", "program": "${workspaceRoot}/test",
"stopAtEntry": true "stopAtEntry": true
} }
},
"cpptools": {
"adapter": "vscode-cpptools",
"configuration": {
"request": "launch",
"program": "${workspaceRoot}/test",
"stopOnEntry": true,
"MIMode": "lldb"
}
} }
} }
} }

View file

@ -1,4 +1,4 @@
def Settings( **kwargs ): def Settings( **kwargs ):
return { return {
'flags': [ '-x', 'c++', '-Wall', '-Wextra' ] 'flags': [ '-x', 'c++', '-Wall', '-Wextra', '-std=c++17' ]
} }

View file

@ -1,2 +1,3 @@
bin/ bin/
obj/Debug obj/Debug
obj/

View file

@ -1,12 +1,44 @@
{ {
"adapters": {
"netcoredbg-debuglog": {
"attach": {
"pidProperty": "processId",
"pidSelect": "ask"
},
"command": [
"${gadgetDir}/netcoredbg/netcoredbg",
"--interpreter=vscode",
"--engineLogging=${workspaceRoot}/netcoredbg.engine.log",
"--log=${workspaceRoot}/netcoredbg.log"
],
"configuration": {
"cwd": "${workspaceRoot}"
},
"name": "netcoredbg"
}
},
"configurations": { "configurations": {
//
// NOTE:
// If you add to this, you must update tests/get_configurations.test.vim
//
"launch - netcoredbg": { "launch - netcoredbg": {
"adapter": "netcoredbg", "adapter": "netcoredbg",
"configuration": { "configuration": {
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/bin/Debug/netcoreapp2.2/csharp.dll", "program": "${workspaceRoot}/bin/Debug/netcoreapp3.1/csharp.dll",
"args": [], "args": [],
"stopAtEntry": true "stopAtEntry": false
}
},
"launch - netcoredbg - with debug log": {
"adapter": "netcoredbg-debuglog",
"configuration": {
"request": "launch",
"program": "${workspaceRoot}/bin/Debug/netcoreapp3.1/csharp.dll",
"args": [],
"stopAtEntry": false
} }
}, },
"launch - mono": { "launch - mono": {

View file

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View file

@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15 # Visual Studio 15
VisualStudioVersion = 15.0.26124.0 VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "csharp", "csharp.csproj", "{91DB205F-E422-430B-BBB8-955110C7B3B6}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -15,4 +17,18 @@ Global
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Debug|x64.ActiveCfg = Debug|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Debug|x64.Build.0 = Debug|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Debug|x86.ActiveCfg = Debug|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Debug|x86.Build.0 = Debug|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Release|Any CPU.Build.0 = Release|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Release|x64.ActiveCfg = Release|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Release|x64.Build.0 = Release|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Release|x86.ActiveCfg = Release|Any CPU
{91DB205F-E422-430B-BBB8-955110C7B3B6}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal EndGlobal

View file

@ -1,5 +0,0 @@
{
"version": 1,
"dgSpecHash": "6/vdr7YprlSIoQecv/nNuLNflFpO0X7eN7jHUinZTsgian9nYpmHMWirsDWMi5l+29TH+Qy8O/QfaB/48QtjRQ==",
"success": true
}

View file

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/Users/ben/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/Users/ben/.nuget/packages/;/usr/local/share/dotnet/sdk/NuGetFallbackFolder</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">5.7.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="$([MSBuild]::EnsureTrailingSlash($(NuGetPackageFolders)))" />
</ItemGroup>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.props" Condition="Exists('/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.props')" />
</ImportGroup>
</Project>

View file

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="/usr/local/share/dotnet/sdk/NuGetFallbackFolder/netstandard.library/2.0.3/build/netstandard2.0/NETStandard.Library.targets" Condition="Exists('/usr/local/share/dotnet/sdk/NuGetFallbackFolder/netstandard.library/2.0.3/build/netstandard2.0/NETStandard.Library.targets')" />
<Import Project="/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.targets" Condition="Exists('/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.targets')" />
</ImportGroup>
</Project>

View file

@ -1,748 +0,0 @@
{
"version": 3,
"targets": {
".NETCoreApp,Version=v2.2": {
"Microsoft.NETCore.App/2.2.0": {
"type": "package",
"dependencies": {
"Microsoft.NETCore.DotNetHostPolicy": "2.2.0",
"Microsoft.NETCore.Platforms": "2.2.0",
"Microsoft.NETCore.Targets": "2.0.0",
"NETStandard.Library": "2.0.3"
},
"compile": {
"ref/netcoreapp2.2/Microsoft.CSharp.dll": {},
"ref/netcoreapp2.2/Microsoft.VisualBasic.dll": {},
"ref/netcoreapp2.2/Microsoft.Win32.Primitives.dll": {},
"ref/netcoreapp2.2/System.AppContext.dll": {},
"ref/netcoreapp2.2/System.Buffers.dll": {},
"ref/netcoreapp2.2/System.Collections.Concurrent.dll": {},
"ref/netcoreapp2.2/System.Collections.Immutable.dll": {},
"ref/netcoreapp2.2/System.Collections.NonGeneric.dll": {},
"ref/netcoreapp2.2/System.Collections.Specialized.dll": {},
"ref/netcoreapp2.2/System.Collections.dll": {},
"ref/netcoreapp2.2/System.ComponentModel.Annotations.dll": {},
"ref/netcoreapp2.2/System.ComponentModel.DataAnnotations.dll": {},
"ref/netcoreapp2.2/System.ComponentModel.EventBasedAsync.dll": {},
"ref/netcoreapp2.2/System.ComponentModel.Primitives.dll": {},
"ref/netcoreapp2.2/System.ComponentModel.TypeConverter.dll": {},
"ref/netcoreapp2.2/System.ComponentModel.dll": {},
"ref/netcoreapp2.2/System.Configuration.dll": {},
"ref/netcoreapp2.2/System.Console.dll": {},
"ref/netcoreapp2.2/System.Core.dll": {},
"ref/netcoreapp2.2/System.Data.Common.dll": {},
"ref/netcoreapp2.2/System.Data.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.Contracts.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.Debug.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.DiagnosticSource.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.FileVersionInfo.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.Process.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.StackTrace.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.TextWriterTraceListener.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.Tools.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.TraceSource.dll": {},
"ref/netcoreapp2.2/System.Diagnostics.Tracing.dll": {},
"ref/netcoreapp2.2/System.Drawing.Primitives.dll": {},
"ref/netcoreapp2.2/System.Drawing.dll": {},
"ref/netcoreapp2.2/System.Dynamic.Runtime.dll": {},
"ref/netcoreapp2.2/System.Globalization.Calendars.dll": {},
"ref/netcoreapp2.2/System.Globalization.Extensions.dll": {},
"ref/netcoreapp2.2/System.Globalization.dll": {},
"ref/netcoreapp2.2/System.IO.Compression.Brotli.dll": {},
"ref/netcoreapp2.2/System.IO.Compression.FileSystem.dll": {},
"ref/netcoreapp2.2/System.IO.Compression.ZipFile.dll": {},
"ref/netcoreapp2.2/System.IO.Compression.dll": {},
"ref/netcoreapp2.2/System.IO.FileSystem.DriveInfo.dll": {},
"ref/netcoreapp2.2/System.IO.FileSystem.Primitives.dll": {},
"ref/netcoreapp2.2/System.IO.FileSystem.Watcher.dll": {},
"ref/netcoreapp2.2/System.IO.FileSystem.dll": {},
"ref/netcoreapp2.2/System.IO.IsolatedStorage.dll": {},
"ref/netcoreapp2.2/System.IO.MemoryMappedFiles.dll": {},
"ref/netcoreapp2.2/System.IO.Pipes.dll": {},
"ref/netcoreapp2.2/System.IO.UnmanagedMemoryStream.dll": {},
"ref/netcoreapp2.2/System.IO.dll": {},
"ref/netcoreapp2.2/System.Linq.Expressions.dll": {},
"ref/netcoreapp2.2/System.Linq.Parallel.dll": {},
"ref/netcoreapp2.2/System.Linq.Queryable.dll": {},
"ref/netcoreapp2.2/System.Linq.dll": {},
"ref/netcoreapp2.2/System.Memory.dll": {},
"ref/netcoreapp2.2/System.Net.Http.dll": {},
"ref/netcoreapp2.2/System.Net.HttpListener.dll": {},
"ref/netcoreapp2.2/System.Net.Mail.dll": {},
"ref/netcoreapp2.2/System.Net.NameResolution.dll": {},
"ref/netcoreapp2.2/System.Net.NetworkInformation.dll": {},
"ref/netcoreapp2.2/System.Net.Ping.dll": {},
"ref/netcoreapp2.2/System.Net.Primitives.dll": {},
"ref/netcoreapp2.2/System.Net.Requests.dll": {},
"ref/netcoreapp2.2/System.Net.Security.dll": {},
"ref/netcoreapp2.2/System.Net.ServicePoint.dll": {},
"ref/netcoreapp2.2/System.Net.Sockets.dll": {},
"ref/netcoreapp2.2/System.Net.WebClient.dll": {},
"ref/netcoreapp2.2/System.Net.WebHeaderCollection.dll": {},
"ref/netcoreapp2.2/System.Net.WebProxy.dll": {},
"ref/netcoreapp2.2/System.Net.WebSockets.Client.dll": {},
"ref/netcoreapp2.2/System.Net.WebSockets.dll": {},
"ref/netcoreapp2.2/System.Net.dll": {},
"ref/netcoreapp2.2/System.Numerics.Vectors.dll": {},
"ref/netcoreapp2.2/System.Numerics.dll": {},
"ref/netcoreapp2.2/System.ObjectModel.dll": {},
"ref/netcoreapp2.2/System.Reflection.DispatchProxy.dll": {},
"ref/netcoreapp2.2/System.Reflection.Emit.ILGeneration.dll": {},
"ref/netcoreapp2.2/System.Reflection.Emit.Lightweight.dll": {},
"ref/netcoreapp2.2/System.Reflection.Emit.dll": {},
"ref/netcoreapp2.2/System.Reflection.Extensions.dll": {},
"ref/netcoreapp2.2/System.Reflection.Metadata.dll": {},
"ref/netcoreapp2.2/System.Reflection.Primitives.dll": {},
"ref/netcoreapp2.2/System.Reflection.TypeExtensions.dll": {},
"ref/netcoreapp2.2/System.Reflection.dll": {},
"ref/netcoreapp2.2/System.Resources.Reader.dll": {},
"ref/netcoreapp2.2/System.Resources.ResourceManager.dll": {},
"ref/netcoreapp2.2/System.Resources.Writer.dll": {},
"ref/netcoreapp2.2/System.Runtime.CompilerServices.VisualC.dll": {},
"ref/netcoreapp2.2/System.Runtime.Extensions.dll": {},
"ref/netcoreapp2.2/System.Runtime.Handles.dll": {},
"ref/netcoreapp2.2/System.Runtime.InteropServices.RuntimeInformation.dll": {},
"ref/netcoreapp2.2/System.Runtime.InteropServices.WindowsRuntime.dll": {},
"ref/netcoreapp2.2/System.Runtime.InteropServices.dll": {},
"ref/netcoreapp2.2/System.Runtime.Loader.dll": {},
"ref/netcoreapp2.2/System.Runtime.Numerics.dll": {},
"ref/netcoreapp2.2/System.Runtime.Serialization.Formatters.dll": {},
"ref/netcoreapp2.2/System.Runtime.Serialization.Json.dll": {},
"ref/netcoreapp2.2/System.Runtime.Serialization.Primitives.dll": {},
"ref/netcoreapp2.2/System.Runtime.Serialization.Xml.dll": {},
"ref/netcoreapp2.2/System.Runtime.Serialization.dll": {},
"ref/netcoreapp2.2/System.Runtime.dll": {},
"ref/netcoreapp2.2/System.Security.Claims.dll": {},
"ref/netcoreapp2.2/System.Security.Cryptography.Algorithms.dll": {},
"ref/netcoreapp2.2/System.Security.Cryptography.Csp.dll": {},
"ref/netcoreapp2.2/System.Security.Cryptography.Encoding.dll": {},
"ref/netcoreapp2.2/System.Security.Cryptography.Primitives.dll": {},
"ref/netcoreapp2.2/System.Security.Cryptography.X509Certificates.dll": {},
"ref/netcoreapp2.2/System.Security.Principal.dll": {},
"ref/netcoreapp2.2/System.Security.SecureString.dll": {},
"ref/netcoreapp2.2/System.Security.dll": {},
"ref/netcoreapp2.2/System.ServiceModel.Web.dll": {},
"ref/netcoreapp2.2/System.ServiceProcess.dll": {},
"ref/netcoreapp2.2/System.Text.Encoding.Extensions.dll": {},
"ref/netcoreapp2.2/System.Text.Encoding.dll": {},
"ref/netcoreapp2.2/System.Text.RegularExpressions.dll": {},
"ref/netcoreapp2.2/System.Threading.Overlapped.dll": {},
"ref/netcoreapp2.2/System.Threading.Tasks.Dataflow.dll": {},
"ref/netcoreapp2.2/System.Threading.Tasks.Extensions.dll": {},
"ref/netcoreapp2.2/System.Threading.Tasks.Parallel.dll": {},
"ref/netcoreapp2.2/System.Threading.Tasks.dll": {},
"ref/netcoreapp2.2/System.Threading.Thread.dll": {},
"ref/netcoreapp2.2/System.Threading.ThreadPool.dll": {},
"ref/netcoreapp2.2/System.Threading.Timer.dll": {},
"ref/netcoreapp2.2/System.Threading.dll": {},
"ref/netcoreapp2.2/System.Transactions.Local.dll": {},
"ref/netcoreapp2.2/System.Transactions.dll": {},
"ref/netcoreapp2.2/System.ValueTuple.dll": {},
"ref/netcoreapp2.2/System.Web.HttpUtility.dll": {},
"ref/netcoreapp2.2/System.Web.dll": {},
"ref/netcoreapp2.2/System.Windows.dll": {},
"ref/netcoreapp2.2/System.Xml.Linq.dll": {},
"ref/netcoreapp2.2/System.Xml.ReaderWriter.dll": {},
"ref/netcoreapp2.2/System.Xml.Serialization.dll": {},
"ref/netcoreapp2.2/System.Xml.XDocument.dll": {},
"ref/netcoreapp2.2/System.Xml.XPath.XDocument.dll": {},
"ref/netcoreapp2.2/System.Xml.XPath.dll": {},
"ref/netcoreapp2.2/System.Xml.XmlDocument.dll": {},
"ref/netcoreapp2.2/System.Xml.XmlSerializer.dll": {},
"ref/netcoreapp2.2/System.Xml.dll": {},
"ref/netcoreapp2.2/System.dll": {},
"ref/netcoreapp2.2/WindowsBase.dll": {},
"ref/netcoreapp2.2/mscorlib.dll": {},
"ref/netcoreapp2.2/netstandard.dll": {}
},
"build": {
"build/netcoreapp2.2/Microsoft.NETCore.App.props": {},
"build/netcoreapp2.2/Microsoft.NETCore.App.targets": {}
}
},
"Microsoft.NETCore.DotNetAppHost/2.2.0": {
"type": "package"
},
"Microsoft.NETCore.DotNetHostPolicy/2.2.0": {
"type": "package",
"dependencies": {
"Microsoft.NETCore.DotNetHostResolver": "2.2.0"
}
},
"Microsoft.NETCore.DotNetHostResolver/2.2.0": {
"type": "package",
"dependencies": {
"Microsoft.NETCore.DotNetAppHost": "2.2.0"
}
},
"Microsoft.NETCore.Platforms/2.2.0": {
"type": "package",
"compile": {
"lib/netstandard1.0/_._": {}
},
"runtime": {
"lib/netstandard1.0/_._": {}
}
},
"Microsoft.NETCore.Targets/2.0.0": {
"type": "package",
"compile": {
"lib/netstandard1.0/_._": {}
},
"runtime": {
"lib/netstandard1.0/_._": {}
}
},
"NETStandard.Library/2.0.3": {
"type": "package",
"dependencies": {
"Microsoft.NETCore.Platforms": "1.1.0"
},
"compile": {
"lib/netstandard1.0/_._": {}
},
"runtime": {
"lib/netstandard1.0/_._": {}
},
"build": {
"build/netstandard2.0/NETStandard.Library.targets": {}
}
}
}
},
"libraries": {
"Microsoft.NETCore.App/2.2.0": {
"sha512": "7z5l8Jp324S8bU8+yyWeYHXUFYvKyiI5lqS1dXgTzOx1H69Qbf6df12kCKlNX45LpMfCMd4U3M6p7Rl5Zk7SLA==",
"type": "package",
"path": "microsoft.netcore.app/2.2.0",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.TXT",
"Microsoft.NETCore.App.versions.txt",
"THIRD-PARTY-NOTICES.TXT",
"build/netcoreapp2.2/Microsoft.NETCore.App.PlatformManifest.txt",
"build/netcoreapp2.2/Microsoft.NETCore.App.props",
"build/netcoreapp2.2/Microsoft.NETCore.App.targets",
"microsoft.netcore.app.2.2.0.nupkg.sha512",
"microsoft.netcore.app.nuspec",
"ref/netcoreapp2.2/Microsoft.CSharp.dll",
"ref/netcoreapp2.2/Microsoft.CSharp.xml",
"ref/netcoreapp2.2/Microsoft.VisualBasic.dll",
"ref/netcoreapp2.2/Microsoft.VisualBasic.xml",
"ref/netcoreapp2.2/Microsoft.Win32.Primitives.dll",
"ref/netcoreapp2.2/Microsoft.Win32.Primitives.xml",
"ref/netcoreapp2.2/System.AppContext.dll",
"ref/netcoreapp2.2/System.Buffers.dll",
"ref/netcoreapp2.2/System.Buffers.xml",
"ref/netcoreapp2.2/System.Collections.Concurrent.dll",
"ref/netcoreapp2.2/System.Collections.Concurrent.xml",
"ref/netcoreapp2.2/System.Collections.Immutable.dll",
"ref/netcoreapp2.2/System.Collections.Immutable.xml",
"ref/netcoreapp2.2/System.Collections.NonGeneric.dll",
"ref/netcoreapp2.2/System.Collections.NonGeneric.xml",
"ref/netcoreapp2.2/System.Collections.Specialized.dll",
"ref/netcoreapp2.2/System.Collections.Specialized.xml",
"ref/netcoreapp2.2/System.Collections.dll",
"ref/netcoreapp2.2/System.Collections.xml",
"ref/netcoreapp2.2/System.ComponentModel.Annotations.dll",
"ref/netcoreapp2.2/System.ComponentModel.Annotations.xml",
"ref/netcoreapp2.2/System.ComponentModel.DataAnnotations.dll",
"ref/netcoreapp2.2/System.ComponentModel.EventBasedAsync.dll",
"ref/netcoreapp2.2/System.ComponentModel.EventBasedAsync.xml",
"ref/netcoreapp2.2/System.ComponentModel.Primitives.dll",
"ref/netcoreapp2.2/System.ComponentModel.Primitives.xml",
"ref/netcoreapp2.2/System.ComponentModel.TypeConverter.dll",
"ref/netcoreapp2.2/System.ComponentModel.TypeConverter.xml",
"ref/netcoreapp2.2/System.ComponentModel.dll",
"ref/netcoreapp2.2/System.ComponentModel.xml",
"ref/netcoreapp2.2/System.Configuration.dll",
"ref/netcoreapp2.2/System.Console.dll",
"ref/netcoreapp2.2/System.Console.xml",
"ref/netcoreapp2.2/System.Core.dll",
"ref/netcoreapp2.2/System.Data.Common.dll",
"ref/netcoreapp2.2/System.Data.Common.xml",
"ref/netcoreapp2.2/System.Data.dll",
"ref/netcoreapp2.2/System.Diagnostics.Contracts.dll",
"ref/netcoreapp2.2/System.Diagnostics.Contracts.xml",
"ref/netcoreapp2.2/System.Diagnostics.Debug.dll",
"ref/netcoreapp2.2/System.Diagnostics.Debug.xml",
"ref/netcoreapp2.2/System.Diagnostics.DiagnosticSource.dll",
"ref/netcoreapp2.2/System.Diagnostics.DiagnosticSource.xml",
"ref/netcoreapp2.2/System.Diagnostics.FileVersionInfo.dll",
"ref/netcoreapp2.2/System.Diagnostics.FileVersionInfo.xml",
"ref/netcoreapp2.2/System.Diagnostics.Process.dll",
"ref/netcoreapp2.2/System.Diagnostics.Process.xml",
"ref/netcoreapp2.2/System.Diagnostics.StackTrace.dll",
"ref/netcoreapp2.2/System.Diagnostics.StackTrace.xml",
"ref/netcoreapp2.2/System.Diagnostics.TextWriterTraceListener.dll",
"ref/netcoreapp2.2/System.Diagnostics.TextWriterTraceListener.xml",
"ref/netcoreapp2.2/System.Diagnostics.Tools.dll",
"ref/netcoreapp2.2/System.Diagnostics.Tools.xml",
"ref/netcoreapp2.2/System.Diagnostics.TraceSource.dll",
"ref/netcoreapp2.2/System.Diagnostics.TraceSource.xml",
"ref/netcoreapp2.2/System.Diagnostics.Tracing.dll",
"ref/netcoreapp2.2/System.Diagnostics.Tracing.xml",
"ref/netcoreapp2.2/System.Drawing.Primitives.dll",
"ref/netcoreapp2.2/System.Drawing.Primitives.xml",
"ref/netcoreapp2.2/System.Drawing.dll",
"ref/netcoreapp2.2/System.Dynamic.Runtime.dll",
"ref/netcoreapp2.2/System.Globalization.Calendars.dll",
"ref/netcoreapp2.2/System.Globalization.Extensions.dll",
"ref/netcoreapp2.2/System.Globalization.dll",
"ref/netcoreapp2.2/System.IO.Compression.Brotli.dll",
"ref/netcoreapp2.2/System.IO.Compression.FileSystem.dll",
"ref/netcoreapp2.2/System.IO.Compression.ZipFile.dll",
"ref/netcoreapp2.2/System.IO.Compression.ZipFile.xml",
"ref/netcoreapp2.2/System.IO.Compression.dll",
"ref/netcoreapp2.2/System.IO.Compression.xml",
"ref/netcoreapp2.2/System.IO.FileSystem.DriveInfo.dll",
"ref/netcoreapp2.2/System.IO.FileSystem.DriveInfo.xml",
"ref/netcoreapp2.2/System.IO.FileSystem.Primitives.dll",
"ref/netcoreapp2.2/System.IO.FileSystem.Watcher.dll",
"ref/netcoreapp2.2/System.IO.FileSystem.Watcher.xml",
"ref/netcoreapp2.2/System.IO.FileSystem.dll",
"ref/netcoreapp2.2/System.IO.FileSystem.xml",
"ref/netcoreapp2.2/System.IO.IsolatedStorage.dll",
"ref/netcoreapp2.2/System.IO.IsolatedStorage.xml",
"ref/netcoreapp2.2/System.IO.MemoryMappedFiles.dll",
"ref/netcoreapp2.2/System.IO.MemoryMappedFiles.xml",
"ref/netcoreapp2.2/System.IO.Pipes.dll",
"ref/netcoreapp2.2/System.IO.Pipes.xml",
"ref/netcoreapp2.2/System.IO.UnmanagedMemoryStream.dll",
"ref/netcoreapp2.2/System.IO.dll",
"ref/netcoreapp2.2/System.Linq.Expressions.dll",
"ref/netcoreapp2.2/System.Linq.Expressions.xml",
"ref/netcoreapp2.2/System.Linq.Parallel.dll",
"ref/netcoreapp2.2/System.Linq.Parallel.xml",
"ref/netcoreapp2.2/System.Linq.Queryable.dll",
"ref/netcoreapp2.2/System.Linq.Queryable.xml",
"ref/netcoreapp2.2/System.Linq.dll",
"ref/netcoreapp2.2/System.Linq.xml",
"ref/netcoreapp2.2/System.Memory.dll",
"ref/netcoreapp2.2/System.Memory.xml",
"ref/netcoreapp2.2/System.Net.Http.dll",
"ref/netcoreapp2.2/System.Net.Http.xml",
"ref/netcoreapp2.2/System.Net.HttpListener.dll",
"ref/netcoreapp2.2/System.Net.HttpListener.xml",
"ref/netcoreapp2.2/System.Net.Mail.dll",
"ref/netcoreapp2.2/System.Net.Mail.xml",
"ref/netcoreapp2.2/System.Net.NameResolution.dll",
"ref/netcoreapp2.2/System.Net.NameResolution.xml",
"ref/netcoreapp2.2/System.Net.NetworkInformation.dll",
"ref/netcoreapp2.2/System.Net.NetworkInformation.xml",
"ref/netcoreapp2.2/System.Net.Ping.dll",
"ref/netcoreapp2.2/System.Net.Ping.xml",
"ref/netcoreapp2.2/System.Net.Primitives.dll",
"ref/netcoreapp2.2/System.Net.Primitives.xml",
"ref/netcoreapp2.2/System.Net.Requests.dll",
"ref/netcoreapp2.2/System.Net.Requests.xml",
"ref/netcoreapp2.2/System.Net.Security.dll",
"ref/netcoreapp2.2/System.Net.Security.xml",
"ref/netcoreapp2.2/System.Net.ServicePoint.dll",
"ref/netcoreapp2.2/System.Net.ServicePoint.xml",
"ref/netcoreapp2.2/System.Net.Sockets.dll",
"ref/netcoreapp2.2/System.Net.Sockets.xml",
"ref/netcoreapp2.2/System.Net.WebClient.dll",
"ref/netcoreapp2.2/System.Net.WebClient.xml",
"ref/netcoreapp2.2/System.Net.WebHeaderCollection.dll",
"ref/netcoreapp2.2/System.Net.WebHeaderCollection.xml",
"ref/netcoreapp2.2/System.Net.WebProxy.dll",
"ref/netcoreapp2.2/System.Net.WebProxy.xml",
"ref/netcoreapp2.2/System.Net.WebSockets.Client.dll",
"ref/netcoreapp2.2/System.Net.WebSockets.Client.xml",
"ref/netcoreapp2.2/System.Net.WebSockets.dll",
"ref/netcoreapp2.2/System.Net.WebSockets.xml",
"ref/netcoreapp2.2/System.Net.dll",
"ref/netcoreapp2.2/System.Numerics.Vectors.dll",
"ref/netcoreapp2.2/System.Numerics.Vectors.xml",
"ref/netcoreapp2.2/System.Numerics.dll",
"ref/netcoreapp2.2/System.ObjectModel.dll",
"ref/netcoreapp2.2/System.ObjectModel.xml",
"ref/netcoreapp2.2/System.Reflection.DispatchProxy.dll",
"ref/netcoreapp2.2/System.Reflection.DispatchProxy.xml",
"ref/netcoreapp2.2/System.Reflection.Emit.ILGeneration.dll",
"ref/netcoreapp2.2/System.Reflection.Emit.ILGeneration.xml",
"ref/netcoreapp2.2/System.Reflection.Emit.Lightweight.dll",
"ref/netcoreapp2.2/System.Reflection.Emit.Lightweight.xml",
"ref/netcoreapp2.2/System.Reflection.Emit.dll",
"ref/netcoreapp2.2/System.Reflection.Emit.xml",
"ref/netcoreapp2.2/System.Reflection.Extensions.dll",
"ref/netcoreapp2.2/System.Reflection.Metadata.dll",
"ref/netcoreapp2.2/System.Reflection.Metadata.xml",
"ref/netcoreapp2.2/System.Reflection.Primitives.dll",
"ref/netcoreapp2.2/System.Reflection.Primitives.xml",
"ref/netcoreapp2.2/System.Reflection.TypeExtensions.dll",
"ref/netcoreapp2.2/System.Reflection.TypeExtensions.xml",
"ref/netcoreapp2.2/System.Reflection.dll",
"ref/netcoreapp2.2/System.Resources.Reader.dll",
"ref/netcoreapp2.2/System.Resources.ResourceManager.dll",
"ref/netcoreapp2.2/System.Resources.ResourceManager.xml",
"ref/netcoreapp2.2/System.Resources.Writer.dll",
"ref/netcoreapp2.2/System.Resources.Writer.xml",
"ref/netcoreapp2.2/System.Runtime.CompilerServices.VisualC.dll",
"ref/netcoreapp2.2/System.Runtime.CompilerServices.VisualC.xml",
"ref/netcoreapp2.2/System.Runtime.Extensions.dll",
"ref/netcoreapp2.2/System.Runtime.Extensions.xml",
"ref/netcoreapp2.2/System.Runtime.Handles.dll",
"ref/netcoreapp2.2/System.Runtime.InteropServices.RuntimeInformation.dll",
"ref/netcoreapp2.2/System.Runtime.InteropServices.RuntimeInformation.xml",
"ref/netcoreapp2.2/System.Runtime.InteropServices.WindowsRuntime.dll",
"ref/netcoreapp2.2/System.Runtime.InteropServices.WindowsRuntime.xml",
"ref/netcoreapp2.2/System.Runtime.InteropServices.dll",
"ref/netcoreapp2.2/System.Runtime.InteropServices.xml",
"ref/netcoreapp2.2/System.Runtime.Loader.dll",
"ref/netcoreapp2.2/System.Runtime.Loader.xml",
"ref/netcoreapp2.2/System.Runtime.Numerics.dll",
"ref/netcoreapp2.2/System.Runtime.Numerics.xml",
"ref/netcoreapp2.2/System.Runtime.Serialization.Formatters.dll",
"ref/netcoreapp2.2/System.Runtime.Serialization.Formatters.xml",
"ref/netcoreapp2.2/System.Runtime.Serialization.Json.dll",
"ref/netcoreapp2.2/System.Runtime.Serialization.Json.xml",
"ref/netcoreapp2.2/System.Runtime.Serialization.Primitives.dll",
"ref/netcoreapp2.2/System.Runtime.Serialization.Primitives.xml",
"ref/netcoreapp2.2/System.Runtime.Serialization.Xml.dll",
"ref/netcoreapp2.2/System.Runtime.Serialization.Xml.xml",
"ref/netcoreapp2.2/System.Runtime.Serialization.dll",
"ref/netcoreapp2.2/System.Runtime.dll",
"ref/netcoreapp2.2/System.Runtime.xml",
"ref/netcoreapp2.2/System.Security.Claims.dll",
"ref/netcoreapp2.2/System.Security.Claims.xml",
"ref/netcoreapp2.2/System.Security.Cryptography.Algorithms.dll",
"ref/netcoreapp2.2/System.Security.Cryptography.Algorithms.xml",
"ref/netcoreapp2.2/System.Security.Cryptography.Csp.dll",
"ref/netcoreapp2.2/System.Security.Cryptography.Csp.xml",
"ref/netcoreapp2.2/System.Security.Cryptography.Encoding.dll",
"ref/netcoreapp2.2/System.Security.Cryptography.Encoding.xml",
"ref/netcoreapp2.2/System.Security.Cryptography.Primitives.dll",
"ref/netcoreapp2.2/System.Security.Cryptography.Primitives.xml",
"ref/netcoreapp2.2/System.Security.Cryptography.X509Certificates.dll",
"ref/netcoreapp2.2/System.Security.Cryptography.X509Certificates.xml",
"ref/netcoreapp2.2/System.Security.Principal.dll",
"ref/netcoreapp2.2/System.Security.Principal.xml",
"ref/netcoreapp2.2/System.Security.SecureString.dll",
"ref/netcoreapp2.2/System.Security.dll",
"ref/netcoreapp2.2/System.ServiceModel.Web.dll",
"ref/netcoreapp2.2/System.ServiceProcess.dll",
"ref/netcoreapp2.2/System.Text.Encoding.Extensions.dll",
"ref/netcoreapp2.2/System.Text.Encoding.Extensions.xml",
"ref/netcoreapp2.2/System.Text.Encoding.dll",
"ref/netcoreapp2.2/System.Text.RegularExpressions.dll",
"ref/netcoreapp2.2/System.Text.RegularExpressions.xml",
"ref/netcoreapp2.2/System.Threading.Overlapped.dll",
"ref/netcoreapp2.2/System.Threading.Overlapped.xml",
"ref/netcoreapp2.2/System.Threading.Tasks.Dataflow.dll",
"ref/netcoreapp2.2/System.Threading.Tasks.Dataflow.xml",
"ref/netcoreapp2.2/System.Threading.Tasks.Extensions.dll",
"ref/netcoreapp2.2/System.Threading.Tasks.Extensions.xml",
"ref/netcoreapp2.2/System.Threading.Tasks.Parallel.dll",
"ref/netcoreapp2.2/System.Threading.Tasks.Parallel.xml",
"ref/netcoreapp2.2/System.Threading.Tasks.dll",
"ref/netcoreapp2.2/System.Threading.Tasks.xml",
"ref/netcoreapp2.2/System.Threading.Thread.dll",
"ref/netcoreapp2.2/System.Threading.Thread.xml",
"ref/netcoreapp2.2/System.Threading.ThreadPool.dll",
"ref/netcoreapp2.2/System.Threading.ThreadPool.xml",
"ref/netcoreapp2.2/System.Threading.Timer.dll",
"ref/netcoreapp2.2/System.Threading.Timer.xml",
"ref/netcoreapp2.2/System.Threading.dll",
"ref/netcoreapp2.2/System.Threading.xml",
"ref/netcoreapp2.2/System.Transactions.Local.dll",
"ref/netcoreapp2.2/System.Transactions.Local.xml",
"ref/netcoreapp2.2/System.Transactions.dll",
"ref/netcoreapp2.2/System.ValueTuple.dll",
"ref/netcoreapp2.2/System.Web.HttpUtility.dll",
"ref/netcoreapp2.2/System.Web.HttpUtility.xml",
"ref/netcoreapp2.2/System.Web.dll",
"ref/netcoreapp2.2/System.Windows.dll",
"ref/netcoreapp2.2/System.Xml.Linq.dll",
"ref/netcoreapp2.2/System.Xml.ReaderWriter.dll",
"ref/netcoreapp2.2/System.Xml.ReaderWriter.xml",
"ref/netcoreapp2.2/System.Xml.Serialization.dll",
"ref/netcoreapp2.2/System.Xml.XDocument.dll",
"ref/netcoreapp2.2/System.Xml.XDocument.xml",
"ref/netcoreapp2.2/System.Xml.XPath.XDocument.dll",
"ref/netcoreapp2.2/System.Xml.XPath.XDocument.xml",
"ref/netcoreapp2.2/System.Xml.XPath.dll",
"ref/netcoreapp2.2/System.Xml.XPath.xml",
"ref/netcoreapp2.2/System.Xml.XmlDocument.dll",
"ref/netcoreapp2.2/System.Xml.XmlSerializer.dll",
"ref/netcoreapp2.2/System.Xml.XmlSerializer.xml",
"ref/netcoreapp2.2/System.Xml.dll",
"ref/netcoreapp2.2/System.dll",
"ref/netcoreapp2.2/WindowsBase.dll",
"ref/netcoreapp2.2/mscorlib.dll",
"ref/netcoreapp2.2/netstandard.dll",
"runtime.json"
]
},
"Microsoft.NETCore.DotNetAppHost/2.2.0": {
"sha512": "DrhaKInRKKvN6Ns2VNIlC7ZffLOp9THf8cO6X4fytPRJovJUbF49/zzx4WfgX9E44FMsw9hT8hrKiIqDSHvGvA==",
"type": "package",
"path": "microsoft.netcore.dotnetapphost/2.2.0",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"microsoft.netcore.dotnetapphost.2.2.0.nupkg.sha512",
"microsoft.netcore.dotnetapphost.nuspec",
"runtime.json"
]
},
"Microsoft.NETCore.DotNetHostPolicy/2.2.0": {
"sha512": "FJie7IoPZFaPgNDxhZGmDBQP/Bs5vPdfca/G2Wf9gd6LIvMYkZcibtmJwB4tcf4KXkaOYfIOo4Cl9sEPMsSzkw==",
"type": "package",
"path": "microsoft.netcore.dotnethostpolicy/2.2.0",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"microsoft.netcore.dotnethostpolicy.2.2.0.nupkg.sha512",
"microsoft.netcore.dotnethostpolicy.nuspec",
"runtime.json"
]
},
"Microsoft.NETCore.DotNetHostResolver/2.2.0": {
"sha512": "spDm3AJYmebthDNhzY17YLPtvbc+Y1lCLVeiIH1uLJ/hZaM+40pBiPefFR8J1u66Ndkqi8ipR2tEbqPnYnjRhw==",
"type": "package",
"path": "microsoft.netcore.dotnethostresolver/2.2.0",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"microsoft.netcore.dotnethostresolver.2.2.0.nupkg.sha512",
"microsoft.netcore.dotnethostresolver.nuspec",
"runtime.json"
]
},
"Microsoft.NETCore.Platforms/2.2.0": {
"sha512": "T/J+XZo+YheFTJh8/4uoeJDdz5qOmOMkjg6/VL8mHJ9AnP8+fmV/kcbxeXsob0irRNiChf+V0ig1MCRLp/+Kog==",
"type": "package",
"path": "microsoft.netcore.platforms/2.2.0",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"lib/netstandard1.0/_._",
"microsoft.netcore.platforms.2.2.0.nupkg.sha512",
"microsoft.netcore.platforms.nuspec",
"runtime.json",
"useSharedDesignerContext.txt",
"version.txt"
]
},
"Microsoft.NETCore.Targets/2.0.0": {
"sha512": "odP/tJj1z6GylFpNo7pMtbd/xQgTC3Ex2If63dRTL38bBNMwsBnJ+RceUIyHdRBC0oik/3NehYT+oECwBhIM3Q==",
"type": "package",
"path": "microsoft.netcore.targets/2.0.0",
"files": [
".nupkg.metadata",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"lib/netstandard1.0/_._",
"microsoft.netcore.targets.2.0.0.nupkg.sha512",
"microsoft.netcore.targets.nuspec",
"runtime.json",
"useSharedDesignerContext.txt",
"version.txt"
]
},
"NETStandard.Library/2.0.3": {
"sha512": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
"type": "package",
"path": "netstandard.library/2.0.3",
"files": [
".nupkg.metadata",
"LICENSE.TXT",
"THIRD-PARTY-NOTICES.TXT",
"build/netstandard2.0/NETStandard.Library.targets",
"build/netstandard2.0/ref/Microsoft.Win32.Primitives.dll",
"build/netstandard2.0/ref/System.AppContext.dll",
"build/netstandard2.0/ref/System.Collections.Concurrent.dll",
"build/netstandard2.0/ref/System.Collections.NonGeneric.dll",
"build/netstandard2.0/ref/System.Collections.Specialized.dll",
"build/netstandard2.0/ref/System.Collections.dll",
"build/netstandard2.0/ref/System.ComponentModel.Composition.dll",
"build/netstandard2.0/ref/System.ComponentModel.EventBasedAsync.dll",
"build/netstandard2.0/ref/System.ComponentModel.Primitives.dll",
"build/netstandard2.0/ref/System.ComponentModel.TypeConverter.dll",
"build/netstandard2.0/ref/System.ComponentModel.dll",
"build/netstandard2.0/ref/System.Console.dll",
"build/netstandard2.0/ref/System.Core.dll",
"build/netstandard2.0/ref/System.Data.Common.dll",
"build/netstandard2.0/ref/System.Data.dll",
"build/netstandard2.0/ref/System.Diagnostics.Contracts.dll",
"build/netstandard2.0/ref/System.Diagnostics.Debug.dll",
"build/netstandard2.0/ref/System.Diagnostics.FileVersionInfo.dll",
"build/netstandard2.0/ref/System.Diagnostics.Process.dll",
"build/netstandard2.0/ref/System.Diagnostics.StackTrace.dll",
"build/netstandard2.0/ref/System.Diagnostics.TextWriterTraceListener.dll",
"build/netstandard2.0/ref/System.Diagnostics.Tools.dll",
"build/netstandard2.0/ref/System.Diagnostics.TraceSource.dll",
"build/netstandard2.0/ref/System.Diagnostics.Tracing.dll",
"build/netstandard2.0/ref/System.Drawing.Primitives.dll",
"build/netstandard2.0/ref/System.Drawing.dll",
"build/netstandard2.0/ref/System.Dynamic.Runtime.dll",
"build/netstandard2.0/ref/System.Globalization.Calendars.dll",
"build/netstandard2.0/ref/System.Globalization.Extensions.dll",
"build/netstandard2.0/ref/System.Globalization.dll",
"build/netstandard2.0/ref/System.IO.Compression.FileSystem.dll",
"build/netstandard2.0/ref/System.IO.Compression.ZipFile.dll",
"build/netstandard2.0/ref/System.IO.Compression.dll",
"build/netstandard2.0/ref/System.IO.FileSystem.DriveInfo.dll",
"build/netstandard2.0/ref/System.IO.FileSystem.Primitives.dll",
"build/netstandard2.0/ref/System.IO.FileSystem.Watcher.dll",
"build/netstandard2.0/ref/System.IO.FileSystem.dll",
"build/netstandard2.0/ref/System.IO.IsolatedStorage.dll",
"build/netstandard2.0/ref/System.IO.MemoryMappedFiles.dll",
"build/netstandard2.0/ref/System.IO.Pipes.dll",
"build/netstandard2.0/ref/System.IO.UnmanagedMemoryStream.dll",
"build/netstandard2.0/ref/System.IO.dll",
"build/netstandard2.0/ref/System.Linq.Expressions.dll",
"build/netstandard2.0/ref/System.Linq.Parallel.dll",
"build/netstandard2.0/ref/System.Linq.Queryable.dll",
"build/netstandard2.0/ref/System.Linq.dll",
"build/netstandard2.0/ref/System.Net.Http.dll",
"build/netstandard2.0/ref/System.Net.NameResolution.dll",
"build/netstandard2.0/ref/System.Net.NetworkInformation.dll",
"build/netstandard2.0/ref/System.Net.Ping.dll",
"build/netstandard2.0/ref/System.Net.Primitives.dll",
"build/netstandard2.0/ref/System.Net.Requests.dll",
"build/netstandard2.0/ref/System.Net.Security.dll",
"build/netstandard2.0/ref/System.Net.Sockets.dll",
"build/netstandard2.0/ref/System.Net.WebHeaderCollection.dll",
"build/netstandard2.0/ref/System.Net.WebSockets.Client.dll",
"build/netstandard2.0/ref/System.Net.WebSockets.dll",
"build/netstandard2.0/ref/System.Net.dll",
"build/netstandard2.0/ref/System.Numerics.dll",
"build/netstandard2.0/ref/System.ObjectModel.dll",
"build/netstandard2.0/ref/System.Reflection.Extensions.dll",
"build/netstandard2.0/ref/System.Reflection.Primitives.dll",
"build/netstandard2.0/ref/System.Reflection.dll",
"build/netstandard2.0/ref/System.Resources.Reader.dll",
"build/netstandard2.0/ref/System.Resources.ResourceManager.dll",
"build/netstandard2.0/ref/System.Resources.Writer.dll",
"build/netstandard2.0/ref/System.Runtime.CompilerServices.VisualC.dll",
"build/netstandard2.0/ref/System.Runtime.Extensions.dll",
"build/netstandard2.0/ref/System.Runtime.Handles.dll",
"build/netstandard2.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll",
"build/netstandard2.0/ref/System.Runtime.InteropServices.dll",
"build/netstandard2.0/ref/System.Runtime.Numerics.dll",
"build/netstandard2.0/ref/System.Runtime.Serialization.Formatters.dll",
"build/netstandard2.0/ref/System.Runtime.Serialization.Json.dll",
"build/netstandard2.0/ref/System.Runtime.Serialization.Primitives.dll",
"build/netstandard2.0/ref/System.Runtime.Serialization.Xml.dll",
"build/netstandard2.0/ref/System.Runtime.Serialization.dll",
"build/netstandard2.0/ref/System.Runtime.dll",
"build/netstandard2.0/ref/System.Security.Claims.dll",
"build/netstandard2.0/ref/System.Security.Cryptography.Algorithms.dll",
"build/netstandard2.0/ref/System.Security.Cryptography.Csp.dll",
"build/netstandard2.0/ref/System.Security.Cryptography.Encoding.dll",
"build/netstandard2.0/ref/System.Security.Cryptography.Primitives.dll",
"build/netstandard2.0/ref/System.Security.Cryptography.X509Certificates.dll",
"build/netstandard2.0/ref/System.Security.Principal.dll",
"build/netstandard2.0/ref/System.Security.SecureString.dll",
"build/netstandard2.0/ref/System.ServiceModel.Web.dll",
"build/netstandard2.0/ref/System.Text.Encoding.Extensions.dll",
"build/netstandard2.0/ref/System.Text.Encoding.dll",
"build/netstandard2.0/ref/System.Text.RegularExpressions.dll",
"build/netstandard2.0/ref/System.Threading.Overlapped.dll",
"build/netstandard2.0/ref/System.Threading.Tasks.Parallel.dll",
"build/netstandard2.0/ref/System.Threading.Tasks.dll",
"build/netstandard2.0/ref/System.Threading.Thread.dll",
"build/netstandard2.0/ref/System.Threading.ThreadPool.dll",
"build/netstandard2.0/ref/System.Threading.Timer.dll",
"build/netstandard2.0/ref/System.Threading.dll",
"build/netstandard2.0/ref/System.Transactions.dll",
"build/netstandard2.0/ref/System.ValueTuple.dll",
"build/netstandard2.0/ref/System.Web.dll",
"build/netstandard2.0/ref/System.Windows.dll",
"build/netstandard2.0/ref/System.Xml.Linq.dll",
"build/netstandard2.0/ref/System.Xml.ReaderWriter.dll",
"build/netstandard2.0/ref/System.Xml.Serialization.dll",
"build/netstandard2.0/ref/System.Xml.XDocument.dll",
"build/netstandard2.0/ref/System.Xml.XPath.XDocument.dll",
"build/netstandard2.0/ref/System.Xml.XPath.dll",
"build/netstandard2.0/ref/System.Xml.XmlDocument.dll",
"build/netstandard2.0/ref/System.Xml.XmlSerializer.dll",
"build/netstandard2.0/ref/System.Xml.dll",
"build/netstandard2.0/ref/System.dll",
"build/netstandard2.0/ref/mscorlib.dll",
"build/netstandard2.0/ref/netstandard.dll",
"build/netstandard2.0/ref/netstandard.xml",
"lib/netstandard1.0/_._",
"netstandard.library.2.0.3.nupkg.sha512",
"netstandard.library.nuspec"
]
}
},
"projectFileDependencyGroups": {
".NETCoreApp,Version=v2.2": [
"Microsoft.NETCore.App >= 2.2.0"
]
},
"packageFolders": {
"/Users/ben/.nuget/packages/": {},
"/usr/local/share/dotnet/sdk/NuGetFallbackFolder": {}
},
"project": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/Users/ben/.vim/bundle/vimspector/support/test/csharp/csharp.csproj",
"projectName": "csharp",
"projectPath": "/Users/ben/.vim/bundle/vimspector/support/test/csharp/csharp.csproj",
"packagesPath": "/Users/ben/.nuget/packages/",
"outputPath": "/Users/ben/.vim/bundle/vimspector/support/test/csharp/obj/",
"projectStyle": "PackageReference",
"fallbackFolders": [
"/usr/local/share/dotnet/sdk/NuGetFallbackFolder"
],
"configFilePaths": [
"/Users/ben/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"netcoreapp2.2"
],
"sources": {
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"netcoreapp2.2": {
"projectReferences": {}
}
},
"warningProperties": {
"warnAsError": [
"NU1605"
]
}
},
"frameworks": {
"netcoreapp2.2": {
"dependencies": {
"Microsoft.NETCore.App": {
"suppressParent": "All",
"target": "Package",
"version": "[2.2.0, )",
"autoReferenced": true
}
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48"
],
"assetTargetFallback": true,
"warn": true,
"runtimeIdentifierGraphPath": "/usr/local/share/dotnet/sdk/3.1.402/RuntimeIdentifierGraph.json"
}
}
}
}

View file

@ -1,4 +1,18 @@
{ {
"adapters": {
"dlv-dap": {
"variables": {
"port": "${unusedLocalPort}"
},
"command": [
"$HOME/go/bin/dlv",
"dap",
"--listen",
"127.0.0.1:${port}"
],
"port": "${port}"
}
},
"configurations": { "configurations": {
"run": { "run": {
"adapter": "vscode-go", "adapter": "vscode-go",
@ -12,6 +26,21 @@
"env": { "GO111MODULE": "off" } "env": { "GO111MODULE": "off" }
} }
}, },
"run-dap": {
"adapter": "dlv-dap",
"configuration": {
"request": "launch",
"env": { "GO111MODULE": "off" },
"mode": "debug", // debug|test
"program": "${workspaceRoot}/hello-world.go"
// "args": [],
// "buildFlags": ...
// "stackTraceDepth": ...,
// "showGlobalVariables": true,
}
},
"run-exec": { "run-exec": {
// NOTE: To use this you _must_ disable optimistaion: // NOTE: To use this you _must_ disable optimistaion:
// go build -o hello_world -gcflags="all=-N -l" // go build -o hello_world -gcflags="all=-N -l"

View file

@ -0,0 +1,29 @@
{
"configurations": {
"run-cmd": {
"adapter": "vscode-go",
"configuration": {
"request": "launch",
"program": "${workspaceRoot}/cmd/namestartswithvowel/main.go",
"mode": "debug",
"dlvToolPath": "$HOME/go/bin/dlv",
"dlvLoadConfig": {
"maxArrayValues": 1000,
"maxStringLen": 1000
}
}
},
"test-current-file": {
"adapter": "vscode-go",
"configuration": {
"request": "launch",
"mode": "test",
"program": "${fileDirname}",
"cwd": "${fileDirname}",
"dlvToolPath": "$GOPATH/bin/dlv",
"env": {},
"args": []
}
}
}
}

View file

@ -0,0 +1,33 @@
# Purpose
This example comes with two example vimspector configs for the Go programming language.
1) `run-cmd` will launch the main programme under `cmd/namestartswithvowel`.
1) `test-current-file` will run the tests in the current file in debug mode.
## Example use-cases
### run-cmd
* Open `cmd/namestartswithvowel/main.go`
* Add a breakpoint somewhere within the programme
* Start the debugger (`:call vimspector#Continue()` or your relevant keymapping)
* Select the first launch configuration (`1: run-cmd`)
### test-current-file
* Open `internal/vowels/vowels_test.go`
* Add a breakpoint somewhere within the test
* Start the debugger (`:call vimspector#Continue()` or your relevant keymapping)
* Select the second launch configuration (`2: test-current-file`)
## Additional Configuration
There are two additional configuration options specified under `run-cmd`; these parameters configure the maximum string/array size to be shown while debugging.
```
"dlvLoadConfig": {
"maxArrayValues": 1000,
"maxStringLen": 1000
}
```

View file

@ -0,0 +1,20 @@
package main
import (
"fmt"
"example.com/internal/vowels"
)
func main() {
names := []string{"Simon", "Bob", "Jennifer", "Amy", "Duke", "Elizabeth"}
for _, n := range names {
if vowels.NameStartsWithVowel(n) {
fmt.Printf("%s starts with a vowel!\n", n)
continue
}
fmt.Printf("%s does not start with a vowel!\n", n)
}
}

View file

@ -0,0 +1,3 @@
module example.com
go 1.16

View file

@ -0,0 +1,9 @@
package vowels
import "strings"
func NameStartsWithVowel(name string) bool {
s := strings.Split(strings.ToLower(name), "")
return s[0] == "a" || s[0] == "e" || s[0] == "i" || s[0] == "o" || s[0] == "u"
}

View file

@ -0,0 +1,30 @@
package vowels
import (
"fmt"
"testing"
)
func TestNameStartsWithVowel(t *testing.T) {
testCases := []struct {
input string
expectedOutput bool
}{
{
input: "Simon",
expectedOutput: false,
},
{
input: "Andy",
expectedOutput: true,
},
}
for _, tt := range testCases {
t.Run(fmt.Sprintf("%s should product %t", tt.input, tt.expectedOutput), func(t *testing.T) {
out := NameStartsWithVowel(tt.input)
if out != tt.expectedOutput {
t.Errorf("%s produced %t, when %t was expected", tt.input, out, tt.expectedOutput)
}
})
}
}

View file

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

View file

@ -24,6 +24,24 @@
}, },
"delay": "5000m" "delay": "5000m"
} }
},
"python-remote-ssh": {
"variables": {
"port": "8765"
},
"port": "${port}",
"host": "${host}",
"launch": {
"remote": {
"host": "${host}",
"account": "${account}",
"runCommand": [
"python3", "-m", "debugpy", "--listen", "0.0.0.0:${port}",
"--wait-for-client",
"%CMD%"
]
}
}
} }
}, },
"configurations": { "configurations": {
@ -164,6 +182,23 @@
"stopOnEntry": false, "stopOnEntry": false,
"console": "integratedTerminal" "console": "integratedTerminal"
} }
},
"run - remote host": {
"adapter": "python-remote-ssh",
"remote-cmdLine": [
"${remoteRoot}/main.py"
],
"remote-request": "launch",
"configuration": {
"request": "attach",
"redirectOutput": true,
"pathMappings": [
{
"localRoot": "${workspaceRoot}",
"remoteRoot": "${remoteRoot}"
}
]
}
} }
} }
} }

View file

@ -70,6 +70,12 @@ RUN mkdir -p /home/linuxbrew/.linuxbrew &&\
RUN /home/linuxbrew/.linuxbrew/bin/brew install golang RUN /home/linuxbrew/.linuxbrew/bin/brew install golang
# dotnet
RUN curl -sSL https://dot.net/v1/dotnet-install.sh \
| bash /dev/stdin --channel LTS --install-dir /usr/share/dotnet && \
update-alternatives --install /usr/bin/dotnet dotnet \
/usr/share/dotnet/dotnet 1
# clean up # clean up
RUN /home/linuxbrew/.linuxbrew/bin/brew cleanup && \ RUN /home/linuxbrew/.linuxbrew/bin/brew cleanup && \
rm -rf ~/.cache && \ rm -rf ~/.cache && \

View file

@ -12,6 +12,7 @@ function Test_Get_Configurations()
let configs = vimspector#GetConfigurations() let configs = vimspector#GetConfigurations()
call assert_equal([ call assert_equal([
\ 'launch - netcoredbg', \ 'launch - netcoredbg',
\ 'launch - netcoredbg - with debug log',
\ 'launch - mono', \ 'launch - mono',
\ ], configs) \ ], configs)

View file

@ -0,0 +1,65 @@
function! SetUp()
call vimspector#test#setup#SetUpWithMappings( v:none )
endfunction
function! ClearDown()
call vimspector#test#setup#ClearDown()
endfunction
function! SetUp_Test_Go_Simple()
let g:vimspector_enable_mappings = 'HUMAN'
endfunction
function! Test_CSharp_Simple()
let fn='Program.cs'
lcd ../support/test/csharp
exe 'edit ' . fn
call vimspector#SetLineBreakpoint( fn, 31 )
call vimspector#LaunchWithSettings( {
\ 'configuration': 'launch - netcoredbg'
\ } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 31, 7 )
call WaitForAssert( {->
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 31 )
\ } )
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 32, 12 )
call WaitForAssert( {->
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 32 )
\ } )
call vimspector#test#setup#Reset()
lcd -
%bwipeout!
endfunction
function! Test_Run_To_Cursor()
let fn='Program.cs'
lcd ../support/test/csharp
exe 'edit ' . fn
call vimspector#SetLineBreakpoint( fn, 31 )
call vimspector#LaunchWithSettings( {
\ 'configuration': 'launch - netcoredbg'
\ } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 31, 7 )
call WaitForAssert( {->
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 31 )
\ } )
call cursor( 33, 1 )
call vimspector#RunToCursor()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 33, 1 )
call WaitForAssert( {->
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 33 )
\ } )
call vimspector#test#setup#Reset()
lcd -
%bwipeout!
endfunction

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

@ -99,7 +99,7 @@ function! ThisTestIsFlaky()
let g:test_is_flaky = v:true let g:test_is_flaky = v:true
endfunction endfunction
function! AssertMatchist( expected, actual ) abort function! AssertMatchList( expected, actual ) abort
let ret = assert_equal( len( a:expected ), len( a:actual ) ) let ret = assert_equal( len( a:expected ), len( a:actual ) )
let len = min( [ len( a:expected ), len( a:actual ) ] ) let len = min( [ len( a:expected ), len( a:actual ) ] )
let idx = 0 let idx = 0

View file

@ -114,6 +114,26 @@ function! Test_Use_Mappings_HUMAN()
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 9 ) \ vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 9 )
\ } ) \ } )
" Stop
call feedkeys( "\<F3>", 'xt' )
call WaitForAssert( {->
\ assert_equal( [],
\ getbufline( g:vimspector_session_windows.variables,
\ 1,
\ '$' ) )
\ } )
call WaitForAssert( {->
\ assert_equal( [],
\ getbufline( g:vimspector_session_windows.stack_trace,
\ 1,
\ '$' ) )
\ } )
call WaitForAssert( {->
\ assert_equal( [],
\ getbufline( g:vimspector_session_windows.watches,
\ 1,
\ '$' ) )
\ } )
call vimspector#test#setup#Reset() call vimspector#test#setup#Reset()

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

@ -30,7 +30,7 @@ function! Test_Multiple_Threads_Continue()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call cursor( 1, 1 ) call cursor( 1, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( thread_l ) \ ' .*: .*@threads.cpp:' . string( thread_l )
@ -45,7 +45,7 @@ function! Test_Multiple_Threads_Continue()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call cursor( 1, 1 ) call cursor( 1, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( thread_l ) \ ' .*: .*@threads.cpp:' . string( thread_l )
@ -56,7 +56,7 @@ function! Test_Multiple_Threads_Continue()
\ ) \ )
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -70,7 +70,7 @@ function! Test_Multiple_Threads_Continue()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call cursor( 1, 1 ) call cursor( 1, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( thread_l ) \ ' .*: .*@threads.cpp:' . string( thread_l )
@ -81,7 +81,7 @@ function! Test_Multiple_Threads_Continue()
\ ) \ )
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -95,7 +95,7 @@ function! Test_Multiple_Threads_Continue()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call cursor( 1, 1 ) call cursor( 1, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( thread_l ) \ ' .*: .*@threads.cpp:' . string( thread_l )
@ -106,7 +106,7 @@ function! Test_Multiple_Threads_Continue()
\ ) \ )
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -121,7 +121,7 @@ function! Test_Multiple_Threads_Continue()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call cursor( 1, 1 ) call cursor( 1, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( thread_l ) \ ' .*: .*@threads.cpp:' . string( thread_l )
@ -132,7 +132,7 @@ function! Test_Multiple_Threads_Continue()
\ ) \ )
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -146,7 +146,7 @@ function! Test_Multiple_Threads_Continue()
" So we break out of the loop " So we break out of the loop
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( notify_l ) \ ' .*: .*@threads.cpp:' . string( notify_l )
@ -157,7 +157,7 @@ function! Test_Multiple_Threads_Continue()
\ ) \ )
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -192,7 +192,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Thread [0-9]\+: .* (paused)', \ '- Thread [0-9]\+: .* (paused)',
\ ' .*: .*@threads.cpp:' . string( thread_l ) \ ' .*: .*@threads.cpp:' . string( thread_l )
@ -205,7 +205,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#StepOver() call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -218,7 +218,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ ], \ ],
@ -230,7 +230,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#StepOver() call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -244,7 +244,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -257,7 +257,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#StepOver() call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -273,7 +273,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -287,7 +287,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#StepOver() call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -304,7 +304,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -319,7 +319,7 @@ function! Test_Multiple_Threads_Step()
call vimspector#StepOver() call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -338,7 +338,7 @@ function! Test_Multiple_Threads_Step()
" So we break out of the loop " So we break out of the loop
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -352,6 +352,209 @@ function! Test_Multiple_Threads_Step()
\ ) \ )
\ } ) \ } )
call vimspector#ClearBreakpoints()
call vimspector#test#setup#Reset()
%bwipe!
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( {->
\ AssertMatchList(
\ [
\ '- 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 win_gotoid( g:vimspector_session_windows.stack_trace )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 1,
\ 'vimspectorCurrentThread',
\ 200 ) } )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 2,
\ 'vimspectorCurrentFrame',
\ 200 ) } )
wincmd w
call vimspector#DownFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- 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 win_gotoid( g:vimspector_session_windows.stack_trace )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 1,
\ 'vimspectorCurrentThread',
\ 200 ) } )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 2,
\ 'vimspectorCurrentFrame',
\ 200 ) } )
wincmd w
call vimspector#UpFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- 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 win_gotoid( g:vimspector_session_windows.stack_trace )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 1,
\ 'vimspectorCurrentThread',
\ 200 ) } )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 3,
\ 'vimspectorCurrentFrame',
\ 200 ) } )
wincmd w
call feedkeys( "\<Plug>VimspectorUpFrame", 'x' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 23, 1 )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- 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 win_gotoid( g:vimspector_session_windows.stack_trace )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 1,
\ 'vimspectorCurrentThread',
\ 200 ) } )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 4,
\ 'vimspectorCurrentFrame',
\ 200 ) } )
wincmd w
call feedkeys( "\<Plug>VimspectorDownFrame", 'x' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- 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 win_gotoid( g:vimspector_session_windows.stack_trace )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 1,
\ 'vimspectorCurrentThread',
\ 200 ) } )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 3,
\ 'vimspectorCurrentFrame',
\ 200 ) } )
wincmd w
call vimspector#DownFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- 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 win_gotoid( g:vimspector_session_windows.stack_trace )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 1,
\ 'vimspectorCurrentThread',
\ 200 ) } )
call WaitForAssert( { ->
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
\ 'VimspectorStackTrace',
\ 2,
\ 'vimspectorCurrentFrame',
\ 200 ) } )
wincmd w
call vimspector#ClearBreakpoints() call vimspector#ClearBreakpoints()
call vimspector#test#setup#Reset() call vimspector#test#setup#Reset()
%bwipe! %bwipe!

View file

@ -12,7 +12,7 @@
"externalConsole": false, "externalConsole": false,
"stopAtEntry": true, "stopAtEntry": true,
"stopOnEntry": true, "stopOnEntry": true,
"MImode": "${VIMSPECTOR_MIMODE}" "MIMode": "${VIMSPECTOR_MIMODE}"
}, },
"breakpoints": { "breakpoints": {
"exception": { "exception": {
@ -33,7 +33,7 @@
"externalConsole": false, "externalConsole": false,
"stopAtEntry": false, "stopAtEntry": false,
"stopOnEntry": false, "stopOnEntry": false,
"MImode": "${VIMSPECTOR_MIMODE}" "MIMode": "${VIMSPECTOR_MIMODE}"
}, },
"breakpoints": { "breakpoints": {
"exception": { "exception": {
@ -55,7 +55,7 @@
"externalConsole": false, "externalConsole": false,
"stopAtEntry": false, "stopAtEntry": false,
"stopOnEntry": false, "stopOnEntry": false,
"MImode": "${VIMSPECTOR_MIMODE}" "MIMode": "${VIMSPECTOR_MIMODE}"
}, },
"breakpoints": { "breakpoints": {
"exception": { "exception": {
@ -82,7 +82,7 @@
"configuration": { "configuration": {
"request": "launch", "request": "launch",
"program": "${workspaceRoot}/${fileBasenameNoExtension}", "program": "${workspaceRoot}/${fileBasenameNoExtension}",
"MImode": "${VIMSPECTOR_MIMODE}", "MIMode": "${VIMSPECTOR_MIMODE}",
"externalConsole": false, "externalConsole": false,
"args": [ "args": [
"CALCULATED_LIST", "${CALCULATED_LIST}", "CALCULATED_LIST", "${CALCULATED_LIST}",

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()

View file

@ -194,6 +194,7 @@ function! Test_ExpandVariables()
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' *+ t (Test): {...}', \ ' *+ t (Test): {...}',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -211,7 +212,7 @@ function! Test_ExpandVariables()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' \*- t (Test): {...}', \ ' \*- t (Test): {...}',
@ -219,6 +220,7 @@ function! Test_ExpandVariables()
\ ' \*- c (char): 0 ''\\0\{1,3}''', \ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0', \ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?', \ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -229,7 +231,7 @@ function! Test_ExpandVariables()
" Step - stays expanded " Step - stays expanded
call vimspector#StepOver() call vimspector#StepOver()
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' - t (Test): {...}', \ ' - t (Test): {...}',
@ -237,6 +239,7 @@ function! Test_ExpandVariables()
\ ' - c (char): 0 ''\\0\{1,3}''', \ ' - c (char): 0 ''\\0\{1,3}''',
\ ' - fffff (float): 0', \ ' - fffff (float): 0',
\ ' + another_test (AnotherTest):\( {...}\)\?', \ ' + another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -253,6 +256,7 @@ function! Test_ExpandVariables()
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' + t (Test): {...}', \ ' + t (Test): {...}',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -267,6 +271,7 @@ function! Test_ExpandVariables()
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' + t (Test): {...}', \ ' + t (Test): {...}',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -278,7 +283,7 @@ function! Test_ExpandVariables()
call setpos( '.', [ 0, 2, 1 ] ) call setpos( '.', [ 0, 2, 1 ] )
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' - t (Test): {...}', \ ' - t (Test): {...}',
@ -286,6 +291,7 @@ function! Test_ExpandVariables()
\ ' \*- c (char): 99 ''c''', \ ' \*- c (char): 99 ''c''',
\ ' \*- fffff (float): 0', \ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?', \ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -302,6 +308,7 @@ function! Test_ExpandVariables()
\ assert_equal( \ assert_equal(
\ [ \ [
\ '+ Scope: Locals', \ '+ Scope: Locals',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -316,6 +323,7 @@ function! Test_ExpandVariables()
\ assert_equal( \ assert_equal(
\ [ \ [
\ '+ Scope: Locals', \ '+ Scope: Locals',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -331,6 +339,7 @@ function! Test_ExpandVariables()
\ assert_equal( \ assert_equal(
\ [ \ [
\ '+ Scope: Locals', \ '+ Scope: Locals',
\ '+ Scope: Registers',
\ ], \ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ), \ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1, \ 1,
@ -378,7 +387,7 @@ function! Test_ExpandWatch()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -397,7 +406,7 @@ function! Test_ExpandWatch()
" Step - stays expanded " Step - stays expanded
call vimspector#StepOver() call vimspector#StepOver()
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -449,7 +458,7 @@ function! Test_ExpandWatch()
call setpos( '.', [ 0, 3, 1 ] ) call setpos( '.', [ 0, 3, 1 ] )
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -513,6 +522,49 @@ function Test_EvaluateConsole()
endfunction endfunction
function Test_EvaluateInput()
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 vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 27, 1 )
VimspectorEval -exec print (int) printf("hello")
call assert_equal( bufnr( 'vimspector.Console' ),
\ winbufnr( g:vimspector_session_windows.output ) )
call WaitForAssert( {->
\ assert_equal(
\ [
\ ''
\ ],
\ getbufline( bufnr( 'vimspector.Console' ), '$', '$' )
\ )
\ } )
let len = getbufinfo( 'vimspector.Console' )[ 0 ].linecount
call WaitForAssert( {->
\ assert_equal(
\ [
\ 'Evaluating: -exec print (int) printf("hello")',
\ ],
\ getbufline( bufnr( 'vimspector.Console' ), len-2, len-2 )
\ )
\ } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer(
\ 'vimspector.Console', len, v:null )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function Test_EvaluatePromptConsole() function Test_EvaluatePromptConsole()
let fn = 'testdata/cpp/simple/struct.cpp' let fn = 'testdata/cpp/simple/struct.cpp'
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{ call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
@ -564,7 +616,7 @@ function! Test_EvaluateFailure()
" Add a wtch " Add a wtch
call vimspector#AddWatch( 'test' ) call vimspector#AddWatch( 'test' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: test', \ 'Expression: test',
@ -615,7 +667,7 @@ function! Test_VariableEval()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -647,7 +699,7 @@ function! Test_VariableEval()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -681,7 +733,7 @@ function! Test_VariableEval()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ 'Evaluation error', \ 'Evaluation error',
\ ], \ ],
@ -725,7 +777,7 @@ function! Test_VariableEvalExpand()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -743,7 +795,7 @@ function! Test_VariableEvalExpand()
call feedkeys( "jjjj\<CR>", 'xt' ) call feedkeys( "jjjj\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -763,7 +815,7 @@ function! Test_VariableEvalExpand()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchist( \ AssertMatchList(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -787,3 +839,297 @@ function! Test_VariableEvalExpand()
call vimspector#test#setup#Reset() call vimspector#test#setup#Reset()
%bwipe! %bwipe!
endfunction endfunction
function! Test_SetVariableValue_Local()
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): {...}',
\ '+ Scope: Registers',
\ ],
\ 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( {->
\ AssertMatchList(
\ [
\ '- Scope: Locals',
\ ' \*- t (Test): {...}',
\ ' \*- i (int): 0',
\ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1,
\ '$' )
\ )
\ } )
call setpos( '.', [ 0, 3, 1 ] )
" We can't just fire the keys to the inpit prompt because we use inputsave()
" and inputrestore(), so mock that out and fire away.
py3 <<EOF
from unittest import mock
with mock.patch( 'vimspector.utils.InputSave' ):
vim.eval( 'feedkeys( "\<C-CR>\<C-u>100\<CR>", "xt" )' )
EOF
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- Scope: Locals',
\ ' \*- t (Test): {...}',
\ ' \*- i (int): 100',
\ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1,
\ '$' )
\ )
\ } )
" Now set it via the more comforable scripting interface
call vimspector#SetVariableValue( '1234' )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- Scope: Locals',
\ ' \*- t (Test): {...}',
\ ' \*- i (int): 1234',
\ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1,
\ '$' )
\ )
\ } )
" Something fails
call vimspector#SetVariableValue( 'this is invalid' )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '- Scope: Locals',
\ ' \*- t (Test): {...}',
\ ' \*- i (int): 1234',
\ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ '+ Scope: Registers',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! Test_SetVariableValue_Watch()
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( {->
\ AssertMatchList(
\ [
\ '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,
\ '$' )
\ )
\ } )
call setpos( '.', [ 0, 4, 1 ] )
" We can't just fire the keys to the inpit prompt because we use inputsave()
" and inputrestore(), so mock that out and fire away.
" Note: mapleder is ,
py3 <<EOF
from unittest import mock
with mock.patch( 'vimspector.utils.InputSave' ):
vim.eval( 'feedkeys( ",\<CR>\<C-u>100\<CR>", "xt" )' )
EOF
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ 'Watches: ----',
\ 'Expression: t',
\ ' \*- Result: {...}',
\ ' \*- i (int): 100',
\ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
\ 1,
\ '$' )
\ )
\ } )
" Now set it via the more comforable scripting interface
call vimspector#SetVariableValue( '1234' )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ 'Watches: ----',
\ 'Expression: t',
\ ' \*- Result: {...}',
\ ' \*- i (int): 1234',
\ ' \*- c (char): 0 ''\\0\{1,3}''',
\ ' \*- fffff (float): 0',
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#test#setup#Reset()
%bwipe!
endfunction
function! Test_SetVariableValue_Balloon()
let fn = 'testdata/cpp/simple/struct.cpp'
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
\ configuration: 'run-to-breakpoint'
\ } } )
call vimspector#StepOver()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
" leader is ,
xmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
nmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
"evaluate the prev line
call setpos( '.', [ 0, 24, 8 ] )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 24, 8 )
call feedkeys( ',d', 'xt' )
call WaitForAssert( {->
\ assert_notequal( v:none, g:vimspector_session_windows.eval )
\ } )
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '{...}',
\ ' - i: 0',
\ ' - c: 0 ''\\0\{1,3}''',
\ ' - fffff: 0',
\ ' + another_test: ',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
\ 1,
\ '$' )
\ )
\ } )
" Move down to the ffff line
call feedkeys( 'jjj', 'xt' )
" We can't just fire the keys to the inpit prompt because we use inputsave()
" and inputrestore(), so mock that out and fire away.
" Note: mapleder is ,
py3 <<EOF
from unittest import mock
with mock.patch( 'vimspector.utils.InputSave' ):
vim.eval( 'feedkeys( "\<C-CR>\<C-u>100\<CR>", "xt" )' )
EOF
call WaitForAssert( {->
\ AssertMatchList(
\ [
\ '{...}',
\ ' - i: 0',
\ ' - c: 0 ''\\0\{1,3}''',
\ ' - fffff: 100',
\ ' + another_test: ',
\ ],
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
\ 1,
\ '$' )
\ )
\ } )
call vimspector#test#setup#Reset()
%bwipe!
endfunction