Compare commits
244 commits
setup-guid
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c12519b9d | ||
|
|
2bb8561eb6 |
||
|
|
a868102b5e |
||
|
|
dc862fe565 | ||
|
|
b4bcfca932 |
||
|
|
3df0602a69 |
||
|
|
1c2dda4a6a |
||
|
|
db5ed8e802 | ||
|
|
17ca1522f8 | ||
|
|
561a5b9aa2 | ||
|
|
46cfdc678d | ||
|
|
51d78fce5f |
||
|
|
14f34ea6d1 |
||
|
|
a720d0e1d5 | ||
|
|
7c7e3f9c3f | ||
|
|
57ce099280 | ||
|
|
27eb464b8e |
||
|
|
f1e2c12e5b | ||
|
|
26cd7c5c7e |
||
|
|
59c9cd10ab | ||
|
|
9c806d2a01 |
||
|
|
3af97f1928 |
||
|
|
da39c4955c |
||
|
|
21ebb22fd4 | ||
|
|
aa0cddc0da |
||
|
|
5075f3a11a | ||
|
|
bab81953d7 |
||
|
|
0500e41429 |
||
|
|
1cbb400d42 |
||
|
|
5ea1f0d9d4 | ||
|
|
a51b8b23c9 | ||
|
|
99c0c4f763 |
||
|
|
daa8865fea |
||
|
|
f4d756fe86 |
||
|
|
d43904eb57 | ||
|
|
aacd62f09f | ||
|
|
0e9497ce8f | ||
|
|
2708e8e6ec |
||
|
|
adf6163653 |
||
|
|
0af9d70b0d |
||
|
|
9113dbb698 | ||
|
|
08679d1c3e | ||
|
|
4e04a862cb | ||
|
|
a7e8e93920 | ||
|
|
2b84439413 | ||
|
|
0c88cc8bad | ||
|
|
a47d0b921c |
||
|
|
026ac22280 | ||
|
|
297c0bea56 | ||
|
|
a9a26a5a60 |
||
|
|
1e25313cb5 | ||
|
|
bc15c94513 | ||
|
|
f389d65a24 | ||
|
|
b4195eee93 | ||
|
|
6ad9101cf2 |
||
|
|
a41db89523 | ||
|
|
dd88e051a4 | ||
|
|
fa92c2a8d5 | ||
|
|
6709b45c77 |
||
|
|
278fc3cd8c | ||
|
|
13a5a1b947 | ||
|
|
7d83419a4f | ||
|
|
7b3016aa90 |
||
|
|
d70d51a614 | ||
|
|
caeb6610ed |
||
|
|
0d9e7835a8 | ||
|
|
054ea35428 | ||
|
|
244d7d8fdf | ||
|
|
35e5b3d56e | ||
|
|
842d9fbc2d | ||
|
|
6a24a17f2e |
||
|
|
91e0426e88 |
||
|
|
bf24b37190 |
||
|
|
2d589475eb |
||
|
|
1414f261a1 | ||
|
|
a39017dd06 | ||
|
|
c05335c799 | ||
|
|
efc5c76866 | ||
|
|
154e727b96 | ||
|
|
6b74e584d5 | ||
|
|
85bb8594ab | ||
|
|
63fd3165fb | ||
|
|
afb912dd08 | ||
|
|
b92a89f0d4 | ||
|
|
6f88b400e1 | ||
|
|
af2670ef9a |
||
|
|
2b24611036 |
||
|
|
d84ebdd0ee |
||
|
|
6b67d165b9 | ||
|
|
a53d68f043 | ||
|
|
6d3f3e207b | ||
|
|
5716bbefa9 |
||
|
|
2615cff97a | ||
|
|
01ea50cb70 | ||
|
|
7d2770f3c4 | ||
|
|
2a635294d0 | ||
|
|
38c843219e | ||
|
|
c012f9520e | ||
|
|
943ae6c7c9 | ||
|
|
82db32780b | ||
|
|
4cb4b814a1 |
||
|
|
d2b92b7ce5 | ||
|
|
5bd83d3e37 | ||
|
|
f6517892c1 |
||
|
|
edcb057ead | ||
|
|
06f9bfc057 | ||
|
|
804b499286 | ||
|
|
49a9a4b367 | ||
|
|
f2d407256e | ||
|
|
94242fa532 | ||
|
|
ba83a59e88 | ||
|
|
675a68c601 | ||
|
|
e1078375fe | ||
|
|
26452289a8 | ||
|
|
ec9122284e | ||
|
|
131cfcdd33 | ||
|
|
c2082cffae | ||
|
|
9e1a1ab4b5 | ||
|
|
32f9a6ec43 | ||
|
|
d8d6eb2286 | ||
|
|
1d38b8198f |
||
|
|
f40ac5db23 | ||
|
|
11edcddd9c |
||
|
|
f9c5a33301 |
||
|
|
fdfa8b265b |
||
|
|
a8651e257b |
||
|
|
d8eb6a0463 | ||
|
|
09efcf5e50 | ||
|
|
5201995279 | ||
|
|
fd03e074f3 |
||
|
|
fd0c6e7675 | ||
|
|
6fac220ee5 | ||
|
|
0810d7154c | ||
|
|
476300f815 | ||
|
|
95b900a0a7 |
||
|
|
0e0cc6d4ae | ||
|
|
c33fddd150 |
||
|
|
448ee33a6a | ||
|
|
ae289a88c7 | ||
|
|
3c7311e33a | ||
|
|
d561c4aea5 | ||
|
|
3c54cd268f | ||
|
|
bcf4120ba4 | ||
|
|
50dc55e0e8 | ||
|
|
716181e056 | ||
|
|
840ee09242 | ||
|
|
0bb8416e11 | ||
|
|
d81bdf30ef | ||
|
|
e70b8f37a3 |
||
|
|
5754e96067 | ||
|
|
4958de92d3 | ||
|
|
6b546cd621 | ||
|
|
323e22b8a9 | ||
|
|
5a1eb9250a | ||
|
|
cc84e15932 | ||
|
|
7dcb15f11c | ||
|
|
44711899cb | ||
|
|
0313efa06f | ||
|
|
51d551fe52 | ||
|
|
ae137ecdd0 | ||
|
|
d6c68d691c | ||
|
|
47680565c4 | ||
|
|
8c39a861bd | ||
|
|
639e89f5db | ||
|
|
5a23ec5beb | ||
|
|
e0b0a7f3d2 | ||
|
|
0ff9dc5f9e | ||
|
|
0c79384529 | ||
|
|
789377eab4 | ||
|
|
4466fce20b | ||
|
|
13102dc711 | ||
|
|
91bebc1826 | ||
|
|
3239963893 | ||
|
|
31e44548d3 | ||
|
|
e5e13ffcdd | ||
|
|
894ca522d3 | ||
|
|
322b7e0a38 | ||
|
|
bc1146df3b | ||
|
|
d2ed8a828c | ||
|
|
fccafd6739 | ||
|
|
672ac78fef | ||
|
|
64f2c8eb01 | ||
|
|
cb174c176d | ||
|
|
2d082cc923 | ||
|
|
0d703779dc | ||
|
|
f3c39e12ab | ||
|
|
cfae062da1 | ||
|
|
0b4da4c82b | ||
|
|
64e38b57ab | ||
|
|
0895c5e829 | ||
|
|
052d63dee5 | ||
|
|
93568ba05d | ||
|
|
e0b1d6ed81 | ||
|
|
3c857cebf4 | ||
|
|
2f1c93a2ac | ||
|
|
cb441be7bc | ||
|
|
b9ed7f34b4 | ||
|
|
04a5e889f9 | ||
|
|
f60b259dbc | ||
|
|
b95ae00054 | ||
|
|
4617250f41 | ||
|
|
0ced5eb1d4 | ||
|
|
747ad9b804 | ||
|
|
d2990d7bae | ||
|
|
819d6366ac | ||
|
|
4e994968ff | ||
|
|
7432be9532 | ||
|
|
07858cc250 | ||
|
|
4c0ba92ac6 | ||
|
|
7c4eef9096 | ||
|
|
85ca867cc2 |
||
|
|
cb922bdc83 |
||
|
|
e99ac0d658 |
||
|
|
0cc4322b18 | ||
|
|
7f77842ab8 | ||
|
|
4454dead0f |
||
|
|
30eec0d93c | ||
|
|
52eff32651 |
||
|
|
5303de8195 |
||
|
|
75e8450cf3 | ||
|
|
35f7e08fbb | ||
|
|
d38da376c2 | ||
|
|
1f20115960 | ||
|
|
442a18f8f2 |
||
|
|
e010d3217c | ||
|
|
1556e63ef0 |
||
|
|
205eb7cdb3 |
||
|
|
44a0f819e2 |
||
|
|
4206d0e57c | ||
|
|
b180b14ed4 |
||
|
|
d52eb3a6e9 | ||
|
|
b72aa18dec | ||
|
|
07ea3880ac |
||
|
|
38ed75dda7 |
||
|
|
0ad826704b |
||
|
|
65708f55e0 |
||
|
|
7bd22d2bbd | ||
|
|
ce8dd9113c | ||
|
|
ec68811c8a | ||
|
|
47c404f823 | ||
|
|
f59ba048cb |
||
|
|
f20c4c9725 | ||
|
|
66130389c5 | ||
|
|
28c5534704 |
83 changed files with 7805 additions and 2090 deletions
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
10
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -17,12 +17,12 @@ assignees: ''
|
|||
|
||||
> Please answer the following questions
|
||||
|
||||
* Does your issue reproduce using `vim -Nu /path/to/vimspector/support/minimal_vimrc` ? \[Yes/No]
|
||||
* Does your issue reproduce using `vim --clean -Nu /path/to/vimspector/support/minimal_vimrc` ? \[Yes/No]
|
||||
* If you are using Neovim, does your issue reproduce using Vim? \[Yes/No]
|
||||
|
||||
> List of steps to reproduce:
|
||||
|
||||
> 1. Run `vim -Nu /path/to/vimspector/support/minimal_vimrc`
|
||||
> 1. Run `vim ---clean Nu /path/to/vimspector/support/minimal_vimrc`
|
||||
> 2. Open _this project_...
|
||||
> 3. Press _this sequence of keys_
|
||||
|
||||
|
|
@ -57,6 +57,12 @@ discussing on Gitter rather than raising an issue.
|
|||
* Version of Vimspector: (e.g. output of `git rev-parse HEAD` if cloned or the
|
||||
name of the tarball used to install otherwise)
|
||||
|
||||
* Output of `:VimspectorDebugInfo`
|
||||
|
||||
```
|
||||
paste here
|
||||
```
|
||||
|
||||
* Output of `vim --version` or `nvim --version`
|
||||
|
||||
```
|
||||
|
|
|
|||
12
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
12
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Questions and support
|
||||
url: http://gitter.im/vimspector/Lobby
|
||||
about: Please ask and answer questions here.
|
||||
- name: Discussions
|
||||
url: https://github.com/puremourning/vimspector/discussions
|
||||
about: Please post questions and useful hints here
|
||||
- name: Support for additional languages
|
||||
url: https://github.com/puremourning/vimspector/wiki/languages
|
||||
about: Please see here for information on support for additional languages
|
||||
|
||||
20
.github/workflows/build.yaml
vendored
20
.github/workflows/build.yaml
vendored
|
|
@ -13,7 +13,7 @@ defaults:
|
|||
|
||||
jobs:
|
||||
PythonLint:
|
||||
runs-on: ubuntu-16.04
|
||||
runs-on: ubuntu-18.04
|
||||
container: 'puremourning/vimspector:test'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
|
@ -22,7 +22,7 @@ jobs:
|
|||
- name: 'Run flake8'
|
||||
run: '$HOME/.local/bin/flake8 python3/ *.py'
|
||||
VimscriptLint:
|
||||
runs-on: 'ubuntu-16.04'
|
||||
runs-on: 'ubuntu-18.04'
|
||||
container: 'puremourning/vimspector:test'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
run: $HOME/.local/bin/vint autoload/ compiler/ plugin/ tests/ syntax/
|
||||
|
||||
Linux:
|
||||
runs-on: 'ubuntu-16.04'
|
||||
runs-on: 'ubuntu-18.04'
|
||||
container:
|
||||
image: 'puremourning/vimspector:test'
|
||||
options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined
|
||||
|
|
@ -111,6 +111,16 @@ jobs:
|
|||
path: gadgets/macos/download
|
||||
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
|
||||
name: 'Print vim version information'
|
||||
|
||||
|
|
@ -143,10 +153,10 @@ jobs:
|
|||
# if: failure()
|
||||
# with:
|
||||
# NGROK_AUTH_TOKEN: ${{ secrets.NGROK_AUTH_TOKEN }}
|
||||
# SSH_PASS: ${{ secrets.SSH_PASS }}
|
||||
# SSH_PASS: ${{ secrets.SSH_PASS }} # [V]imspector
|
||||
|
||||
PublishRelease:
|
||||
runs-on: 'ubuntu-16.04'
|
||||
runs-on: 'ubuntu-18.04'
|
||||
needs:
|
||||
- Linux
|
||||
- MacOS
|
||||
|
|
|
|||
27
.github/workflows/lock_old_issues.yaml
vendored
Normal file
27
.github/workflows/lock_old_issues.yaml
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
name: "Lock Old Issues"
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '60'
|
||||
# issue-exclude-created-before: ''
|
||||
# issue-exclude-labels: ''
|
||||
# issue-lock-labels: ''
|
||||
# issue-lock-comment: ''
|
||||
# issue-lock-reason: 'resolved'
|
||||
# pr-lock-inactive-days: '365'
|
||||
# pr-exclude-created-before: ''
|
||||
# pr-exclude-labels: ''
|
||||
# pr-lock-labels: ''
|
||||
# pr-lock-comment: ''
|
||||
# pr-lock-reason: 'resolved'
|
||||
process-only: 'issues'
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -20,3 +20,4 @@ support/test/csharp/*.exe*
|
|||
configurations/
|
||||
venv/
|
||||
test-base/
|
||||
tags
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ pull_request_rules:
|
|||
# CI https://doc.mergify.io/conditions.html#github-actions
|
||||
- status-success=PythonLint
|
||||
- status-success=VimscriptLint
|
||||
- status-success=Linux
|
||||
- status-success=MacOS
|
||||
|
||||
|
||||
actions: &merge-actions
|
||||
merge:
|
||||
method: merge
|
||||
|
|
|
|||
|
|
@ -42,7 +42,17 @@ def Settings( **kwargs ):
|
|||
return {
|
||||
'sys_path': [
|
||||
p.join( PATH_TO_THIS_DIR, 'python3' )
|
||||
]
|
||||
],
|
||||
'ls': {
|
||||
'python': {
|
||||
'analysis': {
|
||||
'extraPaths': [
|
||||
p.join( PATH_TO_THIS_DIR, 'python3' ),
|
||||
],
|
||||
'useLibraryCodeForTypes': True
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if IgnoreExtraConf:
|
||||
|
|
|
|||
|
|
@ -46,6 +46,23 @@ The GitHub issue tracker is for *bug reports* and *features requests* for the
|
|||
Vimspector project, and on-topic comments and follow-ups to them. It is not for
|
||||
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
|
||||
of the following reasons:
|
||||
|
||||
|
|
@ -53,6 +70,7 @@ of the following reasons:
|
|||
* The issue or comment is off-topic
|
||||
* The issue does not represent a Vimspector bug or feature request
|
||||
* The issue cannot be reasonably reproduced using the minimal vimrc
|
||||
* The issue is a duplicate of an existing issue
|
||||
* etc.
|
||||
|
||||
Issue titles are important. It's not usually helpful to write a title like
|
||||
|
|
@ -83,7 +101,7 @@ in the issue report.
|
|||
The minimal vimrc is in `support/test/minimal_vimrc` and can be used as follows:
|
||||
|
||||
```
|
||||
vim -Nu /path/to/vimspector/support/minimal_vimrc
|
||||
vim --clean -Nu /path/to/vimspector/support/minimal_vimrc
|
||||
```
|
||||
|
||||
## Pull Requests
|
||||
|
|
@ -184,6 +202,30 @@ They're also run by CI, so please check for lint failures. The canonical
|
|||
definition of the command to run is the command run in CI, i.e. in
|
||||
`.git/workflows/build.yml`.
|
||||
|
||||
### Debugging Vimspector
|
||||
|
||||
You can debug vimspector's python code using vimspector! We can use debugpy,
|
||||
from within Vim's embedded python and connect to it. Here's how:
|
||||
|
||||
1. In one instance of vim, run the following to get debugpy to start listening
|
||||
for us to connect: `:py3 __import__( 'vimspector', fromlist=[ 'developer' ]
|
||||
).developer.SetUpDebugpy()`
|
||||
|
||||
2. In another instance of Vim, set a breakpoint in the vimspector python code
|
||||
you want to debug and launch vimspector (e.g. `<F5>`). Select the `Python:
|
||||
attach to vim` profile. This will attach to the debugpy running in the other
|
||||
vim.
|
||||
|
||||
3. Back in the first vim (the debuggee), trigger the vimspector code in
|
||||
question, e.g. by starting to debug something else.
|
||||
|
||||
4. You'll see it pause, and the 2nd vim (the debugger), you should be able to
|
||||
step through and inspect as with any other python remote debugging.
|
||||
|
||||
NB. It's also possible to debug the vimscript code using vimspector, but this
|
||||
requires unreleased vim patches and a fair amount of faff. You can always use
|
||||
`:debug` (see the help) for this though.
|
||||
|
||||
# Code of conduct
|
||||
|
||||
Please see [code of conduct](CODE_OF_CONDUCT.md).
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@
|
|||
" See the License for the specific language governing permissions and
|
||||
" limitations under the License.
|
||||
|
||||
if !has( 'python3' )
|
||||
finish
|
||||
endif
|
||||
|
||||
" Boilerplate {{{
|
||||
let s:save_cpo = &cpoptions
|
||||
|
|
@ -41,11 +44,11 @@ function! s:Enabled() abort
|
|||
return s:enabled
|
||||
endfunction
|
||||
|
||||
function! vimspector#Launch() abort
|
||||
function! vimspector#Launch( ... ) abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Start()
|
||||
py3 _vimspector_session.Start( *vim.eval( 'a:000' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#LaunchWithSettings( settings ) abort
|
||||
|
|
@ -55,11 +58,16 @@ function! vimspector#LaunchWithSettings( settings ) abort
|
|||
py3 _vimspector_session.Start( launch_variables = vim.eval( 'a:settings' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#Reset() abort
|
||||
function! vimspector#Reset( ... ) abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Reset()
|
||||
if a:0 == 0
|
||||
let options = {}
|
||||
else
|
||||
let options = a:1
|
||||
endif
|
||||
py3 _vimspector_session.Reset( **vim.eval( 'options' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#Restart() abort
|
||||
|
|
@ -185,11 +193,16 @@ function! vimspector#SetCurrentThread() abort
|
|||
py3 _vimspector_session.SetCurrentThread()
|
||||
endfunction
|
||||
|
||||
function! vimspector#Stop() abort
|
||||
function! vimspector#Stop( ... ) abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Stop()
|
||||
if a:0 == 0
|
||||
let options = {}
|
||||
else
|
||||
let options = a:1
|
||||
endif
|
||||
py3 _vimspector_session.Stop( **vim.eval( 'options' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#ExpandVariable() abort
|
||||
|
|
@ -199,6 +212,17 @@ function! vimspector#ExpandVariable() abort
|
|||
py3 _vimspector_session.ExpandVariable()
|
||||
endfunction
|
||||
|
||||
function! vimspector#SetVariableValue( ... ) abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
if a:0 == 0
|
||||
py3 _vimspector_session.SetVariableValue()
|
||||
else
|
||||
py3 _vimspector_session.SetVariableValue( new_value = vim.eval( 'a:1' ) )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! vimspector#DeleteWatch() abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
|
|
@ -213,12 +237,28 @@ function! vimspector#GoToFrame() abort
|
|||
py3 _vimspector_session.ExpandFrameOrThread()
|
||||
endfunction
|
||||
|
||||
function! vimspector#UpFrame() abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.UpFrame()
|
||||
endfunction
|
||||
|
||||
function! vimspector#DownFrame() abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.DownFrame()
|
||||
endfunction
|
||||
|
||||
function! vimspector#AddWatch( ... ) abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
if a:0 == 0
|
||||
let expr = input( 'Enter watch expression: ' )
|
||||
let expr = input( 'Enter watch expression: ',
|
||||
\ '',
|
||||
\ 'custom,vimspector#CompleteExpr' )
|
||||
else
|
||||
let expr = a:1
|
||||
endif
|
||||
|
|
@ -296,7 +336,7 @@ function! vimspector#GetConfigurations() abort
|
|||
return
|
||||
endif
|
||||
let configurations = py3eval(
|
||||
\ 'list( _vimspector_session.GetConfigurations().keys() )'
|
||||
\ 'list( _vimspector_session.GetConfigurations( {} )[ 1 ].keys() )'
|
||||
\ . ' if _vimspector_session else []' )
|
||||
return configurations
|
||||
endfunction
|
||||
|
|
@ -310,28 +350,6 @@ function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
|
|||
return join( buffers, "\n" )
|
||||
endfunction
|
||||
|
||||
py3 <<EOF
|
||||
def _vimspector_GetExprCompletions( ArgLead, prev_non_keyword_char ):
|
||||
if not _vimspector_session:
|
||||
return []
|
||||
|
||||
items = []
|
||||
for candidate in _vimspector_session.GetCompletionsSync(
|
||||
ArgLead,
|
||||
prev_non_keyword_char ):
|
||||
|
||||
label = candidate.get( 'text', candidate[ 'label' ] )
|
||||
|
||||
start = prev_non_keyword_char - 1
|
||||
|
||||
if 'start' in candidate and 'length' in candidate:
|
||||
start = candidate[ 'start' ]
|
||||
|
||||
items.append( ArgLead[ 0 : start ] + label )
|
||||
|
||||
return items
|
||||
EOF
|
||||
|
||||
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
|
|
@ -340,7 +358,7 @@ function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
|||
let col = len( a:ArgLead )
|
||||
let prev_non_keyword_char = match( a:ArgLead[ 0 : col - 1 ], '\k*$' ) + 1
|
||||
|
||||
return join( py3eval( '_vimspector_GetExprCompletions( '
|
||||
return join( py3eval( '_vimspector_session.GetCommandLineCompletions( '
|
||||
\ . 'vim.eval( "a:ArgLead" ), '
|
||||
\ . 'int( vim.eval( "prev_non_keyword_char" ) ) )' ),
|
||||
\ "\n" )
|
||||
|
|
@ -523,6 +541,30 @@ function! vimspector#OnBufferCreated( file_name ) abort
|
|||
py3 _vimspector_session.RefreshSigns( vim.eval( 'a:file_name' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#ShowEvalBalloon( is_visual ) abort
|
||||
if a:is_visual
|
||||
let expr = py3eval( '__import__( "vimspector", fromlist = [ "utils" ] )'
|
||||
\ . '.utils.GetVisualSelection('
|
||||
\ . ' int( vim.eval( "winbufnr( winnr() )" ) ) )' )
|
||||
let expr = join( expr, '\n' )
|
||||
else
|
||||
let expr = expand( '<cexpr>' )
|
||||
endif
|
||||
|
||||
return py3eval( '_vimspector_session.ShowEvalBalloon('
|
||||
\ . ' int( vim.eval( "winnr()" ) ), "'
|
||||
\ . expr
|
||||
\ . '", 0 )' )
|
||||
endfunction
|
||||
|
||||
function! vimspector#PrintDebugInfo() abort
|
||||
if !s:Enabled()
|
||||
return
|
||||
endif
|
||||
|
||||
py3 _vimspector_session.PrintDebugInfo()
|
||||
endfunction
|
||||
|
||||
|
||||
" Boilerplate {{{
|
||||
let &cpoptions=s:save_cpo
|
||||
|
|
|
|||
|
|
@ -19,16 +19,323 @@ let s:save_cpo = &cpoptions
|
|||
set cpoptions&vim
|
||||
" }}}
|
||||
|
||||
" Returns: py.ShowBalloon( winnr, expresssion )
|
||||
function! vimspector#internal#balloon#BalloonExpr() abort
|
||||
" winnr + 1 because for *no good reason* winnr is 0 based here unlike
|
||||
" everywhere else
|
||||
" int() because for *no good reason* winnr is a string.
|
||||
return py3eval('_vimspector_session.ShowBalloon('
|
||||
\ . 'int( vim.eval( "v:beval_winnr" ) ) + 1,'
|
||||
\ . 'vim.eval( "v:beval_text" ) )' )
|
||||
scriptencoding utf-8
|
||||
|
||||
let s:popup_win_id = 0
|
||||
let s:nvim_border_win_id = 0
|
||||
"
|
||||
" tooltip dimensions
|
||||
let s:min_width = 1
|
||||
let s:min_height = 1
|
||||
let s:max_width = 80
|
||||
let s:max_height = 20
|
||||
|
||||
let s:is_neovim = has( 'nvim' )
|
||||
|
||||
|
||||
" This is used as the balloonexpr in vim to show the Tooltip at the hover
|
||||
" position
|
||||
function! vimspector#internal#balloon#HoverTooltip() abort
|
||||
return py3eval( '_vimspector_session.ShowEvalBalloon('
|
||||
\ . ' int( vim.eval( "v:beval_winnr" ) ) + 1,'
|
||||
\ . ' vim.eval( "v:beval_text"),'
|
||||
\ . ' 1 )' )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#balloon#CreateTooltip( is_hover, ... ) abort
|
||||
let body = []
|
||||
if a:0 > 0
|
||||
let body = a:1
|
||||
endif
|
||||
|
||||
if s:popup_win_id != 0
|
||||
call vimspector#internal#balloon#Close()
|
||||
endif
|
||||
|
||||
if s:is_neovim
|
||||
call s:CreateNeovimTooltip( body )
|
||||
else
|
||||
let config = {
|
||||
\ 'wrap': 0,
|
||||
\ 'filtermode': 'n',
|
||||
\ 'maxwidth': s:max_width,
|
||||
\ 'maxheight': s:max_height,
|
||||
\ 'minwidth': s:min_width,
|
||||
\ 'minheight': s:min_height,
|
||||
\ 'scrollbar': 1,
|
||||
\ 'border': [],
|
||||
\ 'padding': [ 0, 1, 0, 1],
|
||||
\ 'drag': 1,
|
||||
\ 'resize': 1,
|
||||
\ 'close': 'button',
|
||||
\ 'callback': 'vimspector#internal#balloon#CloseCallback',
|
||||
\ }
|
||||
|
||||
let config = vimspector#internal#popup#SetBorderChars( config )
|
||||
|
||||
if a:is_hover
|
||||
let config[ 'filter' ] = 'vimspector#internal#balloon#MouseFilter'
|
||||
let config[ 'mousemoved' ] = [ 0, 0, 0 ]
|
||||
let s:popup_win_id = popup_beval( body, config )
|
||||
else
|
||||
let config[ 'filter' ] = 'vimspector#internal#balloon#CursorFilter'
|
||||
let config[ 'moved' ] = 'any'
|
||||
let config[ 'cursorline' ] = 1
|
||||
let config[ 'mapping' ] = 0
|
||||
let s:popup_win_id = popup_atcursor( body, config )
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
return s:popup_win_id
|
||||
endfunction
|
||||
|
||||
" Filters for vim {{{
|
||||
function! vimspector#internal#balloon#MouseFilter( winid, key ) abort
|
||||
if a:key ==# "\<Esc>"
|
||||
call vimspector#internal#balloon#Close()
|
||||
return 0
|
||||
endif
|
||||
|
||||
if index( [ "\<leftmouse>", "\<2-leftmouse>" ], a:key ) < 0
|
||||
return 0
|
||||
endif
|
||||
|
||||
let handled = 0
|
||||
let mouse_coords = getmousepos()
|
||||
|
||||
" close the popup if mouse is clicked outside the window
|
||||
if mouse_coords[ 'winid' ] != a:winid
|
||||
call vimspector#internal#balloon#Close()
|
||||
return 0
|
||||
endif
|
||||
|
||||
" place the cursor according to the click
|
||||
call win_execute( a:winid,
|
||||
\ ':call cursor( '
|
||||
\ . mouse_coords[ 'line' ]
|
||||
\ . ', '
|
||||
\ . mouse_coords[ 'column' ]
|
||||
\ . ' )' )
|
||||
|
||||
" expand the variable if we got double click
|
||||
if a:key ==? "\<2-leftmouse>"
|
||||
call py3eval( '_vimspector_session.ExpandVariable('
|
||||
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
|
||||
\ . 'line_num = ' . line( '.', a:winid )
|
||||
\ . ')' )
|
||||
let handled = 1
|
||||
endif
|
||||
|
||||
return handled
|
||||
endfunction
|
||||
|
||||
function! s:MatchKey( key, candidates ) abort
|
||||
for candidate in a:candidates
|
||||
" If the mapping string looks like a special character, then try and
|
||||
" expand it. This is... a hack. The whole thing only works if the mapping
|
||||
" is a single key (anyway), and so we assume any string starting with < is a
|
||||
" special key (which will be the common case) and try and map it. If it
|
||||
" fails... it fails.
|
||||
if candidate[ 0 ] == '<'
|
||||
try
|
||||
execute 'let candidate = "\' . candidate . '"'
|
||||
endtry
|
||||
endif
|
||||
|
||||
if candidate ==# a:key
|
||||
return v:true
|
||||
endif
|
||||
endfor
|
||||
|
||||
return v:false
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#balloon#CursorFilter( winid, key ) abort
|
||||
let mappings = py3eval(
|
||||
\ "__import__( 'vimspector',"
|
||||
\." fromlist = [ 'settings' ] ).settings.Dict("
|
||||
\." 'mappings' )[ 'variables' ]" )
|
||||
|
||||
if index( [ "\<LeftMouse>", "\<2-LeftMouse>" ], a:key ) >= 0
|
||||
return vimspector#internal#balloon#MouseFilter( a:winid, a:key )
|
||||
endif
|
||||
|
||||
if s:MatchKey( a:key, mappings.expand_collapse )
|
||||
call py3eval( '_vimspector_session.ExpandVariable('
|
||||
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
|
||||
\ . 'line_num = ' . line( '.', a:winid )
|
||||
\ . ')' )
|
||||
return 1
|
||||
elseif s:MatchKey( a:key, mappings.set_value )
|
||||
call py3eval( '_vimspector_session.SetVariableValue('
|
||||
\ . 'buf = vim.buffers[ ' . winbufnr( a:winid ) . ' ],'
|
||||
\ . 'line_num = ' . line( '.', a:winid )
|
||||
\ . ')' )
|
||||
return 1
|
||||
endif
|
||||
|
||||
return popup_filter_menu( a:winid, a:key )
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
" Closing {{{
|
||||
|
||||
function! vimspector#internal#balloon#CloseCallback( ... ) abort
|
||||
let s:popup_win_id = 0
|
||||
let s:nvim_border_win_id = 0
|
||||
return py3eval( '_vimspector_session.CleanUpTooltip()' )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#balloon#Close() abort
|
||||
if s:popup_win_id == 0
|
||||
return
|
||||
endif
|
||||
|
||||
if s:is_neovim
|
||||
call nvim_win_close( s:popup_win_id, v:true )
|
||||
call nvim_win_close( s:nvim_border_win_id, v:true )
|
||||
|
||||
call vimspector#internal#balloon#CloseCallback()
|
||||
else
|
||||
call popup_close(s:popup_win_id)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
" Neovim pollyfill {{{
|
||||
|
||||
function! vimspector#internal#balloon#ResizeTooltip() abort
|
||||
if !s:is_neovim
|
||||
" Vim does this for us
|
||||
return
|
||||
endif
|
||||
|
||||
if s:popup_win_id <= 0 || s:nvim_border_win_id <= 0
|
||||
" nothing to resize
|
||||
return
|
||||
endif
|
||||
|
||||
noautocmd call win_gotoid( s:popup_win_id )
|
||||
let buf_lines = getline( 1, '$' )
|
||||
|
||||
let width = s:min_width
|
||||
let height = min( [ max( [ s:min_height, len( buf_lines ) ] ),
|
||||
\ s:max_height ] )
|
||||
|
||||
" calculate the longest line
|
||||
for l in buf_lines
|
||||
let width = max( [ width, len( l ) ] )
|
||||
endfor
|
||||
|
||||
let width = min( [ width, s:max_width ] )
|
||||
|
||||
let opts = {
|
||||
\ 'width': width,
|
||||
\ 'height': height,
|
||||
\ }
|
||||
|
||||
" resize the content window
|
||||
call nvim_win_set_config( s:popup_win_id, opts )
|
||||
|
||||
" resize the border window
|
||||
let opts[ 'width' ] = width + 4
|
||||
let opts[ 'height' ] = height + 2
|
||||
|
||||
call nvim_win_set_config( s:nvim_border_win_id, opts )
|
||||
call nvim_buf_set_lines( nvim_win_get_buf( s:nvim_border_win_id ),
|
||||
\ 0,
|
||||
\ -1,
|
||||
\ v:true,
|
||||
\ s:GenerateBorder( width, height ) )
|
||||
endfunction
|
||||
|
||||
" neovim doesn't have the border support, so we have to make our own.
|
||||
" FIXME: This will likely break if the user has `ambiwidth=2`
|
||||
function! s:GenerateBorder( width, height ) abort
|
||||
|
||||
let top = '╭' . repeat('─',a:width + 2) . '╮'
|
||||
let mid = '│' . repeat(' ',a:width + 2) . '│'
|
||||
let bot = '╰' . repeat('─',a:width + 2) . '╯'
|
||||
let lines = [ top ] + repeat( [ mid ], a:height ) + [ bot ]
|
||||
|
||||
return lines
|
||||
endfunction
|
||||
|
||||
function! s:CreateNeovimTooltip( body ) abort
|
||||
" generate border for the float window by creating a background buffer and
|
||||
" overlaying the content buffer
|
||||
" see https://github.com/neovim/neovim/issues/9718#issuecomment-546603628
|
||||
let buf_id = nvim_create_buf( v:false, v:true )
|
||||
call nvim_buf_set_lines( buf_id,
|
||||
\ 0,
|
||||
\ -1,
|
||||
\ v:true,
|
||||
\ s:GenerateBorder( s:max_width, s:max_height ) )
|
||||
|
||||
" default the dimensions initially, then we'll calculate the real size and
|
||||
" resize it.
|
||||
let opts = {
|
||||
\ 'relative': 'cursor',
|
||||
\ 'width': s:max_width + 2,
|
||||
\ 'height': s:max_height + 2,
|
||||
\ 'col': 0,
|
||||
\ 'row': 1,
|
||||
\ 'anchor': 'NW',
|
||||
\ 'style': 'minimal'
|
||||
\ }
|
||||
|
||||
" this is the border window
|
||||
let s:nvim_border_win_id = nvim_open_win( buf_id, 0, opts )
|
||||
call nvim_win_set_option( s:nvim_border_win_id, 'signcolumn', 'no' )
|
||||
call nvim_win_set_option( s:nvim_border_win_id, 'relativenumber', v:false )
|
||||
call nvim_win_set_option( s:nvim_border_win_id, 'number', v:false )
|
||||
|
||||
" when calculating where to display the content window, we need to account
|
||||
" for the border
|
||||
let opts.row += 1
|
||||
let opts.height -= 2
|
||||
let opts.col += 2
|
||||
let opts.width -= 4
|
||||
|
||||
" create the content window
|
||||
let buf_id = nvim_create_buf( v:false, v:true )
|
||||
call nvim_buf_set_lines( buf_id, 0, -1, v:true, a:body )
|
||||
call nvim_buf_set_option( buf_id, 'modifiable', v:false )
|
||||
let s:popup_win_id = nvim_open_win( buf_id, v:false, opts )
|
||||
|
||||
" Apparently none of these work, when 'style' is 'minimal'
|
||||
call nvim_win_set_option( s:popup_win_id, 'wrap', v:false )
|
||||
call nvim_win_set_option( s:popup_win_id, 'cursorline', v:true )
|
||||
call nvim_win_set_option( s:popup_win_id, 'signcolumn', 'no' )
|
||||
call nvim_win_set_option( s:popup_win_id, 'relativenumber', v:false )
|
||||
call nvim_win_set_option( s:popup_win_id, 'number', v:false )
|
||||
|
||||
" Move the cursor into the popup window, as this is the only way we can
|
||||
" interract with the popup in neovim
|
||||
noautocmd call win_gotoid( s:popup_win_id )
|
||||
|
||||
nnoremap <silent> <buffer> <Esc> <cmd>quit<CR>
|
||||
call py3eval( "__import__( 'vimspector', "
|
||||
\." fromlist = [ 'variables' ] )."
|
||||
\.' variables.AddExpandMappings()' )
|
||||
|
||||
" Close the popup whenever we leave this window
|
||||
augroup vimspector#internal#balloon#nvim_float
|
||||
autocmd!
|
||||
autocmd WinLeave <buffer>
|
||||
\ :call vimspector#internal#balloon#Close()
|
||||
\ | autocmd! vimspector#internal#balloon#nvim_float
|
||||
augroup END
|
||||
|
||||
call vimspector#internal#balloon#ResizeTooltip()
|
||||
endfunction
|
||||
|
||||
" }}}
|
||||
|
||||
|
||||
" Boilerplate {{{
|
||||
let &cpoptions=s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ function! vimspector#internal#channel#StartDebugSession( config ) abort
|
|||
\ )
|
||||
endif
|
||||
|
||||
let l:addr = get( a:config, 'host', 'localhost' ) . ':' . 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)'
|
||||
let s:ch = ch_open( l:addr,
|
||||
|
|
@ -95,21 +95,44 @@ EOF
|
|||
endfunction
|
||||
|
||||
function! vimspector#internal#channel#StopDebugSession() abort
|
||||
if exists( 's:ch' ) && ch_status( s:ch ) ==# 'open'
|
||||
|
||||
if exists( 's:job' )
|
||||
" We started the job, so we need to kill it and wait to read all the data
|
||||
" from the socket
|
||||
|
||||
if job_status( s:job ) ==# 'run'
|
||||
call job_stop( s:job, 'term' )
|
||||
endif
|
||||
|
||||
while job_status( s:job ) ==# 'run'
|
||||
call job_stop( s:job, 'kill' )
|
||||
endwhile
|
||||
|
||||
unlet s:job
|
||||
|
||||
if exists( 's:ch' ) && count( [ 'closed', 'fail' ], ch_status( s:ch ) ) == 0
|
||||
" We're going to block on this channel reading, then manually call the
|
||||
" close callback, so remove the automatic close callback to avoid tricky
|
||||
" re-entrancy
|
||||
call ch_setoptions( s:ch, { 'close_cb': '' } )
|
||||
endif
|
||||
|
||||
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_
|
||||
" 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
|
||||
" nothing.
|
||||
call ch_close( s:ch )
|
||||
call s:_OnClose( s:ch )
|
||||
endif
|
||||
|
||||
if exists( 's:job' )
|
||||
if job_status( s:job ) ==# 'run'
|
||||
call job_stop( s:job, 'kill' )
|
||||
endif
|
||||
unlet s:job
|
||||
endif
|
||||
" block until we've read all data from the socket and handled it.
|
||||
while count( [ 'open', 'buffered' ], ch_status( s:ch ) ) == 1
|
||||
let data = ch_read( s:ch, { 'timeout': 10 } )
|
||||
call s:_OnServerData( s:ch, data )
|
||||
endwhile
|
||||
call s:_OnClose( s:ch )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#channel#Reset() abort
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ function! vimspector#internal#neochannel#StartDebugSession( config ) abort
|
|||
endtry
|
||||
endif
|
||||
|
||||
let l:addr = get( a:config, 'host', 'localhost' ) . ':' . a:config[ 'port' ]
|
||||
let l:addr = get( a:config, 'host', '127.0.0.1' ) . ':' . a:config[ 'port' ]
|
||||
|
||||
let attempt = 1
|
||||
while attempt <= 10
|
||||
|
|
|
|||
|
|
@ -159,15 +159,16 @@ function! s:_OnCommandEvent( category, id, data, event ) abort
|
|||
call setbufvar( buffer, '&modified', 0 )
|
||||
endtry
|
||||
|
||||
" if the buffer is visible, scroll it
|
||||
" if the buffer is visible, scroll it, but don't allow autocommands to fire,
|
||||
" as this may close the current window!
|
||||
let w = bufwinnr( buffer )
|
||||
if w > 0
|
||||
let cw = winnr()
|
||||
try
|
||||
execute w . 'wincmd w'
|
||||
normal! Gz-
|
||||
noautocmd execute w . 'wincmd w'
|
||||
noautocmd normal! Gz-
|
||||
finally
|
||||
execute cw . 'wincmd w'
|
||||
noautocmd execute cw . 'wincmd w'
|
||||
endtry
|
||||
endif
|
||||
elseif a:event ==# 'exit'
|
||||
|
|
|
|||
|
|
@ -80,6 +80,56 @@ function! vimspector#internal#neopopup#HideSplash( id ) abort
|
|||
unlet s:db[ a:id ]
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#neopopup#Confirm( confirm_id,
|
||||
\ text,
|
||||
\ options,
|
||||
\ default_value,
|
||||
\ keys ) abort
|
||||
|
||||
" Neovim doesn't have an equivalent of popup_dialog, and it's way too much
|
||||
" effort to write one, so we just use confirm()...
|
||||
" Annoyingly we can't use confirm() here because for some reason it doesn't
|
||||
" render properly in a channel callback. So we use input() and mimic dialog
|
||||
" behaviour.
|
||||
let prompt = a:text
|
||||
for opt in a:options
|
||||
let prompt .= ' ' . opt
|
||||
endfor
|
||||
let prompt .= ': '
|
||||
|
||||
try
|
||||
let result = input( prompt, a:keys[ a:default_value - 1 ] )
|
||||
catch /.*/
|
||||
let result = -1
|
||||
endtry
|
||||
|
||||
" Map the results to what the vim popup stuff would return (s:ConfirmCallback
|
||||
" in popup.vim), i.e.:
|
||||
" - 1-based index of selected item, or
|
||||
" - -1 or 0 for cancellation
|
||||
if result == ''
|
||||
" User pressed ESC/ctrl-c
|
||||
let result = -1
|
||||
else
|
||||
let index = 1
|
||||
for k in a:keys
|
||||
if k ==? result
|
||||
let result = index
|
||||
break
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
|
||||
if index > len( a:keys )
|
||||
let result = -1
|
||||
endif
|
||||
endif
|
||||
|
||||
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
|
||||
\ int( vim.eval( 'a:confirm_id' ) ),
|
||||
\ int( vim.eval( 'result' ) ) )
|
||||
endfunction
|
||||
|
||||
" Boilerplate {{{
|
||||
let &cpoptions=s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
" 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.
|
||||
scriptencoding utf-8
|
||||
|
||||
|
||||
" Boilerplate {{{
|
||||
|
|
@ -32,6 +33,113 @@ function! vimspector#internal#popup#HideSplash( id ) abort
|
|||
call popup_hide( a:id )
|
||||
endfunction
|
||||
|
||||
let s:current_selection = 0
|
||||
let s:selections = []
|
||||
let s:text = []
|
||||
|
||||
function! s:UpdatePopup( id ) abort
|
||||
let buf = copy( s:text )
|
||||
call extend( buf, s:DrawButtons() )
|
||||
call popup_settext( a:id, buf )
|
||||
endfunction
|
||||
|
||||
function! s:ConfirmKeyFilter( keys, id, key ) abort
|
||||
if a:key ==# "\<CR>"
|
||||
call popup_close( a:id, s:current_selection + 1 )
|
||||
return 1
|
||||
elseif index( [ "\<Tab>", "\<Right>" ], a:key ) >= 0
|
||||
let s:current_selection = ( s:current_selection + 1 ) % len( s:selections )
|
||||
call s:UpdatePopup( a:id )
|
||||
return 1
|
||||
elseif index( [ "\<S-Tab>", "\<Left>" ], a:key ) >= 0
|
||||
let s:current_selection = s:current_selection == 0
|
||||
\ ? len( s:selections ) - 1: s:current_selection - 1
|
||||
call s:UpdatePopup( a:id )
|
||||
return 1
|
||||
elseif a:key ==# "\<Esc>" || a:key ==# "\<C-c>"
|
||||
call popup_close( a:id, -1 )
|
||||
return 1
|
||||
endif
|
||||
|
||||
let index = 1
|
||||
for key in a:keys
|
||||
if a:key ==? key
|
||||
call popup_close( a:id, index )
|
||||
return 1
|
||||
endif
|
||||
let index += 1
|
||||
endfor
|
||||
endfunction
|
||||
|
||||
function! s:ConfirmCallback( confirm_id, id, result ) abort
|
||||
py3 __import__( 'vimspector', fromlist = [ 'utils' ] ).utils.ConfirmCallback(
|
||||
\ int( vim.eval( 'a:confirm_id' ) ),
|
||||
\ int( vim.eval( 'a:result' ) ) )
|
||||
endfunction
|
||||
|
||||
function! s:SelectionPosition( idx ) abort
|
||||
return a:idx == 0 ? 0 : len( join( s:selections[ : a:idx - 1 ], ' ' ) ) + 1
|
||||
endfunction
|
||||
|
||||
function! s:DrawButtons() abort
|
||||
return [ {
|
||||
\ 'text': join( s:selections, ' ' ),
|
||||
\ 'props': [
|
||||
\ {
|
||||
\ 'col': s:SelectionPosition( s:current_selection ) + 1,
|
||||
\ 'length': len( s:selections[ s:current_selection ] ),
|
||||
\ 'type': 'VimspectorSelectedItem'
|
||||
\ },
|
||||
\ ]
|
||||
\ } ]
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#popup#Confirm(
|
||||
\ confirm_id,
|
||||
\ text,
|
||||
\ options,
|
||||
\ default_value,
|
||||
\ keys ) abort
|
||||
|
||||
silent! call prop_type_add( 'VimspectorSelectedItem', {
|
||||
\ 'highlight': 'PMenuSel'
|
||||
\ } )
|
||||
|
||||
let lines = split( a:text, "\n", v:true )
|
||||
let buf = []
|
||||
for line in lines
|
||||
call add( buf, { 'text': line, 'props': [] } )
|
||||
endfor
|
||||
|
||||
call add( buf, { 'text': '', 'props': [] } )
|
||||
|
||||
let s:selections = a:options
|
||||
let s:current_selection = ( a:default_value - 1 )
|
||||
|
||||
let s:text = copy( buf )
|
||||
call extend( buf, s:DrawButtons() )
|
||||
|
||||
let config = {
|
||||
\ 'callback': function( 's:ConfirmCallback', [ a:confirm_id ] ),
|
||||
\ 'filter': function( 's:ConfirmKeyFilter', [ a:keys ] ),
|
||||
\ 'mapping': v:false,
|
||||
\ }
|
||||
let config = vimspector#internal#popup#SetBorderChars( config )
|
||||
|
||||
return popup_dialog( buf, config )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#popup#SetBorderChars( config ) abort
|
||||
" When ambiwidth is single, use prettier characters for the border. This
|
||||
" would look silly when ambiwidth is double.
|
||||
if &ambiwidth ==# 'single' && &encoding ==? 'utf-8'
|
||||
let a:config[ 'borderchars' ] = [ '─', '│', '─', '│', '╭', '╮', '┛', '╰' ]
|
||||
endif
|
||||
|
||||
return a:config
|
||||
endfunction
|
||||
|
||||
|
||||
" Boilerplate {{{
|
||||
let &cpoptions=s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
|
|
|||
1085
doc/vimspector-ref.txt
Normal file
1085
doc/vimspector-ref.txt
Normal file
File diff suppressed because it is too large
Load diff
2394
doc/vimspector.txt
Normal file
2394
doc/vimspector.txt
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -28,3 +28,5 @@ gem "tzinfo-data", platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
|||
# Performance-booster for watching directories on Windows
|
||||
gem "wdm", "~> 0.1.0" if Gem.win_platform?
|
||||
|
||||
|
||||
gem "webrick", "~> 1.7"
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (6.0.3.2)
|
||||
activesupport (6.0.3.6)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
zeitwerk (~> 2.2, >= 2.2.2)
|
||||
addressable (2.7.0)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
|
|
@ -16,46 +16,49 @@ GEM
|
|||
colorator (1.1.0)
|
||||
commonmarker (0.17.13)
|
||||
ruby-enum (~> 0.5)
|
||||
concurrent-ruby (1.1.7)
|
||||
dnsruby (1.61.4)
|
||||
concurrent-ruby (1.1.8)
|
||||
dnsruby (1.61.5)
|
||||
simpleidn (~> 0.1)
|
||||
em-websocket (0.5.1)
|
||||
em-websocket (0.5.2)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
ethon (0.12.0)
|
||||
ffi (>= 1.3.0)
|
||||
eventmachine (1.2.7)
|
||||
execjs (2.7.0)
|
||||
faraday (1.0.1)
|
||||
faraday (1.3.0)
|
||||
faraday-net_http (~> 1.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ffi (1.13.1)
|
||||
ruby2_keywords
|
||||
faraday-net_http (1.0.1)
|
||||
ffi (1.15.0)
|
||||
forwardable-extended (2.6.0)
|
||||
gemoji (3.0.1)
|
||||
github-pages (207)
|
||||
github-pages-health-check (= 1.16.1)
|
||||
github-pages (214)
|
||||
github-pages-health-check (= 1.17.0)
|
||||
jekyll (= 3.9.0)
|
||||
jekyll-avatar (= 0.7.0)
|
||||
jekyll-coffeescript (= 1.1.1)
|
||||
jekyll-commonmark-ghpages (= 0.1.6)
|
||||
jekyll-default-layout (= 0.1.4)
|
||||
jekyll-feed (= 0.13.0)
|
||||
jekyll-feed (= 0.15.1)
|
||||
jekyll-gist (= 1.5.0)
|
||||
jekyll-github-metadata (= 2.13.0)
|
||||
jekyll-mentions (= 1.5.1)
|
||||
jekyll-mentions (= 1.6.0)
|
||||
jekyll-optional-front-matter (= 0.3.2)
|
||||
jekyll-paginate (= 1.1.0)
|
||||
jekyll-readme-index (= 0.3.0)
|
||||
jekyll-redirect-from (= 0.15.0)
|
||||
jekyll-redirect-from (= 0.16.0)
|
||||
jekyll-relative-links (= 0.6.1)
|
||||
jekyll-remote-theme (= 0.4.1)
|
||||
jekyll-remote-theme (= 0.4.3)
|
||||
jekyll-sass-converter (= 1.5.2)
|
||||
jekyll-seo-tag (= 2.6.1)
|
||||
jekyll-seo-tag (= 2.7.1)
|
||||
jekyll-sitemap (= 1.4.0)
|
||||
jekyll-swiss (= 1.0.0)
|
||||
jekyll-theme-architect (= 0.1.1)
|
||||
jekyll-theme-cayman (= 0.1.1)
|
||||
jekyll-theme-dinky (= 0.1.1)
|
||||
jekyll-theme-hacker (= 0.1.1)
|
||||
jekyll-theme-hacker (= 0.1.2)
|
||||
jekyll-theme-leap-day (= 0.1.1)
|
||||
jekyll-theme-merlot (= 0.1.1)
|
||||
jekyll-theme-midnight (= 0.1.1)
|
||||
|
|
@ -66,20 +69,20 @@ GEM
|
|||
jekyll-theme-tactile (= 0.1.1)
|
||||
jekyll-theme-time-machine (= 0.1.1)
|
||||
jekyll-titles-from-headings (= 0.5.3)
|
||||
jemoji (= 0.11.1)
|
||||
kramdown (= 2.3.0)
|
||||
jemoji (= 0.12.0)
|
||||
kramdown (= 2.3.1)
|
||||
kramdown-parser-gfm (= 1.1.0)
|
||||
liquid (= 4.0.3)
|
||||
mercenary (~> 0.3)
|
||||
minima (= 2.5.1)
|
||||
nokogiri (>= 1.10.4, < 2.0)
|
||||
rouge (= 3.19.0)
|
||||
rouge (= 3.26.0)
|
||||
terminal-table (~> 1.4)
|
||||
github-pages-health-check (1.16.1)
|
||||
github-pages-health-check (1.17.0)
|
||||
addressable (~> 2.3)
|
||||
dnsruby (~> 1.60)
|
||||
octokit (~> 4.0)
|
||||
public_suffix (~> 3.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
typhoeus (~> 1.3)
|
||||
html-pipeline (2.14.0)
|
||||
activesupport (>= 2)
|
||||
|
|
@ -114,14 +117,14 @@ GEM
|
|||
rouge (>= 2.0, < 4.0)
|
||||
jekyll-default-layout (0.1.4)
|
||||
jekyll (~> 3.0)
|
||||
jekyll-feed (0.13.0)
|
||||
jekyll-feed (0.15.1)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-gist (1.5.0)
|
||||
octokit (~> 4.2)
|
||||
jekyll-github-metadata (2.13.0)
|
||||
jekyll (>= 3.4, < 5.0)
|
||||
octokit (~> 4.0, != 4.4.0)
|
||||
jekyll-mentions (1.5.1)
|
||||
jekyll-mentions (1.6.0)
|
||||
html-pipeline (~> 2.3)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-optional-front-matter (0.3.2)
|
||||
|
|
@ -129,18 +132,19 @@ GEM
|
|||
jekyll-paginate (1.1.0)
|
||||
jekyll-readme-index (0.3.0)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
jekyll-redirect-from (0.15.0)
|
||||
jekyll-redirect-from (0.16.0)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-relative-links (0.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-remote-theme (0.4.1)
|
||||
jekyll-remote-theme (0.4.3)
|
||||
addressable (~> 2.0)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
rubyzip (>= 1.3.0)
|
||||
jekyll-sass-converter (>= 1.0, <= 3.0.0, != 2.0.0)
|
||||
rubyzip (>= 1.3.0, < 3.0)
|
||||
jekyll-sass-converter (1.5.2)
|
||||
sass (~> 3.4)
|
||||
jekyll-seo-tag (2.6.1)
|
||||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-seo-tag (2.7.1)
|
||||
jekyll (>= 3.8, < 5.0)
|
||||
jekyll-sitemap (1.4.0)
|
||||
jekyll (>= 3.7, < 5.0)
|
||||
jekyll-swiss (1.0.0)
|
||||
|
|
@ -153,8 +157,8 @@ GEM
|
|||
jekyll-theme-dinky (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-hacker (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
jekyll-theme-hacker (0.1.2)
|
||||
jekyll (> 3.5, < 5.0)
|
||||
jekyll-seo-tag (~> 2.0)
|
||||
jekyll-theme-leap-day (0.1.1)
|
||||
jekyll (~> 3.5)
|
||||
|
|
@ -188,41 +192,44 @@ GEM
|
|||
jekyll (>= 3.3, < 5.0)
|
||||
jekyll-watch (2.2.1)
|
||||
listen (~> 3.0)
|
||||
jemoji (0.11.1)
|
||||
jemoji (0.12.0)
|
||||
gemoji (~> 3.0)
|
||||
html-pipeline (~> 2.2)
|
||||
jekyll (>= 3.0, < 5.0)
|
||||
kramdown (2.3.0)
|
||||
kramdown (2.3.1)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
liquid (4.0.3)
|
||||
listen (3.2.1)
|
||||
listen (3.5.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
mercenary (0.3.6)
|
||||
mini_portile2 (2.4.0)
|
||||
mini_portile2 (2.5.1)
|
||||
minima (2.5.1)
|
||||
jekyll (>= 3.5, < 5.0)
|
||||
jekyll-feed (~> 0.9)
|
||||
jekyll-seo-tag (~> 2.1)
|
||||
minitest (5.14.1)
|
||||
minitest (5.14.4)
|
||||
multipart-post (2.1.1)
|
||||
nokogiri (1.10.10)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
octokit (4.18.0)
|
||||
nokogiri (1.11.5)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.20.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
pathutil (0.16.2)
|
||||
forwardable-extended (~> 2.6)
|
||||
public_suffix (3.1.1)
|
||||
public_suffix (4.0.6)
|
||||
racc (1.5.2)
|
||||
rb-fsevent (0.10.4)
|
||||
rb-inotify (0.10.1)
|
||||
ffi (~> 1.0)
|
||||
rexml (3.2.4)
|
||||
rouge (3.19.0)
|
||||
ruby-enum (0.8.0)
|
||||
rexml (3.2.5)
|
||||
rouge (3.26.0)
|
||||
ruby-enum (0.9.0)
|
||||
i18n
|
||||
ruby2_keywords (0.0.4)
|
||||
rubyzip (2.3.0)
|
||||
safe_yaml (1.0.5)
|
||||
sass (3.7.4)
|
||||
|
|
@ -233,20 +240,21 @@ GEM
|
|||
sawyer (0.8.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
simpleidn (0.1.1)
|
||||
simpleidn (0.2.1)
|
||||
unf (~> 0.1.4)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thread_safe (0.3.6)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (1.2.7)
|
||||
tzinfo (1.2.9)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
zeitwerk (2.4.0)
|
||||
webrick (1.7.0)
|
||||
zeitwerk (2.4.2)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
|
@ -256,6 +264,7 @@ DEPENDENCIES
|
|||
jekyll-feed (~> 0.6)
|
||||
minima (~> 2.0)
|
||||
tzinfo-data
|
||||
webrick (~> 1.7)
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.4
|
||||
2.2.3
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ JSON value `true`, and the suffix is stripped fom the key, resulting in the
|
|||
following:
|
||||
|
||||
```json
|
||||
"stopOnEntry#json": true
|
||||
"stopOnEntry": true
|
||||
```
|
||||
|
||||
Which is what we need.
|
||||
|
|
@ -634,7 +634,9 @@ Vimspector then orchestrates the various tools to set you up.
|
|||
// %CMD% replaced with the remote-cmdLine configured in the launch
|
||||
// configuration. (mandatory)
|
||||
"runCommand": [
|
||||
"python", "-m", "debugpy", "--listen", "0.0.0.0:${port}",
|
||||
"python", "-m", "debugpy",
|
||||
"--listen", "0.0.0.0:${port}",
|
||||
"--wait-for-client",
|
||||
"%CMD%"
|
||||
]
|
||||
|
||||
|
|
@ -720,7 +722,7 @@ Vimspector then orchestrates the various tools to set you up.
|
|||
"variables": {
|
||||
// Just an example of how to specify a variable manually rather than
|
||||
// vimspector asking for input from the user
|
||||
"ServiceName": "${fileBasenameNoExtention}"
|
||||
"ServiceName": "${fileBasenameNoExtension}"
|
||||
},
|
||||
|
||||
"adapter": "python-remote",
|
||||
|
|
@ -848,7 +850,9 @@ port.
|
|||
// %CMD% replaced with the remote-cmdLine configured in the launch
|
||||
// configuration. (mandatory)
|
||||
"runCommand": [
|
||||
"python", "-m", "debugpy", "--listen", "0.0.0.0:${port}",
|
||||
"python", "-m", "debugpy",
|
||||
"--listen", "0.0.0.0:${port}",
|
||||
"--wait-for-client",
|
||||
"%CMD%"
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@
|
|||
"properties": {
|
||||
"host": {
|
||||
"type": "string",
|
||||
"default": "localhost",
|
||||
"default": "127.0.0.1",
|
||||
"description": "Connect to this host in multi-session mode"
|
||||
},
|
||||
"port": {
|
||||
|
|
|
|||
|
|
@ -114,32 +114,35 @@ parser.add_argument( '--sudo',
|
|||
|
||||
done_languages = set()
|
||||
for name, gadget in gadgets.GADGETS.items():
|
||||
lang = gadget[ 'language' ]
|
||||
if lang in done_languages:
|
||||
continue
|
||||
langs = gadget[ 'language' ]
|
||||
if not isinstance( langs, list ):
|
||||
langs = [ langs ]
|
||||
for lang in langs:
|
||||
if lang in done_languages:
|
||||
continue
|
||||
|
||||
done_languages.add( lang )
|
||||
if not gadget.get( 'enabled', True ):
|
||||
parser.add_argument(
|
||||
'--force-enable-' + lang,
|
||||
action = 'store_true',
|
||||
help = 'Install the unsupported {} debug adapter for {} support'.format(
|
||||
name,
|
||||
lang ) )
|
||||
continue
|
||||
|
||||
done_languages.add( lang )
|
||||
if not gadget.get( 'enabled', True ):
|
||||
parser.add_argument(
|
||||
'--force-enable-' + lang,
|
||||
'--enable-' + lang,
|
||||
action = 'store_true',
|
||||
help = 'Install the unsupported {} debug adapter for {} support'.format(
|
||||
help = 'Install the {} debug adapter for {} support'.format(
|
||||
name,
|
||||
lang ) )
|
||||
continue
|
||||
|
||||
parser.add_argument(
|
||||
'--enable-' + lang,
|
||||
action = 'store_true',
|
||||
help = 'Install the {} debug adapter for {} support'.format(
|
||||
name,
|
||||
lang ) )
|
||||
|
||||
parser.add_argument(
|
||||
'--disable-' + lang,
|
||||
action = 'store_true',
|
||||
help = "Don't install the {} debug adapter for {} support "
|
||||
'(when supplying --all)'.format( name, lang ) )
|
||||
parser.add_argument(
|
||||
'--disable-' + lang,
|
||||
action = 'store_true',
|
||||
help = "Don't install the {} debug adapter for {} support "
|
||||
'(when supplying --all)'.format( name, lang ) )
|
||||
|
||||
parser.add_argument(
|
||||
"--no-check-certificate",
|
||||
|
|
@ -182,15 +185,25 @@ all_adapters = installer.ReadAdapters(
|
|||
manifest = installer.Manifest()
|
||||
|
||||
for name, gadget in gadgets.GADGETS.items():
|
||||
if not gadget.get( 'enabled', True ):
|
||||
if ( not args.force_all
|
||||
and not getattr( args, 'force_enable_' + gadget[ 'language' ] ) ):
|
||||
continue
|
||||
else:
|
||||
if not args.all and not getattr( args, 'enable_' + gadget[ 'language' ] ):
|
||||
continue
|
||||
if getattr( args, 'disable_' + gadget[ 'language' ] ):
|
||||
continue
|
||||
langs = gadget[ 'language' ]
|
||||
if not isinstance( langs, list ):
|
||||
langs = [ langs ]
|
||||
skip = 0
|
||||
for lang in langs:
|
||||
if not gadget.get( 'enabled', True ):
|
||||
if ( not args.force_all
|
||||
and not getattr( args, 'force_enable_' + lang ) ):
|
||||
skip = skip + 1
|
||||
continue
|
||||
else:
|
||||
if not args.all and not getattr( args, 'enable_' + lang ):
|
||||
skip = skip + 1
|
||||
continue
|
||||
if getattr( args, 'disable_' + lang ):
|
||||
skip = skip + 1
|
||||
continue
|
||||
if skip == len( langs ):
|
||||
continue
|
||||
|
||||
if not args.upgrade:
|
||||
manifest.Clear( name )
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@
|
|||
" See the License for the specific language governing permissions and
|
||||
" limitations under the License.
|
||||
|
||||
if !has( 'python3' )
|
||||
echohl WarningMsg
|
||||
echom 'Vimspector unavailable: Requires Vim compiled with +python3'
|
||||
echohl None
|
||||
finish
|
||||
endif
|
||||
|
||||
" Boilerplate {{{
|
||||
let s:save_cpo = &cpoptions
|
||||
set cpoptions&vim
|
||||
|
|
@ -35,6 +42,8 @@ let s:mappings = get( g:, 'vimspector_enable_mappings', '' )
|
|||
|
||||
nnoremap <silent> <Plug>VimspectorContinue
|
||||
\ :<c-u>call vimspector#Continue()<CR>
|
||||
nnoremap <silent> <Plug>VimspectorLaunch
|
||||
\ :<c-u>call vimspector#Launch( v:true )<CR>
|
||||
nnoremap <silent> <Plug>VimspectorStop
|
||||
\ :<c-u>call vimspector#Stop()<CR>
|
||||
nnoremap <silent> <Plug>VimspectorRestart
|
||||
|
|
@ -60,6 +69,18 @@ nnoremap <silent> <Plug>VimspectorStepOut
|
|||
nnoremap <silent> <Plug>VimspectorRunToCursor
|
||||
\ :<c-u>call vimspector#RunToCursor()<CR>
|
||||
|
||||
" Eval for normal mode
|
||||
nnoremap <silent> <Plug>VimspectorBalloonEval
|
||||
\ :<c-u>call vimspector#ShowEvalBalloon( 0 )<CR>
|
||||
" And for visual modes
|
||||
xnoremap <silent> <Plug>VimspectorBalloonEval
|
||||
\ :<c-u>call vimspector#ShowEvalBalloon( 1 )<CR>
|
||||
|
||||
nnoremap <silent> <Plug>VimspectorUpFrame
|
||||
\ :<c-u>call vimspector#UpFrame()<CR>
|
||||
nnoremap <silent> <Plug>VimspectorDownFrame
|
||||
\ :<c-u>call vimspector#DownFrame()<CR>
|
||||
|
||||
if s:mappings ==# 'VISUAL_STUDIO'
|
||||
nmap <F5> <Plug>VimspectorContinue
|
||||
nmap <S-F5> <Plug>VimspectorStop
|
||||
|
|
@ -72,6 +93,7 @@ if s:mappings ==# 'VISUAL_STUDIO'
|
|||
nmap <S-F11> <Plug>VimspectorStepOut
|
||||
elseif s:mappings ==# 'HUMAN'
|
||||
nmap <F5> <Plug>VimspectorContinue
|
||||
nmap <leader><F5> <Plug>VimspectorLaunch
|
||||
nmap <F3> <Plug>VimspectorStop
|
||||
nmap <F4> <Plug>VimspectorRestart
|
||||
nmap <F6> <Plug>VimspectorPause
|
||||
|
|
@ -93,12 +115,15 @@ command! -bar -nargs=? -complete=custom,vimspector#CompleteOutput
|
|||
command! -bar
|
||||
\ VimspectorToggleLog
|
||||
\ call vimspector#ToggleLog()
|
||||
command! -bar -nargs=1 -complete=custom,vimspector#CompleteExpr
|
||||
command! -bar
|
||||
\ VimspectorDebugInfo
|
||||
\ call vimspector#PrintDebugInfo()
|
||||
command! -nargs=1 -complete=custom,vimspector#CompleteExpr
|
||||
\ VimspectorEval
|
||||
\ call vimspector#Evaluate( <f-args> )
|
||||
command! -bar
|
||||
\ VimspectorReset
|
||||
\ call vimspector#Reset()
|
||||
\ call vimspector#Reset( { 'interactive': v:true } )
|
||||
|
||||
" Installer commands
|
||||
command! -bar -bang -nargs=* -complete=custom,vimspector#CompleteInstall
|
||||
|
|
@ -118,8 +143,11 @@ augroup VimspectorUserAutoCmds
|
|||
autocmd!
|
||||
autocmd User VimspectorUICreated silent
|
||||
autocmd User VimspectorTerminalOpened silent
|
||||
autocmd user VimspectorJumpedToFrame silent
|
||||
autocmd user VimspectorDebugEnded silent
|
||||
augroup END
|
||||
|
||||
" FIXME: Only register this _while_ debugging is active
|
||||
augroup Vimspector
|
||||
autocmd!
|
||||
autocmd BufNew * call vimspector#OnBufferCreated( expand( '<afile>' ) )
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ class CodeView( object ):
|
|||
utils.JumpToWindow( self._window )
|
||||
try:
|
||||
utils.OpenFileInCurrentWindow( frame[ 'source' ][ 'path' ] )
|
||||
vim.command( 'doautocmd <nomodeline> User VimspectorJumpedToFrame' )
|
||||
except vim.error:
|
||||
self._logger.exception( 'Unexpected vim error opening file {}'.format(
|
||||
frame[ 'source' ][ 'path' ] ) )
|
||||
|
|
|
|||
51
python3/vimspector/custom/java.py
Normal file
51
python3/vimspector/custom/java.py
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
# vimspector - A multi-language debugging system for Vim
|
||||
# Copyright 2021 Ben Jackson
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from vimspector.debug_session import DebugSession
|
||||
from vimspector import utils, settings
|
||||
|
||||
|
||||
class JavaDebugAdapter( object ):
|
||||
def __init__( self, debug_session: DebugSession ):
|
||||
self.debug_session = debug_session
|
||||
|
||||
def OnEvent_hotcodereplace( self, message ):
|
||||
# Hack for java debug server hot-code-replace
|
||||
body = message.get( 'body' ) or {}
|
||||
|
||||
if body.get( 'type' ) != 'hotcodereplace':
|
||||
return
|
||||
|
||||
if body.get( 'changeType' ) == 'BUILD_COMPLETE':
|
||||
def handler( result ):
|
||||
if result == 1:
|
||||
self.debug_session._connection.DoRequest( None, {
|
||||
'command': 'redefineClasses',
|
||||
'arguments': {},
|
||||
} )
|
||||
|
||||
mode = settings.Get( 'java_hotcodereplace_mode' )
|
||||
if mode == 'ask':
|
||||
utils.Confirm( self.debug_session._api_prefix,
|
||||
'Code has changed, hot reload?',
|
||||
handler,
|
||||
default_value = 1 )
|
||||
elif mode == 'always':
|
||||
self.debug_session._connection.DoRequest( None, {
|
||||
'command': 'redefineClasses',
|
||||
'arguments': {},
|
||||
} )
|
||||
elif body.get( 'message' ):
|
||||
utils.UserMessage( 'Hot code replace: ' + body[ 'message' ] )
|
||||
|
|
@ -29,14 +29,14 @@ class PendingRequest( object ):
|
|||
|
||||
|
||||
class DebugAdapterConnection( object ):
|
||||
def __init__( self, handler, send_func ):
|
||||
def __init__( self, handlers, send_func ):
|
||||
self._logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( self._logger )
|
||||
|
||||
self._Write = send_func
|
||||
self._SetState( 'READ_HEADER' )
|
||||
self._buffer = bytes()
|
||||
self._handler = handler
|
||||
self._handlers = handlers
|
||||
self._next_message_id = 0
|
||||
self._outstanding_requests = {}
|
||||
|
||||
|
|
@ -124,7 +124,7 @@ class DebugAdapterConnection( object ):
|
|||
|
||||
def Reset( self ):
|
||||
self._Write = None
|
||||
self._handler = None
|
||||
self._handlers = None
|
||||
|
||||
while self._outstanding_requests:
|
||||
_, request = self._outstanding_requests.popitem()
|
||||
|
|
@ -226,7 +226,12 @@ class DebugAdapterConnection( object ):
|
|||
|
||||
# self._logger.debug( 'Message received (raw): %s', payload )
|
||||
|
||||
message = json.loads( payload )
|
||||
try:
|
||||
message = json.loads( payload, strict = False )
|
||||
except Exception:
|
||||
self._logger.exception( "Invalid message received: %s", payload )
|
||||
self._SetState( 'READ_HEADER' )
|
||||
raise
|
||||
|
||||
self._logger.debug( 'Message received: {0}'.format( message ) )
|
||||
|
||||
|
|
@ -237,7 +242,7 @@ class DebugAdapterConnection( object ):
|
|||
|
||||
|
||||
def _OnMessageReceived( self, message ):
|
||||
if not self._handler:
|
||||
if not self._handlers:
|
||||
return
|
||||
|
||||
if message[ 'type' ] == 'response':
|
||||
|
|
@ -270,25 +275,21 @@ class DebugAdapterConnection( object ):
|
|||
self._logger.error( 'Request failed: {0}'.format( reason ) )
|
||||
if request.failure_handler:
|
||||
request.failure_handler( reason, message )
|
||||
elif 'OnFailure' in dir( self._handler ):
|
||||
self._handler.OnFailure( reason, request.msg, message )
|
||||
else:
|
||||
utils.UserMessage( 'Request failed: {0}'.format( reason ) )
|
||||
for h in self._handlers:
|
||||
if 'OnFailure' in dir( h ):
|
||||
h.OnFailure( reason, request.msg, message )
|
||||
|
||||
elif message[ 'type' ] == 'event':
|
||||
method = 'OnEvent_' + message[ 'event' ]
|
||||
if method in dir( self._handler ):
|
||||
getattr( self._handler, method )( message )
|
||||
else:
|
||||
utils.UserMessage( 'Unhandled event: {0}'.format( message[ 'event' ] ),
|
||||
persist = True )
|
||||
for h in self._handlers:
|
||||
if method in dir( h ):
|
||||
getattr( h, method )( message )
|
||||
elif message[ 'type' ] == 'request':
|
||||
method = 'OnRequest_' + message[ 'command' ]
|
||||
if method in dir( self._handler ):
|
||||
getattr( self._handler, method )( message )
|
||||
else:
|
||||
utils.UserMessage(
|
||||
'Unhandled request: {0}'.format( message[ 'command' ] ),
|
||||
persist = True )
|
||||
for h in self._handlers:
|
||||
if method in dir( h ):
|
||||
getattr( h, method )( message )
|
||||
|
||||
|
||||
def _KillTimer( request ):
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import glob
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
|
@ -20,6 +21,7 @@ import shlex
|
|||
import subprocess
|
||||
import functools
|
||||
import vim
|
||||
import importlib
|
||||
|
||||
from vimspector import ( breakpoints,
|
||||
code,
|
||||
|
|
@ -31,11 +33,15 @@ from vimspector import ( breakpoints,
|
|||
variables,
|
||||
settings,
|
||||
terminal,
|
||||
launch )
|
||||
installer )
|
||||
from vimspector.vendor.json_minify import minify
|
||||
|
||||
# We cache this once, and don't allow it to change (FIXME?)
|
||||
VIMSPECTOR_HOME = utils.GetVimspectorBase()
|
||||
|
||||
# cache of what the user entered for any option we ask them
|
||||
USER_CHOICES = {}
|
||||
|
||||
|
||||
class DebugSession( object ):
|
||||
def __init__( self, api_prefix ):
|
||||
|
|
@ -75,13 +81,26 @@ class DebugSession( object ):
|
|||
self._server_capabilities = {}
|
||||
self.ClearTemporaryBreakpoints()
|
||||
|
||||
def GetConfigurations( self ):
|
||||
def GetConfigurations( self, adapters ):
|
||||
current_file = utils.GetBufferFilepath( vim.current.buffer )
|
||||
filetypes = utils.GetBufferFiletypes( vim.current.buffer )
|
||||
return launch.GetConfigurations( {}, current_file, filetypes )[ 1 ]
|
||||
configurations = {}
|
||||
|
||||
for launch_config_file in PathsToAllConfigFiles( VIMSPECTOR_HOME,
|
||||
current_file,
|
||||
filetypes ):
|
||||
self._logger.debug( f'Reading configurations from: {launch_config_file}' )
|
||||
if not launch_config_file or not os.path.exists( launch_config_file ):
|
||||
continue
|
||||
|
||||
def Start( self, launch_variables = None ):
|
||||
with open( launch_config_file, 'r' ) as f:
|
||||
database = json.loads( minify( f.read() ) )
|
||||
configurations.update( database.get( 'configurations' ) or {} )
|
||||
adapters.update( database.get( 'adapters' ) or {} )
|
||||
|
||||
return launch_config_file, configurations
|
||||
|
||||
def Start( self, force_choose=False, launch_variables = None ):
|
||||
# We mutate launch_variables, so don't mutate the default argument.
|
||||
# https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
|
||||
if launch_variables is None:
|
||||
|
|
@ -94,48 +113,166 @@ class DebugSession( object ):
|
|||
self._launch_config = None
|
||||
|
||||
current_file = utils.GetBufferFilepath( vim.current.buffer )
|
||||
filetypes = utils.GetBufferFiletypes( vim.current.buffer )
|
||||
adapters = launch.GetAdapters( current_file )
|
||||
launch_config_file, configurations = launch.GetConfigurations( adapters,
|
||||
current_file,
|
||||
filetypes )
|
||||
adapters = {}
|
||||
launch_config_file, configurations = self.GetConfigurations( adapters )
|
||||
|
||||
if not configurations:
|
||||
utils.UserMessage( 'Unable to find any debug configurations. '
|
||||
'You need to tell vimspector how to launch your '
|
||||
'application.' )
|
||||
return
|
||||
|
||||
glob.glob( install.GetGadgetDir( VIMSPECTOR_HOME ) )
|
||||
for gadget_config_file in PathsToAllGadgetConfigs( VIMSPECTOR_HOME,
|
||||
current_file ):
|
||||
self._logger.debug( f'Reading gadget config: {gadget_config_file}' )
|
||||
if not gadget_config_file or not os.path.exists( gadget_config_file ):
|
||||
continue
|
||||
|
||||
with open( gadget_config_file, 'r' ) as f:
|
||||
a = json.loads( minify( f.read() ) ).get( 'adapters' ) or {}
|
||||
adapters.update( a )
|
||||
|
||||
if 'configuration' in launch_variables:
|
||||
configuration_name = launch_variables.pop( 'configuration' )
|
||||
elif force_choose:
|
||||
# Always display the menu
|
||||
configuration_name = utils.SelectFromList(
|
||||
'Which launch configuration?',
|
||||
sorted( configurations.keys() ) )
|
||||
elif ( len( configurations ) == 1 and
|
||||
next( iter( configurations.values() ) ).get( "autoselect", True ) ):
|
||||
configuration_name = next( iter( configurations.keys() ) )
|
||||
else:
|
||||
# Find a single configuration with 'default' True and autoselect not False
|
||||
defaults = { n: c for n, c in configurations.items()
|
||||
if c.get( 'default', False ) is True
|
||||
and c.get( 'autoselect', True ) is not False }
|
||||
|
||||
if len( defaults ) == 1:
|
||||
configuration_name = next( iter( defaults.keys() ) )
|
||||
else:
|
||||
configuration_name = utils.SelectFromList(
|
||||
'Which launch configuration?',
|
||||
sorted( configurations.keys() ) )
|
||||
|
||||
if not configuration_name or configuration_name not in configurations:
|
||||
return
|
||||
|
||||
if launch_config_file:
|
||||
self._workspace_root = os.path.dirname( launch_config_file )
|
||||
else:
|
||||
self._workspace_root = os.path.dirname( current_file )
|
||||
|
||||
configuration = configurations[ configuration_name ]
|
||||
adapter = configuration.get( 'adapter' )
|
||||
if isinstance( adapter, str ):
|
||||
adapter_dict = adapters.get( adapter )
|
||||
|
||||
if not configurations:
|
||||
configuration_name, configuration = launch.SuggestConfiguration(
|
||||
current_file,
|
||||
filetypes )
|
||||
else:
|
||||
configuration_name, configuration = launch.SelectConfiguration(
|
||||
launch_variables,
|
||||
configurations )
|
||||
if adapter_dict is None:
|
||||
suggested_gadgets = installer.FindGadgetForAdapter( adapter )
|
||||
if suggested_gadgets:
|
||||
response = utils.AskForInput(
|
||||
f"The specified adapter '{adapter}' is not "
|
||||
"installed. Would you like to install the following gadgets? ",
|
||||
' '.join( suggested_gadgets ) )
|
||||
if response:
|
||||
new_launch_variables = dict( launch_variables )
|
||||
new_launch_variables[ 'configuration' ] = configuration_name
|
||||
|
||||
if not configuration:
|
||||
utils.UserMessage( 'Unable to find any debug configurations. '
|
||||
'You need to tell vimspector how to launch your '
|
||||
'application.' )
|
||||
return
|
||||
installer.RunInstaller(
|
||||
self._api_prefix,
|
||||
False, # Don't leave open
|
||||
*shlex.split( response ),
|
||||
then = lambda: self.Start( new_launch_variables ) )
|
||||
return
|
||||
elif response is None:
|
||||
return
|
||||
|
||||
adapter = launch.SelectAdapter( self._api_prefix,
|
||||
self,
|
||||
configuration_name,
|
||||
configuration,
|
||||
adapters,
|
||||
launch_variables )
|
||||
if not adapter:
|
||||
return
|
||||
utils.UserMessage( f"The specified adapter '{adapter}' is not "
|
||||
"available. Did you forget to run "
|
||||
"'install_gadget.py'?",
|
||||
persist = True,
|
||||
error = True )
|
||||
return
|
||||
|
||||
adapter = adapter_dict
|
||||
|
||||
# Additional vars as defined by VSCode:
|
||||
#
|
||||
# ${workspaceFolder} - the path of the folder opened in VS Code
|
||||
# ${workspaceFolderBasename} - the name of the folder opened in VS Code
|
||||
# without any slashes (/)
|
||||
# ${file} - the current opened file
|
||||
# ${relativeFile} - the current opened file relative to workspaceFolder
|
||||
# ${fileBasename} - the current opened file's basename
|
||||
# ${fileBasenameNoExtension} - the current opened file's basename with no
|
||||
# file extension
|
||||
# ${fileDirname} - the current opened file's dirname
|
||||
# ${fileExtname} - the current opened file's extension
|
||||
# ${cwd} - the task runner's current working directory on startup
|
||||
# ${lineNumber} - the current selected line number in the active file
|
||||
# ${selectedText} - the current selected text in the active file
|
||||
# ${execPath} - the path to the running VS Code executable
|
||||
|
||||
def relpath( p, relative_to ):
|
||||
if not p:
|
||||
return ''
|
||||
return os.path.relpath( p, relative_to )
|
||||
|
||||
def splitext( p ):
|
||||
if not p:
|
||||
return [ '', '' ]
|
||||
return os.path.splitext( p )
|
||||
|
||||
variables = {
|
||||
'dollar': '$', # HACK. Hote '$$' also works.
|
||||
'workspaceRoot': self._workspace_root,
|
||||
'workspaceFolder': self._workspace_root,
|
||||
'gadgetDir': install.GetGadgetDir( VIMSPECTOR_HOME ),
|
||||
'file': current_file,
|
||||
}
|
||||
|
||||
calculus = {
|
||||
'relativeFile': lambda: relpath( current_file,
|
||||
self._workspace_root ),
|
||||
'fileBasename': lambda: os.path.basename( current_file ),
|
||||
'fileBasenameNoExtension':
|
||||
lambda: splitext( os.path.basename( current_file ) )[ 0 ],
|
||||
'fileDirname': lambda: os.path.dirname( current_file ),
|
||||
'fileExtname': lambda: splitext( os.path.basename( current_file ) )[ 1 ],
|
||||
# NOTE: this is the window-local cwd for the current window, *not* Vim's
|
||||
# working directory.
|
||||
'cwd': os.getcwd,
|
||||
'unusedLocalPort': utils.GetUnusedLocalPort,
|
||||
}
|
||||
|
||||
# Pretend that vars passed to the launch command were typed in by the user
|
||||
# (they may have been in theory)
|
||||
USER_CHOICES.update( launch_variables )
|
||||
variables.update( launch_variables )
|
||||
|
||||
try:
|
||||
launch.ResolveConfiguration( adapter,
|
||||
configuration,
|
||||
launch_variables,
|
||||
self._workspace_root,
|
||||
current_file )
|
||||
variables.update(
|
||||
utils.ParseVariables( adapter.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
variables.update(
|
||||
utils.ParseVariables( configuration.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
|
||||
|
||||
utils.ExpandReferencesInDict( configuration,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
utils.ExpandReferencesInDict( adapter,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
except KeyboardInterrupt:
|
||||
self._Reset()
|
||||
return
|
||||
|
|
@ -189,7 +326,7 @@ class DebugSession( object ):
|
|||
|
||||
if self._connection:
|
||||
self._logger.debug( "_StopDebugAdapter with callback: start" )
|
||||
self._StopDebugAdapter( start )
|
||||
self._StopDebugAdapter( interactive = False, callback = start )
|
||||
return
|
||||
|
||||
start()
|
||||
|
|
@ -254,22 +391,20 @@ class DebugSession( object ):
|
|||
self._connection = None
|
||||
|
||||
@IfConnected()
|
||||
def Stop( self ):
|
||||
def Stop( self, interactive = False ):
|
||||
self._logger.debug( "Stop debug adapter with no callback" )
|
||||
self._StopDebugAdapter()
|
||||
self._StopDebugAdapter( interactive = interactive )
|
||||
|
||||
def Reset( self ):
|
||||
def Reset( self, interactive = False ):
|
||||
if self._connection:
|
||||
self._logger.debug( "Stop debug adapter with callback : self._Reset()" )
|
||||
self._StopDebugAdapter( lambda: self._Reset() )
|
||||
self._StopDebugAdapter( interactive = interactive,
|
||||
callback = lambda: self._Reset() )
|
||||
else:
|
||||
self._Reset()
|
||||
|
||||
def _Reset( self ):
|
||||
self._logger.info( "Debugging complete." )
|
||||
|
||||
launch.SaveConfiguration( self._configuration )
|
||||
|
||||
if self._uiTab:
|
||||
self._logger.debug( "Clearing down UI" )
|
||||
|
||||
|
|
@ -284,6 +419,7 @@ class DebugSession( object ):
|
|||
self._outputView.Reset()
|
||||
self._codeView.Reset()
|
||||
vim.command( 'tabclose!' )
|
||||
vim.command( 'doautocmd <nomodeline> User VimspectorDebugEnded' )
|
||||
self._stackTraceView = None
|
||||
self._variablesView = None
|
||||
self._outputView = None
|
||||
|
|
@ -392,8 +528,12 @@ class DebugSession( object ):
|
|||
self._stackTraceView.SetCurrentThread()
|
||||
|
||||
@IfConnected()
|
||||
def ExpandVariable( self ):
|
||||
self._variablesView.ExpandVariable()
|
||||
def ExpandVariable( self, buf = None, line_num = None ):
|
||||
self._variablesView.ExpandVariable( buf, line_num )
|
||||
|
||||
@IfConnected()
|
||||
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
|
||||
self._variablesView.SetVariableValue( new_value, buf, line_num )
|
||||
|
||||
@IfConnected()
|
||||
def AddWatch( self, expression ):
|
||||
|
|
@ -410,13 +550,13 @@ class DebugSession( object ):
|
|||
def DeleteWatch( self ):
|
||||
self._variablesView.DeleteWatch()
|
||||
|
||||
|
||||
@IfConnected()
|
||||
def ShowBalloon( self, winnr, expression ):
|
||||
"""Proxy: ballonexpr -> variables.ShowBallon"""
|
||||
def ShowEvalBalloon( self, winnr, expression, is_hover ):
|
||||
frame = self._stackTraceView.GetCurrentFrame()
|
||||
# Check if RIP is in a frame
|
||||
if frame is None:
|
||||
self._logger.debug( 'Balloon: Not in a stack frame' )
|
||||
self._logger.debug( 'Tooltip: Not in a stack frame' )
|
||||
return ''
|
||||
|
||||
# Check if cursor in code window
|
||||
|
|
@ -427,12 +567,24 @@ class DebugSession( object ):
|
|||
return ''
|
||||
|
||||
# Return variable aware function
|
||||
return self._variablesView.ShowBalloon( frame, expression )
|
||||
return self._variablesView.VariableEval( frame, expression, is_hover )
|
||||
|
||||
|
||||
def CleanUpTooltip( self ):
|
||||
return self._variablesView.CleanUpTooltip()
|
||||
|
||||
@IfConnected()
|
||||
def ExpandFrameOrThread( self ):
|
||||
self._stackTraceView.ExpandFrameOrThread()
|
||||
|
||||
@IfConnected()
|
||||
def UpFrame( self ):
|
||||
self._stackTraceView.UpFrame()
|
||||
|
||||
@IfConnected()
|
||||
def DownFrame( self ):
|
||||
self._stackTraceView.DownFrame()
|
||||
|
||||
def ToggleLog( self ):
|
||||
if self._HasUI():
|
||||
return self.ShowOutput( 'Vimspector' )
|
||||
|
|
@ -494,6 +646,18 @@ class DebugSession( object ):
|
|||
return response[ 'body' ][ 'targets' ]
|
||||
|
||||
|
||||
@IfConnected( otherwise=[] )
|
||||
def GetCommandLineCompletions( self, ArgLead, prev_non_keyword_char ):
|
||||
items = []
|
||||
for candidate in self.GetCompletionsSync( ArgLead, prev_non_keyword_char ):
|
||||
label = candidate.get( 'text', candidate[ 'label' ] )
|
||||
start = prev_non_keyword_char - 1
|
||||
if 'start' in candidate and 'length' in candidate:
|
||||
start = candidate[ 'start' ]
|
||||
items.append( ArgLead[ 0 : start ] + label )
|
||||
|
||||
return items
|
||||
|
||||
def RefreshSigns( self, file_name ):
|
||||
if self._connection:
|
||||
self._codeView.Refresh( file_name )
|
||||
|
|
@ -505,6 +669,45 @@ class DebugSession( object ):
|
|||
vim.command( 'tab split' )
|
||||
self._uiTab = vim.current.tabpage
|
||||
|
||||
mode = settings.Get( 'ui_mode' )
|
||||
|
||||
if mode == 'auto':
|
||||
# Go vertical if there isn't enough horizontal space for at least:
|
||||
# the left bar width
|
||||
# + the code min width
|
||||
# + the terminal min width
|
||||
# + enough space for a sign column and number column?
|
||||
min_width = ( settings.Int( 'sidebar_width' )
|
||||
+ 1 + 2 + 3
|
||||
+ settings.Int( 'code_minwidth' )
|
||||
+ 1 + settings.Int( 'terminal_minwidth' ) )
|
||||
|
||||
min_height = ( settings.Int( 'code_minheight' ) + 1 +
|
||||
settings.Int( 'topbar_height' ) + 1 +
|
||||
settings.Int( 'bottombar_height' ) + 1 +
|
||||
2 )
|
||||
|
||||
mode = ( 'vertical'
|
||||
if vim.options[ 'columns' ] < min_width
|
||||
else 'horizontal' )
|
||||
|
||||
if vim.options[ 'lines' ] < min_height:
|
||||
mode = 'horizontal'
|
||||
|
||||
self._logger.debug( 'min_width/height: %s/%s, actual: %s/%s - result: %s',
|
||||
min_width,
|
||||
min_height,
|
||||
vim.options[ 'columns' ],
|
||||
vim.options[ 'lines' ],
|
||||
mode )
|
||||
|
||||
if mode == 'vertical':
|
||||
self._SetUpUIVertical()
|
||||
else:
|
||||
self._SetUpUIHorizontal()
|
||||
|
||||
|
||||
def _SetUpUIHorizontal( self ):
|
||||
# Code window
|
||||
code_window = vim.current.window
|
||||
self._codeView = code.CodeView( code_window, self._api_prefix )
|
||||
|
|
@ -545,12 +748,73 @@ class DebugSession( object ):
|
|||
# TODO: If/when we support multiple sessions, we'll need some way to
|
||||
# indicate which tab was created and store all the tabs
|
||||
vim.vars[ 'vimspector_session_windows' ] = {
|
||||
'mode': 'horizontal',
|
||||
'tabpage': self._uiTab.number,
|
||||
'code': utils.WindowID( code_window, self._uiTab ),
|
||||
'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ),
|
||||
'variables': utils.WindowID( vars_window, self._uiTab ),
|
||||
'watches': utils.WindowID( watch_window, self._uiTab ),
|
||||
'output': utils.WindowID( output_window, self._uiTab ),
|
||||
'eval': None # this is going to be updated every time eval popup is opened
|
||||
}
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.RestoreCurrentWindow():
|
||||
with utils.RestoreCurrentBuffer( vim.current.window ):
|
||||
vim.command( 'doautocmd User VimspectorUICreated' )
|
||||
|
||||
|
||||
def _SetUpUIVertical( self ):
|
||||
# Code window
|
||||
code_window = vim.current.window
|
||||
self._codeView = code.CodeView( code_window, self._api_prefix )
|
||||
|
||||
# Call stack
|
||||
vim.command(
|
||||
f'topleft { settings.Int( "topbar_height" ) }new' )
|
||||
stack_trace_window = vim.current.window
|
||||
one_third = int( vim.eval( 'winwidth( 0 )' ) ) / 3
|
||||
self._stackTraceView = stack_trace.StackTraceView( self,
|
||||
stack_trace_window )
|
||||
|
||||
|
||||
# Watches
|
||||
vim.command( 'leftabove vertical new' )
|
||||
watch_window = vim.current.window
|
||||
|
||||
# Variables
|
||||
vim.command( 'leftabove vertical new' )
|
||||
vars_window = vim.current.window
|
||||
|
||||
|
||||
with utils.LetCurrentWindow( vars_window ):
|
||||
vim.command( f'{ one_third }wincmd |' )
|
||||
with utils.LetCurrentWindow( watch_window ):
|
||||
vim.command( f'{ one_third }wincmd |' )
|
||||
with utils.LetCurrentWindow( stack_trace_window ):
|
||||
vim.command( f'{ one_third }wincmd |' )
|
||||
|
||||
self._variablesView = variables.VariablesView( vars_window,
|
||||
watch_window )
|
||||
|
||||
|
||||
# Output/logging
|
||||
vim.current.window = code_window
|
||||
vim.command( f'rightbelow { settings.Int( "bottombar_height" ) }new' )
|
||||
output_window = vim.current.window
|
||||
self._outputView = output.DAPOutputView( output_window,
|
||||
self._api_prefix )
|
||||
|
||||
# TODO: If/when we support multiple sessions, we'll need some way to
|
||||
# indicate which tab was created and store all the tabs
|
||||
vim.vars[ 'vimspector_session_windows' ] = {
|
||||
'mode': 'vertical',
|
||||
'tabpage': self._uiTab.number,
|
||||
'code': utils.WindowID( code_window, self._uiTab ),
|
||||
'stack_trace': utils.WindowID( stack_trace_window, self._uiTab ),
|
||||
'variables': utils.WindowID( vars_window, self._uiTab ),
|
||||
'watches': utils.WindowID( watch_window, self._uiTab ),
|
||||
'output': utils.WindowID( output_window, self._uiTab ),
|
||||
'eval': None # this is going to be updated every time eval popup is opened
|
||||
}
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.RestoreCurrentWindow():
|
||||
|
|
@ -630,43 +894,80 @@ class DebugSession( object ):
|
|||
self._splash_screen,
|
||||
"Unable to start adapter" )
|
||||
else:
|
||||
if 'custom_handler' in self._adapter:
|
||||
spec = self._adapter[ 'custom_handler' ]
|
||||
if isinstance( spec, dict ):
|
||||
module = spec[ 'module' ]
|
||||
cls = spec[ 'class' ]
|
||||
else:
|
||||
module, cls = spec.rsplit( '.', 1 )
|
||||
|
||||
CustomHandler = getattr( importlib.import_module( module ), cls )
|
||||
handlers = [ CustomHandler( self ), self ]
|
||||
else:
|
||||
handlers = [ self ]
|
||||
|
||||
self._connection = debug_adapter_connection.DebugAdapterConnection(
|
||||
self,
|
||||
handlers,
|
||||
lambda msg: utils.Call(
|
||||
"vimspector#internal#{}#Send".format( self._connection_type ),
|
||||
msg ) )
|
||||
|
||||
self._logger.info( 'Debug Adapter Started' )
|
||||
|
||||
def _StopDebugAdapter( self, callback = None ):
|
||||
self._splash_screen = utils.DisplaySplash(
|
||||
self._api_prefix,
|
||||
self._splash_screen,
|
||||
"Shutting down debug adapter..." )
|
||||
|
||||
def handler( *args ):
|
||||
self._splash_screen = utils.HideSplash( self._api_prefix,
|
||||
self._splash_screen )
|
||||
|
||||
if callback:
|
||||
self._logger.debug( "Setting server exit handler before disconnect" )
|
||||
assert not self._run_on_server_exit
|
||||
self._run_on_server_exit = callback
|
||||
|
||||
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
|
||||
self._connection_type ) )
|
||||
|
||||
def _StopDebugAdapter( self, interactive = False, callback = None ):
|
||||
arguments = {}
|
||||
if self._server_capabilities.get( 'supportTerminateDebuggee' ):
|
||||
# If we attached, we should _not_ terminate the debuggee
|
||||
arguments[ 'terminateDebuggee' ] = False
|
||||
|
||||
self._connection.DoRequest( handler, {
|
||||
'command': 'disconnect',
|
||||
'arguments': arguments,
|
||||
}, failure_handler = handler, timeout = 5000 )
|
||||
def disconnect():
|
||||
self._splash_screen = utils.DisplaySplash(
|
||||
self._api_prefix,
|
||||
self._splash_screen,
|
||||
"Shutting down debug adapter..." )
|
||||
|
||||
# TODO: Use the 'tarminate' request if supportsTerminateRequest set
|
||||
def handler( *args ):
|
||||
self._splash_screen = utils.HideSplash( self._api_prefix,
|
||||
self._splash_screen )
|
||||
|
||||
if callback:
|
||||
self._logger.debug( "Setting server exit handler before disconnect" )
|
||||
assert not self._run_on_server_exit
|
||||
self._run_on_server_exit = callback
|
||||
|
||||
vim.eval( 'vimspector#internal#{}#StopDebugSession()'.format(
|
||||
self._connection_type ) )
|
||||
|
||||
self._connection.DoRequest( handler, {
|
||||
'command': 'disconnect',
|
||||
'arguments': arguments,
|
||||
}, failure_handler = handler, timeout = 5000 )
|
||||
|
||||
if not interactive:
|
||||
disconnect()
|
||||
elif not self._server_capabilities.get( 'supportTerminateDebuggee' ):
|
||||
disconnect()
|
||||
elif not self._stackTraceView.AnyThreadsRunning():
|
||||
disconnect()
|
||||
else:
|
||||
def handle_choice( choice ):
|
||||
if choice == 1:
|
||||
# yes
|
||||
arguments[ 'terminateDebuggee' ] = True
|
||||
elif choice == 2:
|
||||
# no
|
||||
arguments[ 'terminateDebuggee' ] = False
|
||||
elif choice <= 0:
|
||||
# Abort
|
||||
return
|
||||
# Else, use server default
|
||||
|
||||
disconnect()
|
||||
|
||||
utils.Confirm( self._api_prefix,
|
||||
"Terminate debuggee?",
|
||||
handle_choice,
|
||||
default_value = 3,
|
||||
options = [ '(Y)es', '(N)o', '(D)efault' ],
|
||||
keys = [ 'y', 'n', 'd' ] )
|
||||
|
||||
|
||||
def _PrepareAttach( self, adapter_config, launch_config ):
|
||||
|
|
@ -847,6 +1148,7 @@ class DebugSession( object ):
|
|||
def handle_initialize_response( msg ):
|
||||
self._server_capabilities = msg.get( 'body' ) or {}
|
||||
self._breakpoints.SetServerCapabilities( self._server_capabilities )
|
||||
self._variablesView.SetServerCapabilities( self._server_capabilities )
|
||||
self._Launch()
|
||||
|
||||
self._connection.DoRequest( handle_initialize_response, {
|
||||
|
|
@ -889,14 +1191,14 @@ class DebugSession( object ):
|
|||
self._splash_screen = utils.DisplaySplash(
|
||||
self._api_prefix,
|
||||
self._splash_screen,
|
||||
"Attaching to debugee..." )
|
||||
"Attaching to debuggee..." )
|
||||
|
||||
self._PrepareAttach( self._adapter, self._launch_config )
|
||||
elif request == "launch":
|
||||
self._splash_screen = utils.DisplaySplash(
|
||||
self._api_prefix,
|
||||
self._splash_screen,
|
||||
"Launching debugee..." )
|
||||
"Launching debuggee..." )
|
||||
|
||||
# FIXME: This cmdLine hack is not fun.
|
||||
self._PrepareLaunch( self._configuration.get( 'remote-cmdLine', [] ),
|
||||
|
|
@ -968,6 +1270,37 @@ class DebugSession( object ):
|
|||
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 ):
|
||||
pass
|
||||
|
||||
|
|
@ -1030,13 +1363,25 @@ class DebugSession( object ):
|
|||
|
||||
self._connection.DoResponse( message, None, response )
|
||||
|
||||
def OnEvent_exited( self, message ):
|
||||
utils.UserMessage( 'The debugee exited with status code: {}'.format(
|
||||
message[ 'body' ][ 'exitCode' ] ) )
|
||||
def OnEvent_terminated( self, message ):
|
||||
# The debugging _session_ has terminated. This does not mean that the
|
||||
# debuggee has terminated (that's the exited event).
|
||||
#
|
||||
# We will handle this when the server actually exists.
|
||||
#
|
||||
# FIXME we should always wait for this event before disconnecting closing
|
||||
# any socket connection
|
||||
self.SetCurrentFrame( None )
|
||||
|
||||
|
||||
def OnEvent_exited( self, message ):
|
||||
utils.UserMessage( 'The debuggee exited with status code: {}'.format(
|
||||
message[ 'body' ][ 'exitCode' ] ) )
|
||||
self._stackTraceView.OnExited( message )
|
||||
self._codeView.SetCurrentFrame( None )
|
||||
|
||||
def OnEvent_process( self, message ):
|
||||
utils.UserMessage( 'The debugee was started: {}'.format(
|
||||
utils.UserMessage( 'The debuggee was started: {}'.format(
|
||||
message[ 'body' ][ 'name' ] ) )
|
||||
|
||||
def OnEvent_module( self, message ):
|
||||
|
|
@ -1076,11 +1421,6 @@ class DebugSession( object ):
|
|||
else:
|
||||
self._logger.debug( "No server exit handler" )
|
||||
|
||||
def OnEvent_terminated( self, message ):
|
||||
# We will handle this when the server actually exists
|
||||
utils.UserMessage( "Debugging was terminated by the server." )
|
||||
self.SetCurrentFrame( None )
|
||||
|
||||
def OnEvent_output( self, message ):
|
||||
if self._outputView:
|
||||
self._outputView.OnOutput( message[ 'body' ] )
|
||||
|
|
@ -1149,3 +1489,29 @@ class DebugSession( object ):
|
|||
|
||||
def AddFunctionBreakpoint( self, function, options ):
|
||||
return self._breakpoints.AddFunctionBreakpoint( function, options )
|
||||
|
||||
|
||||
def PathsToAllGadgetConfigs( vimspector_base, current_file ):
|
||||
yield install.GetGadgetConfigFile( vimspector_base )
|
||||
for p in sorted( glob.glob(
|
||||
os.path.join( install.GetGadgetConfigDir( vimspector_base ),
|
||||
'*.json' ) ) ):
|
||||
yield p
|
||||
|
||||
yield utils.PathToConfigFile( '.gadgets.json',
|
||||
os.path.dirname( current_file ) )
|
||||
|
||||
|
||||
def PathsToAllConfigFiles( vimspector_base, current_file, filetypes ):
|
||||
for ft in filetypes + [ '_all' ]:
|
||||
for p in sorted( glob.glob(
|
||||
os.path.join( install.GetConfigDirForFiletype( vimspector_base, ft ),
|
||||
'*.json' ) ) ):
|
||||
yield p
|
||||
|
||||
for ft in filetypes:
|
||||
yield utils.PathToConfigFile( f'.vimspector.{ft}.json',
|
||||
os.path.dirname( current_file ) )
|
||||
|
||||
yield utils.PathToConfigFile( '.vimspector.json',
|
||||
os.path.dirname( current_file ) )
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import os
|
|||
|
||||
GADGETS = {
|
||||
'vscode-cpptools': {
|
||||
'language': 'c',
|
||||
'language': [ 'c', 'cpp', 'rust' ],
|
||||
'download': {
|
||||
'url': 'https://github.com/Microsoft/vscode-cpptools/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
|
|
@ -30,12 +30,12 @@ GADGETS = {
|
|||
root,
|
||||
gadget ),
|
||||
'all': {
|
||||
'version': '0.27.0',
|
||||
'version': '1.6.0',
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"name": "cppdbg",
|
||||
"command": [
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7"
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
|
|
@ -49,55 +49,21 @@ GADGETS = {
|
|||
}
|
||||
},
|
||||
},
|
||||
'templates': [
|
||||
{
|
||||
'description': 'gdb/lldb local debugging with vscode-cpptools',
|
||||
'filetypes': ( 'c', 'cpp', 'objc', 'rust' ),
|
||||
'configurations': [
|
||||
{
|
||||
'description': 'Launch local process',
|
||||
'launch_configuration': {
|
||||
'adapter': 'vscode-cpptools',
|
||||
'configuration': {
|
||||
'request': 'launch',
|
||||
'program': '${Binary:${fileBasenameNoExtension\\}}',
|
||||
'args': [ '*${CommandLineArguments}' ],
|
||||
'cwd': '${WorkingDir:${fileDirname\\}}',
|
||||
'externalConsole#json': '${UseExternalConsole:true\nfalse}',
|
||||
'stopAtEntry#json': '${StopAtEntry:true\nfalse}',
|
||||
'MIMode': '${Debugger:gdb\nlldb}',
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'description': 'Attach to local process by PID',
|
||||
'launch_configuration': {
|
||||
'adapter': 'vscode-cpptools',
|
||||
'configuration': {
|
||||
'request': 'attach',
|
||||
'program': '${Binary:${fileBasenameNoExtension\\}}',
|
||||
'MIMode': '${Debugger:gdb\nlldb}',
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'cpptools-linux.vsix',
|
||||
'checksum':
|
||||
'3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435',
|
||||
'c25299bcfb46b22d41aa3f125df7184e6282a35ff9fb69c47def744cb4778f55',
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'cpptools-osx.vsix',
|
||||
'file_name': 'cpptools-osx-arm64.vsix',
|
||||
'checksum':
|
||||
'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c',
|
||||
'ceb3e8cdaa2b5bb45af50913ddd8402089969748af8d70f5d46480408287ba6f',
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'cpptools-win32.vsix',
|
||||
'checksum':
|
||||
'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e',
|
||||
'ef7ac5831874a3c7dbf0feb826bfda2be579aff9b6d990622fff1d0d4ede00d1',
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"name": "cppdbg",
|
||||
|
|
@ -120,39 +86,16 @@ 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': {
|
||||
'language': 'python',
|
||||
'download': {
|
||||
'url': 'https://github.com/microsoft/debugpy/archive/${file_name}'
|
||||
},
|
||||
'all': {
|
||||
'version': '1.0.0b12',
|
||||
'file_name': 'v1.0.0b12.zip',
|
||||
'version': '1.2.1',
|
||||
'file_name': 'v1.2.1.zip',
|
||||
'checksum':
|
||||
'210632bba2221fbb841c9785a615258819ceec401d1abdbeb5f2326f12cc72a1'
|
||||
'29a6c5d1053d2b6f3b1a63e1a8ecff93f951d3cc0b7548431592e9e3007239e6'
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.InstallDebugpy( name,
|
||||
root,
|
||||
|
|
@ -193,7 +136,8 @@ GADGETS = {
|
|||
"port": "${DAPPort}",
|
||||
"configuration": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
}
|
||||
},
|
||||
'custom_handler': 'vimspector.custom.java.JavaDebugAdapter'
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -259,7 +203,7 @@ GADGETS = {
|
|||
},
|
||||
},
|
||||
'netcoredbg': {
|
||||
'language': 'csharp',
|
||||
'language': [ 'csharp', 'fsharp', 'vbnet' ],
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': ( 'https://github.com/Samsung/netcoredbg/releases/download/'
|
||||
|
|
@ -267,15 +211,15 @@ GADGETS = {
|
|||
'format': 'tar',
|
||||
},
|
||||
'all': {
|
||||
'version': '1.2.0-635'
|
||||
'version': '1.2.0-782'
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'netcoredbg-osx.tar.gz',
|
||||
'checksum':
|
||||
'71c773e34d358950f25119bade7e3081c4c2f9d71847bd49027ca5792e918beb',
|
||||
'',
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'netcoredbg-linux-bionic.tar.gz',
|
||||
'file_name': 'netcoredbg-linux-bionic-amd64.tar.gz',
|
||||
'checksum': '',
|
||||
},
|
||||
'windows': {
|
||||
|
|
@ -302,41 +246,6 @@ GADGETS = {
|
|||
},
|
||||
}
|
||||
},
|
||||
'vscode-mono-debug': {
|
||||
'language': 'csharp',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
|
||||
'publishers/ms-vscode/vsextensions/mono-debug/${version}/'
|
||||
'vspackage',
|
||||
'target': 'vscode-mono-debug.vsix.gz',
|
||||
'format': 'zip.gz',
|
||||
},
|
||||
'all': {
|
||||
'file_name': 'vscode-mono-debug.vsix',
|
||||
'version': '0.16.2',
|
||||
'checksum':
|
||||
'121eca297d83daeeb1e6e1d791305d1827998dbd595c330086b3b94d33dba3b9',
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-mono-debug': {
|
||||
"name": "mono-debug",
|
||||
"command": [
|
||||
"mono",
|
||||
"${gadgetDir}/vscode-mono-debug/bin/Release/mono-debug.exe"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
},
|
||||
"configuration": {
|
||||
"cwd": "${workspaceRoot}",
|
||||
"console": "integratedTerminal",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
'vscode-bash-debug': {
|
||||
'language': 'bash',
|
||||
'download': {
|
||||
|
|
@ -410,14 +319,14 @@ GADGETS = {
|
|||
'enabled': False,
|
||||
'download': {
|
||||
'url':
|
||||
'https://github.com/felixfbecker/vscode-php-debug/releases/download/'
|
||||
'https://github.com/xdebug/vscode-php-debug/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': 'v1.13.0',
|
||||
'file_name': 'php-debug.vsix',
|
||||
'version': 'v1.17.0',
|
||||
'file_name': 'php-debug-1.17.0.vsix',
|
||||
'checksum':
|
||||
'8a51e593458fd14623c1c89ebab87347b087d67087717f18bcf77bb788052718',
|
||||
'd0fff272503414b6696cc737bc2e18e060fdd5e5dc4bcaf38ae7373afd8d8bc9',
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-php-debug': {
|
||||
|
|
@ -485,48 +394,12 @@ GADGETS = {
|
|||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': 'v1.5.3',
|
||||
'templates': [
|
||||
{
|
||||
'description': 'LLDB local debugging with CodeLLDB',
|
||||
'filetypes': ( 'c', 'cpp', 'objc', 'rust' ),
|
||||
'configurations': [
|
||||
{
|
||||
'description': 'Launch local process',
|
||||
'launch_configuration': {
|
||||
'adapter': 'CodeLLDB',
|
||||
'configuration': {
|
||||
'request': 'launch',
|
||||
'program': '${Binary:${fileBasenameNoExtension\\}}',
|
||||
'args': [ '*${CommandLineArguments}' ],
|
||||
'cwd': '${WorkingDir:${fileDirname\\}}',
|
||||
'terminal': '${Console:integrated\nexternal}',
|
||||
'stopOnEntry#json': '${StopOnEntry:true\nfalse}',
|
||||
'expressions': '${ExpressionType:native\nsimple\npython}'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
'description': 'Attach to local process by PID',
|
||||
'launch_configuration': {
|
||||
'adapter': 'CodeLLDB',
|
||||
'configuration': {
|
||||
'request': 'attach',
|
||||
'program': '${Binary:${fileBasenameNoExtension\\}}',
|
||||
'pid#json': "${pid}",
|
||||
'stopOnEntry#json': '${StopOnEntry:true\nfalse}',
|
||||
'expressions': '${ExpressionType:native\nsimple\npython}'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
'version': 'v1.6.6',
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'codelldb-x86_64-darwin.vsix',
|
||||
'file_name': 'codelldb-aarch64-darwin.vsix',
|
||||
'checksum':
|
||||
'7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a',
|
||||
'5adc3b9139eabdafd825bd5efc55df4424a203fb2b6087b425cd434956e7ec58',
|
||||
'make_executable': [
|
||||
'adapter/codelldb',
|
||||
'lldb/bin/debugserver',
|
||||
|
|
@ -537,7 +410,7 @@ GADGETS = {
|
|||
'linux': {
|
||||
'file_name': 'codelldb-x86_64-linux.vsix',
|
||||
'checksum':
|
||||
'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139',
|
||||
'eda2cd9b3089dcc0524c273e91ffb5875fe08c930bf643739a2cd1846e1f98d6',
|
||||
'make_executable': [
|
||||
'adapter/codelldb',
|
||||
'lldb/bin/lldb',
|
||||
|
|
@ -548,7 +421,7 @@ GADGETS = {
|
|||
'windows': {
|
||||
'file_name': 'codelldb-x86_64-windows.vsix',
|
||||
'checksum':
|
||||
'',
|
||||
'8ddebe8381a3d22dc3d95139c3797fda06b5cc34aadf300e13b1c516b9da95fe',
|
||||
'make_executable': []
|
||||
},
|
||||
'adapters': {
|
||||
|
|
@ -556,7 +429,6 @@ GADGETS = {
|
|||
'name': 'CodeLLDB',
|
||||
'type': 'CodeLLDB',
|
||||
"command": [
|
||||
# FIXME: This probably doesn't work on windows.
|
||||
"${gadgetDir}/CodeLLDB/adapter/codelldb",
|
||||
"--port", "${unusedLocalPort}"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -229,10 +229,14 @@ def GadgetListToInstallerArgs( *gadget_list ):
|
|||
except KeyError:
|
||||
continue
|
||||
|
||||
lang = gadget[ "language" ]
|
||||
if isinstance( lang, list ):
|
||||
lang = lang[ 0 ]
|
||||
|
||||
if not gadget.get( 'enabled', True ):
|
||||
installer_args.append( f'--force-enable-{ gadget[ "language" ] }' )
|
||||
installer_args.append( f'--force-enable-{lang}' )
|
||||
else:
|
||||
installer_args.append( f'--enable-{ gadget[ "language" ] }' )
|
||||
installer_args.append( f'--enable-{lang}' )
|
||||
|
||||
return installer_args
|
||||
|
||||
|
|
@ -340,11 +344,12 @@ def WriteAdapters( all_adapters, to_file=None ):
|
|||
|
||||
|
||||
def InstallGeneric( name, root, gadget ):
|
||||
extension = os.path.join( root, 'extension' )
|
||||
extension_path = gadget.get( 'extension_path', 'extension' )
|
||||
extension = os.path.join( root, extension_path )
|
||||
for f in gadget.get( 'make_executable', [] ):
|
||||
MakeExecutable( os.path.join( extension, f ) )
|
||||
|
||||
MakeExtensionSymlink( name, root )
|
||||
MakeExtensionSymlink( name, root, extension_path )
|
||||
|
||||
|
||||
def InstallCppTools( name, root, gadget ):
|
||||
|
|
@ -353,7 +358,8 @@ def InstallCppTools( name, root, gadget ):
|
|||
# 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
|
||||
# hack that really is not funny.
|
||||
MakeExecutable( os.path.join( extension, 'debugAdapters', 'OpenDebugAD7' ) )
|
||||
MakeExecutable(
|
||||
os.path.join( extension, 'debugAdapters', 'bin', 'OpenDebugAD7' ) )
|
||||
with open( os.path.join( extension, 'package.json' ) ) as f:
|
||||
package = json.load( f )
|
||||
runtime_dependencies = package[ 'runtimeDependencies' ]
|
||||
|
|
@ -699,8 +705,8 @@ def ExtractZipTo( file_path, destination, format ):
|
|||
CheckCall( [ 'tar', 'zxvf', file_path ] )
|
||||
|
||||
|
||||
def MakeExtensionSymlink( name, root ):
|
||||
MakeSymlink( name, os.path.join( root, 'extension' ) ),
|
||||
def MakeExtensionSymlink( name, root, extension_path = 'extension' ):
|
||||
MakeSymlink( name, os.path.join( root, extension_path ) ),
|
||||
|
||||
|
||||
def MakeSymlink( link, pointing_to, in_folder = None ):
|
||||
|
|
|
|||
|
|
@ -1,335 +0,0 @@
|
|||
# vimspector - A multi-language debugging system for Vim
|
||||
# Copyright 2020 Ben Jackson
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import logging
|
||||
import json
|
||||
import glob
|
||||
import shlex
|
||||
import copy
|
||||
|
||||
from vimspector import install, installer, utils, gadgets
|
||||
from vimspector.vendor.json_minify import minify
|
||||
|
||||
_logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( _logger )
|
||||
|
||||
# We cache this once, and don't allow it to change (FIXME?)
|
||||
VIMSPECTOR_HOME = utils.GetVimspectorBase()
|
||||
|
||||
# cache of what the user entered for any option we ask them
|
||||
USER_CHOICES = {}
|
||||
|
||||
|
||||
|
||||
def GetAdapters( current_file ):
|
||||
adapters = {}
|
||||
for gadget_config_file in PathsToAllGadgetConfigs( VIMSPECTOR_HOME,
|
||||
current_file ):
|
||||
_logger.debug( f'Reading gadget config: {gadget_config_file}' )
|
||||
if not gadget_config_file or not os.path.exists( gadget_config_file ):
|
||||
continue
|
||||
|
||||
with open( gadget_config_file, 'r' ) as f:
|
||||
a = json.loads( minify( f.read() ) ).get( 'adapters' ) or {}
|
||||
adapters.update( a )
|
||||
|
||||
return adapters
|
||||
|
||||
|
||||
def PathsToAllGadgetConfigs( vimspector_base, current_file ):
|
||||
yield install.GetGadgetConfigFile( vimspector_base )
|
||||
for p in sorted( glob.glob(
|
||||
os.path.join( install.GetGadgetConfigDir( vimspector_base ),
|
||||
'*.json' ) ) ):
|
||||
yield p
|
||||
|
||||
yield utils.PathToConfigFile( '.gadgets.json',
|
||||
os.path.dirname( current_file ) )
|
||||
|
||||
|
||||
def GetConfigurations( adapters, current_file, filetypes ):
|
||||
configurations = {}
|
||||
for launch_config_file in PathsToAllConfigFiles( VIMSPECTOR_HOME,
|
||||
current_file,
|
||||
filetypes ):
|
||||
_logger.debug( f'Reading configurations from: {launch_config_file}' )
|
||||
if not launch_config_file or not os.path.exists( launch_config_file ):
|
||||
continue
|
||||
|
||||
with open( launch_config_file, 'r' ) as f:
|
||||
database = json.loads( minify( f.read() ) )
|
||||
configurations.update( database.get( 'configurations' ) or {} )
|
||||
adapters.update( database.get( 'adapters' ) or {} )
|
||||
|
||||
# We return the last config file inspected which is the most specific one
|
||||
# (i.e. the project-local one)
|
||||
return launch_config_file, configurations
|
||||
|
||||
|
||||
def PathsToAllConfigFiles( vimspector_base, current_file, filetypes ):
|
||||
for ft in filetypes + [ '_all' ]:
|
||||
for p in sorted( glob.glob(
|
||||
os.path.join( install.GetConfigDirForFiletype( vimspector_base, ft ),
|
||||
'*.json' ) ) ):
|
||||
yield p
|
||||
|
||||
for ft in filetypes:
|
||||
yield utils.PathToConfigFile( f'.vimspector.{ft}.json',
|
||||
os.path.dirname( current_file ) )
|
||||
|
||||
yield utils.PathToConfigFile( '.vimspector.json',
|
||||
os.path.dirname( current_file ) )
|
||||
|
||||
|
||||
def SelectConfiguration( launch_variables, configurations ):
|
||||
if 'configuration' in launch_variables:
|
||||
configuration_name = launch_variables.pop( 'configuration' )
|
||||
elif ( len( configurations ) == 1 and
|
||||
next( iter( configurations.values() ) ).get( "autoselect", True ) ):
|
||||
configuration_name = next( iter( configurations.keys() ) )
|
||||
else:
|
||||
# Find a single configuration with 'default' True and autoselect not False
|
||||
defaults = { n: c for n, c in configurations.items()
|
||||
if c.get( 'default', False ) is True
|
||||
and c.get( 'autoselect', True ) is not False }
|
||||
|
||||
if len( defaults ) == 1:
|
||||
configuration_name = next( iter( defaults.keys() ) )
|
||||
else:
|
||||
configuration_name = utils.SelectFromList(
|
||||
'Which launch configuration?',
|
||||
sorted( configurations.keys() ) )
|
||||
|
||||
if not configuration_name or configuration_name not in configurations:
|
||||
return None, None
|
||||
|
||||
configuration = configurations[ configuration_name ]
|
||||
|
||||
return configuration_name, configuration
|
||||
|
||||
|
||||
def SuggestConfiguration( current_file, filetypes ):
|
||||
nothing = None, None
|
||||
templates = []
|
||||
filetypes = set( filetypes )
|
||||
|
||||
for gadget_name, gadget in gadgets.GADGETS.items():
|
||||
spec = {}
|
||||
spec.update( gadget.get( 'all', {} ) )
|
||||
spec.update( gadget.get( install.GetOS(), {} ) )
|
||||
|
||||
for template in spec.get( 'templates', [] ):
|
||||
if filetypes.intersection( template.get( 'filetypes', set() ) ):
|
||||
# We _must_ copy the template as we end up taking bits out of it to
|
||||
# assign to the resulting config. Python... references... mutabiliy..
|
||||
# fun.
|
||||
templates.append( copy.deepcopy( template ) )
|
||||
|
||||
if not templates:
|
||||
return nothing
|
||||
|
||||
template_idx = utils.SelectFromList(
|
||||
'No debug configurations were found for this project, '
|
||||
'Would you like to use one of the following templates?',
|
||||
[ t[ 'description' ] for t in templates ],
|
||||
ret = 'index' )
|
||||
|
||||
if template_idx is None:
|
||||
return nothing
|
||||
|
||||
template = templates[ template_idx ]
|
||||
|
||||
config_index = utils.SelectFromList(
|
||||
'Which configuration?',
|
||||
[ c[ 'description' ] for c in template[ 'configurations' ] ],
|
||||
ret = 'index' )
|
||||
|
||||
if config_index is None:
|
||||
return nothing
|
||||
|
||||
configuration = template[ 'configurations' ][ config_index ]
|
||||
configuration_name = utils.AskForInput( 'Give the config a name: ',
|
||||
configuration[ 'description' ] )
|
||||
|
||||
configuration[ 'launch_configuration' ][ 'generated' ] = {
|
||||
'name': configuration_name,
|
||||
'path': os.path.join( os.path.dirname( current_file ), '.vimspector.json' ),
|
||||
}
|
||||
|
||||
return configuration_name, configuration[ 'launch_configuration' ]
|
||||
|
||||
|
||||
def SaveConfiguration( configuration ):
|
||||
gen = configuration.pop( 'generated', None )
|
||||
if not gen:
|
||||
return
|
||||
|
||||
if utils.Confirm(
|
||||
f'Would you like to save the configuration named "{ gen[ "name" ] }"',
|
||||
'&Yes\n&No' ) != 1:
|
||||
return
|
||||
|
||||
config_path = utils.AskForInput( 'Enter the path to save to: ',
|
||||
gen[ 'path' ] )
|
||||
|
||||
if not config_path:
|
||||
return
|
||||
|
||||
os.makedirs( os.path.dirname( config_path ), exist_ok = True )
|
||||
current_contents = {}
|
||||
|
||||
if os.path.exists( config_path ):
|
||||
if utils.Confirm( 'File exists, merge with this configuration?\n'
|
||||
'(NOTE: comments and formatting in the existing file '
|
||||
'will be LOST!!)',
|
||||
'&Yes\n&No' ) != 1:
|
||||
return
|
||||
|
||||
with open( config_path, 'r' ) as f:
|
||||
current_contents = json.loads( minify( f.read() ) )
|
||||
|
||||
# TODO: how much of configuration is mangled at this point ?
|
||||
# TODO: how about the defaulted arguments? All the refs are replaced at this
|
||||
# point?
|
||||
current_contents.setdefault( 'configurations', {} )
|
||||
current_contents[ 'configurations' ][ gen[ 'name' ] ] = configuration
|
||||
|
||||
with open( config_path, 'w' ) as f:
|
||||
json.dump( current_contents, f, indent=2 )
|
||||
|
||||
utils.UserMessage( f'Wrote { config_path }', persist = True )
|
||||
|
||||
|
||||
def SelectAdapter( api_prefix,
|
||||
debug_session,
|
||||
configuration_name,
|
||||
configuration,
|
||||
adapters,
|
||||
launch_variables ):
|
||||
adapter = configuration.get( 'adapter' )
|
||||
|
||||
if isinstance( adapter, str ):
|
||||
adapter_dict = adapters.get( adapter )
|
||||
|
||||
if adapter_dict is None:
|
||||
suggested_gadgets = installer.FindGadgetForAdapter( adapter )
|
||||
if suggested_gadgets:
|
||||
response = utils.AskForInput(
|
||||
f"The specified adapter '{adapter}' is not "
|
||||
"installed. Would you like to install the following gadgets? ",
|
||||
' '.join( suggested_gadgets ) )
|
||||
if response:
|
||||
new_launch_variables = dict( launch_variables )
|
||||
new_launch_variables[ 'configuration' ] = configuration_name
|
||||
|
||||
installer.RunInstaller(
|
||||
api_prefix,
|
||||
False, # Don't leave open
|
||||
*shlex.split( response ),
|
||||
then = debug_session.Start( new_launch_variables ) )
|
||||
return None
|
||||
elif response is None:
|
||||
return None
|
||||
|
||||
utils.UserMessage( f"The specified adapter '{adapter}' is not "
|
||||
"available. Did you forget to run "
|
||||
"'install_gadget.py'?",
|
||||
persist = True,
|
||||
error = True )
|
||||
return None
|
||||
|
||||
adapter = adapter_dict
|
||||
|
||||
return adapter
|
||||
|
||||
|
||||
def ResolveConfiguration( adapter,
|
||||
configuration,
|
||||
launch_variables,
|
||||
workspace_root,
|
||||
current_file ):
|
||||
# Additional vars as defined by VSCode:
|
||||
#
|
||||
# ${workspaceFolder} - the path of the folder opened in VS Code
|
||||
# ${workspaceFolderBasename} - the name of the folder opened in VS Code
|
||||
# without any slashes (/)
|
||||
# ${file} - the current opened file
|
||||
# ${relativeFile} - the current opened file relative to workspaceFolder
|
||||
# ${fileBasename} - the current opened file's basename
|
||||
# ${fileBasenameNoExtension} - the current opened file's basename with no
|
||||
# file extension
|
||||
# ${fileDirname} - the current opened file's dirname
|
||||
# ${fileExtname} - the current opened file's extension
|
||||
# ${cwd} - the task runner's current working directory on startup
|
||||
# ${lineNumber} - the current selected line number in the active file
|
||||
# ${selectedText} - the current selected text in the active file
|
||||
# ${execPath} - the path to the running VS Code executable
|
||||
def relpath( p, relative_to ):
|
||||
if not p:
|
||||
return ''
|
||||
return os.path.relpath( p, relative_to )
|
||||
|
||||
def splitext( p ):
|
||||
if not p:
|
||||
return [ '', '' ]
|
||||
return os.path.splitext( p )
|
||||
|
||||
variables = {
|
||||
'dollar': '$', # HACK. Hote '$$' also works.
|
||||
'workspaceRoot': workspace_root,
|
||||
'workspaceFolder': workspace_root,
|
||||
'gadgetDir': install.GetGadgetDir( VIMSPECTOR_HOME ),
|
||||
'file': current_file,
|
||||
}
|
||||
|
||||
calculus = {
|
||||
'relativeFile': lambda: relpath( current_file, workspace_root ),
|
||||
'fileBasename': lambda: os.path.basename( current_file ),
|
||||
'fileBasenameNoExtension':
|
||||
lambda: splitext( os.path.basename( current_file ) )[ 0 ],
|
||||
'fileDirname': lambda: os.path.dirname( current_file ),
|
||||
'fileExtname': lambda: splitext( os.path.basename( current_file ) )[ 1 ],
|
||||
# NOTE: this is the window-local cwd for the current window, *not* Vim's
|
||||
# working directory.
|
||||
'cwd': os.getcwd,
|
||||
'unusedLocalPort': utils.GetUnusedLocalPort,
|
||||
}
|
||||
|
||||
# Pretend that vars passed to the launch command were typed in by the user
|
||||
# (they may have been in theory)
|
||||
USER_CHOICES.update( launch_variables )
|
||||
variables.update( launch_variables )
|
||||
|
||||
variables.update(
|
||||
utils.ParseVariables( adapter.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
variables.update(
|
||||
utils.ParseVariables( configuration.get( 'variables', {} ),
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES ) )
|
||||
|
||||
|
||||
utils.ExpandReferencesInDict( configuration,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
utils.ExpandReferencesInDict( adapter,
|
||||
variables,
|
||||
calculus,
|
||||
USER_CHOICES )
|
||||
|
|
@ -32,8 +32,9 @@ class TabBuffer( object ):
|
|||
BUFFER_MAP = {
|
||||
'console': 'Console',
|
||||
'stdout': 'Console',
|
||||
'output': 'Console',
|
||||
'stderr': 'stderr',
|
||||
'telemetry': 'Telemetry',
|
||||
'telemetry': None,
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -64,8 +65,11 @@ class OutputView( object ):
|
|||
self._api_prefix = api_prefix
|
||||
VIEWS.add( self )
|
||||
|
||||
def Print( self, categroy, text ):
|
||||
self._Print( 'server', text.splitlines() )
|
||||
def Print( self, category, text: typing.Union[ str, list ] ):
|
||||
if not isinstance( text, list ):
|
||||
text = text.splitlines()
|
||||
|
||||
self._Print( category, text )
|
||||
|
||||
def OnOutput( self, event ):
|
||||
category = CategoryToBuffer( event.get( 'category' ) or 'output' )
|
||||
|
|
@ -77,6 +81,10 @@ class OutputView( object ):
|
|||
self._Print( category, text_lines )
|
||||
|
||||
def _Print( self, category, text_lines ):
|
||||
if category is None:
|
||||
# This category is supressed
|
||||
return
|
||||
|
||||
if category not in self._buffers:
|
||||
self._CreateBuffer( category )
|
||||
|
||||
|
|
@ -100,13 +108,26 @@ class OutputView( object ):
|
|||
|
||||
def Clear( self ):
|
||||
for category, tab_buffer in self._buffers.items():
|
||||
if tab_buffer.is_job:
|
||||
utils.CleanUpCommand( category, self._api_prefix )
|
||||
utils.CleanUpHiddenBuffer( tab_buffer.buf )
|
||||
self._CleanUpBuffer( category, tab_buffer )
|
||||
|
||||
# FIXME: nunmenu the WinBar ?
|
||||
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 ):
|
||||
return self._window.valid
|
||||
|
||||
|
|
@ -230,7 +251,7 @@ class OutputView( object ):
|
|||
raise
|
||||
|
||||
vim.command(
|
||||
"nnoremenu 1.{0} WinBar.{1}{2} "
|
||||
"nnoremenu <silent> 1.{0} WinBar.{1}{2} "
|
||||
":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format(
|
||||
tab_buffer.index,
|
||||
utils.Escape( category ),
|
||||
|
|
@ -251,7 +272,8 @@ class DAPOutputView( OutputView ):
|
|||
|
||||
self._connection = None
|
||||
for b in set( BUFFER_MAP.values() ):
|
||||
self._CreateBuffer( b )
|
||||
if b is not None:
|
||||
self._CreateBuffer( b )
|
||||
|
||||
self.AddLogFileView()
|
||||
self._ShowOutput( 'Console' )
|
||||
|
|
|
|||
|
|
@ -20,11 +20,20 @@ from vimspector import utils
|
|||
|
||||
DEFAULTS = {
|
||||
# UI
|
||||
'bottombar_height': 10,
|
||||
'sidebar_width': 50,
|
||||
'code_minwidth': 82,
|
||||
'terminal_maxwidth': 80,
|
||||
'terminal_minwidth': 10,
|
||||
'ui_mode': 'auto',
|
||||
'bottombar_height': 10,
|
||||
|
||||
# For ui_mode = 'horizontal':
|
||||
'sidebar_width': 50,
|
||||
'code_minwidth': 82,
|
||||
'terminal_maxwidth': 80,
|
||||
'terminal_minwidth': 10,
|
||||
|
||||
# For ui_mode = 'vertical':
|
||||
'topbar_height': 15,
|
||||
'code_minheight': 20,
|
||||
'terminal_maxheight': 15,
|
||||
'terminal_minheight': 5,
|
||||
|
||||
# Signs
|
||||
'sign_priority': {
|
||||
|
|
@ -33,11 +42,28 @@ DEFAULTS = {
|
|||
'vimspectorBP': 9,
|
||||
'vimspectorBPCond': 9,
|
||||
'vimspectorBPDisabled': 9,
|
||||
'vimspectorCurrentThread': 200
|
||||
'vimspectorCurrentThread': 200,
|
||||
'vimspectorCurrentFrame': 200,
|
||||
},
|
||||
|
||||
# Installer
|
||||
'install_gadgets': [],
|
||||
|
||||
# Mappings
|
||||
'mappings': {
|
||||
'variables': {
|
||||
'expand_collapse': [ '<CR>', '<2-LeftMouse>' ],
|
||||
'delete': [ '<Del>' ],
|
||||
'set_value': [ '<C-CR>', '<leader><CR>' ]
|
||||
},
|
||||
'stack_trace': {
|
||||
'expand_or_jump': [ '<CR>', '<2-LeftMouse>' ],
|
||||
'focus_thread': [ '<leader><CR>' ],
|
||||
}
|
||||
},
|
||||
|
||||
# Custom
|
||||
'java_hotcodereplace_mode': 'ask',
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -69,9 +95,44 @@ if hasattr( vim, 'Dictionary' ):
|
|||
DICT_TYPE = vim.Dictionary
|
||||
|
||||
|
||||
def Dict( option: str ):
|
||||
d = DICT_TYPE( DEFAULTS.get( option, {} ) )
|
||||
d.update( utils.GetVimValue( vim.vars,
|
||||
f'vimspector_{ option }',
|
||||
{} ) )
|
||||
return d
|
||||
def Dict( option ):
|
||||
return _UpdateDict( DICT_TYPE( DEFAULTS.get( option, {} ) ),
|
||||
vim.vars.get( f'vimspector_{ option }', DICT_TYPE() ) )
|
||||
|
||||
|
||||
def _UpdateDict( target, override ):
|
||||
"""Apply the updates in |override| to the dict |target|. This is like
|
||||
dict.update, but recursive. i.e. if the existing element is a dict, then
|
||||
override elements of the sub-dict rather than wholesale replacing.
|
||||
e.g.
|
||||
UpdateDict(
|
||||
{
|
||||
'outer': { 'inner': { 'key': 'oldValue', 'existingKey': True } }
|
||||
},
|
||||
{
|
||||
'outer': { 'inner': { 'key': 'newValue' } },
|
||||
'newKey': { 'newDict': True },
|
||||
}
|
||||
)
|
||||
yields:
|
||||
{
|
||||
'outer': {
|
||||
'inner': {
|
||||
'key': 'newValue',
|
||||
'existingKey': True
|
||||
}
|
||||
},
|
||||
'newKey': { newDict: True }
|
||||
}
|
||||
"""
|
||||
|
||||
for key, value in override.items():
|
||||
current_value = target.get( key )
|
||||
if not isinstance( current_value, DICT_TYPE ):
|
||||
target[ key ] = value
|
||||
elif isinstance( value, DICT_TYPE ):
|
||||
target[ key ] = _UpdateDict( current_value, value )
|
||||
else:
|
||||
target[ key ] = value
|
||||
|
||||
return target
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import os
|
|||
import logging
|
||||
import typing
|
||||
|
||||
from vimspector import utils, signs
|
||||
from vimspector import utils, signs, settings
|
||||
|
||||
|
||||
class Thread:
|
||||
|
|
@ -102,28 +102,33 @@ class StackTraceView( object ):
|
|||
self._scratch_buffers = []
|
||||
|
||||
# FIXME: This ID is by group, so should be module scope
|
||||
self._next_sign_id = 1
|
||||
self._current_thread_sign_id = 0 # 1 when used
|
||||
self._current_frame_sign_id = 0 # 2 when used
|
||||
|
||||
utils.SetUpHiddenBuffer( self._buf, 'vimspector.StackTrace' )
|
||||
utils.SetUpUIWindow( win )
|
||||
|
||||
mappings = settings.Dict( 'mappings' )[ 'stack_trace' ]
|
||||
|
||||
with utils.LetCurrentWindow( win ):
|
||||
vim.command( 'nnoremap <silent> <buffer> <CR> '
|
||||
':<C-U>call vimspector#GoToFrame()<CR>' )
|
||||
vim.command( 'nnoremap <silent> <buffer> <leader><CR> '
|
||||
':<C-U>call vimspector#SetCurrentThread()<CR>' )
|
||||
vim.command( 'nnoremap <silent> <buffer> <2-LeftMouse> '
|
||||
':<C-U>call vimspector#GoToFrame()<CR>' )
|
||||
for mapping in utils.GetVimList( mappings, 'expand_or_jump' ):
|
||||
vim.command( f'nnoremap <silent> <buffer> { mapping } '
|
||||
':<C-U>call vimspector#GoToFrame()<CR>' )
|
||||
|
||||
for mapping in utils.GetVimList( mappings, 'focus_thread' ):
|
||||
vim.command( f'nnoremap <silent> <buffer> { mapping } '
|
||||
':<C-U>call vimspector#SetCurrentThread()<CR>' )
|
||||
|
||||
if utils.UseWinBar():
|
||||
vim.command( 'nnoremenu 1.1 WinBar.Pause/Continue '
|
||||
vim.command( 'nnoremenu <silent> 1.1 WinBar.Pause/Continue '
|
||||
':call vimspector#PauseContinueThread()<CR>' )
|
||||
vim.command( 'nnoremenu 1.2 WinBar.Expand/Collapse '
|
||||
vim.command( 'nnoremenu <silent> 1.2 WinBar.Expand/Collapse '
|
||||
':call vimspector#GoToFrame()<CR>' )
|
||||
vim.command( 'nnoremenu 1.3 WinBar.Focus '
|
||||
vim.command( 'nnoremenu <silent> 1.3 WinBar.Focus '
|
||||
':call vimspector#SetCurrentThread()<CR>' )
|
||||
|
||||
win.options[ 'cursorline' ] = False
|
||||
win.options[ 'signcolumn' ] = 'auto'
|
||||
|
||||
|
||||
if not signs.SignDefined( 'vimspectorCurrentThread' ):
|
||||
|
|
@ -133,6 +138,13 @@ class StackTraceView( object ):
|
|||
texthl = 'MatchParen',
|
||||
linehl = 'CursorLine' )
|
||||
|
||||
if not signs.SignDefined( 'vimspectorCurrentFrame' ):
|
||||
signs.DefineSign( 'vimspectorCurrentFrame',
|
||||
text = '▶ ',
|
||||
double_text = '▶',
|
||||
texthl = 'Special',
|
||||
linehl = 'CursorLine' )
|
||||
|
||||
self._line_to_frame = {}
|
||||
self._line_to_thread = {}
|
||||
|
||||
|
|
@ -154,9 +166,12 @@ class StackTraceView( object ):
|
|||
self._sources = {}
|
||||
self._requesting_threads = StackTraceView.ThreadRequestState.NO
|
||||
self._pending_thread_request = None
|
||||
if self._next_sign_id:
|
||||
signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' )
|
||||
self._next_sign_id = 0
|
||||
if self._current_thread_sign_id:
|
||||
signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' )
|
||||
self._current_thread_sign_id = 0
|
||||
if self._current_frame_sign_id:
|
||||
signs.UnplaceSign( self._current_frame_sign_id, 'VimspectorStackTrace' )
|
||||
self._current_frame_sign_id = 0
|
||||
|
||||
with utils.ModifiableScratchBuffer( self._buf ):
|
||||
utils.ClearBuffer( self._buf )
|
||||
|
|
@ -188,11 +203,12 @@ class StackTraceView( object ):
|
|||
return
|
||||
|
||||
def consume_threads( message ):
|
||||
requesting = False
|
||||
if self._requesting_threads == StackTraceView.ThreadRequestState.PENDING:
|
||||
# We may have hit a thread event, so try again.
|
||||
self._requesting_threads = StackTraceView.ThreadRequestState.NO
|
||||
self.LoadThreads( *self._pending_thread_request )
|
||||
return
|
||||
requesting = True
|
||||
|
||||
self._requesting_threads = StackTraceView.ThreadRequestState.NO
|
||||
self._pending_thread_request = None
|
||||
|
|
@ -211,8 +227,6 @@ class StackTraceView( object ):
|
|||
stoppedThreadId = stopEvent.get( 'threadId' )
|
||||
allThreadsStopped = stopEvent.get( 'allThreadsStopped', False )
|
||||
|
||||
requesting = False
|
||||
|
||||
# FIXME: This is horribly inefficient
|
||||
for t in message[ 'body' ][ 'threads' ]:
|
||||
thread = None
|
||||
|
|
@ -240,7 +254,10 @@ class StackTraceView( object ):
|
|||
# If this is a stopped event, load the stack trace for the "current"
|
||||
# thread. Don't do this on other thrads requests because some servers
|
||||
# just break when that happens.
|
||||
if infer_current_frame:
|
||||
#
|
||||
# Don't do this if we're also satisfying a cached request already (we'll
|
||||
# do it then)
|
||||
if infer_current_frame and not requesting:
|
||||
if thread.id == self._current_thread:
|
||||
if thread.CanExpand():
|
||||
self._LoadStackTrace( thread, True, reason )
|
||||
|
|
@ -268,10 +285,10 @@ class StackTraceView( object ):
|
|||
self._line_to_frame.clear()
|
||||
self._line_to_thread.clear()
|
||||
|
||||
if self._next_sign_id:
|
||||
signs.UnplaceSign( self._next_sign_id, 'VimspectorStackTrace' )
|
||||
if self._current_thread_sign_id:
|
||||
signs.UnplaceSign( self._current_thread_sign_id, 'VimspectorStackTrace' )
|
||||
else:
|
||||
self._next_sign_id = 1
|
||||
self._current_thread_sign_id = 1
|
||||
|
||||
with utils.ModifiableScratchBuffer( self._buf ):
|
||||
with utils.RestoreCursorPosition():
|
||||
|
|
@ -285,7 +302,7 @@ class StackTraceView( object ):
|
|||
f'({thread.State()})' )
|
||||
|
||||
if self._current_thread == thread.id:
|
||||
signs.PlaceSign( self._next_sign_id,
|
||||
signs.PlaceSign( self._current_thread_sign_id,
|
||||
'VimspectorStackTrace',
|
||||
'vimspectorCurrentThread',
|
||||
self._buf.name,
|
||||
|
|
@ -362,12 +379,61 @@ class StackTraceView( object ):
|
|||
self._JumpToFrame( frame )
|
||||
|
||||
|
||||
|
||||
def _GetFrameOffset( self, delta ):
|
||||
thread: Thread
|
||||
for thread in self._threads:
|
||||
if thread.id != self._current_thread:
|
||||
continue
|
||||
|
||||
if not thread.stacktrace:
|
||||
return
|
||||
|
||||
frame_idx = None
|
||||
for index, frame in enumerate( thread.stacktrace ):
|
||||
if frame == self._current_frame:
|
||||
frame_idx = index
|
||||
break
|
||||
|
||||
if frame_idx is not None:
|
||||
target_idx = frame_idx + delta
|
||||
if target_idx >= 0 and target_idx < len( thread.stacktrace ):
|
||||
return thread.stacktrace[ target_idx ]
|
||||
|
||||
break
|
||||
|
||||
|
||||
def UpFrame( self ):
|
||||
frame = self._GetFrameOffset( 1 )
|
||||
if not frame:
|
||||
utils.UserMessage( 'Top of stack' )
|
||||
else:
|
||||
self._JumpToFrame( frame, 'up' )
|
||||
|
||||
|
||||
def DownFrame( self ):
|
||||
frame = self._GetFrameOffset( -1 )
|
||||
if not frame:
|
||||
utils.UserMessage( 'Bottom of stack' )
|
||||
else:
|
||||
self._JumpToFrame( frame, 'down' )
|
||||
|
||||
|
||||
def AnyThreadsRunning( self ):
|
||||
for thread in self._threads:
|
||||
if thread.state != Thread.TERMINATED:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def _JumpToFrame( self, frame, reason = '' ):
|
||||
def do_jump():
|
||||
if 'line' in frame and frame[ 'line' ] > 0:
|
||||
# Should this set the current _Thread_ too ? If i jump to a frame in
|
||||
# Thread 2, should that become the focussed thread ?
|
||||
self._current_frame = frame
|
||||
self._DrawThreads()
|
||||
return self._session.SetCurrentFrame( self._current_frame, reason )
|
||||
return False
|
||||
|
||||
|
|
@ -457,10 +523,19 @@ class StackTraceView( object ):
|
|||
|
||||
self.LoadThreads( infer_current_frame )
|
||||
|
||||
def OnExited( self, event ):
|
||||
for thread in self._threads:
|
||||
thread.Exited()
|
||||
|
||||
def _DrawStackTrace( self, thread: Thread ):
|
||||
if not thread.IsExpanded():
|
||||
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:
|
||||
if frame.get( 'source' ):
|
||||
source = frame[ 'source' ]
|
||||
|
|
@ -485,6 +560,14 @@ class StackTraceView( object ):
|
|||
source[ 'name' ],
|
||||
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 )
|
||||
|
||||
def _ResolveSource( self, source, and_then ):
|
||||
|
|
|
|||
|
|
@ -23,12 +23,53 @@ def LaunchTerminal( api_prefix,
|
|||
env = params.get( 'env' ) or {}
|
||||
|
||||
term_options = {
|
||||
'vertical': 1,
|
||||
'norestore': 1,
|
||||
'cwd': cwd,
|
||||
'env': env,
|
||||
}
|
||||
|
||||
if settings.Get( 'ui_mode' ) == 'horizontal':
|
||||
# force-horizontal
|
||||
term_options[ 'vertical' ] = 1
|
||||
elif utils.GetVimValue( vim.vars[ 'vimspector_session_windows' ],
|
||||
'mode' ) == 'horizontal':
|
||||
# horizontal, which means that we should have enough space for:
|
||||
# - sidebar
|
||||
# - code min
|
||||
# - term min width
|
||||
# - + 2 vertical spaders
|
||||
# - + 3 columns for signs
|
||||
term_options[ 'vertical' ] = 1
|
||||
|
||||
# if we don't have enough space for terminal_maxwidth, then see if we have
|
||||
# enough vertically for terminal_maxheight, in which case,
|
||||
# that seems a better fit
|
||||
term_horiz_max = ( settings.Int( 'sidebar_width' ) +
|
||||
1 + 2 + 3 +
|
||||
settings.Int( 'code_minwidth' ) +
|
||||
1 + settings.Int( 'terminal_maxwidth' ) )
|
||||
term_vert_max = ( settings.Int( 'bottombar_height' ) + 1 +
|
||||
settings.Int( 'code_minheight' ) + 1 +
|
||||
settings.Int( 'terminal_minheight' ) )
|
||||
|
||||
if ( vim.options[ 'columns' ] < term_horiz_max and
|
||||
vim.options[ 'lines' ] >= term_vert_max ):
|
||||
# Looks like it, let's try that layout
|
||||
term_options[ 'vertical' ] = 0
|
||||
|
||||
|
||||
else:
|
||||
# vertical - we need enough space horizontally for the code+terminal, but we
|
||||
# may fit better with code above terminal
|
||||
term_options[ 'vertical' ] = 0
|
||||
|
||||
term_horiz_max = ( settings.Int( 'code_minwidth' ) + 3 +
|
||||
settings.Int( 'terminal_maxwidth' ) + 1 )
|
||||
|
||||
if vim.options[ 'columns' ] > term_horiz_max:
|
||||
term_options[ 'vertical' ] = 1
|
||||
|
||||
|
||||
if not window_for_start or not window_for_start.valid:
|
||||
# TOOD: Where? Maybe we should just use botright vertical ...
|
||||
window_for_start = vim.current.window
|
||||
|
|
@ -50,13 +91,23 @@ def LaunchTerminal( api_prefix,
|
|||
# If we're making a vertical split from the code window, make it no more
|
||||
# than 80 columns and no fewer than 10. Also try and keep the code window
|
||||
# at least 82 columns
|
||||
if term_options[ 'vertical' ] and not term_options.get( 'curwin', 0 ):
|
||||
if term_options.get( 'curwin', 0 ):
|
||||
pass
|
||||
elif term_options[ 'vertical' ]:
|
||||
term_options[ 'term_cols' ] = max(
|
||||
min ( int( vim.eval( 'winwidth( 0 )' ) )
|
||||
- settings.Int( 'code_minwidth' ),
|
||||
settings.Int( 'terminal_maxwidth' ) ),
|
||||
settings.Int( 'terminal_minwidth' )
|
||||
)
|
||||
else:
|
||||
term_options[ 'term_rows' ] = max(
|
||||
min ( int( vim.eval( 'winheight( 0 )' ) )
|
||||
- settings.Int( 'code_minheight' ),
|
||||
settings.Int( 'terminal_maxheight' ) ),
|
||||
settings.Int( 'terminal_minheight' )
|
||||
)
|
||||
|
||||
|
||||
buffer_number = int(
|
||||
utils.Call(
|
||||
|
|
|
|||
|
|
@ -333,65 +333,84 @@ def UserMessage( msg, persist=False, error=False ):
|
|||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def AskingForUserInput():
|
||||
def InputSave():
|
||||
vim.eval( 'inputsave()' )
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
vim.eval( 'inputrestore()' )
|
||||
# Clear the command line so that subsequent
|
||||
vim.command( 'redraw' )
|
||||
|
||||
|
||||
def SelectFromList( prompt,
|
||||
options,
|
||||
ret = 'text',
|
||||
default_index = None ):
|
||||
with AskingForUserInput():
|
||||
def SelectFromList( prompt, options ):
|
||||
with InputSave():
|
||||
display_options = [ prompt ]
|
||||
display_options.extend( [
|
||||
'{0}{1}: {2}'.format( '*' if i == default_index else ' ',
|
||||
i + 1,
|
||||
v )
|
||||
for i, v in enumerate( options )
|
||||
] )
|
||||
display_options.extend( [ '{0}: {1}'.format( i + 1, v )
|
||||
for i, v in enumerate( options ) ] )
|
||||
try:
|
||||
selection = int( vim.eval(
|
||||
'inputlist( ' + json.dumps( display_options ) + ' )' ) ) - 1
|
||||
if selection < 0 or selection >= len( options ):
|
||||
if default_index is not None:
|
||||
selection = default_index
|
||||
else:
|
||||
return None
|
||||
|
||||
if ret == 'text':
|
||||
return options[ selection ]
|
||||
else:
|
||||
return selection
|
||||
return None
|
||||
return options[ selection ]
|
||||
except ( KeyboardInterrupt, vim.error ):
|
||||
return None
|
||||
|
||||
|
||||
def AskForInput( prompt, default_value = None ):
|
||||
def AskForInput( prompt, default_value = None, completion = None ):
|
||||
if default_value is None:
|
||||
default_option = ''
|
||||
else:
|
||||
default_option = ", '{}'".format( Escape( default_value ) )
|
||||
default_value = ''
|
||||
|
||||
with AskingForUserInput():
|
||||
args = [ prompt, default_value ]
|
||||
|
||||
if completion is not None:
|
||||
if completion == 'expr':
|
||||
args.append( 'custom,vimspector#CompleteExpr' )
|
||||
else:
|
||||
args.append( completion )
|
||||
|
||||
with InputSave():
|
||||
try:
|
||||
return vim.eval( "input( '{}' {} )".format( Escape( prompt ),
|
||||
default_option ) )
|
||||
return Call( 'input', *args )
|
||||
except ( KeyboardInterrupt, vim.error ):
|
||||
return None
|
||||
|
||||
|
||||
def Confirm( msg, *args ):
|
||||
with AskingForUserInput():
|
||||
try:
|
||||
return int( Call( 'confirm', msg, *args ) )
|
||||
except ( KeyboardInterrupt, vim.error ):
|
||||
return 0
|
||||
CONFIRM = {}
|
||||
CONFIRM_ID = 0
|
||||
|
||||
|
||||
def ConfirmCallback( confirm_id, result ):
|
||||
try:
|
||||
handler = CONFIRM.pop( confirm_id )
|
||||
except KeyError:
|
||||
UserMessage( f"Internal error: unexpected callback id { confirm_id }",
|
||||
persist = True,
|
||||
error = True )
|
||||
return
|
||||
|
||||
handler( result )
|
||||
|
||||
|
||||
def Confirm( api_prefix,
|
||||
prompt,
|
||||
handler,
|
||||
default_value = 2,
|
||||
options: list = None,
|
||||
keys: list = None ):
|
||||
if not options:
|
||||
options = [ '(Y)es', '(N)o' ]
|
||||
if not keys:
|
||||
keys = [ 'y', 'n' ]
|
||||
|
||||
global CONFIRM_ID
|
||||
CONFIRM_ID += 1
|
||||
CONFIRM[ CONFIRM_ID ] = handler
|
||||
Call( f'vimspector#internal#{ api_prefix }popup#Confirm',
|
||||
CONFIRM_ID,
|
||||
prompt,
|
||||
options,
|
||||
default_value,
|
||||
keys )
|
||||
|
||||
|
||||
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
||||
|
|
@ -422,8 +441,10 @@ def AppendToBuffer( buf, line_or_lines, modified=False ):
|
|||
|
||||
|
||||
|
||||
def ClearBuffer( buf ):
|
||||
def ClearBuffer( buf, modified = False ):
|
||||
buf[ : ] = None
|
||||
if not modified:
|
||||
buf.options[ 'modified' ] = False
|
||||
|
||||
|
||||
def SetBufferContents( buf, lines, modified=False ):
|
||||
|
|
@ -484,8 +505,8 @@ VAR_MATCH = re.compile(
|
|||
{(?P<braceddefault> # or An {id:default} - default param, as
|
||||
(?P<defname>[_a-z][_a-z0-9]*) # an ID
|
||||
: # then a colon
|
||||
(?P<default>(?:[^}]|\})*) # then anything up to }, or a \}
|
||||
)} | #
|
||||
(?P<default>(?:\\}|[^}])*) # then anything up to }, or a \}
|
||||
)} | # then a }
|
||||
(?P<invalid>) # or Something else - invalid
|
||||
)
|
||||
""",
|
||||
|
|
@ -513,7 +534,6 @@ def _Substitute( template, mapping ):
|
|||
if mo.group( 'braceddefault' ) is not None:
|
||||
named = mo.group( 'defname' )
|
||||
if named not in mapping:
|
||||
''
|
||||
raise MissingSubstitution(
|
||||
named,
|
||||
mo.group( 'default' ).replace( '\\}', '}' ) )
|
||||
|
|
@ -536,7 +556,10 @@ def ExpandReferencesInString( orig_s,
|
|||
|
||||
# Parse any variables passed in in mapping, and ask for any that weren't,
|
||||
# storing the result in mapping
|
||||
while True:
|
||||
bug_catcher = 0
|
||||
while bug_catcher < 100:
|
||||
++bug_catcher
|
||||
|
||||
try:
|
||||
s = _Substitute( s, mapping )
|
||||
break
|
||||
|
|
@ -552,25 +575,14 @@ def ExpandReferencesInString( orig_s,
|
|||
if default_value is None and e.default_value is not None:
|
||||
try:
|
||||
default_value = _Substitute( e.default_value, mapping )
|
||||
except MissingSubstitution as f:
|
||||
if f.name in calculus:
|
||||
default_value = calculus[ f.name ]()
|
||||
except MissingSubstitution as e2:
|
||||
if e2.name in calculus:
|
||||
default_value = calculus[ e2.name ]()
|
||||
else:
|
||||
default_value = e.default_value
|
||||
|
||||
value_list = None
|
||||
if default_value:
|
||||
default_value_list = default_value.split( '\n' )
|
||||
if len( default_value_list ) > 1:
|
||||
value_list = default_value_list
|
||||
|
||||
if value_list:
|
||||
mapping[ key ] = SelectFromList( f'Select value for { key }: ',
|
||||
default_value_list,
|
||||
default_index = 0 )
|
||||
else:
|
||||
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
||||
default_value )
|
||||
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
||||
default_value )
|
||||
|
||||
if mapping[ key ] is None:
|
||||
raise KeyboardInterrupt
|
||||
|
|
@ -605,6 +617,8 @@ def CoerceType( mapping: typing.Dict[ str, typing.Any ], key: str ):
|
|||
mapping[ key ] = DICT_TYPES[ new_type ]( value )
|
||||
|
||||
|
||||
# TODO: Should we just run the substitution on the whole JSON string instead?
|
||||
# That woul dallow expansion in bool and number values, such as ports etc. ?
|
||||
def ExpandReferencesInDict( obj, mapping, calculus, user_choices ):
|
||||
for k in list( obj.keys() ):
|
||||
obj[ k ] = ExpandReferencesInObject( obj[ k ],
|
||||
|
|
@ -667,15 +681,19 @@ def ParseVariables( variables_list,
|
|||
return new_variables
|
||||
|
||||
|
||||
def DisplayBaloon( is_term, display ):
|
||||
def DisplayBalloon( is_term, display, is_hover = False ):
|
||||
if not is_term:
|
||||
display = '\n'.join( display )
|
||||
# To enable the Windows GUI to display the balloon correctly
|
||||
# Refer https://github.com/vim/vim/issues/1512#issuecomment-492070685
|
||||
vim.eval( "balloon_show( '' )" )
|
||||
display = '\n'.join( display )
|
||||
|
||||
vim.eval( "balloon_show( {0} )".format(
|
||||
json.dumps( display ) ) )
|
||||
created_win_id = int( vim.eval(
|
||||
"vimspector#internal#balloon#CreateTooltip({}, {})".format(
|
||||
int( is_hover ), json.dumps( display )
|
||||
)
|
||||
) )
|
||||
|
||||
return created_win_id
|
||||
|
||||
|
||||
def GetBufferFilepath( buf ):
|
||||
|
|
@ -736,7 +754,7 @@ def SetSyntax( current_syntax, syntax, *args ):
|
|||
syntax = ''
|
||||
|
||||
if current_syntax == syntax:
|
||||
return
|
||||
return syntax
|
||||
|
||||
# We use set syn= because just setting vim.Buffer.options[ 'syntax' ]
|
||||
# doesn't actually trigger the Syntax autocommand, and i'm not sure that
|
||||
|
|
@ -752,6 +770,28 @@ def GetBufferFiletypes( buf ):
|
|||
return ft.split( '.' )
|
||||
|
||||
|
||||
def GetVisualSelection( bufnr ):
|
||||
start_line, start_col = vim.current.buffer.mark( "<" )
|
||||
end_line, end_col = vim.current.buffer.mark( ">" )
|
||||
|
||||
|
||||
# lines are 1 based, but columns are 0 based
|
||||
# don't ask me why...
|
||||
start_line -= 1
|
||||
end_line -= 1
|
||||
|
||||
lines = vim.buffers[ bufnr ][ start_line : end_line + 1 ]
|
||||
# Do end first, in case it's on the same line as start (as doing start first
|
||||
# would change the offset)
|
||||
lines[ -1 ] = lines[ -1 ][ : end_col + 1 ]
|
||||
lines[ 0 ] = lines[ 0 ][ start_col : ]
|
||||
|
||||
_logger.debug( f'Visual selection: { lines } from '
|
||||
f'{ start_line }/{ start_col } -> { end_line }/{ end_col }' )
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def DisplaySplash( api_prefix, splash, text ):
|
||||
if splash:
|
||||
return Call( f'vimspector#internal#{api_prefix}popup#UpdateSplash',
|
||||
|
|
@ -820,7 +860,6 @@ def WindowID( window, tab=None ):
|
|||
return int( Call( 'win_getid', window.number, tab.number ) )
|
||||
|
||||
|
||||
@memoize
|
||||
def UseWinBar():
|
||||
# Buggy neovim doesn't render correctly when the WinBar is defined:
|
||||
# https://github.com/neovim/neovim/issues/12689
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import logging
|
|||
from functools import partial
|
||||
import typing
|
||||
|
||||
from vimspector import utils
|
||||
from vimspector import utils, settings
|
||||
|
||||
|
||||
class Expandable:
|
||||
|
|
@ -32,8 +32,9 @@ class Expandable:
|
|||
a 'variablesReference' to be resolved by the 'variables' request. Records the
|
||||
current state expanded/collapsed. Implementations just implement
|
||||
VariablesReference to get the variables."""
|
||||
def __init__( self ):
|
||||
def __init__( self, container: 'Expandable' = None ):
|
||||
self.variables: typing.List[ 'Variable' ] = None
|
||||
self.container: Expandable = container
|
||||
# None is Falsy and represents collapsed _by default_. WHen set to False,
|
||||
# this means the user explicitly collapsed it. When True, the user expanded
|
||||
# it (or we expanded it by default).
|
||||
|
|
@ -48,6 +49,9 @@ class Expandable:
|
|||
def IsExpandable( self ):
|
||||
return self.VariablesReference() > 0
|
||||
|
||||
def IsContained( self ):
|
||||
return self.container is not None
|
||||
|
||||
@abc.abstractmethod
|
||||
def VariablesReference( self ):
|
||||
assert False
|
||||
|
|
@ -92,8 +96,8 @@ class WatchFailure( WatchResult ):
|
|||
|
||||
class Variable( Expandable ):
|
||||
"""Holds one level of an expanded value tree. Also itself expandable."""
|
||||
def __init__( self, variable: dict ):
|
||||
super().__init__()
|
||||
def __init__( self, container: Expandable, variable: dict ):
|
||||
super().__init__( container = container )
|
||||
self.variable = variable
|
||||
# A new variable appearing is marked as changed
|
||||
self.changed = True
|
||||
|
|
@ -117,17 +121,48 @@ class Watch:
|
|||
self.expression = expression
|
||||
self.result = None
|
||||
|
||||
@staticmethod
|
||||
def New( frame, expression, context ):
|
||||
watch = {
|
||||
'expression': expression,
|
||||
'context': context,
|
||||
}
|
||||
if frame:
|
||||
watch[ 'frameId' ] = frame[ 'id' ]
|
||||
|
||||
return Watch( watch )
|
||||
|
||||
|
||||
class View:
|
||||
lines: typing.Dict[ int, Expandable ]
|
||||
draw: typing.Callable
|
||||
syntax: str
|
||||
|
||||
def __init__( self, win, lines, draw ):
|
||||
self.lines = lines
|
||||
self.draw = draw
|
||||
self.buf = win.buffer
|
||||
self.syntax = None
|
||||
if win is not None:
|
||||
self.buf = win.buffer
|
||||
utils.SetUpUIWindow( win )
|
||||
|
||||
utils.SetUpUIWindow( win )
|
||||
|
||||
class BufView( View ):
|
||||
def __init__( self, buf, lines, draw ):
|
||||
super().__init__( None, lines, draw )
|
||||
self.buf = buf
|
||||
|
||||
|
||||
def AddExpandMappings( mappings = None ):
|
||||
if mappings is None:
|
||||
mappings = settings.Dict( 'mappings' )[ 'variables' ]
|
||||
for mapping in utils.GetVimList( mappings, 'expand_collapse' ):
|
||||
vim.command( f'nnoremap <silent> <buffer> { mapping } '
|
||||
':<C-u>call vimspector#ExpandVariable()<CR>' )
|
||||
|
||||
for mapping in utils.GetVimList( mappings, 'set_value' ):
|
||||
vim.command( f'nnoremap <silent> <buffer> { mapping } '
|
||||
':<C-u>call vimspector#SetVariableValue()<CR>' )
|
||||
|
||||
|
||||
class VariablesView( object ):
|
||||
|
|
@ -137,19 +172,22 @@ class VariablesView( object ):
|
|||
|
||||
self._connection = None
|
||||
self._current_syntax = ''
|
||||
self._server_capabilities = None
|
||||
|
||||
def AddExpandMappings():
|
||||
vim.command( 'nnoremap <silent> <buffer> <CR> '
|
||||
':<C-u>call vimspector#ExpandVariable()<CR>' )
|
||||
vim.command( 'nnoremap <silent> <buffer> <2-LeftMouse> '
|
||||
':<C-u>call vimspector#ExpandVariable()<CR>' )
|
||||
self._variable_eval: Scope = None
|
||||
self._variable_eval_view: View = None
|
||||
|
||||
mappings = settings.Dict( 'mappings' )[ 'variables' ]
|
||||
|
||||
# Set up the "Variables" buffer in the variables_win
|
||||
self._scopes: typing.List[ Scope ] = []
|
||||
self._vars = View( variables_win, {}, self._DrawScopes )
|
||||
utils.SetUpHiddenBuffer( self._vars.buf, 'vimspector.Variables' )
|
||||
with utils.LetCurrentWindow( variables_win ):
|
||||
AddExpandMappings()
|
||||
if utils.UseWinBar():
|
||||
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
|
||||
':call vimspector#SetVariableValue()<CR>' )
|
||||
AddExpandMappings( mappings )
|
||||
|
||||
# Set up the "Watches" buffer in the watches_win (and create a WinBar in
|
||||
# there)
|
||||
|
|
@ -161,17 +199,20 @@ class VariablesView( object ):
|
|||
'vimspector#AddWatchPrompt',
|
||||
'vimspector#OmniFuncWatch' )
|
||||
with utils.LetCurrentWindow( watches_win ):
|
||||
AddExpandMappings()
|
||||
vim.command(
|
||||
'nnoremap <buffer> <DEL> :call vimspector#DeleteWatch()<CR>' )
|
||||
AddExpandMappings( mappings )
|
||||
for mapping in utils.GetVimList( mappings, 'delete' ):
|
||||
vim.command(
|
||||
f'nnoremap <buffer> { mapping } :call vimspector#DeleteWatch()<CR>' )
|
||||
|
||||
if utils.UseWinBar():
|
||||
vim.command( 'nnoremenu 1.1 WinBar.New '
|
||||
vim.command( 'nnoremenu <silent> 1.1 WinBar.New '
|
||||
':call vimspector#AddWatch()<CR>' )
|
||||
vim.command( 'nnoremenu 1.2 WinBar.Expand/Collapse '
|
||||
vim.command( 'nnoremenu <silent> 1.2 WinBar.Expand/Collapse '
|
||||
':call vimspector#ExpandVariable()<CR>' )
|
||||
vim.command( 'nnoremenu 1.3 WinBar.Delete '
|
||||
vim.command( 'nnoremenu <silent> 1.3 WinBar.Delete '
|
||||
':call vimspector#DeleteWatch()<CR>' )
|
||||
vim.command( 'nnoremenu <silent> 1.1 WinBar.Set '
|
||||
':call vimspector#SetVariableValue()<CR>' )
|
||||
|
||||
# Set the (global!) balloon expr if supported
|
||||
has_balloon = int( vim.eval( "has( 'balloon_eval' )" ) )
|
||||
|
|
@ -183,7 +224,9 @@ class VariablesView( object ):
|
|||
'balloonexpr': vim.options[ 'balloonexpr' ],
|
||||
'balloondelay': vim.options[ 'balloondelay' ],
|
||||
}
|
||||
vim.options[ 'balloonexpr' ] = 'vimspector#internal#balloon#BalloonExpr()'
|
||||
vim.options[ 'balloonexpr' ] = ( "vimspector#internal#"
|
||||
"balloon#HoverTooltip()" )
|
||||
|
||||
vim.options[ 'balloondelay' ] = 250
|
||||
|
||||
if has_balloon:
|
||||
|
|
@ -201,21 +244,30 @@ class VariablesView( object ):
|
|||
utils.ClearBuffer( self._vars.buf )
|
||||
with utils.ModifiableScratchBuffer( self._watch.buf ):
|
||||
utils.ClearBuffer( self._watch.buf )
|
||||
self.ClearTooltip()
|
||||
self._current_syntax = ''
|
||||
|
||||
def ConnectionUp( self, connection ):
|
||||
self._connection = connection
|
||||
|
||||
def SetServerCapabilities( self, capabilities ):
|
||||
self._server_capabilities = capabilities
|
||||
|
||||
def ConnectionClosed( self ):
|
||||
self.Clear()
|
||||
self._connection = None
|
||||
self._server_capabilities = None
|
||||
|
||||
def Reset( self ):
|
||||
self._server_capabilities = None
|
||||
|
||||
for k, v in self._oldoptions.items():
|
||||
vim.options[ k ] = v
|
||||
|
||||
utils.CleanUpHiddenBuffer( self._vars.buf )
|
||||
utils.CleanUpHiddenBuffer( self._watch.buf )
|
||||
self.ClearTooltip()
|
||||
|
||||
|
||||
def LoadScopes( self, frame ):
|
||||
def scopes_consumer( message ):
|
||||
|
|
@ -267,15 +319,97 @@ class VariablesView( object ):
|
|||
},
|
||||
} )
|
||||
|
||||
def AddWatch( self, frame, expression ):
|
||||
watch = {
|
||||
'expression': expression,
|
||||
'context': 'watch',
|
||||
}
|
||||
if frame:
|
||||
watch[ 'frameId' ] = frame[ 'id' ]
|
||||
def _DrawBalloonEval( self ):
|
||||
watch = self._variable_eval
|
||||
view = self._variable_eval_view
|
||||
|
||||
self._watches.append( Watch( watch ) )
|
||||
with utils.RestoreCursorPosition():
|
||||
with utils.ModifiableScratchBuffer( view.buf ):
|
||||
utils.ClearBuffer( view.buf )
|
||||
view.syntax = utils.SetSyntax( view.syntax,
|
||||
self._current_syntax,
|
||||
view.buf )
|
||||
|
||||
self._DrawWatchResult( view,
|
||||
0,
|
||||
watch,
|
||||
is_short = True )
|
||||
|
||||
vim.eval( "vimspector#internal#balloon#ResizeTooltip()" )
|
||||
|
||||
def ClearTooltip( self ):
|
||||
# This will actually end up calling CleanUpTooltip via the popup close
|
||||
# callback
|
||||
vim.eval( 'vimspector#internal#balloon#Close()' )
|
||||
|
||||
def CleanUpTooltip( self ) :
|
||||
# remove reference to old tooltip window
|
||||
self._variable_eval_view = None
|
||||
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = None
|
||||
|
||||
def VariableEval( self, frame, expression, is_hover ):
|
||||
"""Callback to display variable under cursor `:h ballonexpr`"""
|
||||
if not self._connection:
|
||||
return ''
|
||||
|
||||
def handler( message ):
|
||||
|
||||
watch = self._variable_eval
|
||||
if watch.result is None:
|
||||
watch.result = WatchResult( message[ 'body' ] )
|
||||
else:
|
||||
watch.result.Update( message[ 'body' ] )
|
||||
|
||||
popup_win_id = utils.DisplayBalloon( self._is_term, [], is_hover )
|
||||
# record the global eval window id
|
||||
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = int( popup_win_id )
|
||||
popup_bufnr = int( vim.eval( "winbufnr({})".format( popup_win_id ) ) )
|
||||
|
||||
# We don't need to do any UI window setup here, as it's already done as
|
||||
# part of the popup creation, so just pass the buffer to the View instance
|
||||
self._variable_eval_view = BufView(
|
||||
vim.buffers[ popup_bufnr ],
|
||||
{},
|
||||
self._DrawBalloonEval
|
||||
)
|
||||
|
||||
if watch.result.IsExpandable():
|
||||
# Always expand the first level
|
||||
watch.result.expanded = Expandable.EXPANDED_BY_US
|
||||
|
||||
if watch.result.IsExpanded():
|
||||
self._connection.DoRequest( partial( self._ConsumeVariables,
|
||||
self._variable_eval_view.draw,
|
||||
watch.result ), {
|
||||
'command': 'variables',
|
||||
'arguments': {
|
||||
'variablesReference': watch.result.VariablesReference(),
|
||||
},
|
||||
} )
|
||||
|
||||
self._DrawBalloonEval()
|
||||
|
||||
def failure_handler( reason, message ):
|
||||
display = [ reason ]
|
||||
float_win_id = utils.DisplayBalloon( self._is_term, display, is_hover )
|
||||
# record the global eval window id
|
||||
vim.vars[ 'vimspector_session_windows' ][ 'eval' ] = int( float_win_id )
|
||||
|
||||
self._variable_eval = Watch.New( frame,
|
||||
expression,
|
||||
'hover' )
|
||||
|
||||
# Send async request
|
||||
self._connection.DoRequest( handler, {
|
||||
'command': 'evaluate',
|
||||
'arguments': self._variable_eval.expression,
|
||||
}, failure_handler )
|
||||
|
||||
# Return working (meanwhile)
|
||||
return ''
|
||||
|
||||
def AddWatch( self, frame, expression ):
|
||||
self._watches.append( Watch.New( frame, expression, 'watch' ) )
|
||||
self.EvaluateWatches()
|
||||
|
||||
def DeleteWatch( self ):
|
||||
|
|
@ -338,19 +472,34 @@ class VariablesView( object ):
|
|||
watch.result = WatchFailure( reason )
|
||||
self._DrawWatches()
|
||||
|
||||
def ExpandVariable( self ):
|
||||
if vim.current.buffer == self._vars.buf:
|
||||
def _GetVariable( self, buf = None, line_num = None ):
|
||||
none = ( None, None )
|
||||
|
||||
if buf is None:
|
||||
buf = vim.current.buffer
|
||||
|
||||
if line_num is None:
|
||||
line_num = vim.current.window.cursor[ 0 ]
|
||||
|
||||
if buf == self._vars.buf:
|
||||
view = self._vars
|
||||
elif vim.current.buffer == self._watch.buf:
|
||||
elif buf == self._watch.buf:
|
||||
view = self._watch
|
||||
elif ( self._variable_eval_view is not None
|
||||
and buf == self._variable_eval_view.buf ):
|
||||
view = self._variable_eval_view
|
||||
else:
|
||||
return
|
||||
return none
|
||||
|
||||
current_line = vim.current.window.cursor[ 0 ]
|
||||
if current_line not in view.lines:
|
||||
return
|
||||
if line_num not in view.lines:
|
||||
return none
|
||||
|
||||
variable = view.lines[ current_line ]
|
||||
return view.lines[ line_num ], view
|
||||
|
||||
def ExpandVariable( self, buf = None, line_num = None ):
|
||||
variable, view = self._GetVariable( buf, line_num )
|
||||
if variable is None:
|
||||
return
|
||||
|
||||
if variable.IsExpanded():
|
||||
# Collapse
|
||||
|
|
@ -371,25 +520,101 @@ class VariablesView( object ):
|
|||
},
|
||||
} )
|
||||
|
||||
def _DrawVariables( self, view, variables, indent ):
|
||||
def SetVariableValue( self, new_value = None, buf = None, line_num = None ):
|
||||
variable: Variable
|
||||
view: View
|
||||
|
||||
if not self._server_capabilities.get( 'supportsSetVariable' ):
|
||||
return
|
||||
|
||||
variable, view = self._GetVariable( buf, line_num )
|
||||
if variable is None:
|
||||
return
|
||||
|
||||
if not variable.IsContained():
|
||||
return
|
||||
|
||||
if new_value is None:
|
||||
new_value = utils.AskForInput( 'New Value: ',
|
||||
variable.variable.get( 'value', '' ),
|
||||
completion = 'expr' )
|
||||
|
||||
if new_value is None:
|
||||
return
|
||||
|
||||
|
||||
def handler( message ):
|
||||
# Annoyingly the response to setVariable request doesn't return a
|
||||
# Variable, but some part of it, so take a copy of the existing Variable
|
||||
# dict and update it, then call its update method with the updated copy.
|
||||
new_variable = dict( variable.variable )
|
||||
new_variable.update( message[ 'body' ] )
|
||||
|
||||
# Clear any existing known children (FIXME: Is this the right thing to do)
|
||||
variable.variables = None
|
||||
|
||||
# If the variable is expanded, re-request its children
|
||||
if variable.IsExpanded():
|
||||
self._connection.DoRequest( partial( self._ConsumeVariables,
|
||||
view.draw,
|
||||
variable ), {
|
||||
'command': 'variables',
|
||||
'arguments': {
|
||||
'variablesReference': variable.VariablesReference()
|
||||
},
|
||||
} )
|
||||
|
||||
variable.Update( new_variable )
|
||||
view.draw()
|
||||
|
||||
def failure_handler( reason, message ):
|
||||
utils.UserMessage( f'Cannot set value: { reason }', error = True )
|
||||
|
||||
self._connection.DoRequest( handler, {
|
||||
'command': 'setVariable',
|
||||
'arguments': {
|
||||
'variablesReference': variable.container.VariablesReference(),
|
||||
'name': variable.variable[ 'name' ],
|
||||
'value': new_value
|
||||
},
|
||||
}, failure_handler = failure_handler )
|
||||
|
||||
|
||||
|
||||
def _DrawVariables( self, view, variables, indent, is_short = False ):
|
||||
assert indent > 0
|
||||
for variable in variables:
|
||||
line = utils.AppendToBuffer(
|
||||
view.buf,
|
||||
'{indent}{marker}{icon} {name} ({type_}): {value}'.format(
|
||||
text = ''
|
||||
if is_short:
|
||||
text = '{indent}{icon} {name}: {value}'.format(
|
||||
# We borrow 1 space of indent to draw the change marker
|
||||
indent = ' ' * ( indent - 1 ),
|
||||
icon = '+' if ( variable.IsExpandable()
|
||||
and not variable.IsExpanded() ) else '-',
|
||||
name = variable.variable.get( 'name', '' ),
|
||||
value = variable.variable.get( 'value', '<unknown>' )
|
||||
)
|
||||
else:
|
||||
text = '{indent}{marker}{icon} {name} ({type_}): {value}'.format(
|
||||
# We borrow 1 space of indent to draw the change marker
|
||||
indent = ' ' * ( indent - 1 ),
|
||||
marker = '*' if variable.changed else ' ',
|
||||
icon = '+' if ( variable.IsExpandable()
|
||||
and not variable.IsExpanded() ) else '-',
|
||||
name = variable.variable[ 'name' ],
|
||||
name = variable.variable.get( 'name', '' ),
|
||||
type_ = variable.variable.get( 'type', '' ),
|
||||
value = variable.variable.get( 'value',
|
||||
'<unknown>' ) ).split( '\n' ) )
|
||||
value = variable.variable.get( 'value', '<unknown>' )
|
||||
)
|
||||
|
||||
line = utils.AppendToBuffer(
|
||||
view.buf,
|
||||
text.split( '\n' )
|
||||
)
|
||||
|
||||
view.lines[ line ] = variable
|
||||
|
||||
if variable.ShouldDrawDrillDown():
|
||||
self._DrawVariables( view, variable.variables, indent + 2 )
|
||||
self._DrawVariables( view, variable.variables, indent + 2, is_short )
|
||||
|
||||
def _DrawScopes( self ):
|
||||
# FIXME: The drawing is dumb and draws from scratch every time. This is
|
||||
|
|
@ -416,7 +641,7 @@ class VariablesView( object ):
|
|||
'Expression: '
|
||||
+ watch.expression[ 'expression' ] )
|
||||
watch.line = line
|
||||
self._DrawWatchResult( 2, watch )
|
||||
self._DrawWatchResult( self._watch, 2, watch )
|
||||
|
||||
def _DrawScope( self, indent, scope ):
|
||||
icon = '+' if scope.IsExpandable() and not scope.IsExpanded() else '-'
|
||||
|
|
@ -432,27 +657,36 @@ class VariablesView( object ):
|
|||
indent += 2
|
||||
self._DrawVariables( self._vars, scope.variables, indent )
|
||||
|
||||
def _DrawWatchResult( self, indent, watch ):
|
||||
def _DrawWatchResult( self, view, indent, watch, is_short = False ):
|
||||
if not watch.result:
|
||||
return
|
||||
|
||||
assert indent > 0
|
||||
icon = '+' if ( watch.result.IsExpandable() and
|
||||
not watch.result.IsExpanded() ) else '-'
|
||||
assert is_short or indent > 0
|
||||
|
||||
line = '{indent}{marker}{icon} Result: {result}'.format(
|
||||
if is_short:
|
||||
# The first result is always expanded in a hover (short format)
|
||||
icon = ''
|
||||
marker = ''
|
||||
leader = ''
|
||||
else:
|
||||
icon = '+' if ( watch.result.IsExpandable() and
|
||||
not watch.result.IsExpanded() ) else '-'
|
||||
marker = '*' if watch.result.changed else ' '
|
||||
leader = ' Result: '
|
||||
|
||||
line = '{indent}{marker}{icon}{leader}{result}'.format(
|
||||
# We borrow 1 space of indent to draw the change marker
|
||||
indent = ' ' * ( indent - 1 ),
|
||||
marker = '*' if watch.result.changed else ' ',
|
||||
marker = marker,
|
||||
icon = icon,
|
||||
leader = leader,
|
||||
result = watch.result.result.get( 'result', '<unknown>' ) )
|
||||
|
||||
line = utils.AppendToBuffer( self._watch.buf, line.split( '\n' ) )
|
||||
self._watch.lines[ line ] = watch.result
|
||||
line = utils.AppendToBuffer( view.buf, line.split( '\n' ) )
|
||||
view.lines[ line ] = watch.result
|
||||
|
||||
if watch.result.ShouldDrawDrillDown():
|
||||
indent = 4
|
||||
self._DrawVariables( self._watch, watch.result.variables, indent )
|
||||
self._DrawVariables( view, watch.result.variables, indent + 2, is_short )
|
||||
|
||||
def _ConsumeVariables( self, draw, parent, message ):
|
||||
new_variables = []
|
||||
|
|
@ -467,9 +701,8 @@ class VariablesView( object ):
|
|||
variable = v
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
variable = Variable( variable_body )
|
||||
variable = Variable( parent, variable_body )
|
||||
else:
|
||||
variable.Update( variable_body )
|
||||
|
||||
|
|
@ -489,47 +722,10 @@ class VariablesView( object ):
|
|||
|
||||
draw()
|
||||
|
||||
def ShowBalloon( self, frame, expression ):
|
||||
"""Callback to display variable under cursor `:h ballonexpr`"""
|
||||
if not self._connection:
|
||||
return ''
|
||||
|
||||
def handler( message ):
|
||||
# TODO: this result count be expandable, but we have no way to allow the
|
||||
# user to interact with the balloon to expand it, unless we use a popup
|
||||
# instead, but even then we don't really want to trap the cursor.
|
||||
body = message[ 'body' ]
|
||||
result = body[ 'result' ]
|
||||
if result is None:
|
||||
result = 'null'
|
||||
display = [
|
||||
'Type: ' + body.get( 'type', '<unknown>' ),
|
||||
'Value: ' + result
|
||||
]
|
||||
utils.DisplayBaloon( self._is_term, display )
|
||||
|
||||
def failure_handler( reason, message ):
|
||||
display = [ reason ]
|
||||
utils.DisplayBaloon( self._is_term, display )
|
||||
|
||||
# Send async request
|
||||
self._connection.DoRequest( handler, {
|
||||
'command': 'evaluate',
|
||||
'arguments': {
|
||||
'expression': expression,
|
||||
'frameId': frame[ 'id' ],
|
||||
'context': 'hover',
|
||||
}
|
||||
}, failure_handler )
|
||||
|
||||
# Return working (meanwhile)
|
||||
return '...'
|
||||
|
||||
|
||||
def SetSyntax( self, syntax ):
|
||||
# TODO: Switch to View.syntax
|
||||
self._current_syntax = utils.SetSyntax( self._current_syntax,
|
||||
syntax,
|
||||
self._vars.buf,
|
||||
self._watch.buf )
|
||||
|
||||
# vim: sw=2
|
||||
|
|
|
|||
12
run_tests
12
run_tests
|
|
@ -21,7 +21,7 @@ out_fd=1
|
|||
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
"--basedir")
|
||||
"--basedir"|"--base-dir"|"--test-base")
|
||||
shift
|
||||
SetBaseDir $1
|
||||
shift
|
||||
|
|
@ -36,7 +36,7 @@ while [ -n "$1" ]; do
|
|||
INSTALL=$1
|
||||
shift
|
||||
;;
|
||||
"--update")
|
||||
"--update"|"--upgrade")
|
||||
UPDATE=1
|
||||
shift
|
||||
;;
|
||||
|
|
@ -91,7 +91,8 @@ if [ "$INSTALL" = "1" ] || [ "$INSTALL" = "script" ]; then
|
|||
if ! python3 $(dirname $0)/install_gadget.py \
|
||||
--basedir ${BASEDIR} \
|
||||
${INSTALLER_ARGS} \
|
||||
--all; then
|
||||
--all \
|
||||
--force-enable-csharp; then
|
||||
echo "Script installation reported errors" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -102,7 +103,7 @@ if [ "$INSTALL" = "1" ] || [ "$INSTALL" = "vim" ]; then
|
|||
--cmd "${BASEDIR_CMD}" \
|
||||
-c 'autocmd User VimspectorInstallSuccess qa!' \
|
||||
-c 'autocmd User VimspectorInstallFailed cquit!' \
|
||||
-c "VimspectorInstall --all"; then
|
||||
-c "VimspectorInstall --all netcoredbg"; then
|
||||
echo "Vim installation reported errors" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
|
@ -144,6 +145,9 @@ set -e
|
|||
pushd tests/testdata/cpp/simple
|
||||
make clean all
|
||||
popd
|
||||
pushd support/test/csharp
|
||||
dotnet build
|
||||
popd
|
||||
set +e
|
||||
echo "%DONE - built test programs"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
" setup boilerplate to make this file usable with vim -Nu <tihs file> {{{
|
||||
scriptencoding utf-8
|
||||
execute 'source' expand( '<sfile>:p:h' ) . '/minimal_vimrc'
|
||||
set noequalalways
|
||||
let mapleader = ','
|
||||
let maplocalleader = "\<Space>"
|
||||
" }}}
|
||||
|
||||
" Custom Layout {{{
|
||||
|
||||
function! s:CustomiseUI()
|
||||
let wins = g:vimspector_session_windows
|
||||
|
|
@ -31,6 +38,10 @@ function! s:CustomiseUI()
|
|||
endfunction
|
||||
|
||||
function s:SetUpTerminal()
|
||||
if !has_key( g:vimspector_session_windows, 'terminal' )
|
||||
" There's a neovim bug which means that this doesn't work in neovim
|
||||
return
|
||||
endif
|
||||
let terminal_win = g:vimspector_session_windows.terminal
|
||||
|
||||
" Make the terminal window at most 80 columns wide, ensuring there is enough
|
||||
|
|
@ -43,7 +54,7 @@ function s:SetUpTerminal()
|
|||
let padding = 4
|
||||
let cols = max( [ min( [ &columns - left_bar - code - padding, 80 ] ), 10 ] )
|
||||
call win_gotoid( terminal_win )
|
||||
execute cols . 'wincmd |'
|
||||
execute string(cols) . 'wincmd |'
|
||||
endfunction
|
||||
|
||||
function! s:CustomiseWinBar()
|
||||
|
|
@ -66,9 +77,85 @@ augroup TestUICustomistaion
|
|||
autocmd User VimspectorUICreated call s:CustomiseWinBar()
|
||||
augroup END
|
||||
|
||||
" }}}
|
||||
|
||||
" Custom sign priority {{{
|
||||
|
||||
let g:vimspector_sign_priority = {
|
||||
\ 'vimspectorBP': 3,
|
||||
\ 'vimspectorBPCond': 2,
|
||||
\ 'vimspectorBPDisabled': 1,
|
||||
\ 'vimspectorPC': 999,
|
||||
\ }
|
||||
|
||||
" }}}
|
||||
|
||||
" Custom mappings while debuggins {{{
|
||||
let s:mapped = {}
|
||||
|
||||
function! s:OnJumpToFrame() abort
|
||||
if has_key( s:mapped, string( bufnr() ) )
|
||||
return
|
||||
endif
|
||||
|
||||
nmap <silent> <buffer> <LocalLeader>dn <Plug>VimspectorStepOver
|
||||
nmap <silent> <buffer> <LocalLeader>ds <Plug>VimspectorStepInto
|
||||
nmap <silent> <buffer> <LocalLeader>df <Plug>VimspectorStepOut
|
||||
nmap <silent> <buffer> <LocalLeader>dc <Plug>VimspectorContinue
|
||||
nmap <silent> <buffer> <LocalLeader>di <Plug>VimspectorBalloonEval
|
||||
xmap <silent> <buffer> <LocalLeader>di <Plug>VimspectorBalloonEval
|
||||
|
||||
let s:mapped[ string( bufnr() ) ] = { 'modifiable': &modifiable }
|
||||
|
||||
setlocal nomodifiable
|
||||
|
||||
endfunction
|
||||
|
||||
function! s:OnDebugEnd() abort
|
||||
|
||||
let original_buf = bufnr()
|
||||
let hidden = &hidden
|
||||
|
||||
try
|
||||
set hidden
|
||||
for bufnr in keys( s:mapped )
|
||||
try
|
||||
execute 'noautocmd buffer' bufnr
|
||||
silent! nunmap <buffer> <LocalLeader>dn
|
||||
silent! nunmap <buffer> <LocalLeader>ds
|
||||
silent! nunmap <buffer> <LocalLeader>df
|
||||
silent! nunmap <buffer> <LocalLeader>dc
|
||||
silent! nunmap <buffer> <LocalLeader>di
|
||||
silent! xunmap <buffer> <LocalLeader>di
|
||||
|
||||
let &l:modifiable = s:mapped[ bufnr ][ 'modifiable' ]
|
||||
endtry
|
||||
endfor
|
||||
finally
|
||||
execute 'noautocmd buffer' original_buf
|
||||
let &hidden = hidden
|
||||
endtry
|
||||
|
||||
let s:mapped = {}
|
||||
endfunction
|
||||
|
||||
augroup TestCustomMappings
|
||||
au!
|
||||
autocmd User VimspectorJumpedToFrame call s:OnJumpToFrame()
|
||||
autocmd User VimspectorDebugEnded call s:OnDebugEnd()
|
||||
augroup END
|
||||
|
||||
" }}}
|
||||
|
||||
" Custom mappings for special buffers {{{
|
||||
|
||||
let g:vimspector_mappings = {
|
||||
\ 'stack_trace': {},
|
||||
\ 'variables': {
|
||||
\ 'set_value': [ '<Tab>', '<C-CR>', 'C' ],
|
||||
\ }
|
||||
\ }
|
||||
|
||||
" }}}
|
||||
|
||||
" vim: foldmethod=marker
|
||||
|
|
|
|||
8
support/gadget_upgrade/README.md
Normal file
8
support/gadget_upgrade/README.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Manually updating shipped gadgets
|
||||
|
||||
Download the gadget files manuall from their official source into this dir.
|
||||
Run `./checksum.py <list of files>` to get the checksums.
|
||||
|
||||
Update ../../python3/vimspector/gadgets.py with the new version and the
|
||||
checksums.
|
||||
|
||||
13
support/gadget_upgrade/checksum.py
Executable file
13
support/gadget_upgrade/checksum.py
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
|
||||
|
||||
def GetChecksumSHA254( file_path ):
|
||||
with open( file_path, 'rb' ) as existing_file:
|
||||
return hashlib.sha256( existing_file.read() ).hexdigest()
|
||||
|
||||
|
||||
for arg in sys.argv[ 1: ]:
|
||||
print( f"{ arg } = { GetChecksumSHA254( arg ) }" )
|
||||
15
support/test/bash/.vimspector.json
Normal file
15
support/test/bash/.vimspector.json
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json",
|
||||
"configurations": {
|
||||
"Run Current Script": {
|
||||
"adapter": "vscode-bash",
|
||||
"autoselect": false,
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${file}",
|
||||
"cwd": "${fileDirname}",
|
||||
"args": [ "*${args}" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,15 @@
|
|||
"program": "${workspaceRoot}/test",
|
||||
"stopAtEntry": true
|
||||
}
|
||||
},
|
||||
"cpptools": {
|
||||
"adapter": "vscode-cpptools",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/test",
|
||||
"stopOnEntry": true,
|
||||
"MIMode": "lldb"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
def Settings( **kwargs ):
|
||||
return {
|
||||
'flags': [ '-x', 'c++', '-Wall', '-Wextra' ]
|
||||
'flags': [ '-x', 'c++', '-Wall', '-Wextra', '-std=c++17' ]
|
||||
}
|
||||
|
|
|
|||
1
support/test/csharp/.gitignore
vendored
1
support/test/csharp/.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
bin/
|
||||
obj/Debug
|
||||
obj/
|
||||
|
|
|
|||
|
|
@ -1,25 +1,57 @@
|
|||
{
|
||||
"configurations": {
|
||||
"launch - netcoredbg": {
|
||||
"adapter": "netcoredbg",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/bin/Debug/netcoreapp2.2/csharp.dll",
|
||||
"args": [],
|
||||
"stopAtEntry": true
|
||||
}
|
||||
"adapters": {
|
||||
"netcoredbg-debuglog": {
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
"launch - mono": {
|
||||
"adapter": "vscode-mono-debug",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/Program.exe",
|
||||
"console": "integratedTerminal",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
"command": [
|
||||
"${gadgetDir}/netcoredbg/netcoredbg",
|
||||
"--interpreter=vscode",
|
||||
"--engineLogging=${workspaceRoot}/netcoredbg.engine.log",
|
||||
"--log=${workspaceRoot}/netcoredbg.log"
|
||||
],
|
||||
"configuration": {
|
||||
"cwd": "${workspaceRoot}"
|
||||
},
|
||||
"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": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio 15
|
||||
VisualStudioVersion = 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
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -15,4 +17,18 @@ Global
|
|||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"version": 1,
|
||||
"dgSpecHash": "6/vdr7YprlSIoQecv/nNuLNflFpO0X7eN7jHUinZTsgian9nYpmHMWirsDWMi5l+29TH+Qy8O/QfaB/48QtjRQ==",
|
||||
"success": true
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
|
||||
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/Users/ben/.nuget/packages/</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/Users/ben/.nuget/packages/;/usr/local/share/dotnet/sdk/NuGetFallbackFolder</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">5.7.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="$([MSBuild]::EnsureTrailingSlash($(NuGetPackageFolders)))" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.props" Condition="Exists('/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.props')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="/usr/local/share/dotnet/sdk/NuGetFallbackFolder/netstandard.library/2.0.3/build/netstandard2.0/NETStandard.Library.targets" Condition="Exists('/usr/local/share/dotnet/sdk/NuGetFallbackFolder/netstandard.library/2.0.3/build/netstandard2.0/NETStandard.Library.targets')" />
|
||||
<Import Project="/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.targets" Condition="Exists('/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/build/netcoreapp2.2/Microsoft.NETCore.App.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -1,748 +0,0 @@
|
|||
{
|
||||
"version": 3,
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v2.2": {
|
||||
"Microsoft.NETCore.App/2.2.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.DotNetHostPolicy": "2.2.0",
|
||||
"Microsoft.NETCore.Platforms": "2.2.0",
|
||||
"Microsoft.NETCore.Targets": "2.0.0",
|
||||
"NETStandard.Library": "2.0.3"
|
||||
},
|
||||
"compile": {
|
||||
"ref/netcoreapp2.2/Microsoft.CSharp.dll": {},
|
||||
"ref/netcoreapp2.2/Microsoft.VisualBasic.dll": {},
|
||||
"ref/netcoreapp2.2/Microsoft.Win32.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.AppContext.dll": {},
|
||||
"ref/netcoreapp2.2/System.Buffers.dll": {},
|
||||
"ref/netcoreapp2.2/System.Collections.Concurrent.dll": {},
|
||||
"ref/netcoreapp2.2/System.Collections.Immutable.dll": {},
|
||||
"ref/netcoreapp2.2/System.Collections.NonGeneric.dll": {},
|
||||
"ref/netcoreapp2.2/System.Collections.Specialized.dll": {},
|
||||
"ref/netcoreapp2.2/System.Collections.dll": {},
|
||||
"ref/netcoreapp2.2/System.ComponentModel.Annotations.dll": {},
|
||||
"ref/netcoreapp2.2/System.ComponentModel.DataAnnotations.dll": {},
|
||||
"ref/netcoreapp2.2/System.ComponentModel.EventBasedAsync.dll": {},
|
||||
"ref/netcoreapp2.2/System.ComponentModel.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.ComponentModel.TypeConverter.dll": {},
|
||||
"ref/netcoreapp2.2/System.ComponentModel.dll": {},
|
||||
"ref/netcoreapp2.2/System.Configuration.dll": {},
|
||||
"ref/netcoreapp2.2/System.Console.dll": {},
|
||||
"ref/netcoreapp2.2/System.Core.dll": {},
|
||||
"ref/netcoreapp2.2/System.Data.Common.dll": {},
|
||||
"ref/netcoreapp2.2/System.Data.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Contracts.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Debug.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.DiagnosticSource.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.FileVersionInfo.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Process.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.StackTrace.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.TextWriterTraceListener.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Tools.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.TraceSource.dll": {},
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Tracing.dll": {},
|
||||
"ref/netcoreapp2.2/System.Drawing.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.Drawing.dll": {},
|
||||
"ref/netcoreapp2.2/System.Dynamic.Runtime.dll": {},
|
||||
"ref/netcoreapp2.2/System.Globalization.Calendars.dll": {},
|
||||
"ref/netcoreapp2.2/System.Globalization.Extensions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Globalization.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.Compression.Brotli.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.Compression.FileSystem.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.Compression.ZipFile.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.Compression.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.DriveInfo.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.Watcher.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.IsolatedStorage.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.MemoryMappedFiles.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.Pipes.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.UnmanagedMemoryStream.dll": {},
|
||||
"ref/netcoreapp2.2/System.IO.dll": {},
|
||||
"ref/netcoreapp2.2/System.Linq.Expressions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Linq.Parallel.dll": {},
|
||||
"ref/netcoreapp2.2/System.Linq.Queryable.dll": {},
|
||||
"ref/netcoreapp2.2/System.Linq.dll": {},
|
||||
"ref/netcoreapp2.2/System.Memory.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Http.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.HttpListener.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Mail.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.NameResolution.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.NetworkInformation.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Ping.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Requests.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Security.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.ServicePoint.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.Sockets.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.WebClient.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.WebHeaderCollection.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.WebProxy.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.WebSockets.Client.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.WebSockets.dll": {},
|
||||
"ref/netcoreapp2.2/System.Net.dll": {},
|
||||
"ref/netcoreapp2.2/System.Numerics.Vectors.dll": {},
|
||||
"ref/netcoreapp2.2/System.Numerics.dll": {},
|
||||
"ref/netcoreapp2.2/System.ObjectModel.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.DispatchProxy.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.ILGeneration.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.Lightweight.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.Extensions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.Metadata.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.TypeExtensions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Reflection.dll": {},
|
||||
"ref/netcoreapp2.2/System.Resources.Reader.dll": {},
|
||||
"ref/netcoreapp2.2/System.Resources.ResourceManager.dll": {},
|
||||
"ref/netcoreapp2.2/System.Resources.Writer.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.CompilerServices.VisualC.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Extensions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Handles.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.RuntimeInformation.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.WindowsRuntime.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Loader.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Numerics.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Formatters.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Json.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Xml.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.dll": {},
|
||||
"ref/netcoreapp2.2/System.Runtime.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Claims.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Algorithms.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Csp.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Encoding.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Primitives.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.X509Certificates.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.Principal.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.SecureString.dll": {},
|
||||
"ref/netcoreapp2.2/System.Security.dll": {},
|
||||
"ref/netcoreapp2.2/System.ServiceModel.Web.dll": {},
|
||||
"ref/netcoreapp2.2/System.ServiceProcess.dll": {},
|
||||
"ref/netcoreapp2.2/System.Text.Encoding.Extensions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Text.Encoding.dll": {},
|
||||
"ref/netcoreapp2.2/System.Text.RegularExpressions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Overlapped.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Dataflow.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Extensions.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Parallel.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Thread.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.ThreadPool.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.Timer.dll": {},
|
||||
"ref/netcoreapp2.2/System.Threading.dll": {},
|
||||
"ref/netcoreapp2.2/System.Transactions.Local.dll": {},
|
||||
"ref/netcoreapp2.2/System.Transactions.dll": {},
|
||||
"ref/netcoreapp2.2/System.ValueTuple.dll": {},
|
||||
"ref/netcoreapp2.2/System.Web.HttpUtility.dll": {},
|
||||
"ref/netcoreapp2.2/System.Web.dll": {},
|
||||
"ref/netcoreapp2.2/System.Windows.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.Linq.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.ReaderWriter.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.Serialization.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.XDocument.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.XPath.XDocument.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.XPath.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.XmlDocument.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.XmlSerializer.dll": {},
|
||||
"ref/netcoreapp2.2/System.Xml.dll": {},
|
||||
"ref/netcoreapp2.2/System.dll": {},
|
||||
"ref/netcoreapp2.2/WindowsBase.dll": {},
|
||||
"ref/netcoreapp2.2/mscorlib.dll": {},
|
||||
"ref/netcoreapp2.2/netstandard.dll": {}
|
||||
},
|
||||
"build": {
|
||||
"build/netcoreapp2.2/Microsoft.NETCore.App.props": {},
|
||||
"build/netcoreapp2.2/Microsoft.NETCore.App.targets": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.DotNetAppHost/2.2.0": {
|
||||
"type": "package"
|
||||
},
|
||||
"Microsoft.NETCore.DotNetHostPolicy/2.2.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.DotNetHostResolver": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.DotNetHostResolver/2.2.0": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.DotNetAppHost": "2.2.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Platforms/2.2.0": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/netstandard1.0/_._": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard1.0/_._": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.NETCore.Targets/2.0.0": {
|
||||
"type": "package",
|
||||
"compile": {
|
||||
"lib/netstandard1.0/_._": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard1.0/_._": {}
|
||||
}
|
||||
},
|
||||
"NETStandard.Library/2.0.3": {
|
||||
"type": "package",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Platforms": "1.1.0"
|
||||
},
|
||||
"compile": {
|
||||
"lib/netstandard1.0/_._": {}
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netstandard1.0/_._": {}
|
||||
},
|
||||
"build": {
|
||||
"build/netstandard2.0/NETStandard.Library.targets": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"Microsoft.NETCore.App/2.2.0": {
|
||||
"sha512": "7z5l8Jp324S8bU8+yyWeYHXUFYvKyiI5lqS1dXgTzOx1H69Qbf6df12kCKlNX45LpMfCMd4U3M6p7Rl5Zk7SLA==",
|
||||
"type": "package",
|
||||
"path": "microsoft.netcore.app/2.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"LICENSE.TXT",
|
||||
"Microsoft.NETCore.App.versions.txt",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"build/netcoreapp2.2/Microsoft.NETCore.App.PlatformManifest.txt",
|
||||
"build/netcoreapp2.2/Microsoft.NETCore.App.props",
|
||||
"build/netcoreapp2.2/Microsoft.NETCore.App.targets",
|
||||
"microsoft.netcore.app.2.2.0.nupkg.sha512",
|
||||
"microsoft.netcore.app.nuspec",
|
||||
"ref/netcoreapp2.2/Microsoft.CSharp.dll",
|
||||
"ref/netcoreapp2.2/Microsoft.CSharp.xml",
|
||||
"ref/netcoreapp2.2/Microsoft.VisualBasic.dll",
|
||||
"ref/netcoreapp2.2/Microsoft.VisualBasic.xml",
|
||||
"ref/netcoreapp2.2/Microsoft.Win32.Primitives.dll",
|
||||
"ref/netcoreapp2.2/Microsoft.Win32.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.AppContext.dll",
|
||||
"ref/netcoreapp2.2/System.Buffers.dll",
|
||||
"ref/netcoreapp2.2/System.Buffers.xml",
|
||||
"ref/netcoreapp2.2/System.Collections.Concurrent.dll",
|
||||
"ref/netcoreapp2.2/System.Collections.Concurrent.xml",
|
||||
"ref/netcoreapp2.2/System.Collections.Immutable.dll",
|
||||
"ref/netcoreapp2.2/System.Collections.Immutable.xml",
|
||||
"ref/netcoreapp2.2/System.Collections.NonGeneric.dll",
|
||||
"ref/netcoreapp2.2/System.Collections.NonGeneric.xml",
|
||||
"ref/netcoreapp2.2/System.Collections.Specialized.dll",
|
||||
"ref/netcoreapp2.2/System.Collections.Specialized.xml",
|
||||
"ref/netcoreapp2.2/System.Collections.dll",
|
||||
"ref/netcoreapp2.2/System.Collections.xml",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.Annotations.dll",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.Annotations.xml",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.DataAnnotations.dll",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.EventBasedAsync.dll",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.EventBasedAsync.xml",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.TypeConverter.dll",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.TypeConverter.xml",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.dll",
|
||||
"ref/netcoreapp2.2/System.ComponentModel.xml",
|
||||
"ref/netcoreapp2.2/System.Configuration.dll",
|
||||
"ref/netcoreapp2.2/System.Console.dll",
|
||||
"ref/netcoreapp2.2/System.Console.xml",
|
||||
"ref/netcoreapp2.2/System.Core.dll",
|
||||
"ref/netcoreapp2.2/System.Data.Common.dll",
|
||||
"ref/netcoreapp2.2/System.Data.Common.xml",
|
||||
"ref/netcoreapp2.2/System.Data.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Contracts.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Contracts.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Debug.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Debug.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.DiagnosticSource.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.DiagnosticSource.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.FileVersionInfo.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.FileVersionInfo.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Process.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Process.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.StackTrace.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.StackTrace.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.TextWriterTraceListener.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.TextWriterTraceListener.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Tools.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Tools.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.TraceSource.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.TraceSource.xml",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Tracing.dll",
|
||||
"ref/netcoreapp2.2/System.Diagnostics.Tracing.xml",
|
||||
"ref/netcoreapp2.2/System.Drawing.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.Drawing.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.Drawing.dll",
|
||||
"ref/netcoreapp2.2/System.Dynamic.Runtime.dll",
|
||||
"ref/netcoreapp2.2/System.Globalization.Calendars.dll",
|
||||
"ref/netcoreapp2.2/System.Globalization.Extensions.dll",
|
||||
"ref/netcoreapp2.2/System.Globalization.dll",
|
||||
"ref/netcoreapp2.2/System.IO.Compression.Brotli.dll",
|
||||
"ref/netcoreapp2.2/System.IO.Compression.FileSystem.dll",
|
||||
"ref/netcoreapp2.2/System.IO.Compression.ZipFile.dll",
|
||||
"ref/netcoreapp2.2/System.IO.Compression.ZipFile.xml",
|
||||
"ref/netcoreapp2.2/System.IO.Compression.dll",
|
||||
"ref/netcoreapp2.2/System.IO.Compression.xml",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.DriveInfo.dll",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.DriveInfo.xml",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.Watcher.dll",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.Watcher.xml",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.dll",
|
||||
"ref/netcoreapp2.2/System.IO.FileSystem.xml",
|
||||
"ref/netcoreapp2.2/System.IO.IsolatedStorage.dll",
|
||||
"ref/netcoreapp2.2/System.IO.IsolatedStorage.xml",
|
||||
"ref/netcoreapp2.2/System.IO.MemoryMappedFiles.dll",
|
||||
"ref/netcoreapp2.2/System.IO.MemoryMappedFiles.xml",
|
||||
"ref/netcoreapp2.2/System.IO.Pipes.dll",
|
||||
"ref/netcoreapp2.2/System.IO.Pipes.xml",
|
||||
"ref/netcoreapp2.2/System.IO.UnmanagedMemoryStream.dll",
|
||||
"ref/netcoreapp2.2/System.IO.dll",
|
||||
"ref/netcoreapp2.2/System.Linq.Expressions.dll",
|
||||
"ref/netcoreapp2.2/System.Linq.Expressions.xml",
|
||||
"ref/netcoreapp2.2/System.Linq.Parallel.dll",
|
||||
"ref/netcoreapp2.2/System.Linq.Parallel.xml",
|
||||
"ref/netcoreapp2.2/System.Linq.Queryable.dll",
|
||||
"ref/netcoreapp2.2/System.Linq.Queryable.xml",
|
||||
"ref/netcoreapp2.2/System.Linq.dll",
|
||||
"ref/netcoreapp2.2/System.Linq.xml",
|
||||
"ref/netcoreapp2.2/System.Memory.dll",
|
||||
"ref/netcoreapp2.2/System.Memory.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Http.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Http.xml",
|
||||
"ref/netcoreapp2.2/System.Net.HttpListener.dll",
|
||||
"ref/netcoreapp2.2/System.Net.HttpListener.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Mail.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Mail.xml",
|
||||
"ref/netcoreapp2.2/System.Net.NameResolution.dll",
|
||||
"ref/netcoreapp2.2/System.Net.NameResolution.xml",
|
||||
"ref/netcoreapp2.2/System.Net.NetworkInformation.dll",
|
||||
"ref/netcoreapp2.2/System.Net.NetworkInformation.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Ping.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Ping.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Requests.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Requests.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Security.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Security.xml",
|
||||
"ref/netcoreapp2.2/System.Net.ServicePoint.dll",
|
||||
"ref/netcoreapp2.2/System.Net.ServicePoint.xml",
|
||||
"ref/netcoreapp2.2/System.Net.Sockets.dll",
|
||||
"ref/netcoreapp2.2/System.Net.Sockets.xml",
|
||||
"ref/netcoreapp2.2/System.Net.WebClient.dll",
|
||||
"ref/netcoreapp2.2/System.Net.WebClient.xml",
|
||||
"ref/netcoreapp2.2/System.Net.WebHeaderCollection.dll",
|
||||
"ref/netcoreapp2.2/System.Net.WebHeaderCollection.xml",
|
||||
"ref/netcoreapp2.2/System.Net.WebProxy.dll",
|
||||
"ref/netcoreapp2.2/System.Net.WebProxy.xml",
|
||||
"ref/netcoreapp2.2/System.Net.WebSockets.Client.dll",
|
||||
"ref/netcoreapp2.2/System.Net.WebSockets.Client.xml",
|
||||
"ref/netcoreapp2.2/System.Net.WebSockets.dll",
|
||||
"ref/netcoreapp2.2/System.Net.WebSockets.xml",
|
||||
"ref/netcoreapp2.2/System.Net.dll",
|
||||
"ref/netcoreapp2.2/System.Numerics.Vectors.dll",
|
||||
"ref/netcoreapp2.2/System.Numerics.Vectors.xml",
|
||||
"ref/netcoreapp2.2/System.Numerics.dll",
|
||||
"ref/netcoreapp2.2/System.ObjectModel.dll",
|
||||
"ref/netcoreapp2.2/System.ObjectModel.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.DispatchProxy.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.DispatchProxy.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.ILGeneration.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.ILGeneration.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.Lightweight.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.Lightweight.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.Emit.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.Extensions.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.Metadata.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.Metadata.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.TypeExtensions.dll",
|
||||
"ref/netcoreapp2.2/System.Reflection.TypeExtensions.xml",
|
||||
"ref/netcoreapp2.2/System.Reflection.dll",
|
||||
"ref/netcoreapp2.2/System.Resources.Reader.dll",
|
||||
"ref/netcoreapp2.2/System.Resources.ResourceManager.dll",
|
||||
"ref/netcoreapp2.2/System.Resources.ResourceManager.xml",
|
||||
"ref/netcoreapp2.2/System.Resources.Writer.dll",
|
||||
"ref/netcoreapp2.2/System.Resources.Writer.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.CompilerServices.VisualC.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.CompilerServices.VisualC.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Extensions.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Extensions.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Handles.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.RuntimeInformation.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.RuntimeInformation.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.WindowsRuntime.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.WindowsRuntime.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.InteropServices.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Loader.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Loader.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Numerics.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Numerics.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Formatters.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Formatters.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Json.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Json.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Xml.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.Xml.xml",
|
||||
"ref/netcoreapp2.2/System.Runtime.Serialization.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.dll",
|
||||
"ref/netcoreapp2.2/System.Runtime.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Claims.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Claims.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Algorithms.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Algorithms.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Csp.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Csp.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Encoding.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Encoding.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Primitives.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.Primitives.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.X509Certificates.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Cryptography.X509Certificates.xml",
|
||||
"ref/netcoreapp2.2/System.Security.Principal.dll",
|
||||
"ref/netcoreapp2.2/System.Security.Principal.xml",
|
||||
"ref/netcoreapp2.2/System.Security.SecureString.dll",
|
||||
"ref/netcoreapp2.2/System.Security.dll",
|
||||
"ref/netcoreapp2.2/System.ServiceModel.Web.dll",
|
||||
"ref/netcoreapp2.2/System.ServiceProcess.dll",
|
||||
"ref/netcoreapp2.2/System.Text.Encoding.Extensions.dll",
|
||||
"ref/netcoreapp2.2/System.Text.Encoding.Extensions.xml",
|
||||
"ref/netcoreapp2.2/System.Text.Encoding.dll",
|
||||
"ref/netcoreapp2.2/System.Text.RegularExpressions.dll",
|
||||
"ref/netcoreapp2.2/System.Text.RegularExpressions.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Overlapped.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Overlapped.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Dataflow.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Dataflow.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Extensions.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Extensions.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Parallel.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.Parallel.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Tasks.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Thread.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Thread.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.ThreadPool.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.ThreadPool.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.Timer.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.Timer.xml",
|
||||
"ref/netcoreapp2.2/System.Threading.dll",
|
||||
"ref/netcoreapp2.2/System.Threading.xml",
|
||||
"ref/netcoreapp2.2/System.Transactions.Local.dll",
|
||||
"ref/netcoreapp2.2/System.Transactions.Local.xml",
|
||||
"ref/netcoreapp2.2/System.Transactions.dll",
|
||||
"ref/netcoreapp2.2/System.ValueTuple.dll",
|
||||
"ref/netcoreapp2.2/System.Web.HttpUtility.dll",
|
||||
"ref/netcoreapp2.2/System.Web.HttpUtility.xml",
|
||||
"ref/netcoreapp2.2/System.Web.dll",
|
||||
"ref/netcoreapp2.2/System.Windows.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.Linq.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.ReaderWriter.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.ReaderWriter.xml",
|
||||
"ref/netcoreapp2.2/System.Xml.Serialization.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.XDocument.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.XDocument.xml",
|
||||
"ref/netcoreapp2.2/System.Xml.XPath.XDocument.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.XPath.XDocument.xml",
|
||||
"ref/netcoreapp2.2/System.Xml.XPath.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.XPath.xml",
|
||||
"ref/netcoreapp2.2/System.Xml.XmlDocument.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.XmlSerializer.dll",
|
||||
"ref/netcoreapp2.2/System.Xml.XmlSerializer.xml",
|
||||
"ref/netcoreapp2.2/System.Xml.dll",
|
||||
"ref/netcoreapp2.2/System.dll",
|
||||
"ref/netcoreapp2.2/WindowsBase.dll",
|
||||
"ref/netcoreapp2.2/mscorlib.dll",
|
||||
"ref/netcoreapp2.2/netstandard.dll",
|
||||
"runtime.json"
|
||||
]
|
||||
},
|
||||
"Microsoft.NETCore.DotNetAppHost/2.2.0": {
|
||||
"sha512": "DrhaKInRKKvN6Ns2VNIlC7ZffLOp9THf8cO6X4fytPRJovJUbF49/zzx4WfgX9E44FMsw9hT8hrKiIqDSHvGvA==",
|
||||
"type": "package",
|
||||
"path": "microsoft.netcore.dotnetapphost/2.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"LICENSE.TXT",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"microsoft.netcore.dotnetapphost.2.2.0.nupkg.sha512",
|
||||
"microsoft.netcore.dotnetapphost.nuspec",
|
||||
"runtime.json"
|
||||
]
|
||||
},
|
||||
"Microsoft.NETCore.DotNetHostPolicy/2.2.0": {
|
||||
"sha512": "FJie7IoPZFaPgNDxhZGmDBQP/Bs5vPdfca/G2Wf9gd6LIvMYkZcibtmJwB4tcf4KXkaOYfIOo4Cl9sEPMsSzkw==",
|
||||
"type": "package",
|
||||
"path": "microsoft.netcore.dotnethostpolicy/2.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"LICENSE.TXT",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"microsoft.netcore.dotnethostpolicy.2.2.0.nupkg.sha512",
|
||||
"microsoft.netcore.dotnethostpolicy.nuspec",
|
||||
"runtime.json"
|
||||
]
|
||||
},
|
||||
"Microsoft.NETCore.DotNetHostResolver/2.2.0": {
|
||||
"sha512": "spDm3AJYmebthDNhzY17YLPtvbc+Y1lCLVeiIH1uLJ/hZaM+40pBiPefFR8J1u66Ndkqi8ipR2tEbqPnYnjRhw==",
|
||||
"type": "package",
|
||||
"path": "microsoft.netcore.dotnethostresolver/2.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"LICENSE.TXT",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"microsoft.netcore.dotnethostresolver.2.2.0.nupkg.sha512",
|
||||
"microsoft.netcore.dotnethostresolver.nuspec",
|
||||
"runtime.json"
|
||||
]
|
||||
},
|
||||
"Microsoft.NETCore.Platforms/2.2.0": {
|
||||
"sha512": "T/J+XZo+YheFTJh8/4uoeJDdz5qOmOMkjg6/VL8mHJ9AnP8+fmV/kcbxeXsob0irRNiChf+V0ig1MCRLp/+Kog==",
|
||||
"type": "package",
|
||||
"path": "microsoft.netcore.platforms/2.2.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
".signature.p7s",
|
||||
"LICENSE.TXT",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"lib/netstandard1.0/_._",
|
||||
"microsoft.netcore.platforms.2.2.0.nupkg.sha512",
|
||||
"microsoft.netcore.platforms.nuspec",
|
||||
"runtime.json",
|
||||
"useSharedDesignerContext.txt",
|
||||
"version.txt"
|
||||
]
|
||||
},
|
||||
"Microsoft.NETCore.Targets/2.0.0": {
|
||||
"sha512": "odP/tJj1z6GylFpNo7pMtbd/xQgTC3Ex2If63dRTL38bBNMwsBnJ+RceUIyHdRBC0oik/3NehYT+oECwBhIM3Q==",
|
||||
"type": "package",
|
||||
"path": "microsoft.netcore.targets/2.0.0",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
"LICENSE.TXT",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"lib/netstandard1.0/_._",
|
||||
"microsoft.netcore.targets.2.0.0.nupkg.sha512",
|
||||
"microsoft.netcore.targets.nuspec",
|
||||
"runtime.json",
|
||||
"useSharedDesignerContext.txt",
|
||||
"version.txt"
|
||||
]
|
||||
},
|
||||
"NETStandard.Library/2.0.3": {
|
||||
"sha512": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==",
|
||||
"type": "package",
|
||||
"path": "netstandard.library/2.0.3",
|
||||
"files": [
|
||||
".nupkg.metadata",
|
||||
"LICENSE.TXT",
|
||||
"THIRD-PARTY-NOTICES.TXT",
|
||||
"build/netstandard2.0/NETStandard.Library.targets",
|
||||
"build/netstandard2.0/ref/Microsoft.Win32.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.AppContext.dll",
|
||||
"build/netstandard2.0/ref/System.Collections.Concurrent.dll",
|
||||
"build/netstandard2.0/ref/System.Collections.NonGeneric.dll",
|
||||
"build/netstandard2.0/ref/System.Collections.Specialized.dll",
|
||||
"build/netstandard2.0/ref/System.Collections.dll",
|
||||
"build/netstandard2.0/ref/System.ComponentModel.Composition.dll",
|
||||
"build/netstandard2.0/ref/System.ComponentModel.EventBasedAsync.dll",
|
||||
"build/netstandard2.0/ref/System.ComponentModel.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.ComponentModel.TypeConverter.dll",
|
||||
"build/netstandard2.0/ref/System.ComponentModel.dll",
|
||||
"build/netstandard2.0/ref/System.Console.dll",
|
||||
"build/netstandard2.0/ref/System.Core.dll",
|
||||
"build/netstandard2.0/ref/System.Data.Common.dll",
|
||||
"build/netstandard2.0/ref/System.Data.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.Contracts.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.Debug.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.FileVersionInfo.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.Process.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.StackTrace.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.TextWriterTraceListener.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.Tools.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.TraceSource.dll",
|
||||
"build/netstandard2.0/ref/System.Diagnostics.Tracing.dll",
|
||||
"build/netstandard2.0/ref/System.Drawing.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.Drawing.dll",
|
||||
"build/netstandard2.0/ref/System.Dynamic.Runtime.dll",
|
||||
"build/netstandard2.0/ref/System.Globalization.Calendars.dll",
|
||||
"build/netstandard2.0/ref/System.Globalization.Extensions.dll",
|
||||
"build/netstandard2.0/ref/System.Globalization.dll",
|
||||
"build/netstandard2.0/ref/System.IO.Compression.FileSystem.dll",
|
||||
"build/netstandard2.0/ref/System.IO.Compression.ZipFile.dll",
|
||||
"build/netstandard2.0/ref/System.IO.Compression.dll",
|
||||
"build/netstandard2.0/ref/System.IO.FileSystem.DriveInfo.dll",
|
||||
"build/netstandard2.0/ref/System.IO.FileSystem.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.IO.FileSystem.Watcher.dll",
|
||||
"build/netstandard2.0/ref/System.IO.FileSystem.dll",
|
||||
"build/netstandard2.0/ref/System.IO.IsolatedStorage.dll",
|
||||
"build/netstandard2.0/ref/System.IO.MemoryMappedFiles.dll",
|
||||
"build/netstandard2.0/ref/System.IO.Pipes.dll",
|
||||
"build/netstandard2.0/ref/System.IO.UnmanagedMemoryStream.dll",
|
||||
"build/netstandard2.0/ref/System.IO.dll",
|
||||
"build/netstandard2.0/ref/System.Linq.Expressions.dll",
|
||||
"build/netstandard2.0/ref/System.Linq.Parallel.dll",
|
||||
"build/netstandard2.0/ref/System.Linq.Queryable.dll",
|
||||
"build/netstandard2.0/ref/System.Linq.dll",
|
||||
"build/netstandard2.0/ref/System.Net.Http.dll",
|
||||
"build/netstandard2.0/ref/System.Net.NameResolution.dll",
|
||||
"build/netstandard2.0/ref/System.Net.NetworkInformation.dll",
|
||||
"build/netstandard2.0/ref/System.Net.Ping.dll",
|
||||
"build/netstandard2.0/ref/System.Net.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.Net.Requests.dll",
|
||||
"build/netstandard2.0/ref/System.Net.Security.dll",
|
||||
"build/netstandard2.0/ref/System.Net.Sockets.dll",
|
||||
"build/netstandard2.0/ref/System.Net.WebHeaderCollection.dll",
|
||||
"build/netstandard2.0/ref/System.Net.WebSockets.Client.dll",
|
||||
"build/netstandard2.0/ref/System.Net.WebSockets.dll",
|
||||
"build/netstandard2.0/ref/System.Net.dll",
|
||||
"build/netstandard2.0/ref/System.Numerics.dll",
|
||||
"build/netstandard2.0/ref/System.ObjectModel.dll",
|
||||
"build/netstandard2.0/ref/System.Reflection.Extensions.dll",
|
||||
"build/netstandard2.0/ref/System.Reflection.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.Reflection.dll",
|
||||
"build/netstandard2.0/ref/System.Resources.Reader.dll",
|
||||
"build/netstandard2.0/ref/System.Resources.ResourceManager.dll",
|
||||
"build/netstandard2.0/ref/System.Resources.Writer.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.CompilerServices.VisualC.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Extensions.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Handles.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.InteropServices.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Numerics.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Serialization.Formatters.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Serialization.Json.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Serialization.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Serialization.Xml.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.Serialization.dll",
|
||||
"build/netstandard2.0/ref/System.Runtime.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Claims.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Cryptography.Algorithms.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Cryptography.Csp.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Cryptography.Encoding.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Cryptography.Primitives.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Cryptography.X509Certificates.dll",
|
||||
"build/netstandard2.0/ref/System.Security.Principal.dll",
|
||||
"build/netstandard2.0/ref/System.Security.SecureString.dll",
|
||||
"build/netstandard2.0/ref/System.ServiceModel.Web.dll",
|
||||
"build/netstandard2.0/ref/System.Text.Encoding.Extensions.dll",
|
||||
"build/netstandard2.0/ref/System.Text.Encoding.dll",
|
||||
"build/netstandard2.0/ref/System.Text.RegularExpressions.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.Overlapped.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.Tasks.Parallel.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.Tasks.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.Thread.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.ThreadPool.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.Timer.dll",
|
||||
"build/netstandard2.0/ref/System.Threading.dll",
|
||||
"build/netstandard2.0/ref/System.Transactions.dll",
|
||||
"build/netstandard2.0/ref/System.ValueTuple.dll",
|
||||
"build/netstandard2.0/ref/System.Web.dll",
|
||||
"build/netstandard2.0/ref/System.Windows.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.Linq.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.ReaderWriter.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.Serialization.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.XDocument.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.XPath.XDocument.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.XPath.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.XmlDocument.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.XmlSerializer.dll",
|
||||
"build/netstandard2.0/ref/System.Xml.dll",
|
||||
"build/netstandard2.0/ref/System.dll",
|
||||
"build/netstandard2.0/ref/mscorlib.dll",
|
||||
"build/netstandard2.0/ref/netstandard.dll",
|
||||
"build/netstandard2.0/ref/netstandard.xml",
|
||||
"lib/netstandard1.0/_._",
|
||||
"netstandard.library.2.0.3.nupkg.sha512",
|
||||
"netstandard.library.nuspec"
|
||||
]
|
||||
}
|
||||
},
|
||||
"projectFileDependencyGroups": {
|
||||
".NETCoreApp,Version=v2.2": [
|
||||
"Microsoft.NETCore.App >= 2.2.0"
|
||||
]
|
||||
},
|
||||
"packageFolders": {
|
||||
"/Users/ben/.nuget/packages/": {},
|
||||
"/usr/local/share/dotnet/sdk/NuGetFallbackFolder": {}
|
||||
},
|
||||
"project": {
|
||||
"version": "1.0.0",
|
||||
"restore": {
|
||||
"projectUniqueName": "/Users/ben/.vim/bundle/vimspector/support/test/csharp/csharp.csproj",
|
||||
"projectName": "csharp",
|
||||
"projectPath": "/Users/ben/.vim/bundle/vimspector/support/test/csharp/csharp.csproj",
|
||||
"packagesPath": "/Users/ben/.nuget/packages/",
|
||||
"outputPath": "/Users/ben/.vim/bundle/vimspector/support/test/csharp/obj/",
|
||||
"projectStyle": "PackageReference",
|
||||
"fallbackFolders": [
|
||||
"/usr/local/share/dotnet/sdk/NuGetFallbackFolder"
|
||||
],
|
||||
"configFilePaths": [
|
||||
"/Users/ben/.nuget/NuGet/NuGet.Config"
|
||||
],
|
||||
"originalTargetFrameworks": [
|
||||
"netcoreapp2.2"
|
||||
],
|
||||
"sources": {
|
||||
"https://api.nuget.org/v3/index.json": {}
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp2.2": {
|
||||
"projectReferences": {}
|
||||
}
|
||||
},
|
||||
"warningProperties": {
|
||||
"warnAsError": [
|
||||
"NU1605"
|
||||
]
|
||||
}
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp2.2": {
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"suppressParent": "All",
|
||||
"target": "Package",
|
||||
"version": "[2.2.0, )",
|
||||
"autoReferenced": true
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
"net461",
|
||||
"net462",
|
||||
"net47",
|
||||
"net471",
|
||||
"net472",
|
||||
"net48"
|
||||
],
|
||||
"assetTargetFallback": true,
|
||||
"warn": true,
|
||||
"runtimeIdentifierGraphPath": "/usr/local/share/dotnet/sdk/3.1.402/RuntimeIdentifierGraph.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,18 @@
|
|||
{
|
||||
"adapters": {
|
||||
"dlv-dap": {
|
||||
"variables": {
|
||||
"port": "${unusedLocalPort}"
|
||||
},
|
||||
"command": [
|
||||
"$HOME/go/bin/dlv",
|
||||
"dap",
|
||||
"--listen",
|
||||
"127.0.0.1:${port}"
|
||||
],
|
||||
"port": "${port}"
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
"run": {
|
||||
"adapter": "vscode-go",
|
||||
|
|
@ -12,6 +26,21 @@
|
|||
"env": { "GO111MODULE": "off" }
|
||||
}
|
||||
},
|
||||
"run-dap": {
|
||||
"adapter": "dlv-dap",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"env": { "GO111MODULE": "off" },
|
||||
|
||||
"mode": "debug", // debug|test
|
||||
"program": "${workspaceRoot}/hello-world.go"
|
||||
|
||||
// "args": [],
|
||||
// "buildFlags": ...
|
||||
// "stackTraceDepth": ...,
|
||||
// "showGlobalVariables": true,
|
||||
}
|
||||
},
|
||||
"run-exec": {
|
||||
// NOTE: To use this you _must_ disable optimistaion:
|
||||
// go build -o hello_world -gcflags="all=-N -l"
|
||||
|
|
|
|||
29
support/test/go/name-starts-with-vowel/.vimspector.json
Normal file
29
support/test/go/name-starts-with-vowel/.vimspector.json
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"configurations": {
|
||||
"run-cmd": {
|
||||
"adapter": "vscode-go",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/cmd/namestartswithvowel/main.go",
|
||||
"mode": "debug",
|
||||
"dlvToolPath": "$HOME/go/bin/dlv",
|
||||
"dlvLoadConfig": {
|
||||
"maxArrayValues": 1000,
|
||||
"maxStringLen": 1000
|
||||
}
|
||||
}
|
||||
},
|
||||
"test-current-file": {
|
||||
"adapter": "vscode-go",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"mode": "test",
|
||||
"program": "${fileDirname}",
|
||||
"cwd": "${fileDirname}",
|
||||
"dlvToolPath": "$GOPATH/bin/dlv",
|
||||
"env": {},
|
||||
"args": []
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
33
support/test/go/name-starts-with-vowel/README.md
Normal file
33
support/test/go/name-starts-with-vowel/README.md
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Purpose
|
||||
|
||||
This example comes with two example vimspector configs for the Go programming language.
|
||||
|
||||
1) `run-cmd` will launch the main programme under `cmd/namestartswithvowel`.
|
||||
1) `test-current-file` will run the tests in the current file in debug mode.
|
||||
|
||||
## Example use-cases
|
||||
|
||||
### run-cmd
|
||||
|
||||
* Open `cmd/namestartswithvowel/main.go`
|
||||
* Add a breakpoint somewhere within the programme
|
||||
* Start the debugger (`:call vimspector#Continue()` or your relevant keymapping)
|
||||
* Select the first launch configuration (`1: run-cmd`)
|
||||
|
||||
### test-current-file
|
||||
|
||||
* Open `internal/vowels/vowels_test.go`
|
||||
* Add a breakpoint somewhere within the test
|
||||
* Start the debugger (`:call vimspector#Continue()` or your relevant keymapping)
|
||||
* Select the second launch configuration (`2: test-current-file`)
|
||||
|
||||
## Additional Configuration
|
||||
|
||||
There are two additional configuration options specified under `run-cmd`; these parameters configure the maximum string/array size to be shown while debugging.
|
||||
|
||||
```
|
||||
"dlvLoadConfig": {
|
||||
"maxArrayValues": 1000,
|
||||
"maxStringLen": 1000
|
||||
}
|
||||
```
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"example.com/internal/vowels"
|
||||
)
|
||||
|
||||
func main() {
|
||||
names := []string{"Simon", "Bob", "Jennifer", "Amy", "Duke", "Elizabeth"}
|
||||
|
||||
for _, n := range names {
|
||||
if vowels.NameStartsWithVowel(n) {
|
||||
fmt.Printf("%s starts with a vowel!\n", n)
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf("%s does not start with a vowel!\n", n)
|
||||
}
|
||||
}
|
||||
3
support/test/go/name-starts-with-vowel/go.mod
Normal file
3
support/test/go/name-starts-with-vowel/go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
module example.com
|
||||
|
||||
go 1.16
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package vowels
|
||||
|
||||
import "strings"
|
||||
|
||||
func NameStartsWithVowel(name string) bool {
|
||||
s := strings.Split(strings.ToLower(name), "")
|
||||
|
||||
return s[0] == "a" || s[0] == "e" || s[0] == "i" || s[0] == "o" || s[0] == "u"
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package vowels
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNameStartsWithVowel(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
expectedOutput bool
|
||||
}{
|
||||
{
|
||||
input: "Simon",
|
||||
expectedOutput: false,
|
||||
},
|
||||
{
|
||||
input: "Andy",
|
||||
expectedOutput: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range testCases {
|
||||
t.Run(fmt.Sprintf("%s should product %t", tt.input, tt.expectedOutput), func(t *testing.T) {
|
||||
out := NameStartsWithVowel(tt.input)
|
||||
if out != tt.expectedOutput {
|
||||
t.Errorf("%s produced %t, when %t was expected", tt.input, out, tt.expectedOutput)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<artifactId>TestApplication</artifactId>
|
||||
<version>1</version>
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
|
|||
2
support/test/kotlin/.gitignore
vendored
Normal file
2
support/test/kotlin/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
.gradle
|
||||
build
|
||||
21
support/test/kotlin/.vimspector.json
Normal file
21
support/test/kotlin/.vimspector.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"configurations": {
|
||||
"kotlin-debug-adapter launch": {
|
||||
"adapter": "cust_kotlin-debug-adapter",
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"projectRoot": "${workspaceFolder}",
|
||||
"mainClass": "vimspector/test/ApplicationKt"
|
||||
}
|
||||
},
|
||||
"kotlin-debug-adapter attach": {
|
||||
"adapter": "cust_kotlin-debug-adapter",
|
||||
"configuration": {
|
||||
"request": "attach",
|
||||
"projectRoot": "${workspaceFolder}",
|
||||
"hostName": "${hostName}",
|
||||
"port": "${port}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
25
support/test/kotlin/build.gradle.kts
Normal file
25
support/test/kotlin/build.gradle.kts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
plugins {
|
||||
kotlin("jvm") version "1.4.0"
|
||||
|
||||
application
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use jcenter for resolving dependencies.
|
||||
// You can declare any Maven/Ivy/file repository here.
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Align versions of all Kotlin components
|
||||
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
|
||||
|
||||
// Use the Kotlin JDK 8 standard library.
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||
}
|
||||
|
||||
application {
|
||||
// Define the main class for the application.
|
||||
mainClassName = "vimspector.test.ApplicationKt"
|
||||
}
|
||||
|
||||
1
support/test/kotlin/settings.gradle.kts
Normal file
1
support/test/kotlin/settings.gradle.kts
Normal file
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = "vimspector-test"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package vimspector.test
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
println("Hello World!")
|
||||
}
|
||||
|
|
@ -24,6 +24,24 @@
|
|||
},
|
||||
"delay": "5000m"
|
||||
}
|
||||
},
|
||||
"python-remote-ssh": {
|
||||
"variables": {
|
||||
"port": "8765"
|
||||
},
|
||||
"port": "${port}",
|
||||
"host": "${host}",
|
||||
"launch": {
|
||||
"remote": {
|
||||
"host": "${host}",
|
||||
"account": "${account}",
|
||||
"runCommand": [
|
||||
"python3", "-m", "debugpy", "--listen", "0.0.0.0:${port}",
|
||||
"--wait-for-client",
|
||||
"%CMD%"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurations": {
|
||||
|
|
@ -164,6 +182,23 @@
|
|||
"stopOnEntry": false,
|
||||
"console": "integratedTerminal"
|
||||
}
|
||||
},
|
||||
"run - remote host": {
|
||||
"adapter": "python-remote-ssh",
|
||||
"remote-cmdLine": [
|
||||
"${remoteRoot}/main.py"
|
||||
],
|
||||
"remote-request": "launch",
|
||||
"configuration": {
|
||||
"request": "attach",
|
||||
"redirectOutput": true,
|
||||
"pathMappings": [
|
||||
{
|
||||
"localRoot": "${workspaceRoot}",
|
||||
"remoteRoot": "${remoteRoot}"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
set SCALAR g
|
||||
array set ARRAY {key1 value1 key2 value2}
|
||||
|
||||
set LIST [list a b c {def} {g h i j} k l m]
|
||||
|
||||
proc Wrap { body } {
|
||||
uplevel 1 $body
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ function! Test_Conditional_Line_Breakpoint()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 16, 1 )
|
||||
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 16 )
|
||||
|
||||
" Add the conditional breakpoint
|
||||
call feedkeys( "\\\<F9>argc==0\<CR>\<CR>", 'xt' )
|
||||
" Add the conditional breakpoint (note , is the mapleader)
|
||||
call feedkeys( ",\<F9>argc==0\<CR>\<CR>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
|
||||
\ 16,
|
||||
\ 'vimspectorBPCond',
|
||||
|
|
@ -360,8 +360,8 @@ function! Test_Conditional_Line_Breakpoint_Hit()
|
|||
exe 'edit' fn
|
||||
call setpos( '.', [ 0, 14, 1 ] )
|
||||
|
||||
" Add the conditional breakpoint (3 times)
|
||||
call feedkeys( "\\\<F9>\<CR>3\<CR>", 'xt' )
|
||||
" Add the conditional breakpoint (3 times) (note , is the mapleader)
|
||||
call feedkeys( ",\<F9>\<CR>3\<CR>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 14,
|
||||
|
|
|
|||
|
|
@ -293,8 +293,8 @@ function! Test_Conditional_Line_Breakpoint()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 16, 1 )
|
||||
call vimspector#test#signs#AssertSignGroupEmptyAtLine( 'VimspectorBP', 16 )
|
||||
|
||||
" Add the conditional breakpoint
|
||||
call feedkeys( "\\\<F9>argc==0\<CR>\<CR>", 'xt' )
|
||||
" Add the conditional breakpoint (, is mapleader)
|
||||
call feedkeys( ",\<F9>argc==0\<CR>\<CR>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine( 'VimspectorBP',
|
||||
\ 16,
|
||||
\ 'vimspectorBPCond',
|
||||
|
|
@ -370,8 +370,8 @@ function! Test_Conditional_Line_Breakpoint_Hit()
|
|||
exe 'edit' fn
|
||||
call setpos( '.', [ 0, 14, 1 ] )
|
||||
|
||||
" Add the conditional breakpoint (3 times)
|
||||
call feedkeys( "\\\<F9>\<CR>3\<CR>", 'xt' )
|
||||
" Add the conditional breakpoint (3 times) (, is mapleader)
|
||||
call feedkeys( ",\<F9>\<CR>3\<CR>", 'xt' )
|
||||
call vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorBP',
|
||||
\ 14,
|
||||
|
|
|
|||
|
|
@ -70,6 +70,12 @@ RUN mkdir -p /home/linuxbrew/.linuxbrew &&\
|
|||
|
||||
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
|
||||
RUN /home/linuxbrew/.linuxbrew/bin/brew cleanup && \
|
||||
rm -rf ~/.cache && \
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ function Test_Get_Configurations()
|
|||
let configs = vimspector#GetConfigurations()
|
||||
call assert_equal([
|
||||
\ 'launch - netcoredbg',
|
||||
\ 'launch - netcoredbg - with debug log',
|
||||
\ 'launch - mono',
|
||||
\ ], configs)
|
||||
|
||||
|
|
|
|||
65
tests/language_csharp.test.vim
Normal file
65
tests/language_csharp.test.vim
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
function! SetUp()
|
||||
call vimspector#test#setup#SetUpWithMappings( v:none )
|
||||
endfunction
|
||||
|
||||
function! ClearDown()
|
||||
call vimspector#test#setup#ClearDown()
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_Go_Simple()
|
||||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
endfunction
|
||||
|
||||
function! Test_CSharp_Simple()
|
||||
let fn='Program.cs'
|
||||
lcd ../support/test/csharp
|
||||
exe 'edit ' . fn
|
||||
|
||||
call vimspector#SetLineBreakpoint( fn, 31 )
|
||||
call vimspector#LaunchWithSettings( {
|
||||
\ 'configuration': 'launch - netcoredbg'
|
||||
\ } )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 31, 7 )
|
||||
call WaitForAssert( {->
|
||||
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 31 )
|
||||
\ } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 32, 12 )
|
||||
call WaitForAssert( {->
|
||||
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 32 )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
|
||||
lcd -
|
||||
%bwipeout!
|
||||
endfunction
|
||||
|
||||
|
||||
function! Test_Run_To_Cursor()
|
||||
let fn='Program.cs'
|
||||
lcd ../support/test/csharp
|
||||
exe 'edit ' . fn
|
||||
|
||||
call vimspector#SetLineBreakpoint( fn, 31 )
|
||||
call vimspector#LaunchWithSettings( {
|
||||
\ 'configuration': 'launch - netcoredbg'
|
||||
\ } )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 31, 7 )
|
||||
call WaitForAssert( {->
|
||||
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 31 )
|
||||
\ } )
|
||||
|
||||
call cursor( 33, 1 )
|
||||
call vimspector#RunToCursor()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 33, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( fn, 33 )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
lcd -
|
||||
%bwipeout!
|
||||
endfunction
|
||||
|
||||
|
|
@ -50,3 +50,59 @@ function! vimspector#test#setup#Reset() abort
|
|||
call popup_clear()
|
||||
endfunction
|
||||
|
||||
let s:g_stack = {}
|
||||
|
||||
function! vimspector#test#setup#PushGlobal( name, value ) abort
|
||||
if !has_key( s:g_stack, a:name )
|
||||
let s:g_stack[ a:name ] = []
|
||||
endif
|
||||
|
||||
let old_value = get( g:, a:name, v:null )
|
||||
call add( s:g_stack[ a:name ], old_value )
|
||||
let g:[ a:name ] = a:value
|
||||
|
||||
return old_value
|
||||
endfunction
|
||||
|
||||
function! vimspector#test#setup#PopGlobal( name ) abort
|
||||
if !has_key( s:g_stack, a:name ) || len( s:g_stack[ a:name ] ) == 0
|
||||
return v:null
|
||||
endif
|
||||
|
||||
let old_value = s:g_stack[ a:name ][ -1 ]
|
||||
call remove( s:g_stack[ a:name ], -1 )
|
||||
|
||||
if old_value is v:null
|
||||
silent! call remove( g:, a:name )
|
||||
else
|
||||
let g:[ a:name ] = old_value
|
||||
endif
|
||||
|
||||
return old_value
|
||||
endfunction
|
||||
|
||||
let s:o_stack = {}
|
||||
|
||||
function! vimspector#test#setup#PushOption( name, value ) abort
|
||||
if !has_key( s:o_stack, a:name )
|
||||
let s:o_stack[ a:name ] = []
|
||||
endif
|
||||
|
||||
let old_value = v:null
|
||||
execute 'let old_value = &' . a:name
|
||||
call add( s:o_stack[ a:name ], old_value )
|
||||
execute 'set ' . a:name . '=' . a:value
|
||||
return old_value
|
||||
endfunction
|
||||
|
||||
function! vimspector#test#setup#PopOption( name ) abort
|
||||
if !has_key( s:o_stack, a:name ) || len( s:o_stack[ a:name ] ) == 0
|
||||
return v:null
|
||||
endif
|
||||
|
||||
let old_value = s:o_stack[ a:name ][ -1 ]
|
||||
call remove( s:o_stack[ a:name ], -1 )
|
||||
|
||||
execute 'set ' . a:name . '=' . old_value
|
||||
return old_value
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ function! ThisTestIsFlaky()
|
|||
let g:test_is_flaky = v:true
|
||||
endfunction
|
||||
|
||||
function! AssertMatchist( expected, actual ) abort
|
||||
function! AssertMatchList( expected, actual ) abort
|
||||
let ret = assert_equal( len( a:expected ), len( a:actual ) )
|
||||
let len = min( [ len( a:expected ), len( a:actual ) ] )
|
||||
let idx = 0
|
||||
|
|
|
|||
|
|
@ -82,6 +82,16 @@ func! Abort( timer_id )
|
|||
qa!
|
||||
endfunc
|
||||
|
||||
func! TestLog( msg )
|
||||
if type( a:msg ) == v:t_string
|
||||
let msg = [ a:msg ]
|
||||
else
|
||||
let msg = a:msg
|
||||
endif
|
||||
|
||||
call extend( s:messages, msg )
|
||||
endfunc
|
||||
|
||||
func RunTheTest(test)
|
||||
echo 'Executing ' . a:test
|
||||
|
||||
|
|
@ -152,8 +162,6 @@ func RunTheTest(test)
|
|||
augroup END
|
||||
|
||||
exe 'call ' . a:test
|
||||
|
||||
au! EarlyExit
|
||||
catch /^\cskipped/
|
||||
call add(s:messages, ' Skipped')
|
||||
call add(s:skipped,
|
||||
|
|
@ -193,6 +201,8 @@ func RunTheTest(test)
|
|||
call s:TestFailed()
|
||||
endtry
|
||||
|
||||
au! EarlyExit
|
||||
|
||||
call timer_stop( timer )
|
||||
|
||||
" In case 'insertmode' was set and something went wrong, make sure it is
|
||||
|
|
|
|||
|
|
@ -106,14 +106,34 @@ function! Test_Use_Mappings_HUMAN()
|
|||
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 16 )
|
||||
\ } )
|
||||
|
||||
" Run to cursor
|
||||
" Run to cursor (note , is the mapleader)
|
||||
call cursor( 9, 1 )
|
||||
call feedkeys( "\\\<F8>", 'xt' )
|
||||
call feedkeys( ",\<F8>", 'xt' )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'simple.cpp', 9, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ vimspector#test#signs#AssertPCIsAtLineInBuffer( 'simple.cpp', 9 )
|
||||
\ } )
|
||||
|
||||
" Stop
|
||||
call feedkeys( "\<F3>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( [],
|
||||
\ getbufline( g:vimspector_session_windows.variables,
|
||||
\ 1,
|
||||
\ '$' ) )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( [],
|
||||
\ getbufline( g:vimspector_session_windows.stack_trace,
|
||||
\ 1,
|
||||
\ '$' ) )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( [],
|
||||
\ getbufline( g:vimspector_session_windows.watches,
|
||||
\ 1,
|
||||
\ '$' ) )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
|
||||
|
|
|
|||
89
tests/python/Test_ExpandReferencesInDict.py
Normal file
89
tests/python/Test_ExpandReferencesInDict.py
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import sys
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from vimspector import utils
|
||||
|
||||
|
||||
class TestExpandReferencesInDict( unittest.TestCase ):
|
||||
def __init__( self, *args, **kwargs ):
|
||||
super().__init__( *args, **kwargs )
|
||||
self.maxDiff = 4096
|
||||
|
||||
def test_ExpandReferencesInDict( self ):
|
||||
mapping = {
|
||||
'one': 'one',
|
||||
'two': 'TWO',
|
||||
'bool': True,
|
||||
'words': 'these are some words'
|
||||
}
|
||||
calculus = {
|
||||
'three': lambda : 1 + 2,
|
||||
}
|
||||
CHOICES = {
|
||||
'five': '5ive!'
|
||||
}
|
||||
|
||||
def AskForInput( prompt, default_value = None ):
|
||||
if default_value is not None:
|
||||
return default_value
|
||||
|
||||
return 'typed text'
|
||||
|
||||
d = {
|
||||
'dollar': '$$',
|
||||
'not_a_var': '$${test}',
|
||||
'one': '${one}',
|
||||
'two': '${one} and ${two}',
|
||||
'three': '${three}',
|
||||
'three_with_default': '${three_with_default:${three\\}}', # uses calculus
|
||||
'four': '${four}',
|
||||
'five': '${five}',
|
||||
'list': [ '*${words}' ],
|
||||
'list1': [ 'start', '*${words}', 'end' ],
|
||||
'list2': [ '*${words}', '${three}' ],
|
||||
'list3': [ '${one}', '*${words}', 'three' ],
|
||||
'dict#json': '{ "key": "value" }',
|
||||
'bool#json': 'false',
|
||||
'one_default': '${one_default:one}',
|
||||
'two_default': '${two_default_1:one} and ${two_default_2:two}',
|
||||
'one_default2': '${one_default2:${one\\}}',
|
||||
'two_default2':
|
||||
'${two_default2_1:${one\\}} and ${two_default2_2:${two\\}}',
|
||||
'unlikely_name#json#s': 'true',
|
||||
'empty_splice': [ '*${empty:}' ],
|
||||
}
|
||||
|
||||
e = {
|
||||
'dollar': '$',
|
||||
'not_a_var': '${test}',
|
||||
'one': 'one',
|
||||
'two': 'one and TWO',
|
||||
'three': '3',
|
||||
'three_with_default': '3',
|
||||
'four': 'typed text',
|
||||
'five': '5ive!',
|
||||
'list': [ 'these', 'are', 'some', 'words' ],
|
||||
'list1': [ 'start', 'these', 'are', 'some', 'words', 'end' ],
|
||||
'list2': [ 'these', 'are', 'some', 'words', '3' ],
|
||||
'list3': [ 'one', 'these', 'are', 'some', 'words', 'three' ],
|
||||
'dict': {
|
||||
'key': 'value',
|
||||
},
|
||||
'bool': False,
|
||||
'one_default': 'one',
|
||||
'two_default': 'one and two',
|
||||
'one_default2': 'one',
|
||||
'two_default2': 'one and TWO',
|
||||
'unlikely_name#json': 'true',
|
||||
'empty_splice': [],
|
||||
}
|
||||
|
||||
with patch( 'vimspector.utils.AskForInput', side_effect = AskForInput ):
|
||||
utils.ExpandReferencesInDict( d, mapping, calculus, CHOICES )
|
||||
|
||||
self.assertDictEqual( d, e )
|
||||
|
||||
|
||||
assert unittest.main( module=__name__,
|
||||
testRunner=unittest.TextTestRunner( sys.stdout ),
|
||||
exit=False ).result.wasSuccessful()
|
||||
|
|
@ -30,7 +30,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@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 cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@threads.cpp:' . string( thread_l )
|
||||
|
|
@ -56,7 +56,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -70,7 +70,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@threads.cpp:' . string( thread_l )
|
||||
|
|
@ -81,7 +81,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -95,7 +95,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@threads.cpp:' . string( thread_l )
|
||||
|
|
@ -106,7 +106,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -121,7 +121,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call cursor( 1, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@threads.cpp:' . string( thread_l )
|
||||
|
|
@ -132,7 +132,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -146,7 +146,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
" So we break out of the loop
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@threads.cpp:' . string( notify_l )
|
||||
|
|
@ -157,7 +157,7 @@ function! Test_Multiple_Threads_Continue()
|
|||
\ )
|
||||
\ } )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -192,7 +192,7 @@ function! Test_Multiple_Threads_Step()
|
|||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread [0-9]\+: .* (paused)',
|
||||
\ ' .*: .*@threads.cpp:' . string( thread_l )
|
||||
|
|
@ -205,7 +205,7 @@ function! Test_Multiple_Threads_Step()
|
|||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -218,7 +218,7 @@ function! Test_Multiple_Threads_Step()
|
|||
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ ],
|
||||
|
|
@ -230,7 +230,7 @@ function! Test_Multiple_Threads_Step()
|
|||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ 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 WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
|
|
@ -257,7 +257,7 @@ function! Test_Multiple_Threads_Step()
|
|||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ 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 WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
|
|
@ -287,7 +287,7 @@ function! Test_Multiple_Threads_Step()
|
|||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ 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 WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
|
|
@ -319,7 +319,7 @@ function! Test_Multiple_Threads_Step()
|
|||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, thread_n, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
|
|
@ -338,7 +338,7 @@ function! Test_Multiple_Threads_Step()
|
|||
" So we break out of the loop
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, notify_l, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
\ '+ Thread [0-9]\+: .* (paused)',
|
||||
|
|
@ -352,6 +352,209 @@ function! Test_Multiple_Threads_Step()
|
|||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#ClearBreakpoints()
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_UpDownStack()
|
||||
let fn='../support/test/python/simple_python/main.py'
|
||||
exe 'edit ' . fn
|
||||
call setpos( '.', [ 0, 6, 1 ] )
|
||||
|
||||
call vimspector#SetLineBreakpoint( fn, 15 )
|
||||
call vimspector#LaunchWithSettings( { 'configuration': 'run' } )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread 1: MainThread (paused)',
|
||||
\ ' 2: DoSomething@main.py:15',
|
||||
\ ' 3: __init__@main.py:8',
|
||||
\ ' 4: Main@main.py:23',
|
||||
\ ' 5: <module>@main.py:29',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call win_gotoid( g:vimspector_session_windows.stack_trace )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 1,
|
||||
\ 'vimspectorCurrentThread',
|
||||
\ 200 ) } )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 2,
|
||||
\ 'vimspectorCurrentFrame',
|
||||
\ 200 ) } )
|
||||
wincmd w
|
||||
|
||||
call vimspector#DownFrame()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread 1: MainThread (paused)',
|
||||
\ ' 2: DoSomething@main.py:15',
|
||||
\ ' 3: __init__@main.py:8',
|
||||
\ ' 4: Main@main.py:23',
|
||||
\ ' 5: <module>@main.py:29',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call win_gotoid( g:vimspector_session_windows.stack_trace )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 1,
|
||||
\ 'vimspectorCurrentThread',
|
||||
\ 200 ) } )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 2,
|
||||
\ 'vimspectorCurrentFrame',
|
||||
\ 200 ) } )
|
||||
wincmd w
|
||||
|
||||
|
||||
call vimspector#UpFrame()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread 1: MainThread (paused)',
|
||||
\ ' 2: DoSomething@main.py:15',
|
||||
\ ' 3: __init__@main.py:8',
|
||||
\ ' 4: Main@main.py:23',
|
||||
\ ' 5: <module>@main.py:29',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call win_gotoid( g:vimspector_session_windows.stack_trace )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 1,
|
||||
\ 'vimspectorCurrentThread',
|
||||
\ 200 ) } )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 3,
|
||||
\ 'vimspectorCurrentFrame',
|
||||
\ 200 ) } )
|
||||
wincmd w
|
||||
|
||||
|
||||
call feedkeys( "\<Plug>VimspectorUpFrame", 'x' )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 23, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread 1: MainThread (paused)',
|
||||
\ ' 2: DoSomething@main.py:15',
|
||||
\ ' 3: __init__@main.py:8',
|
||||
\ ' 4: Main@main.py:23',
|
||||
\ ' 5: <module>@main.py:29',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call win_gotoid( g:vimspector_session_windows.stack_trace )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 1,
|
||||
\ 'vimspectorCurrentThread',
|
||||
\ 200 ) } )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 4,
|
||||
\ 'vimspectorCurrentFrame',
|
||||
\ 200 ) } )
|
||||
wincmd w
|
||||
|
||||
|
||||
call feedkeys( "\<Plug>VimspectorDownFrame", 'x' )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 8, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread 1: MainThread (paused)',
|
||||
\ ' 2: DoSomething@main.py:15',
|
||||
\ ' 3: __init__@main.py:8',
|
||||
\ ' 4: Main@main.py:23',
|
||||
\ ' 5: <module>@main.py:29',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call win_gotoid( g:vimspector_session_windows.stack_trace )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 1,
|
||||
\ 'vimspectorCurrentThread',
|
||||
\ 200 ) } )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 3,
|
||||
\ 'vimspectorCurrentFrame',
|
||||
\ 200 ) } )
|
||||
wincmd w
|
||||
|
||||
|
||||
call vimspector#DownFrame()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 15, 1 )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Thread 1: MainThread (paused)',
|
||||
\ ' 2: DoSomething@main.py:15',
|
||||
\ ' 3: __init__@main.py:8',
|
||||
\ ' 4: Main@main.py:23',
|
||||
\ ' 5: <module>@main.py:29',
|
||||
\ ],
|
||||
\ GetBufLine( winbufnr( g:vimspector_session_windows.stack_trace ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call win_gotoid( g:vimspector_session_windows.stack_trace )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 1,
|
||||
\ 'vimspectorCurrentThread',
|
||||
\ 200 ) } )
|
||||
call WaitForAssert( { ->
|
||||
\ vimspector#test#signs#AssertSignGroupSingletonAtLine(
|
||||
\ 'VimspectorStackTrace',
|
||||
\ 2,
|
||||
\ 'vimspectorCurrentFrame',
|
||||
\ 200 ) } )
|
||||
wincmd w
|
||||
|
||||
|
||||
|
||||
call vimspector#ClearBreakpoints()
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
|
|
|
|||
8
tests/testdata/cpp/simple/.vimspector.json
vendored
8
tests/testdata/cpp/simple/.vimspector.json
vendored
|
|
@ -12,7 +12,7 @@
|
|||
"externalConsole": false,
|
||||
"stopAtEntry": true,
|
||||
"stopOnEntry": true,
|
||||
"MImode": "${VIMSPECTOR_MIMODE}"
|
||||
"MIMode": "${VIMSPECTOR_MIMODE}"
|
||||
},
|
||||
"breakpoints": {
|
||||
"exception": {
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
"externalConsole": false,
|
||||
"stopAtEntry": false,
|
||||
"stopOnEntry": false,
|
||||
"MImode": "${VIMSPECTOR_MIMODE}"
|
||||
"MIMode": "${VIMSPECTOR_MIMODE}"
|
||||
},
|
||||
"breakpoints": {
|
||||
"exception": {
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
"externalConsole": false,
|
||||
"stopAtEntry": false,
|
||||
"stopOnEntry": false,
|
||||
"MImode": "${VIMSPECTOR_MIMODE}"
|
||||
"MIMode": "${VIMSPECTOR_MIMODE}"
|
||||
},
|
||||
"breakpoints": {
|
||||
"exception": {
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
"configuration": {
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/${fileBasenameNoExtension}",
|
||||
"MImode": "${VIMSPECTOR_MIMODE}",
|
||||
"MIMode": "${VIMSPECTOR_MIMODE}",
|
||||
"externalConsole": false,
|
||||
"args": [
|
||||
"CALCULATED_LIST", "${CALCULATED_LIST}",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
let s:fn='../support/test/python/simple_python/main.py'
|
||||
|
||||
function! SetUp()
|
||||
let g:vimspector_ui_mode = get( s:, 'vimspector_ui_mode', 'horizontal' )
|
||||
call vimspector#test#setup#SetUpWithMappings( 'HUMAN' )
|
||||
endfunction
|
||||
|
||||
|
|
@ -16,12 +17,17 @@ function! s:StartDebugging()
|
|||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 23, 1 )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_StandardLayout()
|
||||
call vimspector#test#setup#PushOption( 'columns', 200 )
|
||||
endfunction
|
||||
|
||||
function! Test_StandardLayout()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
|
|
@ -43,6 +49,247 @@ function! Test_StandardLayout()
|
|||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_StandardLayout()
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_NarrowLayout()
|
||||
call vimspector#test#setup#PushOption( 'columns', 100 )
|
||||
let s:vimspector_ui_mode = 'vertical'
|
||||
endfunction
|
||||
|
||||
function! Test_NarrowLayout()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'vertical', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'col', [
|
||||
\ [ 'row', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
|
||||
\ ] ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.code ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.terminal ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.output ],
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_NarrowLayout()
|
||||
unlet s:vimspector_ui_mode
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_AutoLayoutTerminalVert()
|
||||
let s:vimspector_ui_mode = 'auto'
|
||||
call vimspector#test#setup#PushOption( 'columns', 250 )
|
||||
call vimspector#test#setup#PushOption( 'lines', 30 )
|
||||
endfunction
|
||||
|
||||
function! Test_AutoLayoutTerminalVert()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
|
||||
\ ] ],
|
||||
\ [ 'col', [
|
||||
\ [ 'row', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.code ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.terminal ],
|
||||
\ ] ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.output ],
|
||||
\ ] ]
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_AutoLayoutTerminalVert()
|
||||
unlet s:vimspector_ui_mode
|
||||
call vimspector#test#setup#PopOption( 'lines' )
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_AutoLayoutTerminalHorizVert()
|
||||
let s:vimspector_ui_mode = 'auto'
|
||||
" Wide enough to be horizontal layout, but not wide enough to fully fit the
|
||||
" terminal, with enough rows to fit the max terminal below
|
||||
call vimspector#test#setup#PushOption( 'columns',
|
||||
\ 50 + 82 + 3 + 2 + 12 )
|
||||
call vimspector#test#setup#PushOption( 'lines', 50 )
|
||||
endfunction
|
||||
|
||||
function! Test_AutoLayoutTerminalHorizVert()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
|
||||
\ ] ],
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.code ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.terminal ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.output ],
|
||||
\ ] ]
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_AutoLayoutTerminalHorizVert()
|
||||
unlet s:vimspector_ui_mode
|
||||
call vimspector#test#setup#PopOption( 'lines' )
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_AutoLayoutTerminalHorizVertButNotEnoughLines()
|
||||
let s:vimspector_ui_mode = 'auto'
|
||||
" Wide enough to be horizontal layout, but not wide enough to fully fit the
|
||||
" terminal, with enough rows to fit the max terminal below, but there are not
|
||||
" enough lines to do this
|
||||
call vimspector#test#setup#PushOption( 'columns',
|
||||
\ 50 + 82 + 3 + 2 + 12 )
|
||||
call vimspector#test#setup#PushOption( 'lines', 20 )
|
||||
endfunction
|
||||
|
||||
function! Test_AutoLayoutTerminalHorizVertButNotEnoughLines()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'horizontal', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'row', [
|
||||
\ [ 'col', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
|
||||
\ ] ],
|
||||
\ [ 'col', [
|
||||
\ [ 'row', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.code ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.terminal ],
|
||||
\ ] ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.output ],
|
||||
\ ] ],
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_AutoLayoutTerminalHorizVertButNotEnoughLines()
|
||||
unlet s:vimspector_ui_mode
|
||||
call vimspector#test#setup#PopOption( 'lines' )
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_AutoLayoutTerminalHoriz()
|
||||
let s:vimspector_ui_mode = 'vertical'
|
||||
" Vertical layout, but we split the terminal horizonally
|
||||
call vimspector#test#setup#PushOption( 'columns', 200 )
|
||||
call vimspector#test#setup#PushOption( 'lines', 50 )
|
||||
endfunction
|
||||
|
||||
function! Test_AutoLayoutTerminalHoriz()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'vertical', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'col', [
|
||||
\ [ 'row', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
|
||||
\ ] ],
|
||||
\ [ 'row', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.code ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.terminal ],
|
||||
\ ] ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.output ],
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_AutoLayoutTerminalHoriz()
|
||||
unlet s:vimspector_ui_mode
|
||||
call vimspector#test#setup#PopOption( 'lines' )
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
function! SetUp_Test_AutoLayoutTerminalVertVert()
|
||||
let s:vimspector_ui_mode = 'auto'
|
||||
" Not wide enough to go horizontal, but wide enough to put the terminal and
|
||||
" code vertically split
|
||||
call vimspector#test#setup#PushOption( 'columns', 80 )
|
||||
call vimspector#test#setup#PushOption( 'lines', 50 )
|
||||
endfunction
|
||||
|
||||
function! Test_AutoLayoutTerminalVertVert()
|
||||
call s:StartDebugging()
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( s:fn, 25, 1 )
|
||||
|
||||
call assert_equal( 'vertical', g:vimspector_session_windows.mode )
|
||||
call assert_equal(
|
||||
\ [ 'col', [
|
||||
\ [ 'row', [
|
||||
\ [ 'leaf', g:vimspector_session_windows.variables ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.watches ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.stack_trace ],
|
||||
\ ] ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.code ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.terminal ],
|
||||
\ [ 'leaf', g:vimspector_session_windows.output ],
|
||||
\ ] ],
|
||||
\ winlayout( g:vimspector_session_windows.tabpage ) )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! TearDown_Test_AutoLayoutTerminalVertVert()
|
||||
unlet s:vimspector_ui_mode
|
||||
call vimspector#test#setup#PopOption( 'lines' )
|
||||
call vimspector#test#setup#PopOption( 'columns' )
|
||||
endfunction
|
||||
|
||||
|
||||
function! Test_CloseVariables()
|
||||
call s:StartDebugging()
|
||||
|
||||
|
|
@ -409,3 +656,56 @@ function! Test_CustomWinBar()
|
|||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_VimspectorJumpedToFrame()
|
||||
let s:ended = 0
|
||||
let s:au_visited_buffers = {}
|
||||
|
||||
augroup TestVimspectorJumpedToFrame
|
||||
au!
|
||||
au User VimspectorJumpedToFrame
|
||||
\ let s:au_visited_buffers[ bufname() ] = get( s:au_visited_buffers,
|
||||
\ bufname(),
|
||||
\ 0 ) + 1
|
||||
au User VimspectorDebugEnded
|
||||
\ let s:ended = 1
|
||||
augroup END
|
||||
|
||||
lcd ../support/test/python/multiple_files
|
||||
edit moo.py
|
||||
|
||||
let moo = 'moo.py'
|
||||
let cow = getcwd() . '/cow.py'
|
||||
|
||||
call vimspector#SetLineBreakpoint( 'moo.py', 13 )
|
||||
call vimspector#Launch()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'moo.py', 1, 1 )
|
||||
call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'moo.py', 1 )
|
||||
let expected = {}
|
||||
let expected[ moo ] = 1
|
||||
call assert_equal( expected, s:au_visited_buffers )
|
||||
|
||||
call vimspector#Continue()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'moo.py', 13, 1 )
|
||||
call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'moo.py', 13 )
|
||||
let expected[ moo ] += 1
|
||||
call assert_equal( expected, s:au_visited_buffers )
|
||||
|
||||
call vimspector#SetLineBreakpoint( 'cow.py', 2 )
|
||||
call vimspector#Continue()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( 'cow.py', 2, 1 )
|
||||
call vimspector#test#signs#AssertPCIsAtLineInBuffer( 'cow.py', 2 )
|
||||
let expected[ cow ] = 1
|
||||
call assert_equal( expected, s:au_visited_buffers )
|
||||
|
||||
VimspectorReset
|
||||
call WaitForAssert( { -> assert_equal( s:ended, 1 ) } )
|
||||
|
||||
au! TestVimspectorJumpedToFrame
|
||||
unlet! s:au_visited_buffers
|
||||
unlet! s:ended
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
lcd -
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
|
|
|||
28
tests/utils.test.vim
Normal file
28
tests/utils.test.vim
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
function! SetUp()
|
||||
call vimspector#test#setup#SetUpWithMappings( v:none )
|
||||
py3 import vim
|
||||
py3 __import__( 'vimspector' )
|
||||
endfunction
|
||||
|
||||
function! ClearDown()
|
||||
call vimspector#test#setup#ClearDown()
|
||||
endfunction
|
||||
|
||||
function! s:RunPyFile( file_name )
|
||||
redir => py_output
|
||||
try
|
||||
let v:errmsg = ''
|
||||
silent! execute 'py3file python/' .. a:file_name
|
||||
finally
|
||||
redir END
|
||||
call TestLog( [ a:file_name .. ' output:' ] + split( py_output, '\n' ) )
|
||||
endtry
|
||||
|
||||
if v:errmsg !=# ''
|
||||
call assert_report( v:errmsg )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
function! Test_ExpandReferencesInDict()
|
||||
call s:RunPyFile( 'Test_ExpandReferencesInDict.py' )
|
||||
endfunction
|
||||
|
|
@ -194,6 +194,7 @@ function! Test_ExpandVariables()
|
|||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' *+ t (Test): {...}',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -211,7 +212,7 @@ function! Test_ExpandVariables()
|
|||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
|
|
@ -219,6 +220,7 @@ function! Test_ExpandVariables()
|
|||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -229,7 +231,7 @@ function! Test_ExpandVariables()
|
|||
" Step - stays expanded
|
||||
call vimspector#StepOver()
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' - t (Test): {...}',
|
||||
|
|
@ -237,6 +239,7 @@ function! Test_ExpandVariables()
|
|||
\ ' - c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff (float): 0',
|
||||
\ ' + another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -253,6 +256,7 @@ function! Test_ExpandVariables()
|
|||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' + t (Test): {...}',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -267,6 +271,7 @@ function! Test_ExpandVariables()
|
|||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' + t (Test): {...}',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -278,7 +283,7 @@ function! Test_ExpandVariables()
|
|||
call setpos( '.', [ 0, 2, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' - t (Test): {...}',
|
||||
|
|
@ -286,6 +291,7 @@ function! Test_ExpandVariables()
|
|||
\ ' \*- c (char): 99 ''c''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -302,6 +308,7 @@ function! Test_ExpandVariables()
|
|||
\ assert_equal(
|
||||
\ [
|
||||
\ '+ Scope: Locals',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -316,6 +323,7 @@ function! Test_ExpandVariables()
|
|||
\ assert_equal(
|
||||
\ [
|
||||
\ '+ Scope: Locals',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -331,6 +339,7 @@ function! Test_ExpandVariables()
|
|||
\ assert_equal(
|
||||
\ [
|
||||
\ '+ Scope: Locals',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
|
|
@ -378,7 +387,7 @@ function! Test_ExpandWatch()
|
|||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
|
|
@ -397,7 +406,7 @@ function! Test_ExpandWatch()
|
|||
" Step - stays expanded
|
||||
call vimspector#StepOver()
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
|
|
@ -449,7 +458,7 @@ function! Test_ExpandWatch()
|
|||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
|
|
@ -513,6 +522,49 @@ function Test_EvaluateConsole()
|
|||
endfunction
|
||||
|
||||
|
||||
function Test_EvaluateInput()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
" Make sure the Test t is initialised
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 27, 1 )
|
||||
|
||||
VimspectorEval -exec print (int) printf("hello")
|
||||
|
||||
call assert_equal( bufnr( 'vimspector.Console' ),
|
||||
\ winbufnr( g:vimspector_session_windows.output ) )
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ ''
|
||||
\ ],
|
||||
\ getbufline( bufnr( 'vimspector.Console' ), '$', '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
let len = getbufinfo( 'vimspector.Console' )[ 0 ].linecount
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Evaluating: -exec print (int) printf("hello")',
|
||||
\ ],
|
||||
\ getbufline( bufnr( 'vimspector.Console' ), len-2, len-2 )
|
||||
\ )
|
||||
\ } )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer(
|
||||
\ 'vimspector.Console', len, v:null )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
|
||||
function Test_EvaluatePromptConsole()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
|
|
@ -564,7 +616,7 @@ function! Test_EvaluateFailure()
|
|||
" Add a wtch
|
||||
call vimspector#AddWatch( 'test' )
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchist(
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: test',
|
||||
|
|
@ -591,3 +643,493 @@ function! Test_EvaluateFailure()
|
|||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_VariableEval()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
" leader is ,
|
||||
xmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
|
||||
nmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
|
||||
|
||||
"evaluate the prev line
|
||||
call setpos( '.', [ 0, 24, 8 ] )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 24, 8 )
|
||||
call feedkeys( ',d', 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_notequal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 0',
|
||||
\ ' + another_test: ',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
"Close
|
||||
call feedkeys( "\<Esc>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
" test selection
|
||||
call setpos( '.', [ 0, 24, 8 ] )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 24, 8 )
|
||||
|
||||
call feedkeys( 'viw,d', 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_notequal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 0',
|
||||
\ ' + another_test: ',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
"Close
|
||||
call feedkeys( "\<Esc>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
" Get back to normal mode
|
||||
call feedkeys( "\<Esc>", 'xt' )
|
||||
|
||||
" Evaluation error
|
||||
call setpos( '.', [ 0, 25, 1 ] )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 25, 1 )
|
||||
call feedkeys( ',d', 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_notequal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Evaluation error',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
"Close
|
||||
call feedkeys( "\<Esc>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_VariableEvalExpand()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
" leader is ,
|
||||
xmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
|
||||
nmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
|
||||
|
||||
"evaluate the prev line
|
||||
call setpos( '.', [ 0, 24, 8 ] )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 24, 8 )
|
||||
call feedkeys( ',d', 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_notequal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 0',
|
||||
\ ' + another_test: ',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Expand
|
||||
call feedkeys( "jjjj\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 0',
|
||||
\ ' - another_test: ',
|
||||
\ ' - choo: 0 ''\\0\{1,3}''',
|
||||
\ ' + ints: '
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
"Collapse
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 0',
|
||||
\ ' + another_test: ',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
"Close
|
||||
call feedkeys( "\<Esc>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_SetVariableValue_Local()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
" Make sure the Test t is initialised
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' *+ t (Test): {...}',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call assert_equal( 'cpp',
|
||||
\ getbufvar(
|
||||
\ winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ '&syntax' ) )
|
||||
|
||||
" Expand
|
||||
call win_gotoid( g:vimspector_session_windows.variables )
|
||||
call setpos( '.', [ 0, 2, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
\ ' \*- i (int): 0',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
|
||||
" We can't just fire the keys to the inpit prompt because we use inputsave()
|
||||
" and inputrestore(), so mock that out and fire away.
|
||||
py3 <<EOF
|
||||
from unittest import mock
|
||||
with mock.patch( 'vimspector.utils.InputSave' ):
|
||||
vim.eval( 'feedkeys( "\<C-CR>\<C-u>100\<CR>", "xt" )' )
|
||||
EOF
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
\ ' \*- i (int): 100',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Now set it via the more comforable scripting interface
|
||||
call vimspector#SetVariableValue( '1234' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
\ ' \*- i (int): 1234',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Something fails
|
||||
call vimspector#SetVariableValue( 'this is invalid' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '- Scope: Locals',
|
||||
\ ' \*- t (Test): {...}',
|
||||
\ ' \*- i (int): 1234',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ '+ Scope: Registers',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.variables ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_SetVariableValue_Watch()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
" Make sure the Test t is initialised
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call feedkeys( "it\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_equal(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' *+ Result: {...}',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
call assert_equal( 'cpp',
|
||||
\ getbufvar(
|
||||
\ winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ '&syntax' ) )
|
||||
|
||||
" Expand
|
||||
call win_gotoid( g:vimspector_session_windows.watches )
|
||||
call setpos( '.', [ 0, 3, 1 ] )
|
||||
call feedkeys( "\<CR>", 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' \*- Result: {...}',
|
||||
\ ' \*- i (int): 0',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call setpos( '.', [ 0, 4, 1 ] )
|
||||
|
||||
" We can't just fire the keys to the inpit prompt because we use inputsave()
|
||||
" and inputrestore(), so mock that out and fire away.
|
||||
" Note: mapleder is ,
|
||||
py3 <<EOF
|
||||
from unittest import mock
|
||||
with mock.patch( 'vimspector.utils.InputSave' ):
|
||||
vim.eval( 'feedkeys( ",\<CR>\<C-u>100\<CR>", "xt" )' )
|
||||
EOF
|
||||
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' \*- Result: {...}',
|
||||
\ ' \*- i (int): 100',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Now set it via the more comforable scripting interface
|
||||
call vimspector#SetVariableValue( '1234' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ 'Watches: ----',
|
||||
\ 'Expression: t',
|
||||
\ ' \*- Result: {...}',
|
||||
\ ' \*- i (int): 1234',
|
||||
\ ' \*- c (char): 0 ''\\0\{1,3}''',
|
||||
\ ' \*- fffff (float): 0',
|
||||
\ ' \*+ another_test (AnotherTest):\( {...}\)\?',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.watches ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
||||
function! Test_SetVariableValue_Balloon()
|
||||
let fn = 'testdata/cpp/simple/struct.cpp'
|
||||
call s:StartDebugging( #{ fn: fn, line: 24, col: 1, launch: #{
|
||||
\ configuration: 'run-to-breakpoint'
|
||||
\ } } )
|
||||
|
||||
call vimspector#StepOver()
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 26, 1 )
|
||||
|
||||
" leader is ,
|
||||
xmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
|
||||
nmap <buffer> <Leader>d <Plug>VimspectorBalloonEval
|
||||
|
||||
"evaluate the prev line
|
||||
call setpos( '.', [ 0, 24, 8 ] )
|
||||
call vimspector#test#signs#AssertCursorIsAtLineInBuffer( fn, 24, 8 )
|
||||
call feedkeys( ',d', 'xt' )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ assert_notequal( v:none, g:vimspector_session_windows.eval )
|
||||
\ } )
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 0',
|
||||
\ ' + another_test: ',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
" Move down to the ffff line
|
||||
|
||||
call feedkeys( 'jjj', 'xt' )
|
||||
" We can't just fire the keys to the inpit prompt because we use inputsave()
|
||||
" and inputrestore(), so mock that out and fire away.
|
||||
" Note: mapleder is ,
|
||||
py3 <<EOF
|
||||
from unittest import mock
|
||||
with mock.patch( 'vimspector.utils.InputSave' ):
|
||||
vim.eval( 'feedkeys( "\<C-CR>\<C-u>100\<CR>", "xt" )' )
|
||||
EOF
|
||||
|
||||
call WaitForAssert( {->
|
||||
\ AssertMatchList(
|
||||
\ [
|
||||
\ '{...}',
|
||||
\ ' - i: 0',
|
||||
\ ' - c: 0 ''\\0\{1,3}''',
|
||||
\ ' - fffff: 100',
|
||||
\ ' + another_test: ',
|
||||
\ ],
|
||||
\ getbufline( winbufnr( g:vimspector_session_windows.eval ),
|
||||
\ 1,
|
||||
\ '$' )
|
||||
\ )
|
||||
\ } )
|
||||
|
||||
call vimspector#test#setup#Reset()
|
||||
%bwipe!
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
let g:vimspector_test_plugin_path = expand( '<sfile>:p:h:h' )
|
||||
set mouse=a
|
||||
set noequalalways
|
||||
let mapleader = ','
|
||||
let maplocalleader = "\<Space>"
|
||||
|
||||
let &rtp = &rtp . ',' . g:vimspector_test_plugin_path
|
||||
let &runtimepath = &runtimepath . ',' . g:vimspector_test_plugin_path
|
||||
|
||||
filetype plugin indent on
|
||||
syntax enable
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue