Merge pull request #209 from puremourning/install-commands
Simplify and improve gadget installation - add VimspectorInstall and VimspectorUpdate
This commit is contained in:
commit
89ffb1798c
19 changed files with 1566 additions and 1022 deletions
198
README.md
198
README.md
|
|
@ -8,15 +8,12 @@ For a tutorial and usage overview, take a look at the
|
|||
<!--ts-->
|
||||
* [Features and Usage](#features-and-usage)
|
||||
* [Supported debugging features](#supported-debugging-features)
|
||||
* [Supported languages:](#supported-languages)
|
||||
* [Languages known to work](#languages-known-to-work)
|
||||
* [Languages known not to work](#languages-known-not-to-work)
|
||||
* [Supported languages](#supported-languages)
|
||||
* [Other languages](#other-languages)
|
||||
* [Installation](#installation)
|
||||
* [Dependencies](#dependencies)
|
||||
* [Neovim differences](#neovim-differences)
|
||||
* [Windows differences](#windows-differences)
|
||||
* [Language dependencies](#language-dependencies)
|
||||
* [Clone the plugin](#clone-the-plugin)
|
||||
* [Install some gadgets](#install-some-gadgets)
|
||||
* [Manual gadget installation](#manual-gadget-installation)
|
||||
|
|
@ -66,7 +63,7 @@ For a tutorial and usage overview, take a look at the
|
|||
* [Customisation](#customisation)
|
||||
* [Changing the default signs](#changing-the-default-signs)
|
||||
* [Changing the default window sizes](#changing-the-default-window-sizes)
|
||||
* [Changing the terminal size](#changing-the-terminal-size)
|
||||
* [Changing the terminal size](#changing-the-terminal-size)
|
||||
* [Advanced UI customisation](#advanced-ui-customisation)
|
||||
* [Example](#example)
|
||||
* [FAQ](#faq)
|
||||
|
|
@ -74,7 +71,7 @@ For a tutorial and usage overview, take a look at the
|
|||
* [License](#license)
|
||||
* [Sponsorship](#sponsorship)
|
||||
|
||||
<!-- Added by: ben, at: Sat 18 Jul 2020 12:58:35 BST -->
|
||||
<!-- Added by: ben, at: Wed 22 Jul 2020 12:38:39 BST -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
|
|
@ -91,6 +88,12 @@ But for now, here's a (rather old) screenshot of Vimsepctor debugging Vim:
|
|||
|
||||

|
||||
|
||||
And a couple of brief demos:
|
||||
|
||||
[](https://asciinema.org/a/VmptWmFHTNLPfK3DVsrR2bv8S)
|
||||
|
||||
[](https://asciinema.org/a/1wZJSoCgs3AvjkhKwetJOJhDh)
|
||||
|
||||
## Supported debugging features
|
||||
|
||||
- flexible configuration syntax that can be checked in to source control
|
||||
|
|
@ -108,31 +111,32 @@ But for now, here's a (rather old) screenshot of Vimsepctor debugging Vim:
|
|||
- logging/stdout display
|
||||
- simple stable API for custom tooling (e.g. integrate with language server)
|
||||
|
||||
## Supported languages:
|
||||
For other languages, you'll need some other way to install the gadget.
|
||||
|
||||
The following languages are used frequently by the author and are known to work
|
||||
with little effort, and are supported as first-class languages.
|
||||
## Supported languages
|
||||
|
||||
- C, C++, etc. (languages supported by gdb or lldb)
|
||||
- Python 2 and Python 3
|
||||
- TCL
|
||||
- Bash scripts
|
||||
- Java
|
||||
The following table lists the languages that are "built-in" (along with their
|
||||
runtime dependencies). They are categorised by their level of support:
|
||||
|
||||
## Languages known to work
|
||||
* `Tested` : Fully supported, Vimspector regression tests cover them
|
||||
* `Supported` : Fully supported, frequently used and manually tested
|
||||
* `Experimental`: Working, but not frequently used and rarely tested
|
||||
* `Legacy`: No longer supported, please migrate your config
|
||||
|
||||
The following languages are used frequently by the author, but require some sort
|
||||
of hackery that makes it challenging to support generally. These languages are
|
||||
on a best-efforts basis:
|
||||
|
||||
- C# (c-sharp) using dotnet core
|
||||
- Go (requires separate installation of [Delve][])
|
||||
- Node.js (requires node <12 for installation)
|
||||
- Anything running in chrome (i.e. javascript).
|
||||
|
||||
## Languages known not to work
|
||||
|
||||
- C# (c-sharp) using mono debug adapter (vimspector unable to set breakpoints)
|
||||
| Language | Status | Switch (for `install_gadget.py`) | Adapter (for `:VimspectorInstall`) | Dependencies |
|
||||
|------------------|--------------|----------------------------------|------------------------------------|--------------------------------------------|
|
||||
| C, C++, etc. | Tested | `--all` or `--enable-c` | vscode-cpptools | mono-core |
|
||||
| Python | Tested | `--all` or `--enable-python` | debugpy | Python 2.7 or Python 3 |
|
||||
| Go | Tested | `--enable-go` | vscode-go | Go, [Delve][] |
|
||||
| TCL | Supported | `--all` or `--enable-tcl` | tclpro | TCL 8.5 |
|
||||
| Bourne Shell | Supported | `--all` or `--enable-bash` | vscode-bash-debug | Bash v?? |
|
||||
| Node.js | Supported | `--force-enable-node` | vscode-node-debug2 | 6 < Node < 12, Npm |
|
||||
| Javascript | Supported | `--force-enable-chrome` | debugger-for-chrome | Chrome |
|
||||
| Java | Supported | `--force-enable-java ` | vscode-java-debug | Compatible LSP plugin (see [later](#java)) |
|
||||
| C# (dotnet core) | Experimental | `--force-enable-csharp` | netcoredbg | DotNet core |
|
||||
| C# (mono) | Experimental | `--force-enable-csharp` | vscode-mono-debug | Mono |
|
||||
| Rust (CodeLLDB) | Experimental | `--force-enable-rust` | CodeLLDB | Python 3 |
|
||||
| Python.legacy | Legacy | `--force-enable-python.legacy` | vscode-python | Node 10, Python 2.7 or Python 3 |
|
||||
|
||||
## Other languages
|
||||
|
||||
|
|
@ -224,33 +228,6 @@ The following features are not implemented for Windows:
|
|||
|
||||
* Tailing the vimspector log in the Output Window.
|
||||
|
||||
## Language dependencies
|
||||
|
||||
The debug adapters themselves have certain runtime dependencies. They are
|
||||
categorised as follows:
|
||||
|
||||
* `Tested` : Fully supported, Vimspector regression tests cover them
|
||||
* `Supported` : Fully supported, frequently used and manually tested
|
||||
* `Experimental`: Working, but not frequently used and rarely tested
|
||||
* `Legacy`: No longer supported, please migrate your config
|
||||
|
||||
| Language | Status | Switch | Adapter | Dependencies |
|
||||
|------------------|--------------|--------------------------------|---------------------|--------------------------------------------|
|
||||
| C, C++, etc. | Tested | `--all` or `--enable-c` | vscode-cpptools | mono-core |
|
||||
| Python | Tested | `--all` or `--enable-python` | debugpy | Python 2.7 or Python 3 |
|
||||
| Go | Tested | `--enable-go` | vscode-go | Go, [Delve][] |
|
||||
| TCL | Supported | `--all` or `--enable-tcl` | tclpro | TCL 8.5 |
|
||||
| Bourne Shell | Supported | `--all` or `--enable-bash` | vscode-bash-debug | Bash v?? |
|
||||
| Node.js | Supported | `--force-enable-node` | vscode-node-debug2 | 6 < Node < 12, Npm |
|
||||
| Javascript | Supported | `--force-enable-chrome` | debugger-for-chrome | Chrome |
|
||||
| Java | Supported | `--force-enable-java ` | vscode-java-debug | Compatible LSP plugin (see [later](#java)) |
|
||||
| C# (dotnet core) | Experimental | `--force-enable-csharp` | netcoredbg | DotNet core |
|
||||
| C# (mono) | Experimental | `--force-enable-csharp` | vscode-mono-debug | Mono |
|
||||
| Rust (CodeLLDB) | Experimental | `--force-enable-rust` | CodeLLDB | Python 3 |
|
||||
| Python.legacy | Legacy | `--force-enable-python.legacy` | vscode-python | Node 10, Python 2.7 or Python 3 |
|
||||
|
||||
For other languages, you'll need some other way to install the gadget.
|
||||
|
||||
## Clone the plugin
|
||||
|
||||
There are many Vim plugin managers, and I'm not going to state a particular
|
||||
|
|
@ -281,10 +258,32 @@ See support/doc/example_vimrc.vim.
|
|||
|
||||
## Install some gadgets
|
||||
|
||||
There are a couple of ways of doing this, but ***using `install_gadget.py` is
|
||||
highly recommended*** where that's an option.
|
||||
Vimspector is a generic client for Debug Adapters. Debug Adapters (referred to
|
||||
as 'gadgets' or 'adapters') are what actually do the work of talking to the real
|
||||
debugers.
|
||||
|
||||
For supported languages, `install_gadget.py` will:
|
||||
In order for Vimspector to be useful, you need to have some adapters installed.
|
||||
|
||||
There are a few ways to do this:
|
||||
|
||||
* If you downloaded a tarball, gadgets for main supported langauges are already
|
||||
installed for you.
|
||||
* Using `:VimspectorInstall <adapter> <args...>` (use TAB `wildmenu` to see the
|
||||
options, also accepts any `install_gadget.py` option)
|
||||
* Alternatively, using `python3 install_gadget.py <args>` (use `--help` to see
|
||||
all options)
|
||||
* When attempting to launch a debug configuration, if the configured adapter
|
||||
can't be found, vimspector might suggest installing one.
|
||||
* Use `:VimspectorUpdate` to install the latest supported versions of the
|
||||
gadgets.
|
||||
|
||||
Here's a demo of doing somee installs and an upgrade:
|
||||
|
||||
[](https://asciinema.org/a/Hfu4ZvuyTZun8THNen9FQbTay)
|
||||
|
||||
Both `install_gadget.py` and `:VimspectorInstall` do the same set of things,
|
||||
though the default behaviours are slightly different. For supported languages,
|
||||
they will:
|
||||
|
||||
* Download the relevant debug adapter at a version that's been tested from the
|
||||
internet, either as a 'vsix' (Visusal Studio plugin), or clone from GitHub. If
|
||||
|
|
@ -298,25 +297,25 @@ For supported languages, `install_gadget.py` will:
|
|||
|
||||
To install the tested debug adapter for a language, run:
|
||||
|
||||
```
|
||||
./install_gadget.py --enable-<language>
|
||||
```
|
||||
| To install | Script | Command |
|
||||
| --- | --- | --- |
|
||||
| `<adapter>` | | `:VimspectorInstall <adapter>` |
|
||||
| `<adapter1>`, `<adapter2>`, ... | | `:VimspectorInstall <adapter1> <adapter2> ...` |
|
||||
| `<language>` | `./install_gadget.py --enable-<language> ...` | `:VimspectorInstall --enable-<language> ...` |
|
||||
| Supported adapters | `./install_gadget.py --all` | `:VimspectorInstall --all` |
|
||||
| Supported adapters, but not TCL | `./install_gadget.py --all --disable-tcl` | `:VimspectorInstall --all --disable-tcl` |
|
||||
| Supported and experimental adapters | `./install_gadget.py --all --force-all` | `:VimspectorInstall --all` |
|
||||
| Adapter for specific debug config | | Suggested by Vimspector when starting debugging |
|
||||
|
||||
Or to install all supported gagtets:
|
||||
`"VimspectorInstall` runs `install_gadget.py` in the background with some of
|
||||
the options defaulted.
|
||||
|
||||
```
|
||||
./install_gadget.py --all
|
||||
```
|
||||
By default `install_gadget.py` will overwrite your `.gadgets.json` with the set
|
||||
of adapters just installed, whereas `:VimspectorInstall` will _update_ it,
|
||||
overwriting only newly changed or installed adapters.
|
||||
|
||||
To install everything other than TCL (because TCL is sadly not as popular as it
|
||||
should be):
|
||||
|
||||
```
|
||||
./install_gadget.py --all --disable-tcl
|
||||
```
|
||||
|
||||
If you want to just add a new adapter without destroying the exisitng ones, add
|
||||
`--update-gadget-config`, as in:
|
||||
If you want to just add a new adapter using the script without destroying the
|
||||
exisitng ones, add `--update-gadget-config`, as in:
|
||||
|
||||
```bash
|
||||
$ ./install_gadget.py --enable-tcl
|
||||
|
|
@ -339,10 +338,16 @@ Then add this to your `.vimrc`:
|
|||
let g:vimspector_base_dir=expand( '$HOME/.vim/vimspector-config' )
|
||||
```
|
||||
|
||||
See `--help` for more info.
|
||||
When usnig `:VimspectorInstall`, the `g:vimspector_base_dir` setting is
|
||||
respected unless `--basedir` is manually added (not recommended).
|
||||
|
||||
See `--help` for more info on the various options.
|
||||
|
||||
## Manual gadget installation
|
||||
|
||||
If the language you want to debug is not in the supported list above, you can
|
||||
probably still make it work, but it's more effort.
|
||||
|
||||
You essentially need to get a working installation of the debug adapter, find
|
||||
out how to start it, and configure that in an `adapters` entry in either your
|
||||
`.vimspector.json` or in `.gadgets.json`.
|
||||
|
|
@ -352,7 +357,9 @@ its extension manager to install the relevant extension. You can then configure
|
|||
the adapter manually in the `adapters` section of your `.vimspector.json` or in
|
||||
a `gadgets.json`.
|
||||
|
||||
PRs are always welcome to add configuration to do this to `install_gadget.py`.
|
||||
PRs are always welcome to add supported languages (which roughly translates to
|
||||
updating `python/vimspector/gadgets.py` and testing it).
|
||||
|
||||
|
||||
### The gadget directory
|
||||
|
||||
|
|
@ -415,7 +422,8 @@ Example:
|
|||
}
|
||||
```
|
||||
|
||||
The gadget file is automatically written by `install_gadget.py`.
|
||||
The gadget file is automatically written by `install_gadget.py` (or
|
||||
`:VimspectorInstall`).
|
||||
|
||||
Vimspector will also load any fies matching:
|
||||
`</path/to/vimspector>/gadgets/<os>/.gadgets.d/*.json`. These have the same
|
||||
|
|
@ -446,6 +454,11 @@ which can be used to check everything is working. This is used by the regression
|
|||
tests in CI so should always work, and is a good way to check if the problem is
|
||||
your configuration rather than a bug.
|
||||
|
||||
## Upgrade
|
||||
|
||||
After updating the Vimspector code (either via `git pull` or whatever pacakge
|
||||
manager), run `:VimspectorUpdate` to update any already-installed gadets.
|
||||
|
||||
# About
|
||||
|
||||
## Background
|
||||
|
|
@ -865,9 +878,9 @@ an example of getting Vimspector to remotely launch and attach.
|
|||
## Python
|
||||
|
||||
* Python: [debugpy][]
|
||||
* Requires `install_gadget.py --enable-python`, ideally requires a working
|
||||
compiler and the python development headers/libs to build a C python extension
|
||||
for performance.
|
||||
* Install with `install_gadget.py --enable-python` or `:VimspectorInstall
|
||||
debugpy`, ideally requires a working compiler and the python development
|
||||
headers/libs to build a C python extension for performance.
|
||||
* Full options: https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings
|
||||
|
||||
|
||||
|
|
@ -978,7 +991,8 @@ See [my fork of TclProDebug](https://github.com/puremourning/TclProDebug) for in
|
|||
|
||||
* C# - dotnet core
|
||||
|
||||
Requires `install_gadget.py --force-enable-csharp`
|
||||
Install with `install_gadget.py --force-enable-csharp` or `:VimspectorInstall
|
||||
netcoredbg`
|
||||
|
||||
```json
|
||||
{
|
||||
|
|
@ -998,7 +1012,8 @@ Requires `install_gadget.py --force-enable-csharp`
|
|||
|
||||
* C# - mono
|
||||
|
||||
Requires `install_gadget.py --force-enable-csharp`.
|
||||
Install with `install_gadget.py --force-enable-csharp` or `:VimspectorInstall
|
||||
vscode-mono-debug`.
|
||||
|
||||
***Known not to work.***
|
||||
|
||||
|
|
@ -1029,7 +1044,7 @@ Requires `install_gadget.py --force-enable-csharp`.
|
|||
|
||||
Requires:
|
||||
|
||||
* `install_gadget.py --enable-go`
|
||||
* `install_gadget.py --enable-go` or `:VimspectorInstall vscode-go`
|
||||
* [Delve][delve-install] installed, e.g. `go get -u github.com/go-delve/delve/cmd/dlv`
|
||||
* Delve to be in your PATH, or specify the `dlvToolPath` launch option
|
||||
|
||||
|
|
@ -1057,7 +1072,8 @@ https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug
|
|||
Requires:
|
||||
|
||||
* (optional) Xdebug helper for chrome https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjbigjakmdgkmoaaaoc
|
||||
* `install_gadget.py --force-enable-php`
|
||||
* `install_gadget.py --force-enable-php` or `:VimspectorInstall
|
||||
vscode-php-debug`
|
||||
* configured php xdebug extension
|
||||
```ini
|
||||
zend_extension=xdebug.so
|
||||
|
|
@ -1161,7 +1177,8 @@ https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome
|
|||
|
||||
It allows you to debug scripts running inside chrome from within Vim.
|
||||
|
||||
* `./install_gadget.py --force-enable-chrome`
|
||||
* `./install_gadget.py --force-enable-chrome` or `:VimspectorInstall
|
||||
debugger-for-chrome`
|
||||
* Example: `support/test/chrome`
|
||||
|
||||
```json
|
||||
|
|
@ -1195,7 +1212,8 @@ use it with Vimspector.
|
|||
|
||||
* Set up [YCM for java][YcmJava].
|
||||
* Get Vimspector to download the java debug plugin:
|
||||
`install_gadget.py --force-enable-java <other options...>`
|
||||
`install_gadget.py --force-enable-java <other options...>` or
|
||||
`:VimspectorInstall java-debug-adapter`
|
||||
* Configure Vimspector for your project using the `vscode-java` adapter, e.g.:
|
||||
|
||||
```json
|
||||
|
|
@ -1266,7 +1284,7 @@ Rust is supported with any gdb/lldb-based debugger. So it works fine with
|
|||
`vscode-cpptools` and `lldb-vscode` above. However, support for rust is best in
|
||||
[`CodeLLDB`](https://github.com/vadimcn/vscode-lldb#features).
|
||||
|
||||
* `./install_gadget.py --force-enable-rust`
|
||||
* `./install_gadget.py --force-enable-rust` or `:VimspectorInstall CodeLLDB`
|
||||
* Example: `support/test/rust/vimspector_test`
|
||||
|
||||
```json
|
||||
|
|
@ -1478,6 +1496,14 @@ hi link jsonCommentError Comment
|
|||
hi link jsonComment Comment
|
||||
```
|
||||
|
||||
7. What is the difference between a `gadget` and an `adapter`? A gadget is
|
||||
somethin you install with `:VimspectorInstall` or `install_gadget.py`, an
|
||||
`adapter` is something that Vimspector talks to (actually it's the Vimsepctor
|
||||
config describing that thing). These are _usually_ one-to-one,
|
||||
but in theory a single gadget can supply multiple `adapter` configs.
|
||||
Typically this happens when a `gadget` supplies different `adapter` config
|
||||
for, say remote debugging, or debugging in a container, etc.
|
||||
|
||||
# Motivation
|
||||
|
||||
A message from the author about the motivation for this plugin:
|
||||
|
|
|
|||
|
|
@ -20,29 +20,47 @@ set cpoptions&vim
|
|||
" }}}
|
||||
|
||||
|
||||
call vimspector#internal#state#Reset()
|
||||
let s:enabled = vimspector#internal#state#Reset()
|
||||
|
||||
function! vimspector#Launch() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Start()
|
||||
endfunction
|
||||
|
||||
function! vimspector#LaunchWithSettings( settings ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Start( launch_variables = vim.eval( 'a:settings' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#Reset() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Reset()
|
||||
endfunction
|
||||
|
||||
function! vimspector#Restart() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Restart()
|
||||
endfunction
|
||||
|
||||
function! vimspector#ClearBreakpoints() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ClearBreakpoints()
|
||||
endfunction
|
||||
|
||||
function! vimspector#ToggleBreakpoint( ... ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
if a:0 == 0
|
||||
let options = {}
|
||||
else
|
||||
|
|
@ -52,6 +70,9 @@ function! vimspector#ToggleBreakpoint( ... ) abort
|
|||
endfunction
|
||||
|
||||
function! vimspector#AddFunctionBreakpoint( function, ... ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
if a:0 == 0
|
||||
let options = {}
|
||||
else
|
||||
|
|
@ -62,42 +83,72 @@ function! vimspector#AddFunctionBreakpoint( function, ... ) abort
|
|||
endfunction
|
||||
|
||||
function! vimspector#StepOver() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.StepOver()
|
||||
endfunction
|
||||
|
||||
function! vimspector#StepInto() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.StepInto()
|
||||
endfunction
|
||||
|
||||
function! vimspector#StepOut() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.StepOut()
|
||||
endfunction
|
||||
|
||||
function! vimspector#Continue() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Continue()
|
||||
endfunction
|
||||
|
||||
function! vimspector#Pause() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Pause()
|
||||
endfunction
|
||||
|
||||
function! vimspector#Stop() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.Stop()
|
||||
endfunction
|
||||
|
||||
function! vimspector#ExpandVariable() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ExpandVariable()
|
||||
endfunction
|
||||
|
||||
function! vimspector#DeleteWatch() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.DeleteWatch()
|
||||
endfunction
|
||||
|
||||
function! vimspector#GoToFrame() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ExpandFrameOrThread()
|
||||
endfunction
|
||||
|
||||
function! vimspector#AddWatch( ... ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
if a:0 == 0
|
||||
let expr = input( 'Enter watch expression: ' )
|
||||
else
|
||||
|
|
@ -112,37 +163,68 @@ function! vimspector#AddWatch( ... ) abort
|
|||
endfunction
|
||||
|
||||
function! vimspector#AddWatchPrompt( expr ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
stopinsert
|
||||
setlocal nomodified
|
||||
call vimspector#AddWatch( a:expr )
|
||||
endfunction
|
||||
|
||||
function! vimspector#Evaluate( expr ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ShowOutput( 'Console' )
|
||||
py3 _vimspector_session.EvaluateConsole( vim.eval( 'a:expr' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#EvaluateConsole( expr ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
stopinsert
|
||||
setlocal nomodified
|
||||
py3 _vimspector_session.EvaluateConsole( vim.eval( 'a:expr' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#ShowOutput( category ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ShowOutput( vim.eval( 'a:category' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#ShowOutputInWindow( win_id, category ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 __import__( 'vimspector',
|
||||
\ fromlist = [ 'output' ] ).output.ShowOutputInWindow(
|
||||
\ int( vim.eval( 'a:win_id' ) ),
|
||||
\ vim.eval( 'a:category' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#ListBreakpoints() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
py3 _vimspector_session.ListBreakpoints()
|
||||
endfunction
|
||||
|
||||
function! vimspector#CompleteOutput( ArgLead, CmdLine, CursorPos ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
let buffers = py3eval( '_vimspector_session.GetOutputBuffers() '
|
||||
\ . ' if _vimspector_session else []' )
|
||||
return join( buffers, "\n" )
|
||||
endfunction
|
||||
|
||||
function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
return join( py3eval( '_vimspector_session.GetCompletionsSync( '
|
||||
\.' vim.eval( "a:CmdLine" ),'
|
||||
\.' int( vim.eval( "a:CursorPos" ) ) )'
|
||||
|
|
@ -150,6 +232,52 @@ function! vimspector#CompleteExpr( ArgLead, CmdLine, CursorPos ) abort
|
|||
\ "\n" )
|
||||
endfunction
|
||||
|
||||
function! vimspector#Install( ... ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
if a:0 < 1
|
||||
return
|
||||
endif
|
||||
let prefix = vimspector#internal#state#GetAPIPrefix()
|
||||
py3 __import__( 'vimspector',
|
||||
\ fromlist = [ 'installer' ] ).installer.RunInstaller(
|
||||
\ vim.eval( 'prefix' ),
|
||||
\ *vim.eval( 'a:000' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#CompleteInstall( ArgLead, CmdLine, CursorPos ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
return py3eval( '"\n".join('
|
||||
\ . '__import__( "vimspector", fromlist = [ "gadgets" ] )'
|
||||
\ . '.gadgets.GADGETS.keys() '
|
||||
\ . ')' )
|
||||
endfunction
|
||||
|
||||
function! vimspector#Update( ... ) abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
|
||||
let prefix = vimspector#internal#state#GetAPIPrefix()
|
||||
py3 __import__( 'vimspector',
|
||||
\ fromlist = [ 'installer' ] ).installer.RunUpdate(
|
||||
\ vim.eval( 'prefix' ),
|
||||
\ *vim.eval( 'a:000' ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#AbortInstall() abort
|
||||
if !s:enabled
|
||||
return
|
||||
endif
|
||||
|
||||
let prefix = vimspector#internal#state#GetAPIPrefix()
|
||||
py3 __import__( 'vimspector', fromlist = [ 'installer' ] ).installer.Abort()
|
||||
endfunction
|
||||
|
||||
|
||||
" Boilerplate {{{
|
||||
let &cpoptions=s:save_cpo
|
||||
unlet s:save_cpo
|
||||
|
|
|
|||
|
|
@ -146,6 +146,13 @@ function! vimspector#internal#job#Reset() abort
|
|||
call vimspector#internal#job#StopDebugSession()
|
||||
endfunction
|
||||
|
||||
function! s:_OnCommandExit( category, ch, code ) abort
|
||||
py3 __import__( "vimspector",
|
||||
\ fromlist = [ "utils" ] ).utils.OnCommandWithLogComplete(
|
||||
\ vim.eval( 'a:category' ),
|
||||
\ int( vim.eval( 'a:code' ) ) )
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort
|
||||
if ! exists( 's:commands' )
|
||||
let s:commands = {}
|
||||
|
|
@ -157,14 +164,19 @@ function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort
|
|||
|
||||
let l:index = len( s:commands[ a:category ] )
|
||||
|
||||
let buf = '_vimspector_log_' . a:category
|
||||
|
||||
call add( s:commands[ a:category ], job_start(
|
||||
\ a:cmd,
|
||||
\ {
|
||||
\ 'out_io': 'buffer',
|
||||
\ 'in_io': 'null',
|
||||
\ 'err_io': 'buffer',
|
||||
\ 'out_name': '_vimspector_log_' . a:category . '_out',
|
||||
\ 'err_name': '_vimspector_log_' . a:category . '_err',
|
||||
\ 'out_msg': 0,
|
||||
\ 'err_msg': 0,
|
||||
\ 'out_name': buf,
|
||||
\ 'err_name': buf,
|
||||
\ 'exit_cb': funcref( 's:_OnCommandExit', [ a:category ] ),
|
||||
\ 'out_modifiable': 0,
|
||||
\ 'err_modifiable': 0,
|
||||
\ 'stoponexit': 'kill'
|
||||
|
|
@ -176,12 +188,7 @@ function! vimspector#internal#job#StartCommandWithLog( cmd, category ) abort
|
|||
return v:none
|
||||
endif
|
||||
|
||||
let l:stdout = ch_getbufnr(
|
||||
\ job_getchannel( s:commands[ a:category ][ index ] ), 'out' )
|
||||
let l:stderr = ch_getbufnr(
|
||||
\ job_getchannel( s:commands[ a:category ][ index ] ), 'err' )
|
||||
|
||||
return [ l:stdout, l:stderr ]
|
||||
return bufnr( buf )
|
||||
endfunction
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -116,58 +116,65 @@ function! s:_OnCommandEvent( category, id, data, event ) abort
|
|||
return
|
||||
endif
|
||||
|
||||
if a:data == ['']
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key( s:commands, a:category )
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key( s:commands[ a:category ], a:id )
|
||||
return
|
||||
endif
|
||||
|
||||
if a:event ==# 'stdout'
|
||||
let buffer = s:commands[ a:category ][ a:id ].stdout
|
||||
elseif a:event ==# 'stderr'
|
||||
let buffer = s:commands[ a:category ][ a:id ].stderr
|
||||
endif
|
||||
|
||||
try
|
||||
call bufload( buffer )
|
||||
catch /E325/
|
||||
" Ignore E325/ATTENTION
|
||||
endtry
|
||||
|
||||
|
||||
let numlines = py3eval( "len( vim.buffers[ int( vim.eval( 'buffer' ) ) ] )" )
|
||||
let last_line = getbufline( buffer, '$' )[ 0 ]
|
||||
|
||||
call s:MakeBufferWritable( buffer )
|
||||
try
|
||||
if numlines == 1 && last_line ==# ''
|
||||
call setbufline( buffer, 1, a:data[ 0 ] )
|
||||
else
|
||||
call setbufline( buffer, '$', last_line . a:data[ 0 ] )
|
||||
if a:event ==# 'stdout' || a:event ==# 'stderr'
|
||||
if a:data == ['']
|
||||
return
|
||||
endif
|
||||
|
||||
call appendbufline( buffer, '$', a:data[ 1: ] )
|
||||
finally
|
||||
call s:MakeBufferReadOnly( buffer )
|
||||
call setbufvar( buffer, '&modified', 0 )
|
||||
endtry
|
||||
if !has_key( s:commands, a:category )
|
||||
return
|
||||
endif
|
||||
|
||||
if !has_key( s:commands[ a:category ], a:id )
|
||||
return
|
||||
endif
|
||||
|
||||
if a:event ==# 'stdout'
|
||||
let buffer = s:commands[ a:category ][ a:id ].stdout
|
||||
elseif a:event ==# 'stderr'
|
||||
let buffer = s:commands[ a:category ][ a:id ].stderr
|
||||
endif
|
||||
|
||||
" if the buffer is visible, scroll it
|
||||
let w = bufwinnr( buffer )
|
||||
if w > 0
|
||||
let cw = winnr()
|
||||
try
|
||||
execute w . 'wincmd w'
|
||||
normal! Gz.
|
||||
finally
|
||||
execute cw . 'wincmd w'
|
||||
call bufload( buffer )
|
||||
catch /E325/
|
||||
" Ignore E325/ATTENTION
|
||||
endtry
|
||||
|
||||
|
||||
let numlines = py3eval( "len( vim.buffers[ int( vim.eval( 'buffer' ) ) ] )" )
|
||||
let last_line = getbufline( buffer, '$' )[ 0 ]
|
||||
|
||||
call s:MakeBufferWritable( buffer )
|
||||
try
|
||||
if numlines == 1 && last_line ==# ''
|
||||
call setbufline( buffer, 1, a:data[ 0 ] )
|
||||
else
|
||||
call setbufline( buffer, '$', last_line . a:data[ 0 ] )
|
||||
endif
|
||||
|
||||
call appendbufline( buffer, '$', a:data[ 1: ] )
|
||||
finally
|
||||
call s:MakeBufferReadOnly( buffer )
|
||||
call setbufvar( buffer, '&modified', 0 )
|
||||
endtry
|
||||
|
||||
" if the buffer is visible, scroll it
|
||||
let w = bufwinnr( buffer )
|
||||
if w > 0
|
||||
let cw = winnr()
|
||||
try
|
||||
execute w . 'wincmd w'
|
||||
normal! Gz-
|
||||
finally
|
||||
execute cw . 'wincmd w'
|
||||
endtry
|
||||
endif
|
||||
elseif a:event ==# 'exit'
|
||||
py3 __import__( "vimspector",
|
||||
\ fromlist = [ "utils" ] ).utils.OnCommandWithLogComplete(
|
||||
\ vim.eval( 'a:category' ),
|
||||
\ int( vim.eval( 'a:data' ) ) )
|
||||
endif
|
||||
endfunction
|
||||
|
||||
|
|
@ -198,29 +205,29 @@ function! vimspector#internal#neojob#StartCommandWithLog( cmd, category ) abort
|
|||
let s:commands[ a:category ] = {}
|
||||
endif
|
||||
|
||||
let stdout_buf = bufnr( '_vimspector_log_' . a:category . '_out', v:true )
|
||||
let stderr_buf = bufnr( '_vimspector_log_' . a:category . '_err', v:true )
|
||||
let buf = bufnr( '_vimspector_log_' . a:category, v:true )
|
||||
|
||||
" FIXME: This largely duplicates the same stuff in the python layer, but we
|
||||
" don't want to potentially mess up Vim behaviour where the job output is
|
||||
" attached to a buffer set up by Vim. So we sort o mimic that here.
|
||||
call s:SetUpHiddenBuffer( stdout_buf )
|
||||
call s:SetUpHiddenBuffer( stderr_buf )
|
||||
call s:SetUpHiddenBuffer( buf )
|
||||
|
||||
let id = jobstart(a:cmd,
|
||||
\ {
|
||||
\ 'on_stdout': funcref( 's:_OnCommandEvent',
|
||||
\ [ a:category ] ),
|
||||
\ 'on_stderr': funcref( 's:_OnCommandEvent',
|
||||
\ [ a:category ] )
|
||||
\ [ a:category ] ),
|
||||
\ 'on_exit': funcref( 's:_OnCommandEvent',
|
||||
\ [ a:category ] ),
|
||||
\ } )
|
||||
|
||||
let s:commands[ a:category ][ id ] = {
|
||||
\ 'stdout': stdout_buf,
|
||||
\ 'stderr': stderr_buf
|
||||
\ 'stdout': buf,
|
||||
\ 'stderr': buf
|
||||
\ }
|
||||
|
||||
return [ stdout_buf, stderr_buf ]
|
||||
return buf
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#neojob#CleanUpCommand( category ) abort
|
||||
|
|
@ -229,8 +236,11 @@ function! vimspector#internal#neojob#CleanUpCommand( category ) abort
|
|||
endif
|
||||
|
||||
for id in keys( s:commands[ a:category ] )
|
||||
call jobstop( str2nr( id ) )
|
||||
call jobwait( [ str2nr( id ) ] )
|
||||
let id = str2nr( id )
|
||||
if jobwait( [ id ], 0 )[ 0 ] == -1
|
||||
call jobstop( id )
|
||||
endif
|
||||
call jobwait( [ id ], -1 )
|
||||
endfor
|
||||
unlet! s:commands[ a:category ]
|
||||
endfunction
|
||||
|
|
|
|||
|
|
@ -19,18 +19,31 @@ let s:save_cpo = &cpoptions
|
|||
set cpoptions&vim
|
||||
" }}}
|
||||
|
||||
let s:is_neovim = has( 'nvim' )
|
||||
let s:prefix = ''
|
||||
if has( 'nvim' )
|
||||
let s:prefix='neo'
|
||||
endif
|
||||
|
||||
function! vimspector#internal#state#Reset() abort
|
||||
let prefix = ''
|
||||
if s:is_neovim
|
||||
let prefix='neo'
|
||||
endif
|
||||
py3 << EOF
|
||||
import vim
|
||||
from vimspector import debug_session
|
||||
_vimspector_session = debug_session.DebugSession( vim.eval( 'prefix' ) )
|
||||
EOF
|
||||
try
|
||||
py3 import vim
|
||||
py3 _vimspector_session = __import__(
|
||||
\ "vimspector",
|
||||
\ fromlist=[ "debug_session" ] ).debug_session.DebugSession(
|
||||
\ vim.eval( 's:prefix' ) )
|
||||
catch /.*/
|
||||
echohl WarningMsg
|
||||
echom 'Exception while loading vimspector:' v:exception
|
||||
echom 'Vimspector unavailable: Requires Vim compiled with Python 3.6'
|
||||
echohl None
|
||||
return v:false
|
||||
endtry
|
||||
|
||||
return v:true
|
||||
endfunction
|
||||
|
||||
function! vimspector#internal#state#GetAPIPrefix() abort
|
||||
return s:prefix
|
||||
endfunction
|
||||
|
||||
" Boilerplate {{{
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ stages:
|
|||
- bash: pip3 install -r dev_requirements.txt
|
||||
displayName: "Install requirements"
|
||||
|
||||
- bash: $HOME/.local/bin/vint autoload/ compiler/ plugin/ tests/
|
||||
- bash: $HOME/.local/bin/vint autoload/ compiler/ plugin/ tests/ syntax/
|
||||
displayName: "Run vint"
|
||||
|
||||
- job: 'linux'
|
||||
|
|
@ -45,20 +45,17 @@ stages:
|
|||
|
||||
- task: CacheBeta@0
|
||||
inputs:
|
||||
key: v1 | gadgets | $(Agent.OS) | install_gadget.py
|
||||
key: v2 | gadgets | $(Agent.OS) | python3/vimspector/gadgets.py
|
||||
path: gadgets/linux/download
|
||||
displayName: Cache gadgets
|
||||
|
||||
- bash: python3 install_gadget.py --all
|
||||
displayName: 'Install gadgets - python3'
|
||||
|
||||
- bash: vim --version
|
||||
displayName: 'Print vim version information'
|
||||
|
||||
- bash: |
|
||||
eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
|
||||
export GOPATH=$HOME/go
|
||||
./run_tests --report messages --quiet
|
||||
./run_tests --install --update --report messages --quiet
|
||||
displayName: 'Run the tests'
|
||||
env:
|
||||
VIMSPECTOR_MIMODE: gdb
|
||||
|
|
@ -92,17 +89,14 @@ stages:
|
|||
|
||||
- task: CacheBeta@0
|
||||
inputs:
|
||||
key: v1 | gadgets | $(Agent.OS) | install_gadget.py
|
||||
key: v2 | gadgets | $(Agent.OS) | python3/vimspector/gadgets.py
|
||||
path: gadgets/macos/download
|
||||
displayName: Cache gadgets
|
||||
|
||||
- bash: python3 install_gadget.py --all
|
||||
displayName: 'Install gadgets - python3'
|
||||
|
||||
- bash: vim --version
|
||||
displayName: 'Print vim version information'
|
||||
|
||||
- bash: ./run_tests --report messages --quiet
|
||||
- bash: ./run_tests --install --update --report messages --quiet
|
||||
displayName: 'Run the tests'
|
||||
env:
|
||||
VIMSPECTOR_MIMODE: lldb
|
||||
|
|
|
|||
|
|
@ -23,9 +23,6 @@ if sys.version_info.major < 3:
|
|||
|
||||
import argparse
|
||||
import os
|
||||
import string
|
||||
import subprocess
|
||||
import traceback
|
||||
import json
|
||||
import functools
|
||||
import operator
|
||||
|
|
@ -35,628 +32,9 @@ import glob
|
|||
sys.path.insert( 1, os.path.join( os.path.dirname( __file__ ),
|
||||
'python3' ) )
|
||||
|
||||
from vimspector import install, installer
|
||||
from vimspector import install, installer, gadgets
|
||||
from vimspector.vendor.json_minify import minify
|
||||
|
||||
GADGETS = {
|
||||
'vscode-cpptools': {
|
||||
'language': 'c',
|
||||
'download': {
|
||||
'url': 'https://github.com/Microsoft/vscode-cpptools/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'do': lambda name, root, gadget: InstallCppTools( name, root, gadget ),
|
||||
'all': {
|
||||
'version': '0.27.0',
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"name": "cppdbg",
|
||||
"command": [
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
"configuration": {
|
||||
"type": "cppdbg",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'cpptools-linux.vsix',
|
||||
'checksum':
|
||||
'3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435',
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'cpptools-osx.vsix',
|
||||
'checksum':
|
||||
'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c',
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'cpptools-win32.vsix',
|
||||
'checksum':
|
||||
'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e',
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"name": "cppdbg",
|
||||
"command": [
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7.exe"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
"configuration": {
|
||||
"type": "cppdbg",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
"MIMode": "gdb",
|
||||
"MIDebuggerPath": "gdb.exe"
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'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',
|
||||
'checksum':
|
||||
'210632bba2221fbb841c9785a615258819ceec401d1abdbeb5f2326f12cc72a1'
|
||||
},
|
||||
'do': lambda name, root, gadget: InstallDebugpy( name, root, gadget ),
|
||||
'adapters': {
|
||||
'debugpy': {
|
||||
"command": [
|
||||
sys.executable,
|
||||
"${gadgetDir}/debugpy/build/lib/debugpy/adapter"
|
||||
],
|
||||
"name": "debugpy",
|
||||
"configuration": {
|
||||
"python": sys.executable,
|
||||
# Don't debug into subprocesses, as this leads to problems (vimspector
|
||||
# doesn't support the custom messages)
|
||||
# https://github.com/puremourning/vimspector/issues/141
|
||||
"subProcess": False,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'vscode-java-debug': {
|
||||
'language': 'java',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://github.com/microsoft/vscode-java-debug/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': '0.26.0',
|
||||
'file_name': 'vscjava.vscode-java-debug-0.26.0.vsix',
|
||||
'checksum':
|
||||
'de49116ff3a3c941dad0c36d9af59baa62cd931e808a2ab392056cbb235ad5ef',
|
||||
},
|
||||
'adapters': {
|
||||
"vscode-java": {
|
||||
"name": "vscode-java",
|
||||
"port": "${DAPPort}",
|
||||
}
|
||||
},
|
||||
},
|
||||
'java-language-server': {
|
||||
'language': 'javac',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
|
||||
'publishers/georgewfraser/vsextensions/vscode-javac/${version}/'
|
||||
'vspackage',
|
||||
'target': 'georgewfraser.vscode-javac-0.2.31.vsix.gz',
|
||||
'format': 'zip.gz',
|
||||
},
|
||||
'all': {
|
||||
'version': '0.2.31',
|
||||
'file_name': 'georgewfraser.vscode-javac-0.2.31.vsix.gz',
|
||||
'checksum':
|
||||
'5b0248ec1198d3ece9a9c6b9433b30c22e308f0ae6e4c7bd09cd943c454e3e1d',
|
||||
},
|
||||
'adapters': {
|
||||
"vscode-javac": {
|
||||
"name": "vscode-javac",
|
||||
"type": "vscode-javac",
|
||||
"command": [
|
||||
"${gadgetDir}/java-language-server/dist/debug_adapter_mac.sh"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'tclpro': {
|
||||
'language': 'tcl',
|
||||
'repo': {
|
||||
'url': 'https://github.com/puremourning/TclProDebug',
|
||||
'ref': 'master'
|
||||
},
|
||||
'do': lambda name, root, gadget: InstallTclProDebug( name, root, gadget ),
|
||||
'adapters': {
|
||||
"tclpro": {
|
||||
"name": "tclpro",
|
||||
"type": "tclpro",
|
||||
"command": [
|
||||
"${gadgetDir}/tclpro/bin/debugadapter"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
},
|
||||
"configuration": {
|
||||
"target": "${file}",
|
||||
"args": [ "*${args}" ],
|
||||
"tclsh": "tclsh",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"extensionDirs": [
|
||||
"${workspaceRoot}/.tclpro/extensions",
|
||||
"${HOME}/.tclpro/extensions",
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'netcoredbg': {
|
||||
'language': 'csharp',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://github.com/Samsung/netcoredbg/releases/download/latest/'
|
||||
'${file_name}',
|
||||
'format': 'tar',
|
||||
},
|
||||
'all': {
|
||||
'version': 'master'
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'netcoredbg-osx-master.tar.gz',
|
||||
'checksum':
|
||||
'c1dc6ed58c3f5b0473cfb4985a96552999360ceb9795e42d9c9be64af054f821',
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'netcoredbg-linux-master.tar.gz',
|
||||
'checksum': '',
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'netcoredbg-win64-master.zip',
|
||||
'checksum': '',
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.MakeSymlink(
|
||||
gadget_dir,
|
||||
name,
|
||||
os.path.join( root, 'netcoredbg' ) ),
|
||||
'adapters': {
|
||||
'netcoredbg': {
|
||||
"name": "netcoredbg",
|
||||
"command": [
|
||||
"${gadgetDir}/netcoredbg/netcoredbg",
|
||||
"--interpreter=vscode"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
'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.15.8',
|
||||
'checksum':
|
||||
'723eb2b621b99d65a24f215cb64b45f5fe694105613a900a03c859a62a810470',
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-mono-debug': {
|
||||
"name": "mono-debug",
|
||||
"command": [
|
||||
"mono",
|
||||
"${gadgetDir}/vscode-mono-debug/bin/Release/mono-debug.exe"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
'vscode-bash-debug': {
|
||||
'language': 'bash',
|
||||
'download': {
|
||||
'url': 'https://github.com/rogalmic/vscode-bash-debug/releases/'
|
||||
'download/${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'file_name': 'bash-debug-0.3.7.vsix',
|
||||
'version': 'v0.3.7',
|
||||
'checksum':
|
||||
'7b73e5b4604375df8658fb5a72c645c355785a289aa785a986e508342c014bb4',
|
||||
},
|
||||
'do': lambda name, root, gadget: InstallBashDebug( name, root, gadget ),
|
||||
'adapters': {
|
||||
"vscode-bash": {
|
||||
"name": "bashdb",
|
||||
"command": [
|
||||
"node",
|
||||
"${gadgetDir}/vscode-bash-debug/out/bashDebug.js"
|
||||
],
|
||||
"variables": {
|
||||
"BASHDB_HOME": "${gadgetDir}/vscode-bash-debug/bashdb_dir"
|
||||
},
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"type": "bashdb",
|
||||
"program": "${file}",
|
||||
"args": [],
|
||||
"env": {},
|
||||
"pathBash": "bash",
|
||||
"pathBashdb": "${BASHDB_HOME}/bashdb",
|
||||
"pathBashdbLib": "${BASHDB_HOME}",
|
||||
"pathCat": "cat",
|
||||
"pathMkfifo": "mkfifo",
|
||||
"pathPkill": "pkill",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"terminalKind": "integrated",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'vscode-go': {
|
||||
'language': 'go',
|
||||
'download': {
|
||||
'url': 'https://github.com/microsoft/vscode-go/releases/download/'
|
||||
'${version}/${file_name}'
|
||||
},
|
||||
'all': {
|
||||
'version': '0.11.4',
|
||||
'file_name': 'Go-0.11.4.vsix',
|
||||
'checksum':
|
||||
'ff7d7b944da5448974cb3a0086f4a2fd48e2086742d9c013d6964283d416027e'
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-go': {
|
||||
'name': 'delve',
|
||||
'command': [
|
||||
'node',
|
||||
'${gadgetDir}/vscode-go/out/src/debugAdapter/goDebug.js'
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'vscode-php-debug': {
|
||||
'language': 'php',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url':
|
||||
'https://github.com/felixfbecker/vscode-php-debug/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': 'v1.13.0',
|
||||
'file_name': 'php-debug.vsix',
|
||||
'checksum':
|
||||
'8a51e593458fd14623c1c89ebab87347b087d67087717f18bcf77bb788052718',
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-php-debug': {
|
||||
'name': "php-debug",
|
||||
'command': [
|
||||
'node',
|
||||
"${gadgetDir}/vscode-php-debug/out/phpDebug.js",
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
'vscode-node-debug2': {
|
||||
'language': 'node',
|
||||
'enabled': False,
|
||||
'repo': {
|
||||
'url': 'https://github.com/microsoft/vscode-node-debug2',
|
||||
'ref': 'v1.42.0',
|
||||
},
|
||||
'do': lambda name, root, gadget: InstallNodeDebug( name, root, gadget ),
|
||||
'adapters': {
|
||||
'vscode-node': {
|
||||
'name': 'node2',
|
||||
'type': 'node2',
|
||||
'command': [
|
||||
'node',
|
||||
'${gadgetDir}/vscode-node-debug2/out/src/nodeDebug.js'
|
||||
]
|
||||
},
|
||||
},
|
||||
},
|
||||
'debugger-for-chrome': {
|
||||
'language': 'chrome',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
|
||||
'publishers/msjsdiag/vsextensions/'
|
||||
'debugger-for-chrome/${version}/vspackage',
|
||||
'target': 'msjsdiag.debugger-for-chrome-4.12.0.vsix.gz',
|
||||
'format': 'zip.gz',
|
||||
},
|
||||
'all': {
|
||||
'version': '4.12.0',
|
||||
'file_name': 'msjsdiag.debugger-for-chrome-4.12.0.vsix',
|
||||
'checksum':
|
||||
'0df2fe96d059a002ebb0936b0003e6569e5a5c35260dc3791e1657d27d82ccf5'
|
||||
},
|
||||
'adapters': {
|
||||
'chrome': {
|
||||
'name': 'debugger-for-chrome',
|
||||
'type': 'chrome',
|
||||
'command': [
|
||||
'node',
|
||||
'${gadgetDir}/debugger-for-chrome/out/src/chromeDebug.js'
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'CodeLLDB': {
|
||||
'language': 'rust',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://github.com/vadimcn/vscode-lldb/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': 'v1.5.3',
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'codelldb-x86_64-darwin.vsix',
|
||||
'checksum':
|
||||
'7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a',
|
||||
'make_executable': [
|
||||
'adapter/codelldb',
|
||||
'lldb/bin/debugserver',
|
||||
'lldb/bin/lldb',
|
||||
'lldb/bin/lldb-argdumper',
|
||||
],
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'codelldb-x86_64-linux.vsix',
|
||||
'checksum':
|
||||
'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139',
|
||||
'make_executable': [
|
||||
'adapter/codelldb',
|
||||
'lldb/bin/lldb',
|
||||
'lldb/bin/lldb-server',
|
||||
'lldb/bin/lldb-argdumper',
|
||||
],
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'codelldb-x86_64-windows.vsix',
|
||||
'checksum':
|
||||
'',
|
||||
'make_executable': []
|
||||
},
|
||||
'adapters': {
|
||||
'CodeLLDB': {
|
||||
'name': 'CodeLLDB',
|
||||
'type': 'CodeLLDB',
|
||||
"command": [
|
||||
"${gadgetDir}/CodeLLDB/adapter/codelldb",
|
||||
"--port", "${unusedLocalPort}"
|
||||
],
|
||||
"port": "${unusedLocalPort}",
|
||||
"configuration": {
|
||||
"type": "lldb",
|
||||
"name": "lldb",
|
||||
"cargo": {},
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {},
|
||||
"terminal": "integrated",
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def InstallGeneric( name, root, gadget ):
|
||||
extension = os.path.join( root, 'extension' )
|
||||
for f in gadget.get( 'make_executable', [] ):
|
||||
installer.MakeExecutable( os.path.join( extension, f ) )
|
||||
|
||||
installer.MakeExtensionSymlink( vimspector_base, name, root )
|
||||
|
||||
|
||||
def InstallCppTools( name, root, gadget ):
|
||||
extension = os.path.join( root, 'extension' )
|
||||
|
||||
# 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.
|
||||
installer.MakeExecutable( os.path.join( extension,
|
||||
'debugAdapters',
|
||||
'OpenDebugAD7' ) )
|
||||
with open( os.path.join( extension, 'package.json' ) ) as f:
|
||||
package = json.load( f )
|
||||
runtime_dependencies = package[ 'runtimeDependencies' ]
|
||||
for dependency in runtime_dependencies:
|
||||
for binary in dependency.get( 'binaries' ):
|
||||
file_path = os.path.abspath( os.path.join( extension, binary ) )
|
||||
if os.path.exists( file_path ):
|
||||
installer.MakeExecutable( os.path.join( extension, binary ) )
|
||||
|
||||
installer.MakeExtensionSymlink( vimspector_base, name, root )
|
||||
|
||||
|
||||
def InstallBashDebug( name, root, gadget ):
|
||||
installer.MakeExecutable( os.path.join( root,
|
||||
'extension',
|
||||
'bashdb_dir',
|
||||
'bashdb' ) )
|
||||
installer.MakeExtensionSymlink( vimspector_base, name, root )
|
||||
|
||||
|
||||
def InstallDebugpy( name, root, gadget ):
|
||||
wd = os.getcwd()
|
||||
root = os.path.join( root, 'debugpy-{}'.format( gadget[ 'version' ] ) )
|
||||
os.chdir( root )
|
||||
try:
|
||||
subprocess.check_call( [ sys.executable, 'setup.py', 'build' ] )
|
||||
finally:
|
||||
os.chdir( wd )
|
||||
|
||||
installer.MakeSymlink( gadget_dir, name, root )
|
||||
|
||||
|
||||
def InstallTclProDebug( name, root, gadget ):
|
||||
configure = [ './configure' ]
|
||||
|
||||
if OS == 'macos':
|
||||
# Apple removed the headers from system frameworks because they are
|
||||
# determined to make life difficult. And the TCL configure scripts are super
|
||||
# old so don't know about this. So we do their job for them and try and find
|
||||
# a tclConfig.sh.
|
||||
#
|
||||
# NOTE however that in Apple's infinite wisdom, installing the "headers" in
|
||||
# the other location is actually broken because the paths in the
|
||||
# tclConfig.sh are pointing at the _old_ location. You actually do have to
|
||||
# run the package installation which puts the headers back in order to work.
|
||||
# This is why the below list is does not contain stuff from
|
||||
# /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform
|
||||
# '/Applications/Xcode.app/Contents/Developer/Platforms'
|
||||
# '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System'
|
||||
# '/Library/Frameworks/Tcl.framework',
|
||||
# '/Applications/Xcode.app/Contents/Developer/Platforms'
|
||||
# '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System'
|
||||
# '/Library/Frameworks/Tcl.framework/Versions'
|
||||
# '/Current',
|
||||
for p in [ '/usr/local/opt/tcl-tk/lib' ]:
|
||||
if os.path.exists( os.path.join( p, 'tclConfig.sh' ) ):
|
||||
configure.append( '--with-tcl=' + p )
|
||||
break
|
||||
|
||||
|
||||
with installer.CurrentWorkingDir( os.path.join( root, 'lib', 'tclparser' ) ):
|
||||
subprocess.check_call( configure )
|
||||
subprocess.check_call( [ 'make' ] )
|
||||
|
||||
installer.MakeSymlink( gadget_dir, name, root )
|
||||
|
||||
|
||||
def InstallNodeDebug( name, root, gadget ):
|
||||
node_version = subprocess.check_output( [ 'node', '--version' ],
|
||||
universal_newlines=True ).strip()
|
||||
print( "Node.js version: {}".format( node_version ) )
|
||||
if list( map( int, node_version[ 1: ].split( '.' ) ) ) >= [ 12, 0, 0 ]:
|
||||
print( "Can't install vscode-debug-node2:" )
|
||||
print( "Sorry, you appear to be running node 12 or later. That's not "
|
||||
"compatible with the build system for this extension, and as far as "
|
||||
"we know, there isn't a pre-built independent package." )
|
||||
print( "My advice is to install nvm, then do:" )
|
||||
print( " $ nvm install --lts 10" )
|
||||
print( " $ nvm use --lts 10" )
|
||||
print( " $ ./install_gadget.py --enable-node ..." )
|
||||
raise RuntimeError( 'Invalid node environent for node debugger' )
|
||||
|
||||
with installer.CurrentWorkingDir( root ):
|
||||
subprocess.check_call( [ 'npm', 'install' ] )
|
||||
subprocess.check_call( [ 'npm', 'run', 'build' ] )
|
||||
installer.MakeSymlink( gadget_dir, name, root )
|
||||
|
||||
|
||||
def InstallGagdet( name, gadget, failed, all_adapters ):
|
||||
try:
|
||||
v = {}
|
||||
v.update( gadget.get( 'all', {} ) )
|
||||
v.update( gadget.get( OS, {} ) )
|
||||
|
||||
if 'download' in gadget:
|
||||
if 'file_name' not in v:
|
||||
raise RuntimeError( "Unsupported OS {} for gadget {}".format( OS,
|
||||
name ) )
|
||||
|
||||
destination = os.path.join( gadget_dir, 'download', name, v[ 'version' ] )
|
||||
|
||||
url = string.Template( gadget[ 'download' ][ 'url' ] ).substitute( v )
|
||||
|
||||
file_path = installer.DownloadFileTo(
|
||||
url,
|
||||
destination,
|
||||
file_name = gadget[ 'download' ].get( 'target' ),
|
||||
checksum = v.get( 'checksum' ),
|
||||
check_certificate = not args.no_check_certificate )
|
||||
|
||||
root = os.path.join( destination, 'root' )
|
||||
installer.ExtractZipTo(
|
||||
file_path,
|
||||
root,
|
||||
format = gadget[ 'download' ].get( 'format', 'zip' ) )
|
||||
elif 'repo' in gadget:
|
||||
url = string.Template( gadget[ 'repo' ][ 'url' ] ).substitute( v )
|
||||
ref = string.Template( gadget[ 'repo' ][ 'ref' ] ).substitute( v )
|
||||
|
||||
destination = os.path.join( gadget_dir, 'download', name )
|
||||
installer.CloneRepoTo( url, ref, destination )
|
||||
root = destination
|
||||
|
||||
if 'do' in gadget:
|
||||
gadget[ 'do' ]( name, root, v )
|
||||
else:
|
||||
InstallGeneric( name, root, v )
|
||||
|
||||
# Allow per-OS adapter overrides. v already did that for us...
|
||||
all_adapters.update( v.get( 'adapters', {} ) )
|
||||
# Add any other "all" adapters
|
||||
all_adapters.update( gadget.get( 'adapters', {} ) )
|
||||
|
||||
print( "Done installing {}".format( name ) )
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
failed.append( name )
|
||||
print( "FAILED installing {}: {}".format( name, e ) )
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Entry point
|
||||
# ------------------------------------------------------------------------------
|
||||
|
|
@ -691,6 +69,14 @@ parser.add_argument( '--force-all',
|
|||
action = 'store_true',
|
||||
help = 'Enable all unsupported completers' )
|
||||
|
||||
parser.add_argument( '--quiet',
|
||||
action = 'store_true',
|
||||
help = 'Suppress installation output' )
|
||||
|
||||
parser.add_argument( '--verbose',
|
||||
action = 'store_true',
|
||||
help = 'Force installation output' )
|
||||
|
||||
parser.add_argument( '--basedir',
|
||||
action = 'store',
|
||||
help = 'Advanced option. '
|
||||
|
|
@ -723,7 +109,7 @@ parser.add_argument( '--sudo',
|
|||
"run this as root via sudo, pass this flag." )
|
||||
|
||||
done_languages = set()
|
||||
for name, gadget in GADGETS.items():
|
||||
for name, gadget in gadgets.GADGETS.items():
|
||||
lang = gadget[ 'language' ]
|
||||
if lang in done_languages:
|
||||
continue
|
||||
|
|
@ -766,12 +152,9 @@ if args.basedir:
|
|||
vimspector_base = os.path.abspath( args.basedir )
|
||||
|
||||
install.MakeInstallDirs( vimspector_base )
|
||||
|
||||
OS = install.GetOS()
|
||||
gadget_dir = install.GetGadgetDir( vimspector_base, OS )
|
||||
|
||||
print( 'OS = ' + OS )
|
||||
print( 'gadget_dir = ' + gadget_dir )
|
||||
installer.Configure( vimspector_base = vimspector_base,
|
||||
quiet = args.quiet and not args.verbose,
|
||||
no_check_certificate = args.no_check_certificate )
|
||||
|
||||
if args.force_all and not args.all:
|
||||
args.all = True
|
||||
|
|
@ -789,21 +172,11 @@ for custom_file_name in functools.reduce( operator.add,
|
|||
|
||||
|
||||
failed = []
|
||||
if args.update_gadget_config:
|
||||
with open( install.GetGadgetConfigFile( vimspector_base ), 'r' ) as f:
|
||||
all_adapters = json.load( f ).get( 'adapters', {} )
|
||||
else:
|
||||
all_adapters = {}
|
||||
succeeded = []
|
||||
all_adapters = installer.ReadAdapters(
|
||||
read_existing = args.update_gadget_config )
|
||||
|
||||
# Include "built-in" adapter for multi-session mode
|
||||
all_adapters.update( {
|
||||
'multi-session': {
|
||||
'port': '${port}',
|
||||
'host': '${host}'
|
||||
},
|
||||
} )
|
||||
|
||||
for name, gadget in GADGETS.items():
|
||||
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' ] ) ):
|
||||
|
|
@ -814,33 +187,36 @@ for name, gadget in GADGETS.items():
|
|||
if getattr( args, 'disable_' + gadget[ 'language' ] ):
|
||||
continue
|
||||
|
||||
InstallGagdet( name,
|
||||
gadget,
|
||||
failed,
|
||||
all_adapters )
|
||||
installer.InstallGagdet( name,
|
||||
gadget,
|
||||
succeeded,
|
||||
failed,
|
||||
all_adapters )
|
||||
|
||||
|
||||
for name, gadget in CUSTOM_GADGETS.items():
|
||||
InstallGagdet( name, gadget, failed, all_adapters )
|
||||
|
||||
adapter_config = json.dumps ( { 'adapters': all_adapters },
|
||||
indent=2,
|
||||
sort_keys=True )
|
||||
installer.InstallGagdet( name, gadget, succeeded, failed, all_adapters )
|
||||
|
||||
if args.no_gadget_config:
|
||||
print( "" )
|
||||
print( "Would write the following gadgets: " )
|
||||
print( adapter_config )
|
||||
installer.WriteAdapters( all_adapters, to_file = sys.stdout )
|
||||
else:
|
||||
with open( install.GetGadgetConfigFile( vimspector_base ), 'w' ) as f:
|
||||
f.write( adapter_config )
|
||||
|
||||
if failed:
|
||||
raise RuntimeError( 'Failed to install gadgets: {}'.format(
|
||||
','.join( failed ) ) )
|
||||
installer.WriteAdapters( all_adapters )
|
||||
|
||||
if args.basedir:
|
||||
print( "" )
|
||||
print( "***NOTE***: You set --basedir to " + args.basedir +
|
||||
". Therefore you _must_ ensure this is in your vimrc:\n"
|
||||
"let g:vimspector_base_dir='" + vimspector_base + "'" )
|
||||
|
||||
if succeeded:
|
||||
print( "Done" )
|
||||
print( "The following adapters were installed successfully:\n - {}".format(
|
||||
'\n - '.join( succeeded ) ) )
|
||||
|
||||
if failed:
|
||||
sys.exit( 'Failed to install adapters:\n * {}{}'.format(
|
||||
'\n * '.join( failed ),
|
||||
"\nRe-run with --verbose for more info on failures"
|
||||
if args.quiet and not args.verbose else '' ) )
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ endif
|
|||
" - Add commands/mappings/menus?
|
||||
|
||||
let g:loaded_vimpector = 1
|
||||
let g:vimspector_home = expand( '<sfile>:p:h:h' )
|
||||
|
||||
let s:mappings = get( g:, 'vimspector_enable_mappings', '' )
|
||||
|
||||
|
|
@ -97,6 +98,19 @@ command! -bar
|
|||
\ VimspectorReset
|
||||
\ call vimspector#Reset()
|
||||
|
||||
" Installer commands
|
||||
command! -bar -nargs=* -complete=custom,vimspector#CompleteInstall
|
||||
\ VimspectorInstall
|
||||
\ call vimspector#Install( <f-args> )
|
||||
command! -bar -nargs=*
|
||||
\ VimspectorUpdate
|
||||
\ call vimspector#Update( <f-args> )
|
||||
command! -bar -nargs=0
|
||||
\ VimspectorAbortInstall
|
||||
\ call vimspector#AbortInstall()
|
||||
|
||||
|
||||
|
||||
" Dummy autocommands so that we can call this whenever
|
||||
augroup VimspectorUserAutoCmds
|
||||
au!
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ from vimspector import ( breakpoints,
|
|||
stack_trace,
|
||||
utils,
|
||||
variables,
|
||||
settings )
|
||||
settings,
|
||||
installer )
|
||||
from vimspector.vendor.json_minify import minify
|
||||
|
||||
# We cache this once, and don't allow it to change (FIXME?)
|
||||
|
|
@ -51,8 +52,7 @@ class DebugSession( object ):
|
|||
self._logger.info( "API is: {}".format( api_prefix ) )
|
||||
self._logger.info( 'VIMSPECTOR_HOME = %s', VIMSPECTOR_HOME )
|
||||
self._logger.info( 'gadgetDir = %s',
|
||||
install.GetGadgetDir( VIMSPECTOR_HOME,
|
||||
install.GetOS() ) )
|
||||
install.GetGadgetDir( VIMSPECTOR_HOME ) )
|
||||
|
||||
self._uiTab = None
|
||||
self._stackTraceView = None
|
||||
|
|
@ -91,7 +91,7 @@ class DebugSession( object ):
|
|||
configurations = {}
|
||||
adapters = {}
|
||||
|
||||
glob.glob( install.GetGadgetDir( VIMSPECTOR_HOME, install.GetOS() ) )
|
||||
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}' )
|
||||
|
|
@ -152,6 +152,24 @@ class DebugSession( object ):
|
|||
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(
|
||||
self._api_prefix,
|
||||
*shlex.split( response ),
|
||||
then = lambda: self.Start( new_launch_variables ) )
|
||||
return
|
||||
elif response is None:
|
||||
return
|
||||
|
||||
utils.UserMessage( f"The specified adapter '{adapter}' is not "
|
||||
"available. Did you forget to run "
|
||||
"'install_gadget.py'?",
|
||||
|
|
@ -192,7 +210,7 @@ class DebugSession( object ):
|
|||
'dollar': '$', # HACK. Hote '$$' also works.
|
||||
'workspaceRoot': self._workspace_root,
|
||||
'workspaceFolder': self._workspace_root,
|
||||
'gadgetDir': install.GetGadgetDir( VIMSPECTOR_HOME, install.GetOS() ),
|
||||
'gadgetDir': install.GetGadgetDir( VIMSPECTOR_HOME ),
|
||||
'file': current_file,
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +547,6 @@ class DebugSession( object ):
|
|||
stack_trace_window = vim.current.window
|
||||
one_third = int( vim.eval( 'winheight( 0 )' ) ) / 3
|
||||
self._stackTraceView = stack_trace.StackTraceView( self,
|
||||
self._connection,
|
||||
stack_trace_window )
|
||||
|
||||
# Watches
|
||||
|
|
@ -547,17 +564,15 @@ class DebugSession( object ):
|
|||
with utils.LetCurrentWindow( stack_trace_window ):
|
||||
vim.command( f'{ one_third }wincmd _' )
|
||||
|
||||
self._variablesView = variables.VariablesView( self._connection,
|
||||
vars_window,
|
||||
self._variablesView = variables.VariablesView( vars_window,
|
||||
watch_window )
|
||||
|
||||
# Output/logging
|
||||
vim.current.window = code_window
|
||||
vim.command( f'rightbelow { settings.Int( "bottombar_height", 10 ) }new' )
|
||||
output_window = vim.current.window
|
||||
self._outputView = output.OutputView( self._connection,
|
||||
output_window,
|
||||
self._api_prefix )
|
||||
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
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ from vimspector import install, utils
|
|||
def SetUpDebugpy( wait=False, port=5678 ):
|
||||
sys.path.insert(
|
||||
1,
|
||||
os.path.join( install.GetGadgetDir( utils.GetVimspectorBase(),
|
||||
install.GetOS() ),
|
||||
os.path.join( install.GetGadgetDir( utils.GetVimspectorBase() ),
|
||||
'debugpy',
|
||||
'build',
|
||||
'lib' ) )
|
||||
|
|
|
|||
490
python3/vimspector/gadgets.py
Normal file
490
python3/vimspector/gadgets.py
Normal file
|
|
@ -0,0 +1,490 @@
|
|||
# vimspector - A multi-language debugging system for Vim
|
||||
# Copyright 2020 Ben Jackson
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
from vimspector import installer
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
GADGETS = {
|
||||
'vscode-cpptools': {
|
||||
'language': 'c',
|
||||
'download': {
|
||||
'url': 'https://github.com/Microsoft/vscode-cpptools/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.InstallCppTools( name,
|
||||
root,
|
||||
gadget ),
|
||||
'all': {
|
||||
'version': '0.27.0',
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"name": "cppdbg",
|
||||
"command": [
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
"configuration": {
|
||||
"type": "cppdbg",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'cpptools-linux.vsix',
|
||||
'checksum':
|
||||
'3695202e1e75a03de18049323b66d868165123f26151f8c974a480eaf0205435',
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'cpptools-osx.vsix',
|
||||
'checksum':
|
||||
'cb061e3acd7559a539e5586f8d3f535101c4ec4e8a48195856d1d39380b5cf3c',
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'cpptools-win32.vsix',
|
||||
'checksum':
|
||||
'aa294368ed16d48c59e49c8000e146eae5a19ad07b654efed5db8ec93b24229e',
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"name": "cppdbg",
|
||||
"command": [
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/bin/OpenDebugAD7.exe"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
"configuration": {
|
||||
"type": "cppdbg",
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"environment": [],
|
||||
"MIMode": "gdb",
|
||||
"MIDebuggerPath": "gdb.exe"
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'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',
|
||||
'checksum':
|
||||
'210632bba2221fbb841c9785a615258819ceec401d1abdbeb5f2326f12cc72a1'
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.InstallDebugpy( name,
|
||||
root,
|
||||
gadget ),
|
||||
'adapters': {
|
||||
'debugpy': {
|
||||
"command": [
|
||||
sys.executable, # TODO: Will this work from within Vim ?
|
||||
"${gadgetDir}/debugpy/build/lib/debugpy/adapter"
|
||||
],
|
||||
"name": "debugpy",
|
||||
"configuration": {
|
||||
"python": sys.executable, # TODO: Will this work from within Vim ?
|
||||
# Don't debug into subprocesses, as this leads to problems (vimspector
|
||||
# doesn't support the custom messages)
|
||||
# https://github.com/puremourning/vimspector/issues/141
|
||||
"subProcess": False,
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'vscode-java-debug': {
|
||||
'language': 'java',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://github.com/microsoft/vscode-java-debug/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': '0.26.0',
|
||||
'file_name': 'vscjava.vscode-java-debug-0.26.0.vsix',
|
||||
'checksum':
|
||||
'de49116ff3a3c941dad0c36d9af59baa62cd931e808a2ab392056cbb235ad5ef',
|
||||
},
|
||||
'adapters': {
|
||||
"vscode-java": {
|
||||
"name": "vscode-java",
|
||||
"port": "${DAPPort}",
|
||||
}
|
||||
},
|
||||
},
|
||||
'java-language-server': {
|
||||
'language': 'javac',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
|
||||
'publishers/georgewfraser/vsextensions/vscode-javac/${version}/'
|
||||
'vspackage',
|
||||
'target': 'georgewfraser.vscode-javac-0.2.31.vsix.gz',
|
||||
'format': 'zip.gz',
|
||||
},
|
||||
'all': {
|
||||
'version': '0.2.31',
|
||||
'file_name': 'georgewfraser.vscode-javac-0.2.31.vsix.gz',
|
||||
'checksum':
|
||||
'5b0248ec1198d3ece9a9c6b9433b30c22e308f0ae6e4c7bd09cd943c454e3e1d',
|
||||
},
|
||||
'adapters': {
|
||||
"vscode-javac": {
|
||||
"name": "vscode-javac",
|
||||
"type": "vscode-javac",
|
||||
"command": [
|
||||
"${gadgetDir}/java-language-server/dist/debug_adapter_mac.sh"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'tclpro': {
|
||||
'language': 'tcl',
|
||||
'repo': {
|
||||
'url': 'https://github.com/puremourning/TclProDebug',
|
||||
'ref': 'master'
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.InstallTclProDebug( name,
|
||||
root,
|
||||
gadget ),
|
||||
'adapters': {
|
||||
"tclpro": {
|
||||
"name": "tclpro",
|
||||
"type": "tclpro",
|
||||
"command": [
|
||||
"${gadgetDir}/tclpro/bin/debugadapter"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
},
|
||||
"configuration": {
|
||||
"target": "${file}",
|
||||
"args": [ "*${args}" ],
|
||||
"tclsh": "tclsh",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"extensionDirs": [
|
||||
"${workspaceRoot}/.tclpro/extensions",
|
||||
"${HOME}/.tclpro/extensions",
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'netcoredbg': {
|
||||
'language': 'csharp',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://github.com/Samsung/netcoredbg/releases/download/latest/'
|
||||
'${file_name}',
|
||||
'format': 'tar',
|
||||
},
|
||||
'all': {
|
||||
'version': 'master'
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'netcoredbg-osx-master.tar.gz',
|
||||
'checksum':
|
||||
'c1dc6ed58c3f5b0473cfb4985a96552999360ceb9795e42d9c9be64af054f821',
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'netcoredbg-linux-master.tar.gz',
|
||||
'checksum': '',
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'netcoredbg-win64-master.zip',
|
||||
'checksum': '',
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.MakeSymlink(
|
||||
name,
|
||||
os.path.join( root, 'netcoredbg' ) ),
|
||||
'adapters': {
|
||||
'netcoredbg': {
|
||||
"name": "netcoredbg",
|
||||
"command": [
|
||||
"${gadgetDir}/netcoredbg/netcoredbg",
|
||||
"--interpreter=vscode"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
'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.15.8',
|
||||
'checksum':
|
||||
'723eb2b621b99d65a24f215cb64b45f5fe694105613a900a03c859a62a810470',
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-mono-debug': {
|
||||
"name": "mono-debug",
|
||||
"command": [
|
||||
"mono",
|
||||
"${gadgetDir}/vscode-mono-debug/bin/Release/mono-debug.exe"
|
||||
],
|
||||
"attach": {
|
||||
"pidSelect": "none"
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
'vscode-bash-debug': {
|
||||
'language': 'bash',
|
||||
'download': {
|
||||
'url': 'https://github.com/rogalmic/vscode-bash-debug/releases/'
|
||||
'download/${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'file_name': 'bash-debug-0.3.7.vsix',
|
||||
'version': 'v0.3.7',
|
||||
'checksum':
|
||||
'7b73e5b4604375df8658fb5a72c645c355785a289aa785a986e508342c014bb4',
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.InstallBashDebug( name,
|
||||
root,
|
||||
gadget ),
|
||||
'adapters': {
|
||||
"vscode-bash": {
|
||||
"name": "bashdb",
|
||||
"command": [
|
||||
"node",
|
||||
"${gadgetDir}/vscode-bash-debug/out/bashDebug.js"
|
||||
],
|
||||
"variables": {
|
||||
"BASHDB_HOME": "${gadgetDir}/vscode-bash-debug/bashdb_dir"
|
||||
},
|
||||
"configuration": {
|
||||
"request": "launch",
|
||||
"type": "bashdb",
|
||||
"program": "${file}",
|
||||
"args": [],
|
||||
"env": {},
|
||||
"pathBash": "bash",
|
||||
"pathBashdb": "${BASHDB_HOME}/bashdb",
|
||||
"pathBashdbLib": "${BASHDB_HOME}",
|
||||
"pathCat": "cat",
|
||||
"pathMkfifo": "mkfifo",
|
||||
"pathPkill": "pkill",
|
||||
"cwd": "${workspaceRoot}",
|
||||
"terminalKind": "integrated",
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'vscode-go': {
|
||||
'language': 'go',
|
||||
'download': {
|
||||
'url': 'https://github.com/microsoft/vscode-go/releases/download/'
|
||||
'${version}/${file_name}'
|
||||
},
|
||||
'all': {
|
||||
'version': '0.11.4',
|
||||
'file_name': 'Go-0.11.4.vsix',
|
||||
'checksum':
|
||||
'ff7d7b944da5448974cb3a0086f4a2fd48e2086742d9c013d6964283d416027e'
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-go': {
|
||||
'name': 'delve',
|
||||
'command': [
|
||||
'node',
|
||||
'${gadgetDir}/vscode-go/out/src/debugAdapter/goDebug.js'
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'vscode-php-debug': {
|
||||
'language': 'php',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url':
|
||||
'https://github.com/felixfbecker/vscode-php-debug/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': 'v1.13.0',
|
||||
'file_name': 'php-debug.vsix',
|
||||
'checksum':
|
||||
'8a51e593458fd14623c1c89ebab87347b087d67087717f18bcf77bb788052718',
|
||||
},
|
||||
'adapters': {
|
||||
'vscode-php-debug': {
|
||||
'name': "php-debug",
|
||||
'command': [
|
||||
'node',
|
||||
"${gadgetDir}/vscode-php-debug/out/phpDebug.js",
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
'vscode-node-debug2': {
|
||||
'language': 'node',
|
||||
'enabled': False,
|
||||
'repo': {
|
||||
'url': 'https://github.com/microsoft/vscode-node-debug2',
|
||||
'ref': 'v1.42.0',
|
||||
},
|
||||
'do': lambda name, root, gadget: installer.InstallNodeDebug( name,
|
||||
root,
|
||||
gadget ),
|
||||
'adapters': {
|
||||
'vscode-node': {
|
||||
'name': 'node2',
|
||||
'type': 'node2',
|
||||
'command': [
|
||||
'node',
|
||||
'${gadgetDir}/vscode-node-debug2/out/src/nodeDebug.js'
|
||||
]
|
||||
},
|
||||
},
|
||||
},
|
||||
'debugger-for-chrome': {
|
||||
'language': 'chrome',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
|
||||
'publishers/msjsdiag/vsextensions/'
|
||||
'debugger-for-chrome/${version}/vspackage',
|
||||
'target': 'msjsdiag.debugger-for-chrome-4.12.0.vsix.gz',
|
||||
'format': 'zip.gz',
|
||||
},
|
||||
'all': {
|
||||
'version': '4.12.0',
|
||||
'file_name': 'msjsdiag.debugger-for-chrome-4.12.0.vsix',
|
||||
'checksum':
|
||||
'0df2fe96d059a002ebb0936b0003e6569e5a5c35260dc3791e1657d27d82ccf5'
|
||||
},
|
||||
'adapters': {
|
||||
'chrome': {
|
||||
'name': 'debugger-for-chrome',
|
||||
'type': 'chrome',
|
||||
'command': [
|
||||
'node',
|
||||
'${gadgetDir}/debugger-for-chrome/out/src/chromeDebug.js'
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
'CodeLLDB': {
|
||||
'language': 'rust',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://github.com/vadimcn/vscode-lldb/releases/download/'
|
||||
'${version}/${file_name}',
|
||||
},
|
||||
'all': {
|
||||
'version': 'v1.5.3',
|
||||
},
|
||||
'macos': {
|
||||
'file_name': 'codelldb-x86_64-darwin.vsix',
|
||||
'checksum':
|
||||
'7505bc1cdfcfd1cb981e2996aec62d63577440709bac31dcadb41a3b4b44631a',
|
||||
'make_executable': [
|
||||
'adapter/codelldb',
|
||||
'lldb/bin/debugserver',
|
||||
'lldb/bin/lldb',
|
||||
'lldb/bin/lldb-argdumper',
|
||||
],
|
||||
},
|
||||
'linux': {
|
||||
'file_name': 'codelldb-x86_64-linux.vsix',
|
||||
'checksum':
|
||||
'ce7efc3e94d775368e5942a02bf5c326b6809a0b4c389f79ffa6a8f6f6b72139',
|
||||
'make_executable': [
|
||||
'adapter/codelldb',
|
||||
'lldb/bin/lldb',
|
||||
'lldb/bin/lldb-server',
|
||||
'lldb/bin/lldb-argdumper',
|
||||
],
|
||||
},
|
||||
'windows': {
|
||||
'file_name': 'codelldb-x86_64-windows.vsix',
|
||||
'checksum':
|
||||
'',
|
||||
'make_executable': []
|
||||
},
|
||||
'adapters': {
|
||||
'CodeLLDB': {
|
||||
'name': 'CodeLLDB',
|
||||
'type': 'CodeLLDB',
|
||||
"command": [
|
||||
"${gadgetDir}/CodeLLDB/adapter/codelldb",
|
||||
"--port", "${unusedLocalPort}"
|
||||
],
|
||||
"port": "${unusedLocalPort}",
|
||||
"configuration": {
|
||||
"type": "lldb",
|
||||
"name": "lldb",
|
||||
"cargo": {},
|
||||
"args": [],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"env": {},
|
||||
"terminal": "integrated",
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -38,18 +38,16 @@ def MakeInstallDirs( vimspector_base ):
|
|||
mkdirs( GetConfigDirForFiletype( vimspector_base, '_all' ) )
|
||||
|
||||
|
||||
def GetGadgetDir( vimspector_base, OS ):
|
||||
return os.path.join( os.path.abspath( vimspector_base ), 'gadgets', OS )
|
||||
def GetGadgetDir( vimspector_base ):
|
||||
return os.path.join( os.path.abspath( vimspector_base ), 'gadgets', GetOS() )
|
||||
|
||||
|
||||
def GetGadgetConfigFile( vimspector_base ):
|
||||
return os.path.join( GetGadgetDir( vimspector_base, GetOS() ),
|
||||
'.gadgets.json' )
|
||||
return os.path.join( GetGadgetDir( vimspector_base ), '.gadgets.json' )
|
||||
|
||||
|
||||
def GetGadgetConfigDir( vimspector_base ):
|
||||
return os.path.join( GetGadgetDir( vimspector_base, GetOS() ),
|
||||
'.gadgets.d' )
|
||||
return os.path.join( GetGadgetDir( vimspector_base ), '.gadgets.d' )
|
||||
|
||||
|
||||
def GetConfigDirForFiletype( vimspector_base, filetype ):
|
||||
|
|
|
|||
|
|
@ -16,21 +16,397 @@
|
|||
# limitations under the License.
|
||||
|
||||
from urllib import request
|
||||
import io
|
||||
import contextlib
|
||||
import zipfile
|
||||
import gzip
|
||||
import shutil
|
||||
import tarfile
|
||||
import hashlib
|
||||
import time
|
||||
import ssl
|
||||
import subprocess
|
||||
import functools
|
||||
import gzip
|
||||
import hashlib
|
||||
import io
|
||||
import os
|
||||
import shutil
|
||||
import ssl
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import time
|
||||
import traceback
|
||||
import zipfile
|
||||
import json
|
||||
|
||||
from vimspector import install
|
||||
from vimspector import install, gadgets
|
||||
|
||||
OUTPUT_VIEW = None
|
||||
|
||||
|
||||
class Options:
|
||||
vimspector_base = None
|
||||
no_check_certificate = False
|
||||
quiet = False
|
||||
|
||||
|
||||
options = Options()
|
||||
|
||||
|
||||
def Configure( **kwargs ):
|
||||
for k, v in kwargs.items():
|
||||
setattr( options, k, v )
|
||||
|
||||
|
||||
def Print( *args, **kwargs ):
|
||||
if not options.quiet:
|
||||
print( *args, **kwargs )
|
||||
|
||||
|
||||
def CheckCall( *args, **kwargs ):
|
||||
if options.quiet:
|
||||
out = subprocess.PIPE
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
kwargs[ 'stdout' ] = out
|
||||
kwargs[ 'stderr' ] = subprocess.STDOUT
|
||||
|
||||
subprocess.check_call( *args, **kwargs )
|
||||
|
||||
|
||||
def PathToAnyWorkingPython3():
|
||||
# We can't rely on sys.executable because it's usually 'vim' (fixme, not with
|
||||
# neovim?)
|
||||
paths = os.environ[ 'PATH' ].split( os.pathsep )
|
||||
|
||||
if install.GetOS() == 'windows':
|
||||
paths.insert( 0, os.getcwd() )
|
||||
candidates = [ os.path.join( sys.exec_prefix, 'python.exe' ),
|
||||
'python.exe' ]
|
||||
else:
|
||||
candidates = [ os.path.join( sys.exec_prefix, 'bin', 'python3' ),
|
||||
'python3',
|
||||
'python' ]
|
||||
|
||||
for candidate in candidates:
|
||||
for path in paths:
|
||||
filename = os.path.abspath( os.path.join( path, candidate ) )
|
||||
if not os.path.isfile( filename ):
|
||||
continue
|
||||
if not os.access( filename, os.F_OK | os.X_OK ):
|
||||
continue
|
||||
|
||||
return filename
|
||||
|
||||
raise RuntimeError( "Unable to find a working python3" )
|
||||
|
||||
|
||||
def RunInstaller( api_prefix, *args, **kwargs ):
|
||||
from vimspector import utils, output, settings
|
||||
import vim
|
||||
|
||||
args = GadgetListToInstallerArgs( *args )
|
||||
|
||||
vimspector_home = utils.GetVimString( vim.vars, 'vimspector_home' )
|
||||
vimspector_base_dir = utils.GetVimspectorBase()
|
||||
|
||||
global OUTPUT_VIEW
|
||||
_ResetInstaller()
|
||||
|
||||
with utils.RestoreCurrentWindow():
|
||||
vim.command( f'botright { settings.Int( "bottombar_height", 10 ) }new' )
|
||||
win = vim.current.window
|
||||
OUTPUT_VIEW = output.OutputView( win, api_prefix )
|
||||
|
||||
cmd = [
|
||||
PathToAnyWorkingPython3(),
|
||||
'-u',
|
||||
os.path.join( vimspector_home, 'install_gadget.py' ),
|
||||
'--quiet',
|
||||
'--update-gadget-config',
|
||||
]
|
||||
if not vimspector_base_dir == vimspector_home:
|
||||
cmd.extend( [ '--basedir', vimspector_base_dir ] )
|
||||
cmd.extend( args )
|
||||
|
||||
def handler( exit_code ):
|
||||
if exit_code == 0:
|
||||
_ResetInstaller()
|
||||
utils.UserMessage( "Vimspector gadget installation complete!" )
|
||||
vim.command( 'silent doautocmd User VimspectorInstallSuccess' )
|
||||
if 'then' in kwargs:
|
||||
kwargs[ 'then' ]()
|
||||
else:
|
||||
utils.UserMessage( 'Vimspector gadget installation reported errors',
|
||||
error = True )
|
||||
vim.command( 'silent doautocmd User VimspectorInstallFailed' )
|
||||
|
||||
|
||||
OUTPUT_VIEW.RunJobWithOutput( 'Installer',
|
||||
cmd,
|
||||
completion_handler = handler,
|
||||
syntax = 'vimspector-installer' )
|
||||
OUTPUT_VIEW.ShowOutput( 'Installer' )
|
||||
|
||||
|
||||
def RunUpdate( api_prefix, *args ):
|
||||
from vimspector import utils
|
||||
Configure( vimspector_base = utils.GetVimspectorBase() )
|
||||
|
||||
args = list( args )
|
||||
current_adapters = ReadAdapters( read_existing = True )
|
||||
for adapter_name in current_adapters.keys():
|
||||
args.extend( FindGadgetForAdapter( adapter_name ) )
|
||||
|
||||
if args:
|
||||
RunInstaller( api_prefix, *args )
|
||||
|
||||
|
||||
def _ResetInstaller():
|
||||
global OUTPUT_VIEW
|
||||
if OUTPUT_VIEW:
|
||||
OUTPUT_VIEW.Reset()
|
||||
OUTPUT_VIEW = None
|
||||
|
||||
|
||||
def Abort():
|
||||
_ResetInstaller()
|
||||
from vimspector import utils
|
||||
utils.UserMessage( 'Vimspector installation aborted',
|
||||
persist = True,
|
||||
error = True )
|
||||
|
||||
|
||||
def GadgetListToInstallerArgs( *gadget_list ):
|
||||
installer_args = []
|
||||
for name in gadget_list:
|
||||
if name.startswith( '-' ):
|
||||
installer_args.append( name )
|
||||
continue
|
||||
|
||||
try:
|
||||
gadget = gadgets.GADGETS[ name ]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
if not gadget.get( 'enabled', True ):
|
||||
installer_args.append( f'--force-enable-{ gadget[ "language" ] }' )
|
||||
else:
|
||||
installer_args.append( f'--enable-{ gadget[ "language" ] }' )
|
||||
|
||||
return installer_args
|
||||
|
||||
|
||||
def FindGadgetForAdapter( adapter_name ):
|
||||
candidates = []
|
||||
for name, gadget in gadgets.GADGETS.items():
|
||||
v = {}
|
||||
v.update( gadget.get( 'all', {} ) )
|
||||
v.update( gadget.get( install.GetOS(), {} ) )
|
||||
|
||||
adapters = {}
|
||||
adapters.update( v.get( 'adapters', {} ) )
|
||||
adapters.update( gadget.get( 'adapters', {} ) )
|
||||
|
||||
if adapter_name in adapters:
|
||||
candidates.append( name )
|
||||
|
||||
return candidates
|
||||
|
||||
|
||||
def InstallGeneric( name, root, gadget ):
|
||||
extension = os.path.join( root, 'extension' )
|
||||
for f in gadget.get( 'make_executable', [] ):
|
||||
MakeExecutable( os.path.join( extension, f ) )
|
||||
|
||||
MakeExtensionSymlink( name, root )
|
||||
|
||||
|
||||
def InstallCppTools( name, root, gadget ):
|
||||
extension = os.path.join( root, 'extension' )
|
||||
|
||||
# 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' ) )
|
||||
with open( os.path.join( extension, 'package.json' ) ) as f:
|
||||
package = json.load( f )
|
||||
runtime_dependencies = package[ 'runtimeDependencies' ]
|
||||
for dependency in runtime_dependencies:
|
||||
for binary in dependency.get( 'binaries' ):
|
||||
file_path = os.path.abspath( os.path.join( extension, binary ) )
|
||||
if os.path.exists( file_path ):
|
||||
MakeExecutable( os.path.join( extension, binary ) )
|
||||
|
||||
MakeExtensionSymlink( name, root )
|
||||
|
||||
|
||||
def InstallBashDebug( name, root, gadget ):
|
||||
MakeExecutable( os.path.join( root,
|
||||
'extension',
|
||||
'bashdb_dir',
|
||||
'bashdb' ) )
|
||||
MakeExtensionSymlink( name, root )
|
||||
|
||||
|
||||
def InstallDebugpy( name, root, gadget ):
|
||||
wd = os.getcwd()
|
||||
root = os.path.join( root, 'debugpy-{}'.format( gadget[ 'version' ] ) )
|
||||
os.chdir( root )
|
||||
try:
|
||||
CheckCall( [ sys.executable, 'setup.py', 'build' ] )
|
||||
finally:
|
||||
os.chdir( wd )
|
||||
|
||||
MakeSymlink( name, root )
|
||||
|
||||
|
||||
def InstallTclProDebug( name, root, gadget ):
|
||||
configure = [ './configure' ]
|
||||
|
||||
if install.GetOS() == 'macos':
|
||||
# Apple removed the headers from system frameworks because they are
|
||||
# determined to make life difficult. And the TCL configure scripts are super
|
||||
# old so don't know about this. So we do their job for them and try and find
|
||||
# a tclConfig.sh.
|
||||
#
|
||||
# NOTE however that in Apple's infinite wisdom, installing the "headers" in
|
||||
# the other location is actually broken because the paths in the
|
||||
# tclConfig.sh are pointing at the _old_ location. You actually do have to
|
||||
# run the package installation which puts the headers back in order to work.
|
||||
# This is why the below list is does not contain stuff from
|
||||
# /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform
|
||||
# '/Applications/Xcode.app/Contents/Developer/Platforms'
|
||||
# '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System'
|
||||
# '/Library/Frameworks/Tcl.framework',
|
||||
# '/Applications/Xcode.app/Contents/Developer/Platforms'
|
||||
# '/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System'
|
||||
# '/Library/Frameworks/Tcl.framework/Versions'
|
||||
# '/Current',
|
||||
for p in [ '/usr/local/opt/tcl-tk/lib' ]:
|
||||
if os.path.exists( os.path.join( p, 'tclConfig.sh' ) ):
|
||||
configure.append( '--with-tcl=' + p )
|
||||
break
|
||||
|
||||
|
||||
with CurrentWorkingDir( os.path.join( root, 'lib', 'tclparser' ) ):
|
||||
CheckCall( configure )
|
||||
CheckCall( [ 'make' ] )
|
||||
|
||||
MakeSymlink( name, root )
|
||||
|
||||
|
||||
def InstallNodeDebug( name, root, gadget ):
|
||||
node_version = subprocess.check_output( [ 'node', '--version' ],
|
||||
universal_newlines=True ).strip()
|
||||
Print( "Node.js version: {}".format( node_version ) )
|
||||
if list( map( int, node_version[ 1: ].split( '.' ) ) ) >= [ 12, 0, 0 ]:
|
||||
Print( "Can't install vscode-debug-node2:" )
|
||||
Print( "Sorry, you appear to be running node 12 or later. That's not "
|
||||
"compatible with the build system for this extension, and as far as "
|
||||
"we know, there isn't a pre-built independent package." )
|
||||
Print( "My advice is to install nvm, then do:" )
|
||||
Print( " $ nvm install --lts 10" )
|
||||
Print( " $ nvm use --lts 10" )
|
||||
Print( " $ ./install_gadget.py --enable-node ..." )
|
||||
raise RuntimeError( 'Node 10 is required to install node debugger (sadly)' )
|
||||
|
||||
with CurrentWorkingDir( root ):
|
||||
CheckCall( [ 'npm', 'install' ] )
|
||||
CheckCall( [ 'npm', 'run', 'build' ] )
|
||||
MakeSymlink( name, root )
|
||||
|
||||
|
||||
def InstallGagdet( name, gadget, succeeded, failed, all_adapters ):
|
||||
try:
|
||||
print( f"Installing {name}..." )
|
||||
v = {}
|
||||
v.update( gadget.get( 'all', {} ) )
|
||||
v.update( gadget.get( install.GetOS(), {} ) )
|
||||
|
||||
if 'download' in gadget:
|
||||
if 'file_name' not in v:
|
||||
raise RuntimeError( "Unsupported OS {} for gadget {}".format(
|
||||
install.GetOS(),
|
||||
name ) )
|
||||
|
||||
destination = os.path.join(
|
||||
install.GetGadgetDir( options.vimspector_base ),
|
||||
'download',
|
||||
name,
|
||||
v[ 'version' ] )
|
||||
|
||||
url = string.Template( gadget[ 'download' ][ 'url' ] ).substitute( v )
|
||||
|
||||
file_path = DownloadFileTo(
|
||||
url,
|
||||
destination,
|
||||
file_name = gadget[ 'download' ].get( 'target' ),
|
||||
checksum = v.get( 'checksum' ),
|
||||
check_certificate = not options.no_check_certificate )
|
||||
|
||||
root = os.path.join( destination, 'root' )
|
||||
ExtractZipTo(
|
||||
file_path,
|
||||
root,
|
||||
format = gadget[ 'download' ].get( 'format', 'zip' ) )
|
||||
elif 'repo' in gadget:
|
||||
url = string.Template( gadget[ 'repo' ][ 'url' ] ).substitute( v )
|
||||
ref = string.Template( gadget[ 'repo' ][ 'ref' ] ).substitute( v )
|
||||
|
||||
destination = os.path.join(
|
||||
install.GetGadgetDir( options.vimspector_base ),
|
||||
'download',
|
||||
name )
|
||||
CloneRepoTo( url, ref, destination )
|
||||
root = destination
|
||||
|
||||
if 'do' in gadget:
|
||||
gadget[ 'do' ]( name, root, v )
|
||||
else:
|
||||
InstallGeneric( name, root, v )
|
||||
|
||||
# Allow per-OS adapter overrides. v already did that for us...
|
||||
all_adapters.update( v.get( 'adapters', {} ) )
|
||||
# Add any other "all" adapters
|
||||
all_adapters.update( gadget.get( 'adapters', {} ) )
|
||||
|
||||
succeeded.append( name )
|
||||
print( f" - Done installing {name}" )
|
||||
except Exception as e:
|
||||
if not options.quiet:
|
||||
traceback.print_exc()
|
||||
failed.append( name )
|
||||
print( f" - FAILED installing {name}: {e}".format( name, e ) )
|
||||
|
||||
|
||||
def ReadAdapters( read_existing = True ):
|
||||
all_adapters = {}
|
||||
if read_existing:
|
||||
try:
|
||||
with open( install.GetGadgetConfigFile( options.vimspector_base ),
|
||||
'r' ) as f:
|
||||
all_adapters = json.load( f ).get( 'adapters', {} )
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# Include "built-in" adapter for multi-session mode
|
||||
all_adapters.update( {
|
||||
'multi-session': {
|
||||
'port': '${port}',
|
||||
'host': '${host}'
|
||||
},
|
||||
} )
|
||||
|
||||
return all_adapters
|
||||
|
||||
|
||||
def WriteAdapters( all_adapters, to_file=None ):
|
||||
adapter_config = json.dumps ( { 'adapters': all_adapters },
|
||||
indent=2,
|
||||
sort_keys=True )
|
||||
|
||||
if to_file:
|
||||
to_file.write( adapter_config )
|
||||
else:
|
||||
with open( install.GetGadgetConfigFile( options.vimspector_base ),
|
||||
'w' ) as f:
|
||||
f.write( adapter_config )
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
|
|
@ -45,7 +421,7 @@ def CurrentWorkingDir( d ):
|
|||
|
||||
def MakeExecutable( file_path ):
|
||||
# TODO: import stat and use them by _just_ adding the X bit.
|
||||
print( 'Making executable: {}'.format( file_path ) )
|
||||
Print( 'Making executable: {}'.format( file_path ) )
|
||||
os.chmod( file_path, 0o755 )
|
||||
|
||||
|
||||
|
|
@ -62,7 +438,7 @@ def WithRetry( f ):
|
|||
return f( *args, **kwargs )
|
||||
except Exception as e:
|
||||
thrown = e
|
||||
print( "Failed - {}, will retry in {} seconds".format( e, timeout ) )
|
||||
Print( "Failed - {}, will retry in {} seconds".format( e, timeout ) )
|
||||
time.sleep( timeout )
|
||||
raise thrown
|
||||
|
||||
|
|
@ -90,13 +466,13 @@ def DownloadFileTo( url,
|
|||
if os.path.exists( file_path ):
|
||||
if checksum:
|
||||
if ValidateCheckSumSHA256( file_path, checksum ):
|
||||
print( "Checksum matches for {}, using it".format( file_path ) )
|
||||
Print( "Checksum matches for {}, using it".format( file_path ) )
|
||||
return file_path
|
||||
else:
|
||||
print( "Checksum doesn't match for {}, removing it".format(
|
||||
Print( "Checksum doesn't match for {}, removing it".format(
|
||||
file_path ) )
|
||||
|
||||
print( "Removing existing {}".format( file_path ) )
|
||||
Print( "Removing existing {}".format( file_path ) )
|
||||
os.remove( file_path )
|
||||
|
||||
r = request.Request( url, headers = { 'User-Agent': 'Vimspector' } )
|
||||
|
|
@ -123,7 +499,7 @@ def DownloadFileTo( url,
|
|||
GetChecksumSHA254( file_path ),
|
||||
checksum ) )
|
||||
else:
|
||||
print( "Checksum for {}: {}".format( file_path,
|
||||
Print( "Checksum for {}: {}".format( file_path,
|
||||
GetChecksumSHA254( file_path ) ) )
|
||||
|
||||
return file_path
|
||||
|
|
@ -141,7 +517,7 @@ def ValidateCheckSumSHA256( file_path, checksum ):
|
|||
|
||||
def RemoveIfExists( destination ):
|
||||
if os.path.islink( destination ):
|
||||
print( "Removing file {}".format( destination ) )
|
||||
Print( "Removing file {}".format( destination ) )
|
||||
os.remove( destination )
|
||||
return
|
||||
|
||||
|
|
@ -152,21 +528,21 @@ def RemoveIfExists( destination ):
|
|||
return "{}.{}".format( destination, N )
|
||||
|
||||
while os.path.isdir( BackupDir() ):
|
||||
print( "Removing old dir {}".format( BackupDir() ) )
|
||||
Print( "Removing old dir {}".format( BackupDir() ) )
|
||||
try:
|
||||
shutil.rmtree( BackupDir() )
|
||||
print ( "OK, removed it" )
|
||||
Print ( "OK, removed it" )
|
||||
break
|
||||
except OSError:
|
||||
print ( "FAILED" )
|
||||
Print ( "FAILED" )
|
||||
N = N + 1
|
||||
|
||||
if os.path.exists( destination ):
|
||||
print( "Removing dir {}".format( destination ) )
|
||||
Print( "Removing dir {}".format( destination ) )
|
||||
try:
|
||||
shutil.rmtree( destination )
|
||||
except OSError:
|
||||
print( "FAILED, moving {} to dir {}".format( destination, BackupDir() ) )
|
||||
Print( "FAILED, moving {} to dir {}".format( destination, BackupDir() ) )
|
||||
os.rename( destination, BackupDir() )
|
||||
|
||||
|
||||
|
|
@ -187,7 +563,7 @@ class ModePreservingZipFile( zipfile.ZipFile ):
|
|||
|
||||
|
||||
def ExtractZipTo( file_path, destination, format ):
|
||||
print( "Extracting {} to {}".format( file_path, destination ) )
|
||||
Print( "Extracting {} to {}".format( file_path, destination ) )
|
||||
RemoveIfExists( destination )
|
||||
|
||||
if format == 'zip':
|
||||
|
|
@ -209,17 +585,17 @@ def ExtractZipTo( file_path, destination, format ):
|
|||
# windows-generated tar files
|
||||
os.makedirs( destination )
|
||||
with CurrentWorkingDir( destination ):
|
||||
subprocess.check_call( [ 'tar', 'zxvf', file_path ] )
|
||||
CheckCall( [ 'tar', 'zxvf', file_path ] )
|
||||
|
||||
|
||||
def MakeExtensionSymlink( vimspector_base, name, root ):
|
||||
MakeSymlink( install.GetGadgetDir( vimspector_base,
|
||||
install.GetOS() ),
|
||||
name,
|
||||
os.path.join( root, 'extension' ) ),
|
||||
def MakeExtensionSymlink( name, root ):
|
||||
MakeSymlink( name, os.path.join( root, 'extension' ) ),
|
||||
|
||||
|
||||
def MakeSymlink( in_folder, link, pointing_to ):
|
||||
def MakeSymlink( link, pointing_to, in_folder = None ):
|
||||
if not in_folder:
|
||||
in_folder = install.GetGadgetDir( options.vimspector_base )
|
||||
|
||||
RemoveIfExists( os.path.join( in_folder, link ) )
|
||||
|
||||
in_folder = os.path.abspath( in_folder )
|
||||
|
|
@ -233,12 +609,7 @@ def MakeSymlink( in_folder, link, pointing_to ):
|
|||
link_path = os.path.abspath( link_path )
|
||||
if os.path.isdir( link_path ):
|
||||
os.rmdir( link_path )
|
||||
subprocess.check_call( [ 'cmd.exe',
|
||||
'/c',
|
||||
'mklink',
|
||||
'/J',
|
||||
link_path,
|
||||
pointing_to ] )
|
||||
CheckCall( [ 'cmd.exe', '/c', 'mklink', '/J', link_path, pointing_to ] )
|
||||
else:
|
||||
os.symlink( pointing_to_relative, link_path )
|
||||
|
||||
|
|
@ -246,13 +617,10 @@ def MakeSymlink( in_folder, link, pointing_to ):
|
|||
def CloneRepoTo( url, ref, destination ):
|
||||
RemoveIfExists( destination )
|
||||
git_in_repo = [ 'git', '-C', destination ]
|
||||
subprocess.check_call( [ 'git', 'clone', url, destination ] )
|
||||
subprocess.check_call( git_in_repo + [ 'checkout', ref ] )
|
||||
subprocess.check_call( git_in_repo + [ 'submodule', 'sync', '--recursive' ] )
|
||||
subprocess.check_call( git_in_repo + [ 'submodule',
|
||||
'update',
|
||||
'--init',
|
||||
'--recursive' ] )
|
||||
CheckCall( [ 'git', 'clone', url, destination ] )
|
||||
CheckCall( git_in_repo + [ 'checkout', ref ] )
|
||||
CheckCall( git_in_repo + [ 'submodule', 'sync', '--recursive' ] )
|
||||
CheckCall( git_in_repo + [ 'submodule', 'update', '--init', '--recursive' ] )
|
||||
|
||||
|
||||
def AbortIfSUperUser( force_sudo ):
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class TabBuffer( object ):
|
|||
self.index = index
|
||||
self.flag = False
|
||||
self.is_job = False
|
||||
self.job_category = None
|
||||
self.syntax = None
|
||||
|
||||
|
||||
BUFFER_MAP = {
|
||||
|
|
@ -40,18 +40,26 @@ def CategoryToBuffer( category ):
|
|||
return BUFFER_MAP.get( category, category )
|
||||
|
||||
|
||||
VIEWS = set()
|
||||
|
||||
|
||||
def ShowOutputInWindow( win_id, category ):
|
||||
for view in VIEWS:
|
||||
if view._window.valid and utils.WindowID( view._window ) == win_id:
|
||||
view.ShowOutput( category )
|
||||
return
|
||||
|
||||
raise ValueError( f'Unable to find output object for win id {win_id}!' )
|
||||
|
||||
|
||||
class OutputView( object ):
|
||||
def __init__( self, connection, window, api_prefix ):
|
||||
"""Container for a 'tabbed' window of buffers that can be used to display
|
||||
files or the output of commands."""
|
||||
def __init__( self, window, api_prefix ):
|
||||
self._window = window
|
||||
self._connection = connection
|
||||
self._buffers = {}
|
||||
self._api_prefix = api_prefix
|
||||
|
||||
for b in set( BUFFER_MAP.values() ):
|
||||
self._CreateBuffer( b )
|
||||
|
||||
self._CreateBuffer( 'Vimspector', file_name = utils.LOG_FILE )
|
||||
self._ShowOutput( 'Console' )
|
||||
VIEWS.add( self )
|
||||
|
||||
def Print( self, categroy, text ):
|
||||
self._Print( 'server', text.splitlines() )
|
||||
|
|
@ -82,21 +90,15 @@ class OutputView( object ):
|
|||
with utils.RestoreCurrentBuffer( self._window ):
|
||||
self._ShowOutput( category )
|
||||
|
||||
def ConnectionUp( self, connection ):
|
||||
self._connection = connection
|
||||
|
||||
def ConnectionClosed( self ):
|
||||
# Don't clear because output is probably still useful
|
||||
self._connection = None
|
||||
|
||||
def Reset( self ):
|
||||
self.Clear()
|
||||
VIEWS.remove( self )
|
||||
|
||||
|
||||
def Clear( self ):
|
||||
for category, tab_buffer in self._buffers.items():
|
||||
if tab_buffer.is_job:
|
||||
utils.CleanUpCommand( tab_buffer.job_category or category,
|
||||
self._api_prefix )
|
||||
utils.CleanUpCommand( category, self._api_prefix )
|
||||
utils.CleanUpHiddenBuffer( tab_buffer.buf )
|
||||
|
||||
# FIXME: nunmenu the WinBar ?
|
||||
|
|
@ -125,6 +127,115 @@ class OutputView( object ):
|
|||
self._ToggleFlag( category, False )
|
||||
self._ShowOutput( category )
|
||||
|
||||
def _ToggleFlag( self, category, flag ):
|
||||
if self._buffers[ category ].flag != flag:
|
||||
self._buffers[ category ].flag = flag
|
||||
|
||||
if self._window.valid:
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
self._RenderWinBar( category )
|
||||
|
||||
|
||||
def RunJobWithOutput( self, category, cmd, **kwargs ):
|
||||
self._CreateBuffer( category, cmd = cmd, **kwargs )
|
||||
|
||||
|
||||
def _CreateBuffer( self,
|
||||
category,
|
||||
file_name = None,
|
||||
cmd = None,
|
||||
completion_handler = None,
|
||||
syntax = None ):
|
||||
if file_name is not None:
|
||||
assert cmd is None
|
||||
if install.GetOS() == "windows":
|
||||
# FIXME: Can't display fiels in windows (yet?)
|
||||
return
|
||||
|
||||
cmd = [ 'tail', '-F', '-n', '+1', '--', file_name ]
|
||||
|
||||
if cmd is not None:
|
||||
out = utils.SetUpCommandBuffer(
|
||||
cmd,
|
||||
category,
|
||||
self._api_prefix,
|
||||
completion_handler = completion_handler )
|
||||
self._buffers[ category ] = TabBuffer( out, len( self._buffers ) )
|
||||
self._buffers[ category ].is_job = True
|
||||
self._RenderWinBar( category )
|
||||
else:
|
||||
if category == 'Console':
|
||||
name = 'vimspector.Console'
|
||||
else:
|
||||
name = 'vimspector.Output:{0}'.format( category )
|
||||
|
||||
tab_buffer = TabBuffer( utils.NewEmptyBuffer(), len( self._buffers ) )
|
||||
self._buffers[ category ] = tab_buffer
|
||||
|
||||
if category == 'Console':
|
||||
utils.SetUpPromptBuffer( tab_buffer.buf,
|
||||
name,
|
||||
'> ',
|
||||
'vimspector#EvaluateConsole' )
|
||||
else:
|
||||
utils.SetUpHiddenBuffer( tab_buffer.buf, name )
|
||||
|
||||
self._RenderWinBar( category )
|
||||
|
||||
self._buffers[ category ].syntax = utils.SetSyntax(
|
||||
self._buffers[ category ].syntax,
|
||||
syntax,
|
||||
self._buffers[ category ].buf )
|
||||
|
||||
|
||||
def _RenderWinBar( self, category ):
|
||||
if not self._window.valid:
|
||||
return
|
||||
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
tab_buffer = self._buffers[ category ]
|
||||
|
||||
try:
|
||||
if tab_buffer.flag:
|
||||
vim.command( 'nunmenu WinBar.{}'.format( utils.Escape( category ) ) )
|
||||
else:
|
||||
vim.command( 'nunmenu WinBar.{}*'.format( utils.Escape( category ) ) )
|
||||
except vim.error as e:
|
||||
# E329 means the menu doesn't exist; ignore that.
|
||||
if 'E329' not in str( e ):
|
||||
raise
|
||||
|
||||
vim.command(
|
||||
"nnoremenu 1.{0} WinBar.{1}{2} "
|
||||
":call vimspector#ShowOutputInWindow( {3}, '{1}' )<CR>".format(
|
||||
tab_buffer.index,
|
||||
utils.Escape( category ),
|
||||
'*' if tab_buffer.flag else '',
|
||||
utils.WindowID( self._window ) ) )
|
||||
|
||||
def GetCategories( self ):
|
||||
return list( self._buffers.keys() )
|
||||
|
||||
|
||||
class DAPOutputView( OutputView ):
|
||||
"""Specialised OutputView which adds the DAP Console (REPL)"""
|
||||
def __init__( self, *args ):
|
||||
super().__init__( *args )
|
||||
|
||||
self._connection = None
|
||||
for b in set( BUFFER_MAP.values() ):
|
||||
self._CreateBuffer( b )
|
||||
|
||||
self._CreateBuffer( 'Vimspector', file_name = utils.LOG_FILE )
|
||||
self._ShowOutput( 'Console' )
|
||||
|
||||
def ConnectionUp( self, connection ):
|
||||
self._connection = connection
|
||||
|
||||
def ConnectionClosed( self ):
|
||||
# Don't clear because output is probably still useful
|
||||
self._connection = None
|
||||
|
||||
def Evaluate( self, frame, expression ):
|
||||
self._Print( 'Console', [ 'Evaluating: ' + expression ] )
|
||||
|
||||
|
|
@ -146,82 +257,3 @@ class OutputView( object ):
|
|||
request[ 'arguments' ][ 'frameId' ] = frame[ 'id' ]
|
||||
|
||||
self._connection.DoRequest( print_result, request )
|
||||
|
||||
def _ToggleFlag( self, category, flag ):
|
||||
if self._buffers[ category ].flag != flag:
|
||||
self._buffers[ category ].flag = flag
|
||||
|
||||
if self._window.valid:
|
||||
with utils.LetCurrentWindow( self._window ):
|
||||
self._RenderWinBar( category )
|
||||
|
||||
|
||||
def RunJobWithOutput( self, category, cmd ):
|
||||
self._CreateBuffer( category, cmd = cmd )
|
||||
|
||||
|
||||
def _CreateBuffer( self, category, file_name = None, cmd = None ):
|
||||
win = self._window
|
||||
if not win.valid:
|
||||
# We need to borrow the current window
|
||||
win = vim.current.window
|
||||
|
||||
with utils.LetCurrentWindow( win ):
|
||||
with utils.RestoreCurrentBuffer( win ):
|
||||
|
||||
if file_name is not None:
|
||||
assert cmd is None
|
||||
if install.GetOS() == "windows":
|
||||
# FIXME: Can't display fiels in windows (yet?)
|
||||
return
|
||||
|
||||
cmd = [ 'tail', '-F', '-n', '+1', '--', file_name ]
|
||||
|
||||
if cmd is not None:
|
||||
out, err = utils.SetUpCommandBuffer( cmd, category, self._api_prefix )
|
||||
self._buffers[ category + '-out' ] = TabBuffer( out,
|
||||
len( self._buffers ) )
|
||||
self._buffers[ category + '-out' ].is_job = True
|
||||
self._buffers[ category + '-out' ].job_category = category
|
||||
self._buffers[ category + '-err' ] = TabBuffer( err,
|
||||
len( self._buffers ) )
|
||||
self._buffers[ category + '-err' ].is_job = False
|
||||
self._RenderWinBar( category + '-out' )
|
||||
self._RenderWinBar( category + '-err' )
|
||||
else:
|
||||
vim.command( 'enew' )
|
||||
tab_buffer = TabBuffer( vim.current.buffer, len( self._buffers ) )
|
||||
self._buffers[ category ] = tab_buffer
|
||||
if category == 'Console':
|
||||
utils.SetUpPromptBuffer( tab_buffer.buf,
|
||||
'vimspector.Console',
|
||||
'> ',
|
||||
'vimspector#EvaluateConsole' )
|
||||
else:
|
||||
utils.SetUpHiddenBuffer(
|
||||
tab_buffer.buf,
|
||||
'vimspector.Output:{0}'.format( category ) )
|
||||
|
||||
self._RenderWinBar( category )
|
||||
|
||||
def _RenderWinBar( self, category ):
|
||||
tab_buffer = self._buffers[ category ]
|
||||
|
||||
try:
|
||||
if tab_buffer.flag:
|
||||
vim.command( 'nunmenu WinBar.{}'.format( utils.Escape( category ) ) )
|
||||
else:
|
||||
vim.command( 'nunmenu WinBar.{}*'.format( utils.Escape( category ) ) )
|
||||
except vim.error as e:
|
||||
# E329 means the menu doesn't exist; ignore that.
|
||||
if 'E329' not in str( e ):
|
||||
raise
|
||||
|
||||
vim.command( "nnoremenu 1.{0} WinBar.{1}{2} "
|
||||
":call vimspector#ShowOutput( '{1}' )<CR>".format(
|
||||
tab_buffer.index,
|
||||
utils.Escape( category ),
|
||||
'*' if tab_buffer.flag else '' ) )
|
||||
|
||||
def GetCategories( self ):
|
||||
return list( self._buffers.keys() )
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ from vimspector import utils
|
|||
|
||||
|
||||
class StackTraceView( object ):
|
||||
def __init__( self, session, connection, win ):
|
||||
def __init__( self, session, win ):
|
||||
self._logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( self._logger )
|
||||
|
||||
self._buf = win.buffer
|
||||
self._session = session
|
||||
self._connection = connection
|
||||
self._connection = None
|
||||
|
||||
self._current_thread = None
|
||||
self._current_frame = None
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ def BufferForFile( file_name ):
|
|||
return vim.buffers[ BufferNumberForFile( file_name ) ]
|
||||
|
||||
|
||||
def NewEmptyBuffer():
|
||||
bufnr = int( vim.eval( 'bufadd("")' ) )
|
||||
Call( 'bufload', bufnr )
|
||||
return vim.buffers[ bufnr ]
|
||||
|
||||
|
||||
def WindowForBuffer( buf ):
|
||||
for w in vim.current.tabpage.windows:
|
||||
if w.buffer == buf:
|
||||
|
|
@ -71,21 +77,30 @@ def OpenFileInCurrentWindow( file_name ):
|
|||
return vim.buffers[ buffer_number ]
|
||||
|
||||
|
||||
def SetUpCommandBuffer( cmd, name, api_prefix ):
|
||||
bufs = vim.eval(
|
||||
'vimspector#internal#{}job#StartCommandWithLog( {}, "{}" )'.format(
|
||||
api_prefix,
|
||||
json.dumps( cmd ),
|
||||
name ) )
|
||||
COMMAND_HANDLERS = {}
|
||||
|
||||
if bufs is None:
|
||||
|
||||
def OnCommandWithLogComplete( name, exit_code ):
|
||||
cb = COMMAND_HANDLERS.get( name )
|
||||
if cb:
|
||||
cb( exit_code )
|
||||
|
||||
|
||||
def SetUpCommandBuffer( cmd, name, api_prefix, completion_handler = None ):
|
||||
COMMAND_HANDLERS[ name ] = completion_handler
|
||||
|
||||
buf = Call( f'vimspector#internal#{api_prefix}job#StartCommandWithLog',
|
||||
cmd,
|
||||
name )
|
||||
|
||||
if buf is None:
|
||||
raise RuntimeError( "Unable to start job {}: {}".format( cmd, name ) )
|
||||
elif not all( int( b ) > 0 for b in bufs ):
|
||||
elif int( buf ) <= 0:
|
||||
raise RuntimeError( "Unable to get all streams for job {}: {}".format(
|
||||
name,
|
||||
cmd ) )
|
||||
|
||||
return [ vim.buffers[ int( b ) ] for b in bufs ]
|
||||
return vim.buffers[ int( buf ) ]
|
||||
|
||||
|
||||
def CleanUpCommand( name, api_prefix ):
|
||||
|
|
@ -184,9 +199,8 @@ def RestoreCurrentWindow():
|
|||
try:
|
||||
yield
|
||||
finally:
|
||||
if old_tabpage.valid:
|
||||
if old_tabpage.valid and old_window.valid:
|
||||
vim.current.tabpage = old_tabpage
|
||||
if old_window.valid:
|
||||
vim.current.window = old_window
|
||||
|
||||
|
||||
|
|
@ -343,6 +357,7 @@ def AskForInput( prompt, default_value = None ):
|
|||
|
||||
|
||||
def AppendToBuffer( buf, line_or_lines, modified=False ):
|
||||
line = 1
|
||||
try:
|
||||
# After clearing the buffer (using buf[:] = None) there is always a single
|
||||
# empty line in the buffer object and no "is empty" method.
|
||||
|
|
@ -558,7 +573,6 @@ def Call( vimscript_function, *args ):
|
|||
call += 'g:' + arg_name
|
||||
|
||||
call += ')'
|
||||
_logger.debug( 'Calling: {}'.format( call ) )
|
||||
return vim.eval( call )
|
||||
|
||||
|
||||
|
|
@ -605,8 +619,7 @@ def SetSyntax( current_syntax, syntax, *args ):
|
|||
# doesn't actually trigger the Syntax autocommand, and i'm not sure that
|
||||
# 'doautocmd Syntax' is the right solution or not
|
||||
for buf in args:
|
||||
with AnyWindowForBuffer( buf ):
|
||||
vim.command( 'set syntax={}'.format( Escape( syntax ) ) )
|
||||
Call( 'setbufvar', buf.number, '&syntax', syntax )
|
||||
|
||||
return syntax
|
||||
|
||||
|
|
@ -633,16 +646,26 @@ def HideSplash( api_prefix, splash ):
|
|||
return None
|
||||
|
||||
|
||||
def GetVimString( vim_dict, name, default=None ):
|
||||
|
||||
# FIXME: use 'encoding' ?
|
||||
try:
|
||||
value = vim_dict[ name ]
|
||||
except KeyError:
|
||||
return default
|
||||
|
||||
if isinstance( value, bytes ):
|
||||
return value.decode( 'utf-8' )
|
||||
return value
|
||||
|
||||
|
||||
def GetVimspectorBase():
|
||||
base = vim.vars.get( 'vimspector_base_dir' )
|
||||
if base is None:
|
||||
return os.path.abspath( os.path.join( os.path.dirname( __file__ ),
|
||||
'..',
|
||||
'..' ) )
|
||||
elif isinstance( base, bytes ):
|
||||
return base.decode( 'utf-8' )
|
||||
else:
|
||||
return base
|
||||
return GetVimString( vim.vars,
|
||||
'vimspector_base_dir',
|
||||
os.path.abspath(
|
||||
os.path.join( os.path.dirname( __file__ ),
|
||||
'..',
|
||||
'..' ) ) )
|
||||
|
||||
|
||||
def GetUnusedLocalPort():
|
||||
|
|
@ -655,5 +678,7 @@ def GetUnusedLocalPort():
|
|||
return port
|
||||
|
||||
|
||||
def WindowID( window, tab ):
|
||||
def WindowID( window, tab=None ):
|
||||
if tab is None:
|
||||
tab = window.tabpage
|
||||
return int( Call( 'win_getid', window.number, tab.number ) )
|
||||
|
|
|
|||
|
|
@ -124,11 +124,11 @@ class View:
|
|||
|
||||
|
||||
class VariablesView( object ):
|
||||
def __init__( self, connection, variables_win, watches_win ):
|
||||
def __init__( self, variables_win, watches_win ):
|
||||
self._logger = logging.getLogger( __name__ )
|
||||
utils.SetUpLogging( self._logger )
|
||||
|
||||
self._connection = connection
|
||||
self._connection = None
|
||||
self._current_syntax = ''
|
||||
|
||||
# Set up the "Variables" buffer in the variables_win
|
||||
|
|
|
|||
40
run_tests
40
run_tests
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
BASEDIR=$(dirname $0)
|
||||
INSTALL=0
|
||||
UPDATE=0
|
||||
RUN_VIM="vim -N --clean --not-a-term"
|
||||
RUN_TEST="${RUN_VIM} -S lib/run_test.vim"
|
||||
BASEDIR_CMD='py3 pass'
|
||||
|
|
@ -25,6 +26,15 @@ while [ -n "$1" ]; do
|
|||
INSTALL=1
|
||||
shift
|
||||
;;
|
||||
"--install-method")
|
||||
shift
|
||||
INSTALL=$1
|
||||
shift
|
||||
;;
|
||||
"--update")
|
||||
UPDATE=1
|
||||
shift
|
||||
;;
|
||||
"--report")
|
||||
shift
|
||||
VIMSPECTOR_TEST_STDOUT=$1
|
||||
|
|
@ -71,10 +81,36 @@ if [ "${out_fd}" = "1" ]; then
|
|||
exec 3>&1
|
||||
fi
|
||||
|
||||
if [ $INSTALL = 1 ]; then
|
||||
python3 $(dirname $0)/install_gadget.py --basedir ${BASEDIR} --all
|
||||
if [ "$INSTALL" = "1" ] || [ "$INSTALL" = "script" ]; then
|
||||
if ! python3 $(dirname $0)/install_gadget.py --basedir ${BASEDIR} --all; then
|
||||
echo "Script installation reported errors" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$INSTALL" = "1" ] || [ "$INSTALL" = "vim" ]; then
|
||||
if ! $RUN_VIM -u $(dirname $0)/tests/vimrc \
|
||||
--cmd "${BASEDIR_CMD}" \
|
||||
-c 'autocmd User VimspectorInstallSuccess qa!' \
|
||||
-c 'autocmd User VimspectorInstallFailed cquit!' \
|
||||
-c "VimspectorInstall --all"; then
|
||||
echo "Vim installation reported errors" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$UPDATE" = "1" ]; then
|
||||
if ! $RUN_VIM -u $(dirname $0)/tests/vimrc \
|
||||
--cmd "${BASEDIR_CMD}" \
|
||||
-c 'autocmd User VimspectorInstallSuccess qa!' \
|
||||
-c 'autocmd User VimspectorInstallFailed cquit!' \
|
||||
-c "VimspectorUpdate"; then
|
||||
echo "Vim update reported errors" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ -z "$VIMSPECTOR_MIMODE" ]; then
|
||||
if which lldb >/dev/null 2>&1; then
|
||||
export VIMSPECTOR_MIMODE=lldb
|
||||
|
|
|
|||
13
syntax/vimspector-installer.vim
Normal file
13
syntax/vimspector-installer.vim
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
if exists( 'b:current_syntax' )
|
||||
finish
|
||||
endif
|
||||
|
||||
let b:current_syntax = 'vimspector-installer'
|
||||
|
||||
syn keyword VimspectorInstalling Installing
|
||||
syn keyword VimspectorDone Done
|
||||
syn keyword VimspectorError Failed FAILED
|
||||
|
||||
hi default link VimspectorInstalling Constant
|
||||
hi default link VimspectorDone DiffAdd
|
||||
hi default link VimspectorError WarningMsg
|
||||
Loading…
Add table
Add a link
Reference in a new issue