Compare commits

..

4 commits

Author SHA1 Message Date
Ben Jackson
2f05a7f66a WIP: Make multi-session debugging sort of work
This passes the session id around everywhere and ensures that things
like buffer names are all unique.

We now have the _vimspector_session update to point to the active (or
last accessed tab). This feels fairly natural and mostly seems to work.

NOTE: in vscode there is no "multiple tabs" - they actually add the
subprocesses to the stack trace somehow and when you click on a frame in
that it switches to the session for that process. Each process PC is
visible in the editor. It's kind of confusing.

Things still broken:
 - vimspector_session_windows
 - breakpoints need to be project-wide
 - PC display (how to show "all" PCs, or just show the current one for
   the current tab ?)
 - it would be nice for the tterminal buffers to be visible on all tabs.
   not sure how to do that.
2021-03-31 21:55:33 +01:00
Ben Jackson
0cdab6be4e React to the debugpyAttach event and try and start a new session; this gets tripped up by the _vimspector.Variables (etc) buffers already existing. Probably need to add the sesssion ID to the buffer name 2021-03-25 22:08:31 +00:00
Ben Jackson
099431ba55 Start to create session manager
Kind of works, but there's still a single global _vimspector_session
2021-03-24 21:42:15 +00:00
Ben Jackson
fb2bad216f Add a session ID to debug_session - vim only for now 2021-03-24 20:15:34 +00:00
60 changed files with 1794 additions and 1027 deletions

View file

@ -57,12 +57,6 @@ 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-18.04 runs-on: ubuntu-16.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-18.04' runs-on: 'ubuntu-16.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-18.04' runs-on: 'ubuntu-16.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,16 +111,6 @@ 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'
@ -153,10 +143,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 }} # [V]imspector # SSH_PASS: ${{ secrets.SSH_PASS }}
PublishRelease: PublishRelease:
runs-on: 'ubuntu-18.04' runs-on: 'ubuntu-16.04'
needs: needs:
- Linux - Linux
- MacOS - MacOS

View file

@ -1,27 +0,0 @@
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'

View file

@ -9,8 +9,9 @@ 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

@ -46,23 +46,6 @@ 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:
@ -70,7 +53,6 @@ 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

199
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 explanation of the `.vimspector.json` format, see the For detailed explanatin 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)
@ -61,14 +61,14 @@ For detailed explanation of the `.vimspector.json` format, see the
* [Closing debugger](#closing-debugger) * [Closing debugger](#closing-debugger)
* [Terminate debuggee](#terminate-debuggee) * [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)
* [Data visualization / pretty printing](#data-visualization--pretty-printing) * [C Remote debugging](#c-remote-debugging)
* [C++ Remote debugging](#c-remote-debugging) * [C Remote launch and attach](#c-remote-launch-and-attach)
* [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)
@ -100,7 +100,7 @@ For detailed explanation of the `.vimspector.json` format, see the
# 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
@ -145,24 +145,23 @@ 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 | Node, 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) | Tested | `--force-enable-csharp` | netcoredbg | DotNet core | | C# (dotnet core) | Experimental | `--force-enable-csharp` | netcoredbg | DotNet core |
| F#, VB, etc. | Supported | `--force-enable-[fsharp,vbnet]` | `, `--force-enable-vbnet` | netcoredbg | DotNet core | | C# (mono) | Experimental | `--force-enable-csharp` | vscode-mono-debug | Mono |
| C# (mono) | _Retired_ | N/A | N/A | N/A | | F#, VB, etc. | Experimental | `--force-enable-fsharp` (or vbnet) | netcoredbg | DotNet core |
| Python.legacy | _Retired_ | N/A | N/A | N/A | | Python.legacy | Legacy | `--force-enable-python.legacy` | vscode-python | Node 10, Python 2.7 or Python 3 |
## Other languages ## Other languages
@ -291,7 +290,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` and `support/test/go/name-starts-with-vowel`) * Go (`support/test/go/hello_world`)
* Nodejs (`support/test/node/simple`) * Nodejs (`support/test/node/simple`)
* Chrome (`support/test/chrome/`) * Chrome (`support/test/chrome/`)
* etc. * etc.
@ -527,6 +526,13 @@ 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"
} }
} }
} }
@ -1008,8 +1014,6 @@ 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)
@ -1071,8 +1075,6 @@ 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:
@ -1177,38 +1179,6 @@ 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
@ -1294,6 +1264,10 @@ 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": {
@ -1360,6 +1334,34 @@ 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)
@ -1383,8 +1385,35 @@ 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}",
"env": {} "runtimeExecutable": "mono",
"runtimeArgs": [],
"env": [],
"externalConsole": false,
"console": "integratedTerminal"
} }
} }
} }
@ -1401,8 +1430,6 @@ 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": {
@ -1420,7 +1447,7 @@ NOTE: Vimspector uses the ["legacy" vscode-go debug adapter](https://github.com/
``` ```
See the vscode-go docs for See the vscode-go docs for
[troubleshooting information](https://github.com/golang/vscode-go/blob/master/docs/debugging-legacy.md#troubleshooting) [troubleshooting information](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#troubleshooting)
## PHP ## PHP
@ -1739,26 +1766,22 @@ Vimsector uses them, they will not be replaced. So to customise the signs,
define them in your `vimrc`. 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:
```viml ```viml
sign define vimspectorBP text=\ ● texthl=WarningMsg sign define vimspectorBP text=\ ● texthl=WarningMsg
sign define vimspectorBPCond text=\ ◆ texthl=WarningMsg 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
@ -1766,13 +1789,11 @@ glyphs. You can easily change them by defining the sign in your vimrc. For
example, you could put this in your `vimrc` to use some simple ASCII symbols: example, you could put this in your `vimrc` to use some simple ASCII symbols:
```viml ```viml
sign define vimspectorBP text=o texthl=WarningMsg sign define vimspectorBP text=o texthl=WarningMsg
sign define vimspectorBPCond text=o? texthl=WarningMsg 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
@ -2049,10 +2070,6 @@ hi link jsonComment Comment
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

View file

@ -13,9 +13,6 @@
" 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
@ -557,14 +554,6 @@ 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

@ -19,30 +19,36 @@ let s:save_cpo = &cpoptions
set cpoptions&vim set cpoptions&vim
" }}} " }}}
function! s:_OnServerData( channel, data ) abort let s:channels = {}
if !exists( 's:ch' ) || s:ch isnot a:channel let s:jobs = {}
function! s:_OnServerData( session_id, channel, data ) abort
if !has_key( s:channels, a:session_id ) ||
\ s:channels[ a:session_id ] isnot a:channel
return return
endif endif
py3 << EOF py3 _VimspectorSession( vim.eval( 'a:session_id' ) ).OnChannelData(
_vimspector_session.OnChannelData( vim.eval( 'a:data' ) ) \ vim.eval( 'a:data' ) )
EOF
endfunction endfunction
function! s:_OnClose( channel ) abort function! s:_OnClose( session_id, channel ) abort
if !exists( 's:ch' ) || s:ch isnot a:channel if !has_key( s:channels, a:session_id ) ||
\ s:channels[ a:session_id ] isnot a:channel
return return
endif endif
echom 'Channel closed' echom 'Channel closed'
redraw redraw
unlet s:ch unlet s:channels[ a:session_id ]
py3 _vimspector_session.OnServerExit( 0 ) py3 _VimspectorSession( vim.eval( 'a:session_id' ) ).OnServerExit( 0 )
endfunction endfunction
function! vimspector#internal#channel#StartDebugSession( config ) abort function! vimspector#internal#channel#StartDebugSession(
\ session_id,
\ config ) abort
if exists( 's:ch' ) if has_key( s:channels, a:session_id )
echo 'Channel is already running' echo 'Channel is already running'
return v:false return v:false
endif endif
@ -50,7 +56,7 @@ function! vimspector#internal#channel#StartDebugSession( config ) abort
" If we _also_ have a command line, then start the actual job. This allows for " If we _also_ have a command line, then start the actual job. This allows for
" servers which start up and listen on some port " servers which start up and listen on some port
if has_key( a:config, 'command' ) if has_key( a:config, 'command' )
let s:job = job_start( a:config[ 'command' ], let s:jobs[ a:session_id ] = job_start( a:config[ 'command' ],
\ { \ {
\ 'in_mode': 'raw', \ 'in_mode': 'raw',
\ 'out_mode': 'raw', \ 'out_mode': 'raw',
@ -65,16 +71,19 @@ function! vimspector#internal#channel#StartDebugSession( config ) abort
let l:addr = get( a:config, 'host', '127.0.0.1' ) . ':' . a:config[ 'port' ] let l:addr = get( a:config, 'host', '127.0.0.1' ) . ':' . a:config[ 'port' ]
echo 'Connecting to ' . l:addr . '... (waiting fo up to 10 seconds)' echo 'Connecting to ' . l:addr . '... (waiting fo up to 10 seconds)'
let s:ch = ch_open( l:addr, " FIXME: This _always_ waits 10s; the neochannel version is quicker
let s:channels[ a:session_id ] = ch_open( l:addr,
\ { \ {
\ 'mode': 'raw', \ 'mode': 'raw',
\ 'callback': funcref( 's:_OnServerData' ), \ 'callback': funcref( 's:_OnServerData',
\ 'close_cb': funcref( 's:_OnClose' ), \ [ a:session_id ] ),
\ 'close_cb': funcref( 's:_OnClose',
\ [ a:session_id ] ),
\ 'waittime': 10000, \ 'waittime': 10000,
\ } \ }
\ ) \ )
if ch_status( s:ch ) !=# 'open' if ch_status( s:channels[ a:session_id ] ) !=# 'open'
echom 'Unable to connect to' l:addr echom 'Unable to connect to' l:addr
redraw redraw
return v:false return v:false
@ -83,62 +92,67 @@ function! vimspector#internal#channel#StartDebugSession( config ) abort
return v:true return v:true
endfunction endfunction
function! vimspector#internal#channel#Send( msg ) abort function! vimspector#internal#channel#Send( session_id, msg ) abort
call ch_sendraw( s:ch, a:msg ) call ch_sendraw( s:channels[ a:session_id ], a:msg )
return 1 return 1
endfunction endfunction
function! vimspector#internal#channel#Timeout( id ) abort function! vimspector#internal#channel#Timeout( session_id, id ) abort
py3 << EOF py3 _VimspectorSession( vim.eval( 'a:session_id' ) ).OnRequestTimeout(
_vimspector_session.OnRequestTimeout( vim.eval( 'a:id' ) ) \ vim.eval( 'a:id' ) )
EOF
endfunction endfunction
function! vimspector#internal#channel#StopDebugSession() abort function! s:_ChannelExists( session_id ) abort
return has_key( s:channels, a:session_id ) &&
\ count( [ 'closed', 'fail' ],
\ ch_status( s:channels[ a:session_id ] ) ) == 0
endfunction
if exists( 's:job' ) function! vimspector#internal#channel#StopDebugSession( session_id ) abort
if has_key( s:jobs, a:session_id )
" We started the job, so we need to kill it and wait to read all the data " We started the job, so we need to kill it and wait to read all the data
" from the socket " from the socket
if job_status( s:job ) ==# 'run' let job = s:jobs[ a:session_id ]
call job_stop( s:job, 'term' ) if job_status( job ) ==# 'run'
call job_stop( job, 'term' )
endif endif
while job_status( s:job ) ==# 'run' while job_status( job ) ==# 'run'
call job_stop( s:job, 'kill' ) call job_stop( job, 'kill' )
endwhile endwhile
unlet s:job call remove( s:jobs, a:session_id )
if exists( 's:ch' ) && count( [ 'closed', 'fail' ], ch_status( s:ch ) ) == 0 if s:_ChannelExists( a:session_id )
" We're going to block on this channel reading, then manually call the " We're going to block on this channel reading, then manually call the
" close callback, so remove the automatic close callback to avoid tricky " close callback, so remove the automatic close callback to avoid tricky
" re-entrancy " re-entrancy
call ch_setoptions( s:ch, { 'close_cb': '' } ) call ch_setoptions( s:channels[ a:session_id ], { 'close_cb': '' } )
endif endif
elseif s:_ChannelExists( a:session_id )
elseif exists( 's:ch' ) &&
\ count( [ 'closed', 'fail' ], ch_status( s:ch ) ) == 0
" channel is open, close it and trigger the callback. The callback is _not_ " channel is open, close it and trigger the callback. The callback is _not_
" triggered when manually calling ch_close. if we get here and the channel " triggered when manually calling ch_close. if we get here and the channel
" is not open, then we there is a _OnClose callback waiting for us, so do " is not open, then we there is a _OnClose callback waiting for us, so do
" nothing. " nothing.
call ch_close( s:ch ) call ch_close( s:channels[ a:session_id ] )
endif endif
" block until we've read all data from the socket and handled it. " block until we've read all data from the socket and handled it.
while count( [ 'open', 'buffered' ], ch_status( s:ch ) ) == 1 while has_key( s:channels, a:session_id ) &&
let data = ch_read( s:ch, { 'timeout': 10 } ) \ count( [ 'open', 'buffered' ],
call s:_OnServerData( s:ch, data ) \ ch_status( s:channels[ a:session_id ] ) ) == 1
let data = ch_read( s:channels[ a:session_id ], { 'timeout': 10 } )
call s:_OnServerData( s:channels[ a:session_id ], data )
endwhile endwhile
call s:_OnClose( s:ch ) if has_key( s:channels, a:session_id )
call s:_OnClose( a:session_id, s:channels[ a:session_id ] )
endif
endfunction endfunction
function! vimspector#internal#channel#Reset() abort function! vimspector#internal#channel#Reset( session_id ) abort
if exists( 's:ch' ) || exists( 's:job' ) call vimspector#internal#channel#StopDebugSession( a:session_id )
call vimspector#internal#channel#StopDebugSession()
endif
endfunction endfunction
" Boilerplate {{{ " Boilerplate {{{

View file

@ -19,44 +19,54 @@ let s:save_cpo = &cpoptions
set cpoptions&vim set cpoptions&vim
" }}} " }}}
function! s:_OnServerData( channel, data ) abort let s:jobs = {}
if !exists( 's:job' ) || ch_getjob( a:channel ) isnot s:job let s:commands = {}
function! s:_OnServerData( session_id, channel, data ) abort
if !has_key( s:jobs, a:session_id ) ||
\ ch_getjob( a:channel ) isnot s:jobs[ a:session_id ]
call ch_log( 'Get data after process exit' ) call ch_log( 'Get data after process exit' )
return return
endif endif
py3 _vimspector_session.OnChannelData( vim.eval( 'a:data' ) ) py3 _VimspectorSession( vim.eval( 'a:session_id' ) ).OnChannelData(
\ vim.eval( 'a:data' ) )
endfunction endfunction
function! s:_OnServerError( channel, data ) abort function! s:_OnServerError( session_id, channel, data ) abort
if !exists( 's:job' ) || ch_getjob( a:channel ) isnot s:job if !has_key( s:jobs, a:session_id ) ||
\ ch_getjob( a:channel ) isnot s:jobs[ a:session_id ]
call ch_log( 'Get data after process exit' ) call ch_log( 'Get data after process exit' )
return return
endif endif
py3 _vimspector_session.OnServerStderr( vim.eval( 'a:data' ) ) py3 _VimspectorSession( vim.eval( 'a:session_id' ) ).OnServerStderr(
\ vim.eval( 'a:data' ) )
endfunction endfunction
" FIXME: We should wait until both the exit_cb _and_ the channel closed callback " FIXME: We should wait until both the exit_cb _and_ the channel closed callback
" have been received before OnServerExit? " have been received before OnServerExit?
function! s:_OnExit( channel, status ) abort function! s:_OnExit( session_id, channel, status ) abort
if !exists( 's:job' ) || ch_getjob( a:channel ) isnot s:job if !has_key( s:jobs, a:session_id ) ||
\ ch_getjob( a:channel ) isnot s:jobs[ a:session_id ]
call ch_log( 'Unexpected exit callback' ) call ch_log( 'Unexpected exit callback' )
return return
endif endif
echom 'Channel exit with status ' . a:status echom 'Channel exit with status ' . a:status
redraw redraw
if exists( 's:job' ) if has_key( s:jobs, a:session_id )
unlet s:job unlet s:jobs[ a:session_id ]
endif endif
py3 _vimspector_session.OnServerExit( vim.eval( 'a:status' ) ) py3 _VimspectorSession( vim.eval( 'a:session_id' ) ).OnServerExit(
\ vim.eval( 'a:status' ) )
endfunction endfunction
function! s:_OnClose( channel ) abort function! s:_OnClose( session_id, channel ) abort
if !exists( 's:job' ) || job_getchannel( s:job ) != a:channel if !has_key( s:jobs, a:session_id ) ||
\ ch_getjob( a:channel ) isnot s:jobs[ a:session_id ]
call ch_log( 'Channel closed after exit' ) call ch_log( 'Channel closed after exit' )
return return
endif endif
@ -65,34 +75,38 @@ function! s:_OnClose( channel ) abort
redraw redraw
endfunction endfunction
function! vimspector#internal#job#StartDebugSession( config ) abort function! vimspector#internal#job#StartDebugSession( session_id, config ) abort
if exists( 's:job' ) if has_key( s:jobs, a:session_id )
echom 'Not starting: Job is already running' echom 'Not starting: Job is already running'
redraw redraw
return v:false return v:false
endif endif
let s:job = job_start( a:config[ 'command' ], let s:jobs[ a:session_id ] = job_start( a:config[ 'command' ],
\ { \ {
\ 'in_mode': 'raw', \ 'in_mode': 'raw',
\ 'out_mode': 'raw', \ 'out_mode': 'raw',
\ 'err_mode': 'raw', \ 'err_mode': 'raw',
\ 'exit_cb': funcref( 's:_OnExit' ), \ 'exit_cb': funcref( 's:_OnExit',
\ 'close_cb': funcref( 's:_OnClose' ), \ [ a:session_id ] ),
\ 'out_cb': funcref( 's:_OnServerData' ), \ 'close_cb': funcref( 's:_OnClose',
\ 'err_cb': funcref( 's:_OnServerError' ), \ [ a:session_id ] ),
\ 'out_cb': funcref( 's:_OnServerData',
\ [ a:session_id ] ),
\ 'err_cb': funcref( 's:_OnServerError',
\ [ a:session_id ] ),
\ 'stoponexit': 'term', \ 'stoponexit': 'term',
\ 'env': a:config[ 'env' ], \ 'env': a:config[ 'env' ],
\ 'cwd': a:config[ 'cwd' ], \ 'cwd': a:config[ 'cwd' ],
\ } \ }
\ ) \ )
if !exists( 's:job' ) if !has_key( s:jobs, a:session_id )
" The job died immediately after starting and we cleaned up " The job died immediately after starting and we cleaned up
return v:false return v:false
endif endif
let status = job_status( s:job ) let status = job_status( s:jobs[ a:session_id ] )
echom 'Started job, status is: ' . status echom 'Started job, status is: ' . status
redraw redraw
@ -104,20 +118,22 @@ function! vimspector#internal#job#StartDebugSession( config ) abort
return v:true return v:true
endfunction endfunction
function! vimspector#internal#job#Send( msg ) abort function! vimspector#internal#job#Send( session_id, msg ) abort
if ! exists( 's:job' ) if ! has_key( s:jobs, a:session_id )
echom "Can't send message: Job was not initialised correctly" echom "Can't send message: Job was not initialised correctly"
redraw redraw
return 0 return 0
endif endif
if job_status( s:job ) !=# 'run' let job = s:jobs[ a:session_id ]
if job_status( job ) !=# 'run'
echom "Can't send message: Job is not running" echom "Can't send message: Job is not running"
redraw redraw
return 0 return 0
endif endif
let ch = job_getchannel( s:job ) let ch = job_getchannel( job )
if ch ==# 'channel fail' if ch ==# 'channel fail'
echom 'Channel was closed unexpectedly!' echom 'Channel was closed unexpectedly!'
redraw redraw
@ -128,45 +144,55 @@ function! vimspector#internal#job#Send( msg ) abort
return 1 return 1
endfunction endfunction
function! vimspector#internal#job#StopDebugSession() abort function! vimspector#internal#job#StopDebugSession( session_id ) abort
if !exists( 's:job' ) if ! has_key( s:jobs, a:session_id )
echom "Not stopping session: Job doesn't exist" echom "Not stopping session: Job doesn't exist"
redraw redraw
return return
endif endif
if job_status( s:job ) ==# 'run' let job = s:jobs[ a:session_id ]
if job_status( job ) ==# 'run'
echom 'Terminating job' echom 'Terminating job'
redraw redraw
call job_stop( s:job, 'kill' ) call job_stop( job, 'kill' )
endif endif
endfunction endfunction
function! vimspector#internal#job#Reset() abort function! vimspector#internal#job#Reset( session_id ) abort
call vimspector#internal#job#StopDebugSession() call vimspector#internal#job#StopDebugSession( a:session_id )
endfunction endfunction
function! s:_OnCommandExit( category, ch, code ) abort function! s:_OnCommandExit( session_id, category, ch, code ) abort
py3 __import__( "vimspector", py3 __import__( "vimspector",
\ fromlist = [ "utils" ] ).utils.OnCommandWithLogComplete( \ fromlist = [ "utils" ] ).utils.OnCommandWithLogComplete(
\ vim.eval( 'a:session_id' ),
\ vim.eval( 'a:category' ), \ vim.eval( 'a:category' ),
\ int( vim.eval( 'a:code' ) ) ) \ int( vim.eval( 'a:code' ) ) )
endfunction endfunction
function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort function! vimspector#internal#job#StartCommandWithLog(
\ session_id,
\ cmd,
\ category ) abort
if ! exists( 's:commands' ) if ! exists( 's:commands' )
let s:commands = {} let s:commands = {}
endif endif
if ! has_key( s:commands, a:category ) if ! has_key( s:commands, a:session_id )
let s:commands[ a:category ] = [] let s:commands[ a:session_id ] = {}
endif endif
let l:index = len( s:commands[ a:category ] ) if ! has_key( s:commands[ a:session_id ], a:category )
let s:commands[ a:session_id ][ a:category ] = []
endif
let buf = '_vimspector_log_' . a:category let l:index = len( s:commands[ a:session_id ][ a:category ] )
call add( s:commands[ a:category ], job_start( let buf = '_vimspector_log_' . a:session_id . '_' . a:category
call add( s:commands[ a:session_id ][ a:category ], job_start(
\ a:cmd, \ a:cmd,
\ { \ {
\ 'out_io': 'buffer', \ 'out_io': 'buffer',
@ -175,13 +201,14 @@ function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort
\ 'err_msg': 0, \ 'err_msg': 0,
\ 'out_name': buf, \ 'out_name': buf,
\ 'err_name': buf, \ 'err_name': buf,
\ 'exit_cb': funcref( 's:_OnCommandExit', [ a:category ] ), \ 'exit_cb': funcref( 's:_OnCommandExit',
\ [ a:session_id, a:category ] ),
\ 'out_modifiable': 0, \ 'out_modifiable': 0,
\ 'err_modifiable': 0, \ 'err_modifiable': 0,
\ 'stoponexit': 'kill' \ 'stoponexit': 'kill'
\ } ) ) \ } ) )
if job_status( s:commands[ a:category ][ index ] ) !=# 'run' if job_status( s:commands[ a:session_id ][ a:category ][ index ] ) !=# 'run'
echom 'Unable to start job for ' . string( a:cmd ) echom 'Unable to start job for ' . string( a:cmd )
redraw redraw
return v:none return v:none
@ -191,19 +218,27 @@ function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort
endfunction endfunction
function! vimspector#internal#job#CleanUpCommand( category ) abort function! vimspector#internal#job#CleanUpCommand( session_id, category ) abort
if ! exists( 's:commands' ) if ! exists( 's:commands' )
let s:commands = {} let s:commands = {}
endif endif
if ! has_key( s:commands, a:category ) if ! has_key( s:commands, a:session_id )
let s:commands[ a:session_id ] = {}
endif
if ! has_key( s:commands[ a:session_id ], a:category )
return return
endif endif
for j in s:commands[ a:category ] for j in s:commands[ a:session_id ][ a:category ]
call job_stop( j, 'kill' ) call job_stop( j, 'kill' )
endfor endfor
unlet s:commands[ a:category ] unlet s:commands[ a:session_id ][ a:category ]
if len( s:commands[ a:session_id ] ) == 0
unlet s:commands[ a:session_id ]
endif
endfunction endfunction
" Boilerplate {{{ " Boilerplate {{{

View file

@ -20,28 +20,34 @@ set cpoptions&vim
" }}} " }}}
let s:channels = {}
let s:jobs = {}
function! s:_OnEvent( chan_id, data, event ) abort
function! s:_OnEvent( session_id, chan_id, data, event ) abort
if v:exiting isnot# v:null if v:exiting isnot# v:null
return return
endif endif
if !exists( 's:ch' ) || a:chan_id != s:ch if !has_key( s:channels, a:session_id ) ||
\ a:chan_id != s:channels[ a:session_id ]
return return
endif endif
if a:data == [''] if a:data == ['']
echom 'Channel closed' echom 'Channel closed'
redraw redraw
unlet s:ch unlet s:channels[ a:session_id ]
py3 _vimspector_session.OnServerExit( 0 ) py3 _vimspector_session.OnServerExit( 0 )
else else
py3 _vimspector_session.OnChannelData( '\n'.join( vim.eval( 'a:data' ) ) ) py3 _vimspector_session.OnChannelData( '\n'.join( vim.eval( 'a:data' ) ) )
endif endif
endfunction endfunction
function! vimspector#internal#neochannel#StartDebugSession( config ) abort function! vimspector#internal#neochannel#StartDebugSession(
if exists( 's:ch' ) \ session_id,
\ config ) abort
if has_key( s:channels, a:session_id )
echom 'Not starting: Channel is already running' echom 'Not starting: Channel is already running'
redraw redraw
return v:false return v:false
@ -54,12 +60,12 @@ function! vimspector#internal#neochannel#StartDebugSession( config ) abort
try try
let old_env = vimspector#internal#neoterm#PrepareEnvironment( let old_env = vimspector#internal#neoterm#PrepareEnvironment(
\ a:config[ 'env' ] ) \ a:config[ 'env' ] )
let s:job = jobstart( a:config[ 'command' ], let s:jobs[ a:session_id ] = jobstart( a:config[ 'command' ],
\ { \ {
\ 'cwd': a:config[ 'cwd' ], \ 'cwd': a:config[ 'cwd' ],
\ 'env': a:config[ 'env' ], \ 'env': a:config[ 'env' ],
\ } \ }
\ ) \ )
finally finally
call vimspector#internal#neoterm#ResetEnvironment( a:config[ 'env' ], call vimspector#internal#neoterm#ResetEnvironment( a:config[ 'env' ],
\ old_env ) \ old_env )
@ -72,9 +78,10 @@ function! vimspector#internal#neochannel#StartDebugSession( config ) abort
while attempt <= 10 while attempt <= 10
echo 'Connecting to ' . l:addr . '... (attempt' attempt 'of 10)' echo 'Connecting to ' . l:addr . '... (attempt' attempt 'of 10)'
try try
let s:ch = sockconnect( 'tcp', let s:channels[ a:session_id ] = sockconnect(
\ addr, \ 'tcp',
\ { 'on_data': funcref( 's:_OnEvent' ) } ) \ addr,
\ { 'on_data': funcref( 's:_OnEvent', [ a:session_id ] ) } )
redraw redraw
return v:true return v:true
catch /connection refused/ catch /connection refused/
@ -88,30 +95,30 @@ function! vimspector#internal#neochannel#StartDebugSession( config ) abort
return v:false return v:false
endfunction endfunction
function! vimspector#internal#neochannel#Send( msg ) abort function! vimspector#internal#neochannel#Send( session_id, msg ) abort
if ! exists( 's:ch' ) if ! has_key( s:channels, a:session_id )
echom "Can't send message: Channel was not initialised correctly" echom "Can't send message: Channel was not initialised correctly"
redraw redraw
return 0 return 0
endif endif
call chansend( s:ch, a:msg ) call chansend( s:channels[ a:session_id ], a:msg )
return 1 return 1
endfunction endfunction
function! vimspector#internal#neochannel#StopDebugSession() abort function! vimspector#internal#neochannel#StopDebugSession( session_id ) abort
if exists( 's:ch' ) if has_key( s:channels, a:session_id )
call chanclose( s:ch ) call chanclose( s:channels[ a:session_id ] )
" It doesn't look like we get a callback after chanclos. Who knows if we " It doesn't look like we get a callback after chanclos. Who knows if we
" will subsequently receive data callbacks. " will subsequently receive data callbacks.
call s:_OnEvent( s:ch, [ '' ], 'data' ) call s:_OnEvent( a:session_id, s:channels[ a:session_id ], [ '' ], 'data' )
endif endif
if exists( 's:job' ) if has_key( s:jobs, a:session_id )
if vimspector#internal#neojob#JobIsRunning( s:job ) if vimspector#internal#neojob#JobIsRunning( s:jobs[ a:session_id ] )
call jobstop( s:job ) call jobstop( s:jobs[ a:session_id ] )
endif endif
unlet s:job unlet s:jobs[ a:session_id ]
endif endif
endfunction endfunction

View file

@ -19,14 +19,17 @@ let s:save_cpo = &cpoptions
set cpoptions&vim set cpoptions&vim
" }}} " }}}
let s:jobs = {}
let s:commands = {}
function! s:_OnEvent( chan_id, data, event ) abort
function! s:_OnEvent( session_id, chan_id, data, event ) abort
if v:exiting isnot# v:null if v:exiting isnot# v:null
return return
endif endif
if !exists( 's:job' ) || a:chan_id != s:job if !has_key( s:jobs, a:session_id ) || a:chan_id != s:jobs[ a:session_id ]
return return
endif endif
@ -38,13 +41,15 @@ function! s:_OnEvent( chan_id, data, event ) abort
elseif a:event ==# 'exit' elseif a:event ==# 'exit'
echom 'Channel exit with status ' . a:data echom 'Channel exit with status ' . a:data
redraw redraw
unlet s:job unlet s:jobs[ a:session_id ]
py3 _vimspector_session.OnServerExit( vim.eval( 'a:data' ) ) py3 _vimspector_session.OnServerExit( vim.eval( 'a:data' ) )
endif endif
endfunction endfunction
function! vimspector#internal#neojob#StartDebugSession( config ) abort function! vimspector#internal#neojob#StartDebugSession(
if exists( 's:job' ) \ session_id,
\ config ) abort
if has_key( s:jobs, a:session_id )
echom 'Not starging: Job is already running' echom 'Not starging: Job is already running'
redraw redraw
return v:false return v:false
@ -57,11 +62,14 @@ function! vimspector#internal#neojob#StartDebugSession( config ) abort
try try
let old_env = vimspector#internal#neoterm#PrepareEnvironment( let old_env = vimspector#internal#neoterm#PrepareEnvironment(
\ a:config[ 'env' ] ) \ a:config[ 'env' ] )
let s:job = jobstart( a:config[ 'command' ], let s:jobs[ a:session_id ] = jobstart( a:config[ 'command' ],
\ { \ {
\ 'on_stdout': funcref( 's:_OnEvent' ), \ 'on_stdout': funcref( 's:_OnEvent',
\ 'on_stderr': funcref( 's:_OnEvent' ), \ [ a:session_id ] ),
\ 'on_exit': funcref( 's:_OnEvent' ), \ 'on_stderr': funcref( 's:_OnEvent',
\ [ a:session_id ] ),
\ 'on_exit': funcref( 's:_OnEvent',
\ [ a:session_id ] ),
\ 'cwd': a:config[ 'cwd' ], \ 'cwd': a:config[ 'cwd' ],
\ 'env': a:config[ 'env' ], \ 'env': a:config[ 'env' ],
\ } \ }
@ -78,40 +86,40 @@ function! vimspector#internal#neojob#JobIsRunning( job ) abort
return jobwait( [ a:job ], 0 )[ 0 ] == -1 return jobwait( [ a:job ], 0 )[ 0 ] == -1
endfunction endfunction
function! vimspector#internal#neojob#Send( msg ) abort function! vimspector#internal#neojob#Send( session_id, msg ) abort
if ! exists( 's:job' ) if ! has_key( s:jobs, a:session_id )
echom "Can't send message: Job was not initialised correctly" echom "Can't send message: Job was not initialised correctly"
redraw redraw
return 0 return 0
endif endif
if !vimspector#internal#neojob#JobIsRunning( s:job ) if !vimspector#internal#neojob#JobIsRunning( s:jobs[ a:session_id ] )
echom "Can't send message: Job is not running" echom "Can't send message: Job is not running"
redraw redraw
return 0 return 0
endif endif
call chansend( s:job, a:msg ) call chansend( s:jobs[ a:session_id ], a:msg )
return 1 return 1
endfunction endfunction
function! vimspector#internal#neojob#StopDebugSession() abort function! vimspector#internal#neojob#StopDebugSession( session_id ) abort
if !exists( 's:job' ) if !has_key( s:jobs, a:session_id )
return return
endif endif
if vimspector#internal#neojob#JobIsRunning( s:job ) if vimspector#internal#neojob#JobIsRunning( s:jobs[ a:session_id ] )
echom 'Terminating job' echom 'Terminating job'
redraw redraw
call jobstop( s:job ) call jobstop( s:jobs[ a:session_id ] )
endif endif
endfunction endfunction
function! vimspector#internal#neojob#Reset() abort function! vimspector#internal#neojob#Reset( session_id ) abort
call vimspector#internal#neojob#StopDebugSession() call vimspector#internal#neojob#StopDebugSession( a:session_id )
endfunction endfunction
function! s:_OnCommandEvent( category, id, data, event ) abort function! s:_OnCommandEvent( session_id, category, id, data, event ) abort
if v:exiting isnot# v:null if v:exiting isnot# v:null
return return
endif endif
@ -121,18 +129,22 @@ function! s:_OnCommandEvent( category, id, data, event ) abort
return return
endif endif
if !has_key( s:commands, a:category ) if ! has_key( s:commands, a:session_id )
return return
endif endif
if !has_key( s:commands[ a:category ], a:id ) if !has_key( s:commands[ a:session_id ], a:category )
return
endif
if !has_key( s:commands[ a:session_id ][ a:category ], a:id )
return return
endif endif
if a:event ==# 'stdout' if a:event ==# 'stdout'
let buffer = s:commands[ a:category ][ a:id ].stdout let buffer = s:commands[ a:session_id ][ a:category ][ a:id ].stdout
elseif a:event ==# 'stderr' elseif a:event ==# 'stderr'
let buffer = s:commands[ a:category ][ a:id ].stderr let buffer = s:commands[ a:session_id ][ a:category ][ a:id ].stderr
endif endif
try try
@ -159,21 +171,21 @@ 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, but don't allow autocommands to fire, " if the buffer is visible, scroll it
" 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
noautocmd execute w . 'wincmd w' execute w . 'wincmd w'
noautocmd normal! Gz- normal! Gz-
finally finally
noautocmd execute cw . 'wincmd w' execute cw . 'wincmd w'
endtry endtry
endif endif
elseif a:event ==# 'exit' elseif a:event ==# 'exit'
py3 __import__( "vimspector", py3 __import__( "vimspector",
\ fromlist = [ "utils" ] ).utils.OnCommandWithLogComplete( \ fromlist = [ "utils" ] ).utils.OnCommandWithLogComplete(
\ vim.eval( 'a:session_id' ),
\ vim.eval( 'a:category' ), \ vim.eval( 'a:category' ),
\ int( vim.eval( 'a:data' ) ) ) \ int( vim.eval( 'a:data' ) ) )
endif endif
@ -199,11 +211,16 @@ function! s:MakeBufferWritable( buffer ) abort
endfunction endfunction
let s:commands = {} function! vimspector#internal#neojob#StartCommandWithLog(
\ session_id,
\ cmd,
\ category ) abort
if ! has_key( s:commands, a:session_id )
let s:commands[ a:session_id ] = {}
endif
function! vimspector#internal#neojob#StartCommandWithLog( cmd, category ) abort if ! has_key( s:commands[ a:session_id ], a:category )
if ! has_key( s:commands, a:category ) let s:commands[ a:session_id ][ a:category ] = {}
let s:commands[ a:category ] = {}
endif endif
let buf = bufnr( '_vimspector_log_' . a:category, v:true ) let buf = bufnr( '_vimspector_log_' . a:category, v:true )
@ -216,14 +233,14 @@ function! vimspector#internal#neojob#StartCommandWithLog( cmd, category ) abort
let id = jobstart(a:cmd, let id = jobstart(a:cmd,
\ { \ {
\ 'on_stdout': funcref( 's:_OnCommandEvent', \ 'on_stdout': funcref( 's:_OnCommandEvent',
\ [ a:category ] ), \ [ a:session_id, a:category ] ),
\ 'on_stderr': funcref( 's:_OnCommandEvent', \ 'on_stderr': funcref( 's:_OnCommandEvent',
\ [ a:category ] ), \ [ a:session_id, a:category ] ),
\ 'on_exit': funcref( 's:_OnCommandEvent', \ 'on_exit': funcref( 's:_OnCommandEvent',
\ [ a:category ] ), \ [ a:session_id, a:category ] ),
\ } ) \ } )
let s:commands[ a:category ][ id ] = { let s:commands[ a:session_id ][ a:category ][ id ] = {
\ 'stdout': buf, \ 'stdout': buf,
\ 'stderr': buf \ 'stderr': buf
\ } \ }
@ -231,19 +248,25 @@ function! vimspector#internal#neojob#StartCommandWithLog( cmd, category ) abort
return buf return buf
endfunction endfunction
function! vimspector#internal#neojob#CleanUpCommand( category ) abort function! vimspector#internal#neojob#CleanUpCommand(
if ! has_key( s:commands, a:category ) \ session_id,
\ category ) abort
if ! has_key( s:commands, a:session_id )
return return
endif endif
for id in keys( s:commands[ a:category ] ) if ! has_key( s:commands[ a:session_id ], a:category )
return
endif
for id in keys( s:commands[ a:session_id ][ a:category ] )
let id = str2nr( id ) let id = str2nr( id )
if jobwait( [ id ], 0 )[ 0 ] == -1 if jobwait( [ id ], 0 )[ 0 ] == -1
call jobstop( id ) call jobstop( id )
endif endif
call jobwait( [ id ], -1 ) call jobwait( [ id ], -1 )
endfor endfor
unlet! s:commands[ a:category ] unlet! s:commands[ a:session_id ][ a:category ]
endfunction endfunction
" Boilerplate {{{ " Boilerplate {{{

View file

@ -26,11 +26,22 @@ endif
function! vimspector#internal#state#Reset() abort function! vimspector#internal#state#Reset() abort
try try
py3 import vim py3 <<EOF
py3 _vimspector_session = __import__(
\ "vimspector", import vim
\ fromlist=[ "debug_session" ] ).debug_session.DebugSession(
\ vim.eval( 's:prefix' ) ) _vimspector_session_man = __import__(
"vimspector",
fromlist=[ "session_manager" ] ).session_manager.Get()
# Deprecated
_vimspector_session = _vimspector_session_man.NewSession(
vim.eval( 's:prefix' ) )
def _VimspectorSession( session_id ):
return _vimspector_session_man.GetSession( int( session_id ) )
EOF
catch /.*/ catch /.*/
echohl WarningMsg echohl WarningMsg
echom 'Exception while loading vimspector:' v:exception echom 'Exception while loading vimspector:' v:exception
@ -47,6 +58,22 @@ function! vimspector#internal#state#GetAPIPrefix() abort
return s:prefix return s:prefix
endfunction endfunction
function! vimspector#internal#state#SwitchToSession( id ) abort
py3 _vimspector_session = _VimspectorSession( vim.eval( 'a:id' ) )
endfunction
function! vimspector#internal#state#OnTabEnter() abort
py3 <<EOF
session = _vimspector_session_man.SessionForTab(
int( vim.eval( 'tabpagenr()' ) ) )
if session is not None:
_vimspector_session = session
EOF
endfunction
" Boilerplate {{{ " Boilerplate {{{
let &cpoptions=s:save_cpo let &cpoptions=s:save_cpo
unlet s:save_cpo unlet s:save_cpo

View file

@ -1,13 +1,13 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
activesupport (6.0.3.6) activesupport (6.0.3.4)
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.8.0) addressable (2.7.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.8) concurrent-ruby (1.1.7)
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.1) faraday-net_http (1.0.0)
ffi (1.15.0) ffi (1.14.2)
forwardable-extended (2.6.0) forwardable-extended (2.6.0)
gemoji (3.0.1) gemoji (3.0.1)
github-pages (214) github-pages (209)
github-pages-health-check (= 1.17.0) github-pages-health-check (= 1.16.1)
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.3) jekyll-remote-theme (= 0.4.2)
jekyll-sass-converter (= 1.5.2) jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.7.1) jekyll-seo-tag (= 2.6.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.1) kramdown (= 2.3.0)
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.26.0) rouge (= 3.23.0)
terminal-table (~> 1.4) terminal-table (~> 1.4)
github-pages-health-check (1.17.0) github-pages-health-check (1.16.1)
addressable (~> 2.3) addressable (~> 2.3)
dnsruby (~> 1.60) dnsruby (~> 1.60)
octokit (~> 4.0) octokit (~> 4.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (~> 3.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.3) jekyll-remote-theme (0.4.2)
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.7.1) jekyll-seo-tag (2.6.1)
jekyll (>= 3.8, < 5.0) jekyll (>= 3.3, < 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.1) kramdown (2.3.0)
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.5.1) listen (3.4.0)
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.1) mini_portile2 (2.5.0)
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.4) minitest (5.14.3)
multipart-post (2.1.1) multipart-post (2.1.1)
nokogiri (1.11.5) nokogiri (1.11.1)
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 (4.0.6) public_suffix (3.1.1)
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.5) rexml (3.2.4)
rouge (3.26.0) rouge (3.23.0)
ruby-enum (0.9.0) ruby-enum (0.8.0)
i18n i18n
ruby2_keywords (0.0.4) ruby2_keywords (0.0.2)
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.2.1) simpleidn (0.1.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": true "stopOnEntry#json": true
``` ```
Which is what we need. Which is what we need.
@ -722,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": "${fileBasenameNoExtension}" "ServiceName": "${fileBasenameNoExtention}"
}, },
"adapter": "python-remote", "adapter": "python-remote",

View file

@ -13,13 +13,6 @@
" 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
@ -115,9 +108,6 @@ command! -bar -nargs=? -complete=custom,vimspector#CompleteOutput
command! -bar command! -bar
\ VimspectorToggleLog \ VimspectorToggleLog
\ call vimspector#ToggleLog() \ call vimspector#ToggleLog()
command! -bar
\ VimspectorDebugInfo
\ call vimspector#PrintDebugInfo()
command! -nargs=1 -complete=custom,vimspector#CompleteExpr command! -nargs=1 -complete=custom,vimspector#CompleteExpr
\ VimspectorEval \ VimspectorEval
\ call vimspector#Evaluate( <f-args> ) \ call vimspector#Evaluate( <f-args> )
@ -151,6 +141,7 @@ augroup END
augroup Vimspector augroup Vimspector
autocmd! autocmd!
autocmd BufNew * call vimspector#OnBufferCreated( expand( '<afile>' ) ) autocmd BufNew * call vimspector#OnBufferCreated( expand( '<afile>' ) )
autocmd TabEnter * call vimspector#internal#state#OnTabEnter()
augroup END augroup END
" boilerplate {{{ " boilerplate {{{

View file

@ -34,13 +34,24 @@ class ServerBreakpointHandler( object ):
pass pass
# FIXME: THis really should be project scope and not associated with a debug
# session. Breakpoints set by the user should be independent and breakpoints for
# the current active session should be associated with the session when they are
# in use.
#
# Questions include:
# 1. what happens if we set/chnage a breakpiont in session #2 while session #1
# is active ? Maybe we re-send the breakpoints to _all_ active sessions?
#
# More...
class ProjectBreakpoints( object ): class ProjectBreakpoints( object ):
def __init__( self ): def __init__( self, session_id ):
self._connection = None self._connection = None
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ + '.' + str( session_id ) )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger, session_id )
# These are the user-entered breakpoints. # These are the user-entered breakpoints. NOTE: if updating this, also
# update Copy()
self._line_breakpoints = defaultdict( list ) self._line_breakpoints = defaultdict( list )
self._func_breakpoints = [] self._func_breakpoints = []
self._exception_breakpoints = None self._exception_breakpoints = None
@ -91,6 +102,12 @@ class ProjectBreakpoints( object ):
# FIXME: If the adapter type changes, we should probably forget this ? # FIXME: If the adapter type changes, we should probably forget this ?
def Copy( self, other: 'ProjectBreakpoints' ):
self._line_breakpoints = dict( other._line_breakpoints )
self._func_breakpoints = list( other._func_breakpoints )
if other._exception_breakpoints is not None:
self._exception_breakpoints = dict( other._exception_breakpoints )
def BreakpointsAsQuickFix( self ): def BreakpointsAsQuickFix( self ):
# FIXME: Handling of breakpoints is a mess, split between _codeView and this # FIXME: Handling of breakpoints is a mess, split between _codeView and this
# object. This makes no sense and should be centralised so that we don't # object. This makes no sense and should be centralised so that we don't

View file

@ -20,20 +20,20 @@ from collections import defaultdict
from vimspector import utils, terminal, signs from vimspector import utils, terminal, signs
NEXT_SIGN_ID = 1
class CodeView( object ): class CodeView( object ):
def __init__( self, window, api_prefix ): def __init__( self, session_id, window, api_prefix ):
self._window = window self._window = window
self._api_prefix = api_prefix self._api_prefix = api_prefix
self._terminal = None self._terminal = None
self.current_syntax = None self.current_syntax = None
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ + '.' + str( session_id ) )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger )
# FIXME: This ID is by group, so should be module scope
self._next_sign_id = 1
self._breakpoints = defaultdict( list ) self._breakpoints = defaultdict( list )
self._signs = { self._signs = {
'vimspectorPC': None, 'vimspectorPC': None,
@ -92,8 +92,9 @@ class CodeView( object ):
self._UndisplayPC( clear_pc = False ) self._UndisplayPC( clear_pc = False )
# FIXME: Do we relly need to keep using up IDs ? # FIXME: Do we relly need to keep using up IDs ?
self._signs[ 'vimspectorPC' ] = self._next_sign_id global NEXT_SIGN_ID
self._next_sign_id += 1 self._signs[ 'vimspectorPC' ] = NEXT_SIGN_ID
NEXT_SIGN_ID += 1
sign = 'vimspectorPC' sign = 'vimspectorPC'
# If there's also a breakpoint on this line, use vimspectorPCBP # If there's also a breakpoint on this line, use vimspectorPCBP
@ -247,8 +248,9 @@ class CodeView( object ):
if 'line' not in breakpoint: if 'line' not in breakpoint:
continue continue
sign_id = self._next_sign_id global NEXT_SIGN_ID
self._next_sign_id += 1 sign_id = NEXT_SIGN_ID
NEXT_SIGN_ID += 1
self._signs[ 'breakpoints' ].append( sign_id ) self._signs[ 'breakpoints' ].append( sign_id )
if utils.BufferExists( file_name ): if utils.BufferExists( file_name ):
signs.PlaceSign( sign_id, signs.PlaceSign( sign_id,

View file

@ -0,0 +1,77 @@
# 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 session_manager, gadgets, utils
from typing import Sequence
class Debugpy( object ):
parent: DebugSession
sessions: Sequence[ DebugSession ]
def __init__( self, debug_session: DebugSession ):
self.parent = debug_session
self.queue = []
def LaunchSubprocessDebugSession( self, result ):
launch_arguments = self.queue.pop( 0 )
if result == 1:
session = session_manager.Get().NewSession( self.parent._api_prefix )
# Inject the launch config (HACK!). This will actually mean that the
# configuration passed below is ignored.
session._launch_config = launch_arguments
# FIXME: We probably do need to add a StartWithLauncArguments and somehow
# tell the new session that it shoud not support "Restart" requests ?
#
# In fact, what even would Reset do... ?
session._breakpoints.Copy( self.parent._breakpoints )
session._StartWithConfiguration( { 'configuration': launch_arguments },
launch_arguments[ 'connect' ] )
self.HandleNext()
def OnEvent_debugpyAttach( self, message ):
# Debugpy sends us the contents of a launch request that we should use. We
# probaly just jave to guess the rest
launch_arguments = message[ 'body' ]
self.queue.append( launch_arguments )
# We use a queue because the confirm mechanism is quasi-modal and we can't
# do multiple 'confirm' dialogs at once. It's not uncommon for
# multiprocessing to create multiple subprocesses all at the same time.
if len( self.queue ) == 1:
self.HandleNext()
def HandleNext( self ):
if not self.queue:
return
launch_argyments = self.queue[ 0 ]
pid = launch_argyments[ 'subProcessId' ]
utils.Confirm(
self.parent._api_prefix,
f"Subprocess {pid} was launched.\nAttach to it in a new tab?",
self.LaunchSubprocessDebugSession,
default_value = 1,
options = [ 'Yes', 'No' ],
keys = [ 'y', 'n' ] )

View file

@ -29,14 +29,15 @@ class PendingRequest( object ):
class DebugAdapterConnection( object ): class DebugAdapterConnection( object ):
def __init__( self, handlers, send_func ): def __init__( self, handlers, session_id, send_func ):
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ + '.' + str( session_id ) )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger, session_id )
self._Write = send_func self._Write = send_func
self._SetState( 'READ_HEADER' ) self._SetState( 'READ_HEADER' )
self._buffer = bytes() self._buffer = bytes()
self._handlers = handlers self._handlers = handlers
self._session_id = session_id
self._next_message_id = 0 self._next_message_id = 0
self._outstanding_requests = {} self._outstanding_requests = {}
@ -51,10 +52,12 @@ class DebugAdapterConnection( object ):
msg[ 'seq' ] = this_id msg[ 'seq' ] = this_id
msg[ 'type' ] = 'request' msg[ 'type' ] = 'request'
# TODO/FIXME: This is so messy
expiry_id = vim.eval( expiry_id = vim.eval(
'timer_start( {}, "vimspector#internal#channel#Timeout" )'.format( 'timer_start( {}, '
timeout ) ) ' function( "vimspector#internal#channel#Timeout", '
' [ {} ] ) )'.format(
timeout,
self._session_id ) )
request = PendingRequest( msg, request = PendingRequest( msg,
handler, handler,
@ -226,12 +229,7 @@ class DebugAdapterConnection( object ):
# self._logger.debug( 'Message received (raw): %s', payload ) # self._logger.debug( 'Message received (raw): %s', payload )
try: message = json.loads( payload )
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 ) )

View file

@ -42,15 +42,17 @@ VIMSPECTOR_HOME = utils.GetVimspectorBase()
# cache of what the user entered for any option we ask them # cache of what the user entered for any option we ask them
USER_CHOICES = {} USER_CHOICES = {}
class DebugSession( object ): class DebugSession( object ):
def __init__( self, api_prefix ): def __init__( self, session_id, session_manager, api_prefix ):
self._logger = logging.getLogger( __name__ ) self.session_id = session_id
utils.SetUpLogging( self._logger ) self.manager = session_manager
self._logger = logging.getLogger( __name__ + '.' + str( session_id ) )
utils.SetUpLogging( self._logger, session_id )
self._api_prefix = api_prefix self._api_prefix = api_prefix
self._logger.info( "**** INITIALISING NEW VIMSPECTOR SESSION ****" ) self._logger.info( "**** INITIALISING NEW VIMSPECTOR SESSION FOR ID "
f"{session_id } ****" )
self._logger.info( "API is: {}".format( api_prefix ) ) self._logger.info( "API is: {}".format( api_prefix ) )
self._logger.info( 'VIMSPECTOR_HOME = %s', VIMSPECTOR_HOME ) self._logger.info( 'VIMSPECTOR_HOME = %s', VIMSPECTOR_HOME )
self._logger.info( 'gadgetDir = %s', self._logger.info( 'gadgetDir = %s',
@ -61,7 +63,7 @@ class DebugSession( object ):
self._stackTraceView = None self._stackTraceView = None
self._variablesView = None self._variablesView = None
self._outputView = None self._outputView = None
self._breakpoints = breakpoints.ProjectBreakpoints() self._breakpoints = breakpoints.ProjectBreakpoints( session_id )
self._splash_screen = None self._splash_screen = None
self._remote_term = None self._remote_term = None
@ -73,6 +75,11 @@ class DebugSession( object ):
self._ResetServerState() self._ResetServerState()
def __del__( self ):
self.manager.DestroySession( self )
def _ResetServerState( self ): def _ResetServerState( self ):
self._connection = None self._connection = None
self._init_complete = False self._init_complete = False
@ -408,7 +415,13 @@ class DebugSession( object ):
if self._uiTab: if self._uiTab:
self._logger.debug( "Clearing down UI" ) self._logger.debug( "Clearing down UI" )
del vim.vars[ 'vimspector_session_windows' ] try:
# FIXME: vimspector_session_windows is totally buseted with multiple
# sessions
del vim.vars[ 'vimspector_session_windows' ]
except KeyError:
pass
vim.current.tabpage = self._uiTab vim.current.tabpage = self._uiTab
self._splash_screen = utils.HideSplash( self._api_prefix, self._splash_screen = utils.HideSplash( self._api_prefix,
@ -667,6 +680,15 @@ class DebugSession( object ):
def _SetUpUI( self ): def _SetUpUI( self ):
vim.command( 'tab split' ) vim.command( 'tab split' )
# Switch to this session now that we've made it visible. Note that the
# TabEnter autocmd does trigger when the above is run, but that's before the
# following line assigns the tab to this session, so when we try to find
# this session by tab number, it's not found. So we have to manually switch
# to it when creating a new tab.
utils.Call( 'vimspector#internal#state#SwitchToSession',
self.session_id )
self._uiTab = vim.current.tabpage self._uiTab = vim.current.tabpage
mode = settings.Get( 'ui_mode' ) mode = settings.Get( 'ui_mode' )
@ -710,7 +732,9 @@ class DebugSession( object ):
def _SetUpUIHorizontal( self ): 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( self.session_id,
code_window,
self._api_prefix )
# Call stack # Call stack
vim.command( vim.command(
@ -735,7 +759,8 @@ class DebugSession( object ):
with utils.LetCurrentWindow( stack_trace_window ): with utils.LetCurrentWindow( stack_trace_window ):
vim.command( f'{ one_third }wincmd _' ) vim.command( f'{ one_third }wincmd _' )
self._variablesView = variables.VariablesView( vars_window, self._variablesView = variables.VariablesView( self,
vars_window,
watch_window ) watch_window )
# Output/logging # Output/logging
@ -743,7 +768,8 @@ class DebugSession( object ):
vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' ) vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' )
output_window = vim.current.window output_window = vim.current.window
self._outputView = output.DAPOutputView( output_window, self._outputView = output.DAPOutputView( output_window,
self._api_prefix ) self._api_prefix,
session_id = self.session_id )
# 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
@ -766,7 +792,9 @@ class DebugSession( object ):
def _SetUpUIVertical( self ): def _SetUpUIVertical( 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( self.session_id,
code_window,
self._api_prefix )
# Call stack # Call stack
vim.command( vim.command(
@ -793,7 +821,8 @@ class DebugSession( object ):
with utils.LetCurrentWindow( stack_trace_window ): with utils.LetCurrentWindow( stack_trace_window ):
vim.command( f'{ one_third }wincmd |' ) vim.command( f'{ one_third }wincmd |' )
self._variablesView = variables.VariablesView( vars_window, self._variablesView = variables.VariablesView( self,
vars_window,
watch_window ) watch_window )
@ -802,7 +831,8 @@ class DebugSession( object ):
vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' ) vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' )
output_window = vim.current.window output_window = vim.current.window
self._outputView = output.DAPOutputView( output_window, self._outputView = output.DAPOutputView( output_window,
self._api_prefix ) self._api_prefix,
session_id = self.session_id )
# 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
@ -887,8 +917,10 @@ class DebugSession( object ):
vim.vars[ '_vimspector_adapter_spec' ] = self._adapter vim.vars[ '_vimspector_adapter_spec' ] = self._adapter
if not vim.eval( "vimspector#internal#{}#StartDebugSession( " if not vim.eval( "vimspector#internal#{}#StartDebugSession( "
" {},"
" g:_vimspector_adapter_spec " " g:_vimspector_adapter_spec "
")".format( self._connection_type ) ): ")".format( self._connection_type,
self.session_id ) ):
self._logger.error( "Unable to start debug server" ) self._logger.error( "Unable to start debug server" )
self._splash_screen = utils.DisplaySplash( self._api_prefix, self._splash_screen = utils.DisplaySplash( self._api_prefix,
self._splash_screen, self._splash_screen,
@ -908,9 +940,11 @@ class DebugSession( object ):
handlers = [ self ] handlers = [ self ]
self._connection = debug_adapter_connection.DebugAdapterConnection( self._connection = debug_adapter_connection.DebugAdapterConnection(
handlers, handlers = handlers,
lambda msg: utils.Call( session_id = self.session_id,
send_func = lambda msg: utils.Call(
"vimspector#internal#{}#Send".format( self._connection_type ), "vimspector#internal#{}#Send".format( self._connection_type ),
self.session_id,
msg ) ) msg ) )
self._logger.info( 'Debug Adapter Started' ) self._logger.info( 'Debug Adapter Started' )
@ -933,8 +967,9 @@ class DebugSession( object ):
assert not self._run_on_server_exit assert not self._run_on_server_exit
self._run_on_server_exit = callback self._run_on_server_exit = callback
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format( vim.eval( 'vimspector#internal#{}#StopDebugSession( {} )'.format(
self._connection_type ) ) self._connection_type,
self.session_id ) )
self._connection.DoRequest( handler, { self._connection.DoRequest( handler, {
'command': 'disconnect', 'command': 'disconnect',
@ -1179,9 +1214,10 @@ class DebugSession( object ):
self._on_init_complete_handlers = [] self._on_init_complete_handlers = []
self._logger.debug( "LAUNCH!" ) self._logger.debug( "LAUNCH!" )
self._launch_config = {} if self._launch_config is None:
self._launch_config.update( self._adapter.get( 'configuration', {} ) ) self._launch_config = {}
self._launch_config.update( self._configuration[ 'configuration' ] ) self._launch_config.update( self._adapter.get( 'configuration', {} ) )
self._launch_config.update( self._configuration[ 'configuration' ] )
request = self._configuration.get( request = self._configuration.get(
'remote-request', 'remote-request',
@ -1270,37 +1306,6 @@ 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

View file

@ -30,12 +30,12 @@ GADGETS = {
root, root,
gadget ), gadget ),
'all': { 'all': {
'version': '1.6.0', 'version': '0.27.0',
"adapters": { "adapters": {
"vscode-cpptools": { "vscode-cpptools": {
"name": "cppdbg", "name": "cppdbg",
"command": [ "command": [
"${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7" "${gadgetDir}/vscode-cpptools/debugAdapters/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':
'c25299bcfb46b22d41aa3f125df7184e6282a35ff9fb69c47def744cb4778f55', '3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435',
}, },
'macos': { 'macos': {
'file_name': 'cpptools-osx-arm64.vsix', 'file_name': 'cpptools-osx.vsix',
'checksum': 'checksum':
'ceb3e8cdaa2b5bb45af50913ddd8402089969748af8d70f5d46480408287ba6f', 'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c',
}, },
'windows': { 'windows': {
'file_name': 'cpptools-win32.vsix', 'file_name': 'cpptools-win32.vsix',
'checksum': 'checksum':
'ef7ac5831874a3c7dbf0feb826bfda2be579aff9b6d990622fff1d0d4ede00d1', 'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e',
"adapters": { "adapters": {
"vscode-cpptools": { "vscode-cpptools": {
"name": "cppdbg", "name": "cppdbg",
@ -86,6 +86,29 @@ 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': {
@ -113,7 +136,8 @@ GADGETS = {
# doesn't support the custom messages) # doesn't support the custom messages)
# https://github.com/puremourning/vimspector/issues/141 # https://github.com/puremourning/vimspector/issues/141
"subProcess": False, "subProcess": False,
} },
'custom_handler': 'vimspector.custom.python.Debugpy'
} }
}, },
}, },
@ -211,12 +235,13 @@ GADGETS = {
'format': 'tar', 'format': 'tar',
}, },
'all': { 'all': {
'version': '1.2.0-782' 'version': '1.2.0-738'
}, },
'macos': { 'macos': {
'file_name': 'netcoredbg-osx.tar.gz', 'file_name': 'netcoredbg-osx.tar.gz',
'version': '1.2.0-635',
'checksum': 'checksum':
'', '71c773e34d358950f25119bade7e3081c4c2f9d71847bd49027ca5792e918beb',
}, },
'linux': { 'linux': {
'file_name': 'netcoredbg-linux-bionic-amd64.tar.gz', 'file_name': 'netcoredbg-linux-bionic-amd64.tar.gz',
@ -246,6 +271,41 @@ 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': {
@ -323,10 +383,10 @@ GADGETS = {
'${version}/${file_name}', '${version}/${file_name}',
}, },
'all': { 'all': {
'version': 'v1.17.0', 'version': 'v1.14.9',
'file_name': 'php-debug-1.17.0.vsix', 'file_name': 'php-debug.vsix',
'checksum': 'checksum':
'd0fff272503414b6696cc737bc2e18e060fdd5e5dc4bcaf38ae7373afd8d8bc9', '0c5709cbbffe26b12aa63a88142195a9a045a5d8fca7fe63d62c789fe601630d',
}, },
'adapters': { 'adapters': {
'vscode-php-debug': { 'vscode-php-debug': {
@ -394,12 +454,12 @@ GADGETS = {
'${version}/${file_name}', '${version}/${file_name}',
}, },
'all': { 'all': {
'version': 'v1.6.6', 'version': 'v1.5.3',
}, },
'macos': { 'macos': {
'file_name': 'codelldb-aarch64-darwin.vsix', 'file_name': 'codelldb-x86_64-darwin.vsix',
'checksum': 'checksum':
'5adc3b9139eabdafd825bd5efc55df4424a203fb2b6087b425cd434956e7ec58', '7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a',
'make_executable': [ 'make_executable': [
'adapter/codelldb', 'adapter/codelldb',
'lldb/bin/debugserver', 'lldb/bin/debugserver',
@ -410,7 +470,7 @@ GADGETS = {
'linux': { 'linux': {
'file_name': 'codelldb-x86_64-linux.vsix', 'file_name': 'codelldb-x86_64-linux.vsix',
'checksum': 'checksum':
'eda2cd9b3089dcc0524c273e91ffb5875fe08c930bf643739a2cd1846e1f98d6', 'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139',
'make_executable': [ 'make_executable': [
'adapter/codelldb', 'adapter/codelldb',
'lldb/bin/lldb', 'lldb/bin/lldb',
@ -421,7 +481,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,8 +358,7 @@ 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( MakeExecutable( os.path.join( extension, 'debugAdapters', 'OpenDebugAD7' ) )
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,7 +32,6 @@ class TabBuffer( object ):
BUFFER_MAP = { BUFFER_MAP = {
'console': 'Console', 'console': 'Console',
'stdout': 'Console', 'stdout': 'Console',
'output': 'Console',
'stderr': 'stderr', 'stderr': 'stderr',
'telemetry': None, 'telemetry': None,
} }
@ -59,17 +58,20 @@ class OutputView( object ):
files or the output of commands.""" files or the output of commands."""
_buffers: typing.Dict[ str, TabBuffer ] _buffers: typing.Dict[ str, TabBuffer ]
def __init__( self, window, api_prefix ): def __init__( self, window, api_prefix, session_id = None ):
self._window = window self._window = window
self._buffers = {} self._buffers = {}
self._api_prefix = api_prefix self._api_prefix = api_prefix
VIEWS.add( self ) VIEWS.add( self )
def Print( self, category, text: typing.Union[ str, list ] ): if session_id is None:
if not isinstance( text, list ): # FIXME: hack?
text = text.splitlines() self._session_id = hash( self )
else:
self._session_id = session_id
self._Print( category, text ) def Print( self, categroy, text ):
self._Print( 'server', text.splitlines() )
def OnOutput( self, event ): def OnOutput( self, event ):
category = CategoryToBuffer( event.get( 'category' ) or 'output' ) category = CategoryToBuffer( event.get( 'category' ) or 'output' )
@ -108,26 +110,13 @@ 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():
self._CleanUpBuffer( category, tab_buffer ) if tab_buffer.is_job:
utils.CleanUpCommand( self._session_id, 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
@ -191,8 +180,9 @@ class OutputView( object ):
if cmd is not None: if cmd is not None:
out = utils.SetUpCommandBuffer( out = utils.SetUpCommandBuffer(
self._session_id,
cmd, cmd,
category, utils.BufferNameForSession( category, self._session_id ),
self._api_prefix, self._api_prefix,
completion_handler = completion_handler ) completion_handler = completion_handler )
@ -205,6 +195,8 @@ class OutputView( object ):
else: else:
name = 'vimspector.Output:{0}'.format( category ) name = 'vimspector.Output:{0}'.format( category )
name = utils.BufferNameForSession( name, self._session_id )
tab_buffer = TabBuffer( utils.NewEmptyBuffer(), len( self._buffers ) ) tab_buffer = TabBuffer( utils.NewEmptyBuffer(), len( self._buffers ) )
self._buffers[ category ] = tab_buffer self._buffers[ category ] = tab_buffer
@ -267,8 +259,8 @@ class OutputView( object ):
class DAPOutputView( OutputView ): class DAPOutputView( OutputView ):
"""Specialised OutputView which adds the DAP Console (REPL)""" """Specialised OutputView which adds the DAP Console (REPL)"""
def __init__( self, *args ): def __init__( self, *args, **kwargs ):
super().__init__( *args ) super().__init__( *args, **kwargs )
self._connection = None self._connection = None
for b in set( BUFFER_MAP.values() ): for b in set( BUFFER_MAP.values() ):

View file

@ -0,0 +1,58 @@
# vimspector - A multi-language debugging system for Vim
# Copyright 2020 Ben Jackson
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from vimspector.debug_session import DebugSession
# Singleton
_session_manager = None
class SessionManager:
next_session_id = 0
sessions = {}
def NewSession( self, *args, **kwargs ):
session_id = self.next_session_id
self.next_session_id += 1
session = DebugSession( session_id, self, *args, **kwargs )
self.sessions[ session_id ] = session
return session
def DestroySession( self, session: DebugSession ):
# TODO: Call this!
del self.sessions[ session.session_id ]
def GetSession( self, session_id ):
return self.sessions.get( session_id )
def SessionForTab( self, tabnr ):
for _, session in self.sessions.items():
if session._HasUI() and session._uiTab.number == int( tabnr ):
return session
return None
def Get():
global _session_manager
if _session_manager is None:
_session_manager = SessionManager()
return _session_manager

View file

@ -42,8 +42,7 @@ DEFAULTS = {
'vimspectorBP': 9, 'vimspectorBP': 9,
'vimspectorBPCond': 9, 'vimspectorBPCond': 9,
'vimspectorBPDisabled': 9, 'vimspectorBPDisabled': 9,
'vimspectorCurrentThread': 200, 'vimspectorCurrentThread': 200
'vimspectorCurrentFrame': 200,
}, },
# Installer # Installer

View file

@ -86,8 +86,8 @@ class StackTraceView( object ):
_line_to_thread = typing.Dict[ int, Thread ] _line_to_thread = typing.Dict[ int, Thread ]
def __init__( self, session, win ): def __init__( self, session, win ):
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ + '.' + str( session.session_id ) )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger, session.session_id )
self._buf = win.buffer self._buf = win.buffer
self._session = session self._session = session
@ -102,10 +102,12 @@ 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._current_thread_sign_id = 0 # 1 when used self._next_sign_id = 1
self._current_frame_sign_id = 0 # 2 when used
utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' ) utils.SetUpHiddenBuffer(
self._buf,
utils.BufferNameForSession( 'vimspector.StackTrace',
self._session.session_id ) )
utils.SetUpUIWindow( win ) utils.SetUpUIWindow( win )
mappings = settings.Dict( 'mappings' )[ 'stack_trace' ] mappings = settings.Dict( 'mappings' )[ 'stack_trace' ]
@ -128,7 +130,6 @@ class StackTraceView( object ):
':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' ):
@ -138,13 +139,6 @@ 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 = {}
@ -166,12 +160,9 @@ 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._current_thread_sign_id: if self._next_sign_id:
signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' ) signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' )
self._current_thread_sign_id = 0 self._next_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 )
@ -285,10 +276,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._current_thread_sign_id: if self._next_sign_id:
signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' ) signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' )
else: else:
self._current_thread_sign_id = 1 self._next_sign_id = 1
with utils.ModifiableScratchBuffer( self._buf ): with utils.ModifiableScratchBuffer( self._buf ):
with utils.RestoreCursorPosition(): with utils.RestoreCursorPosition():
@ -302,7 +293,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._current_thread_sign_id, signs.PlaceSign( self._next_sign_id,
'VimspectorStackTrace', 'VimspectorStackTrace',
'vimspectorCurrentThread', 'vimspectorCurrentThread',
self._buf.name, self._buf.name,
@ -433,7 +424,6 @@ class StackTraceView( object ):
# 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
@ -531,11 +521,6 @@ class StackTraceView( object ):
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' ]
@ -560,14 +545,6 @@ 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 ):
@ -588,7 +565,10 @@ class StackTraceView( object ):
buf = utils.BufferForFile( buf_name ) buf = utils.BufferForFile( buf_name )
self._scratch_buffers.append( buf ) self._scratch_buffers.append( buf )
utils.SetUpHiddenBuffer( buf, buf_name ) utils.SetUpHiddenBuffer( buf,
utils.BufferNameForSession(
buf_name,
self._session.session_id ) )
source[ 'path' ] = buf_name source[ 'path' ] = buf_name
with utils.ModifiableScratchBuffer( buf ): with utils.ModifiableScratchBuffer( buf ):
utils.SetBufferContents( buf, msg[ 'body' ][ 'content' ] ) utils.SetBufferContents( buf, msg[ 'body' ][ 'content' ] )

View file

@ -32,13 +32,30 @@ LOG_FILE = os.path.expanduser( os.path.join( '~', '.vimspector.log' ) )
_log_handler = logging.FileHandler( LOG_FILE, mode = 'w' ) _log_handler = logging.FileHandler( LOG_FILE, mode = 'w' )
_log_handler.setFormatter( _log_handler.setFormatter(
logging.Formatter( '%(asctime)s - %(levelname)s - %(message)s' ) ) logging.Formatter( '%(asctime)s - %(levelname)s - %(filename)s:%(lineno)s - '
'%(context)s - %(message)s' ) )
def SetUpLogging( logger ): class ContextLogFilter( logging.Filter ):
context: str
def __init__( self, context ):
self.context = str( context )
def filter( self, record: logging.LogRecord ):
if self.context is None:
record.context = 'UNKNOWN'
else:
record.context = self.context
return True
def SetUpLogging( logger, context = None ):
logger.setLevel( logging.DEBUG ) logger.setLevel( logging.DEBUG )
if _log_handler not in logger.handlers: if _log_handler not in logger.handlers:
logger.addHandler( _log_handler ) logger.addHandler( _log_handler )
logger.addFilter( ContextLogFilter( context ) )
_logger = logging.getLogger( __name__ ) _logger = logging.getLogger( __name__ )
@ -87,16 +104,21 @@ def OpenFileInCurrentWindow( file_name ):
COMMAND_HANDLERS = {} COMMAND_HANDLERS = {}
def OnCommandWithLogComplete( name, exit_code ): def OnCommandWithLogComplete( session_id, name, exit_code ):
cb = COMMAND_HANDLERS.get( name ) cb = COMMAND_HANDLERS.get( str( session_id ) + '.' + name )
if cb: if cb:
cb( exit_code ) cb( exit_code )
def SetUpCommandBuffer( cmd, name, api_prefix, completion_handler = None ): def SetUpCommandBuffer( session_id,
COMMAND_HANDLERS[ name ] = completion_handler cmd,
name,
api_prefix,
completion_handler = None ):
COMMAND_HANDLERS[ str( session_id ) + '.' + name ] = completion_handler
buf = Call( f'vimspector#internal#{api_prefix}job#StartCommandWithLog', buf = Call( f'vimspector#internal#{api_prefix}job#StartCommandWithLog',
session_id,
cmd, cmd,
name ) name )
@ -110,10 +132,12 @@ def SetUpCommandBuffer( cmd, name, api_prefix, completion_handler = None ):
return vim.buffers[ int( buf ) ] return vim.buffers[ int( buf ) ]
def CleanUpCommand( name, api_prefix ): def CleanUpCommand( session_id, name, api_prefix ):
return vim.eval( 'vimspector#internal#{}job#CleanUpCommand( "{}" )'.format( return vim.eval(
api_prefix, 'vimspector#internal#{}job#CleanUpCommand( {}, "{}" )'.format(
name ) ) api_prefix,
session_id,
name ) )
def CleanUpHiddenBuffer( buf ): def CleanUpHiddenBuffer( buf ):
@ -397,6 +421,8 @@ def Confirm( api_prefix,
default_value = 2, default_value = 2,
options: list = None, options: list = None,
keys: list = None ): keys: list = None ):
# TODO: Implement a queue here? If calling code calls Confirm (async) multiple
# times, we... well what happens?!
if not options: if not options:
options = [ '(Y)es', '(N)o' ] options = [ '(Y)es', '(N)o' ]
if not keys: if not keys:
@ -864,3 +890,12 @@ def UseWinBar():
# Buggy neovim doesn't render correctly when the WinBar is defined: # Buggy neovim doesn't render correctly when the WinBar is defined:
# https://github.com/neovim/neovim/issues/12689 # https://github.com/neovim/neovim/issues/12689
return not int( Call( 'has', 'nvim' ) ) return not int( Call( 'has', 'nvim' ) )
def BufferNameForSession( name, session_id ):
if session_id == 0:
# Hack for backward compat - don't suffix with the ID for the "first"
# session
return name
return f'{name}[{session_id}]'

View file

@ -166,10 +166,11 @@ def AddExpandMappings( mappings = None ):
class VariablesView( object ): class VariablesView( object ):
def __init__( self, variables_win, watches_win ): def __init__( self, session, variables_win, watches_win ):
self._logger = logging.getLogger( __name__ ) self._logger = logging.getLogger( __name__ + '.' + str( session.session_id ) )
utils.SetUpLogging( self._logger ) utils.SetUpLogging( self._logger, session.session_id )
self._session = session
self._connection = None self._connection = None
self._current_syntax = '' self._current_syntax = ''
self._server_capabilities = None self._server_capabilities = None
@ -182,7 +183,10 @@ class VariablesView( object ):
# 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,
utils.BufferNameForSession( 'vimspector.Variables',
self._session.session_id ) )
with utils.LetCurrentWindow( variables_win ): with utils.LetCurrentWindow( variables_win ):
if utils.UseWinBar(): if utils.UseWinBar():
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set ' vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
@ -193,11 +197,14 @@ class VariablesView( object ):
# there) # there)
self._watches: typing.List[ Watch ] = [] self._watches: typing.List[ Watch ] = []
self._watch = View( watches_win, {}, self._DrawWatches ) self._watch = View( watches_win, {}, self._DrawWatches )
utils.SetUpPromptBuffer( self._watch.buf, utils.SetUpPromptBuffer(
'vimspector.Watches', self._watch.buf,
'Expression: ', utils.BufferNameForSession( 'vimspector.Watches',
'vimspector#AddWatchPrompt', self._session.session_id ),
'vimspector#OmniFuncWatch' ) 'Expression: ',
'vimspector#AddWatchPrompt',
'vimspector#OmniFuncWatch' )
with utils.LetCurrentWindow( watches_win ): with utils.LetCurrentWindow( watches_win ):
AddExpandMappings( mappings ) AddExpandMappings( mappings )
for mapping in utils.GetVimList( mappings, 'delete' ): for mapping in utils.GetVimList( mappings, 'delete' ):
@ -224,9 +231,12 @@ class VariablesView( object ):
'balloonexpr': vim.options[ 'balloonexpr' ], 'balloonexpr': vim.options[ 'balloonexpr' ],
'balloondelay': vim.options[ 'balloondelay' ], 'balloondelay': vim.options[ 'balloondelay' ],
} }
# TODO: How can we make this work. I think we can set ballooneval as a
# buffer-local or maybe window-local variable ? We could pass session_id
# to the expression here, but still how would it work with 2 concurrent
# sessions?
vim.options[ 'balloonexpr' ] = ( "vimspector#internal#" vim.options[ 'balloonexpr' ] = ( "vimspector#internal#"
"balloon#HoverTooltip()" ) "balloon#HoverTooltip()" )
vim.options[ 'balloondelay' ] = 250 vim.options[ 'balloondelay' ] = 250
if has_balloon: if has_balloon:

View file

@ -21,7 +21,7 @@ out_fd=1
while [ -n "$1" ]; do while [ -n "$1" ]; do
case "$1" in case "$1" in
"--basedir"|"--base-dir"|"--test-base") "--basedir")
shift shift
SetBaseDir $1 SetBaseDir $1
shift shift
@ -36,7 +36,7 @@ while [ -n "$1" ]; do
INSTALL=$1 INSTALL=$1
shift shift
;; ;;
"--update"|"--upgrade") "--update")
UPDATE=1 UPDATE=1
shift shift
;; ;;
@ -91,8 +91,7 @@ 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 \ --all; then
--force-enable-csharp; then
echo "Script installation reported errors" >&2 echo "Script installation reported errors" >&2
exit 1 exit 1
fi fi
@ -103,7 +102,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 netcoredbg"; then -c "VimspectorInstall --all"; then
echo "Vim installation reported errors" >&2 echo "Vim installation reported errors" >&2
exit 1 exit 1
fi fi
@ -145,9 +144,6 @@ 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 string(cols) . 'wincmd |' execute cols . 'wincmd |'
endfunction endfunction
function! s:CustomiseWinBar() function! s:CustomiseWinBar()

View file

@ -1,8 +0,0 @@
# 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

@ -1,13 +0,0 @@
#!/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

@ -1,15 +0,0 @@
{
"$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,15 +15,6 @@
"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', '-std=c++17' ] 'flags': [ '-x', 'c++', '-Wall', '-Wextra' ]
} }

View file

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

View file

@ -1,57 +1,25 @@
{ {
"adapters": { "configurations": {
"netcoredbg-debuglog": { "launch - netcoredbg": {
"attach": { "adapter": "netcoredbg",
"pidProperty": "processId", "configuration": {
"pidSelect": "ask" "request": "launch",
"program": "${workspaceRoot}/bin/Debug/netcoreapp2.2/csharp.dll",
"args": [],
"stopAtEntry": true
}
}, },
"command": [ "launch - mono": {
"${gadgetDir}/netcoredbg/netcoredbg", "adapter": "vscode-mono-debug",
"--interpreter=vscode", "configuration": {
"--engineLogging=${workspaceRoot}/netcoredbg.engine.log", "request": "launch",
"--log=${workspaceRoot}/netcoredbg.log" "program": "${workspaceRoot}/Program.exe",
], "console": "integratedTerminal",
"configuration": { "cwd": "${workspaceRoot}",
"cwd": "${workspaceRoot}" "args": [],
}, "env": {}
"name": "netcoredbg" }
}
},
"configurations": {
//
// NOTE:
// If you add to this, you must update tests/get_configurations.test.vim
//
"launch - netcoredbg": {
"adapter": "netcoredbg",
"configuration": {
"request": "launch",
"program": "${workspaceRoot}/bin/Debug/netcoreapp3.1/csharp.dll",
"args": [],
"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": {
"adapter": "vscode-mono-debug",
"configuration": {
"request": "launch",
"program": "${workspaceRoot}/Program.exe",
"console": "integratedTerminal",
"cwd": "${workspaceRoot}",
"args": [],
"env": {}
} }
} }
}
} }

View file

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

View file

@ -3,8 +3,6 @@ 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
@ -17,18 +15,4 @@ 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

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

View file

@ -0,0 +1,21 @@
<?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

@ -0,0 +1,10 @@
<?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

@ -0,0 +1,748 @@
{
"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,29 +0,0 @@
{
"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

@ -1,33 +0,0 @@
# 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

@ -1,20 +0,0 @@
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

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

View file

@ -1,9 +0,0 @@
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

@ -1,30 +0,0 @@
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

@ -0,0 +1,43 @@
{
"$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json",
"configurations": {
"run": {
"adapter": "debugpy",
"configuration": {
"request": "launch",
"type": "python",
"cwd": "${workspaceRoot}",
"program": "${file}",
"stopOnEntry": true,
"console": "integratedTerminal",
"subProcess": true
},
"breakpoints": {
"exception": {
"raised": "N",
"uncaught": "Y",
"userUnhandled": ""
}
}
},
"attach": {
"adapter": "multi-session",
"configuration": {
"request": "attach",
"type": "python",
"cwd": "${workspaceRoot}",
"program": "${file}",
"stopOnEntry": true,
"console": "integratedTerminal",
"subProcess": true
},
"breakpoints": {
"exception": {
"raised": "N",
"uncaught": "Y",
"userUnhandled": ""
}
}
}
}
}

View file

@ -0,0 +1,18 @@
import time
import multiprocessing as mp
def First():
for i in range( 10 ):
print( f"in first x {i}" )
time.sleep( 0.1 )
if __name__ == '__main__':
print( "main" )
p1 = mp.Process( target=First )
p1.start()
p1.join()
print( "Done" )

View file

@ -6,8 +6,9 @@ import os
def Main(): def Main():
print( os.environ.get( 'Something', 'ERROR' ) ) print( os.environ.get( 'Something', 'ERROR' ) )
print( os.environ.get( 'SomethingElse', 'ERROR' ) ) print( os.environ.get( 'SomethingElse', 'ERROR' ) )
print( os.environ.get( 'PATH', 'ERROR' ) )
for k, v in os.environ: for k, v in os.environ.items():
print( f'{ k } = "{ v }"' ) print( f'{ k } = "{ v }"' )

View file

@ -70,12 +70,6 @@ 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,7 +12,6 @@ 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

@ -1,65 +0,0 @@
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

@ -107,3 +107,46 @@ function! Test_Python_Remote_Attach()
lcd - lcd -
%bwipeout! %bwipeout!
endfunction endfunction
function! SetUp_Test_Python_Remote_Attach_With_Run()
let g:vimspector_enable_mappings = 'HUMAN'
endfunction
function! Test_Python_Remote_Attach_With_Run()
lcd ../support/test/python/simple_python
let fn='main.py'
exe 'edit ' . fn
call setpos( '.', [ 0, 6, 1 ] )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 6, 1 )
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 6 )
" Add the breakpoint
call feedkeys( "\<F9>", 'xt' )
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
\ 6,
\ 'vimspectorBP',
\ 9 )
call setpos( '.', [ 0, 1, 1 ] )
" Here we go. Start Debugging (note will wait up to 10s for the script to do
" its virtualenv thing)
call vimspector#LaunchWithSettings( {
\ 'configuration': 'attach-run',
\ } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 6, 1 )
" Step
call feedkeys( "\<F10>", 'xt' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 7, 1 )
call WaitForAssert( {->
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 7 )
\ } )
call vimspector#test#setup#Reset()
lcd -
%bwipeout!
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! AssertMatchList( expected, actual ) abort function! AssertMatchist( 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

@ -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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ 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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
\ '+ Thread [0-9]\+: .* (paused)', \ '+ Thread [0-9]\+: .* (paused)',
@ -366,7 +366,7 @@ function! Test_UpDownStack()
call vimspector#LaunchWithSettings( { 'configuration': 'run' } ) call vimspector#LaunchWithSettings( { 'configuration': 'run' } )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Thread 1: MainThread (paused)', \ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15', \ ' 2: DoSomething@main.py:15',
@ -379,25 +379,11 @@ function! Test_UpDownStack()
\ '$' ) \ '$' )
\ ) \ )
\ } ) \ } )
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#DownFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Thread 1: MainThread (paused)', \ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15', \ ' 2: DoSomething@main.py:15',
@ -410,26 +396,11 @@ function! Test_UpDownStack()
\ '$' ) \ '$' )
\ ) \ )
\ } ) \ } )
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#UpFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Thread 1: MainThread (paused)', \ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15', \ ' 2: DoSomething@main.py:15',
@ -442,26 +413,11 @@ function! Test_UpDownStack()
\ '$' ) \ '$' )
\ ) \ )
\ } ) \ } )
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 feedkeys( "\<Plug>VimspectorUpFrame", 'x' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 23, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 23, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Thread 1: MainThread (paused)', \ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15', \ ' 2: DoSomething@main.py:15',
@ -474,26 +430,11 @@ function! Test_UpDownStack()
\ '$' ) \ '$' )
\ ) \ )
\ } ) \ } )
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 feedkeys( "\<Plug>VimspectorDownFrame", 'x' )
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Thread 1: MainThread (paused)', \ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15', \ ' 2: DoSomething@main.py:15',
@ -506,26 +447,11 @@ function! Test_UpDownStack()
\ '$' ) \ '$' )
\ ) \ )
\ } ) \ } )
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#DownFrame()
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 ) call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Thread 1: MainThread (paused)', \ '- Thread 1: MainThread (paused)',
\ ' 2: DoSomething@main.py:15', \ ' 2: DoSomething@main.py:15',
@ -538,21 +464,6 @@ function! Test_UpDownStack()
\ '$' ) \ '$' )
\ ) \ )
\ } ) \ } )
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()

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

@ -194,7 +194,6 @@ 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,
@ -212,7 +211,7 @@ function! Test_ExpandVariables()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' \*- t (Test): {...}', \ ' \*- t (Test): {...}',
@ -220,7 +219,6 @@ 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,
@ -231,7 +229,7 @@ function! Test_ExpandVariables()
" Step - stays expanded " Step - stays expanded
call vimspector#StepOver() call vimspector#StepOver()
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' - t (Test): {...}', \ ' - t (Test): {...}',
@ -239,7 +237,6 @@ 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,
@ -256,7 +253,6 @@ 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,
@ -271,7 +267,6 @@ 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,
@ -283,7 +278,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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' - t (Test): {...}', \ ' - t (Test): {...}',
@ -291,7 +286,6 @@ 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,
@ -308,7 +302,6 @@ 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,
@ -323,7 +316,6 @@ 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,
@ -339,7 +331,6 @@ 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,
@ -387,7 +378,7 @@ function! Test_ExpandWatch()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -406,7 +397,7 @@ function! Test_ExpandWatch()
" Step - stays expanded " Step - stays expanded
call vimspector#StepOver() call vimspector#StepOver()
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -458,7 +449,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( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -616,7 +607,7 @@ function! Test_EvaluateFailure()
" Add a wtch " Add a wtch
call vimspector#AddWatch( 'test' ) call vimspector#AddWatch( 'test' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: test', \ 'Expression: test',
@ -667,7 +658,7 @@ function! Test_VariableEval()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -699,7 +690,7 @@ function! Test_VariableEval()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -733,7 +724,7 @@ function! Test_VariableEval()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Evaluation error', \ 'Evaluation error',
\ ], \ ],
@ -777,7 +768,7 @@ function! Test_VariableEvalExpand()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -795,7 +786,7 @@ function! Test_VariableEvalExpand()
call feedkeys( "jjjj\<CR>", 'xt' ) call feedkeys( "jjjj\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -815,7 +806,7 @@ function! Test_VariableEvalExpand()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -855,7 +846,6 @@ function! Test_SetVariableValue_Local()
\ [ \ [
\ '- 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,
@ -873,7 +863,7 @@ function! Test_SetVariableValue_Local()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' \*- t (Test): {...}', \ ' \*- t (Test): {...}',
@ -881,7 +871,6 @@ function! Test_SetVariableValue_Local()
\ ' \*- 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,
@ -900,7 +889,7 @@ with mock.patch( 'vimspector.utils.InputSave' ):
EOF EOF
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' \*- t (Test): {...}', \ ' \*- t (Test): {...}',
@ -908,7 +897,6 @@ EOF
\ ' \*- 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,
@ -920,7 +908,7 @@ EOF
call vimspector#SetVariableValue( '1234' ) call vimspector#SetVariableValue( '1234' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' \*- t (Test): {...}', \ ' \*- t (Test): {...}',
@ -928,7 +916,6 @@ EOF
\ ' \*- 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,
@ -940,7 +927,7 @@ EOF
call vimspector#SetVariableValue( 'this is invalid' ) call vimspector#SetVariableValue( 'this is invalid' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '- Scope: Locals', \ '- Scope: Locals',
\ ' \*- t (Test): {...}', \ ' \*- t (Test): {...}',
@ -948,7 +935,6 @@ EOF
\ ' \*- 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,
@ -997,7 +983,7 @@ function! Test_SetVariableValue_Watch()
call feedkeys( "\<CR>", 'xt' ) call feedkeys( "\<CR>", 'xt' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -1026,7 +1012,7 @@ EOF
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -1046,7 +1032,7 @@ EOF
call vimspector#SetVariableValue( '1234' ) call vimspector#SetVariableValue( '1234' )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ 'Watches: ----', \ 'Watches: ----',
\ 'Expression: t', \ 'Expression: t',
@ -1089,7 +1075,7 @@ function! Test_SetVariableValue_Balloon()
\ } ) \ } )
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',
@ -1116,7 +1102,7 @@ with mock.patch( 'vimspector.utils.InputSave' ):
EOF EOF
call WaitForAssert( {-> call WaitForAssert( {->
\ AssertMatchList( \ AssertMatchist(
\ [ \ [
\ '{...}', \ '{...}',
\ ' - i: 0', \ ' - i: 0',