commit
d199aec8ba
6 changed files with 640 additions and 169 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -10,3 +10,5 @@ gadgets/
|
|||
package/
|
||||
*.pyc
|
||||
*.dSYM
|
||||
README.md.orig.*
|
||||
README.md.toc.*
|
||||
|
|
|
|||
480
README.md
480
README.md
|
|
@ -1,60 +1,291 @@
|
|||
# vimspector - A multi language graphical debugger for Vim
|
||||
|
||||
For a tutorial and usage overview, take a look at the
|
||||
[Vimspector website][website]
|
||||
|
||||
[](https://dev.azure.com/puremouron/Vimspector/_build/latest?definitionId=1&branchName=master)
|
||||
|
||||
# Status
|
||||
<!--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)
|
||||
* [Other languages](#other-languages)
|
||||
* [Installation](#installation)
|
||||
* [Dependencies](#dependencies)
|
||||
* [Language dependencies](#language-dependencies)
|
||||
* [Clone the plugin](#clone-the-plugin)
|
||||
* [Install some gadgets](#install-some-gadgets)
|
||||
* [Manual gadget installation](#manual-gadget-installation)
|
||||
* [The gadget directory](#the-gadget-directory)
|
||||
* [About](#about)
|
||||
* [Background](#background)
|
||||
* [Status](#status)
|
||||
* [Experimental](#experimental)
|
||||
* [Mappings](#mappings)
|
||||
* [Visual Studio / VSCode](#visual-studio--vscode)
|
||||
* [Human Mode](#human-mode)
|
||||
* [Usage](#usage)
|
||||
* [Launch and attach by PID:](#launch-and-attach-by-pid)
|
||||
* [Breakpoints](#breakpoints)
|
||||
* [Stepping](#stepping)
|
||||
* [Variables and scopes](#variables-and-scopes)
|
||||
* [Watches](#watches)
|
||||
* [Stack Traces](#stack-traces)
|
||||
* [Program Output:](#program-output)
|
||||
* [Console](#console)
|
||||
* [Debug adapter configuration](#debug-adapter-configuration)
|
||||
* [Supported Languages](#supported-languages-1)
|
||||
* [Partially supported](#partially-supported)
|
||||
* [Unsupported](#unsupported)
|
||||
* [FAQ](#faq)
|
||||
* [License](#license)
|
||||
|
||||
<!-- Added by: ben, at: Sun 19 May 2019 19:53:27 BST -->
|
||||
|
||||
<!--te-->
|
||||
|
||||
# Features and Usage
|
||||
|
||||
The plugin is a capable Vim graphical debugger for multiple languages.
|
||||
It's mostly tested for c++ and python, but in theory supports any
|
||||
language that Visual Studio Code supports (but see caveats).
|
||||
|
||||
It supports:
|
||||
The [Vimspector website][website] has an overview of the UI, along with basic
|
||||
instructions for configuration and setup.
|
||||
|
||||
- breakpoints (function and line)
|
||||
## Supported debugging features
|
||||
|
||||
- breakpoints (function, line and exception breakpoints)
|
||||
- step in/out/over/up, stop, restart
|
||||
- launch and attach
|
||||
- remote launch, remote attach
|
||||
- locals and globals display
|
||||
- watches (expressions)
|
||||
- watch expressions
|
||||
- call stack and navigation
|
||||
- variable value display hover
|
||||
- interractive debug console
|
||||
- interactive debug console
|
||||
- launch debugee within Vim's embedded terminal
|
||||
- logging/stdout display
|
||||
|
||||
The author successfully uses it for debugging Vim code and YouCompletMe's
|
||||
core engine `ycmd` (a complex python application).
|
||||
## Supported languages:
|
||||
|
||||
It should work for any debug adapter that works in VSCode, but there are
|
||||
certain limitations (see FAQ). There are some bugs certainly, and
|
||||
configuring it is a bit of a dark art at this stage.
|
||||
The following languages are used frequently by the author and are known to work
|
||||
with little effort, and are supported as first-class languages.
|
||||
|
||||
It is currently a work in progress, and any feedback/contributions are more
|
||||
than welcome.
|
||||
- C, C++, etc. (languages supported by gdb or lldb)
|
||||
- Python 2 and Python 3
|
||||
- TCL
|
||||
- Bash scripts
|
||||
|
||||
If you are insanely curious and wish to try it out, it's probably best to
|
||||
shout me in the [vimspector gitter channel][gitter]. I'd love to hear from
|
||||
you.
|
||||
## Languages known to work
|
||||
|
||||
In order to use it you have to currently:
|
||||
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:
|
||||
|
||||
- Write an undocumented configuration file that contains essentially
|
||||
undocumented parameters.
|
||||
- Use an undocumented API via things like `:call vimsepctor#Launch()`.
|
||||
- Accept that it isn't complete yet
|
||||
- etc.
|
||||
- Java (see caveats)
|
||||
|
||||
## Experimental
|
||||
## Other languages
|
||||
|
||||
The plugin is currently _experimental_. That means that any part of it
|
||||
can (and probably will) change, including things like:
|
||||
Vimspector should work for any debug adapter that works in Visual Studio Code,
|
||||
but there are certain limitations (see FAQ). If you're trying to get vimspector
|
||||
to work with a language that's not "supported", head over to Gitter and contact
|
||||
the author. It should be possible to get it going.
|
||||
|
||||
- breaking changes to the configuration
|
||||
- keys, layout, functionatlity of the UI
|
||||
# Installation
|
||||
|
||||
If a large number of people start using it then I will do my best to
|
||||
minimise this, or at least announce on Gitter.
|
||||
There are 2 installation methods:
|
||||
|
||||
# Background
|
||||
* Using a release tarball, or
|
||||
* Manually
|
||||
|
||||
Release tarballs come with debug adapters for the default languages
|
||||
pre-packaged. To use a release tarball:
|
||||
|
||||
1. Check the dependencies
|
||||
2. Untar the release tarball for your OS into `$HOME/.vim/pack`:
|
||||
|
||||
```
|
||||
$ mkdir -p $HOME/.vim/pack
|
||||
$ curl -L <url> | tar -C $HOME/.vim/pack zxvf -
|
||||
```
|
||||
|
||||
3. Configure your project's debug profiles (create `.vimspector.json`)
|
||||
|
||||
Alternatively, you can clone the repo and select which gadgets are installed:
|
||||
|
||||
1. Check the dependencies
|
||||
1. Install the plugin as a Vim package. See `:help packages`.
|
||||
2. Install some 'gadgets' (debug adapters)
|
||||
3. Configure your project's debug profiles (create `.vimspector.json`)
|
||||
|
||||
## Dependencies
|
||||
|
||||
Vimspector requires:
|
||||
|
||||
* Vim version 8.1 with at least patch 1264
|
||||
* One of the following operating systems:
|
||||
* Linux
|
||||
* macOS Mojave or pater
|
||||
|
||||
Why such a new vim ? Well 2 reasons:
|
||||
|
||||
1. Because vimspector uses a lot of new Vim features
|
||||
2. Because there are Vim bugs that vimspector triggers that will frustrate you
|
||||
if you hit them.
|
||||
|
||||
Why no Windows support? Because it's effort and it's not a priority for the
|
||||
author. PRs are welcome.
|
||||
|
||||
Which Linux versions? I only test on Ubuntu 18.04 and later and RHEL 6.5 and
|
||||
RHEL 7.6.
|
||||
|
||||
## Language dependencies
|
||||
|
||||
The debug adapters themselves have certain runtime dependencies:
|
||||
|
||||
| Language | Switch | Adapter | Dependencies |
|
||||
|--------------|-------------------|-------------------|------------------------|
|
||||
| C, C++, etc. | `--enable-c` | vscode-cpptools | mono-core |
|
||||
| Python | `--enable-python` | vscode-python | Python 2.7 or Python 3 |
|
||||
| TCL | `--enable-tcl` | tclpro | TCL 8.5 |
|
||||
| Bourne Shell | `--enable-bash` | vscode-bash-debug | Bash v?? |
|
||||
|
||||
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
|
||||
preference, so if you choose to use one, you're on your own with installation
|
||||
issues.
|
||||
|
||||
Install vimspector as a Vim package, either by cloning this repository into your
|
||||
package path, like this:
|
||||
|
||||
```
|
||||
$ git clone https://github.com/puremourning/vimspector ~/.vim/pack/vimspector/opt/vimspector
|
||||
```
|
||||
|
||||
2. Configure vimspector in your `.vimrc`:
|
||||
|
||||
```viml
|
||||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
```
|
||||
|
||||
3. Load vimspector at runtime. This can also be added to your `.vimrc` after
|
||||
configuring vimspector:
|
||||
|
||||
```
|
||||
packadd! vimspector
|
||||
```
|
||||
|
||||
See support/doc/example_vimrc.vim.
|
||||
|
||||
Also, if you want to try out vimspector without changing your vim config, run:
|
||||
|
||||
```
|
||||
vim -Nu /path/to/vimspector/tests/vimrc --cmd "let g:vimspector_enable_mappings='HUMAN'"
|
||||
```
|
||||
|
||||
## 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.
|
||||
|
||||
For supported languages, `install_gadget.py` 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
|
||||
you're in a corporate environment and this is a problem, you may need to
|
||||
install the gadgets manually.
|
||||
* Perform any necessary post-installation actions, such as:
|
||||
* Building any binary components
|
||||
* Ensuring scripts are executable, because the VSIX pacakges are usually
|
||||
broken in this regard.
|
||||
* Set up the `gadgetDir` symlinks for the platform.
|
||||
|
||||
To install the tested debug adapter for a language, run:
|
||||
|
||||
```
|
||||
./install_gadget.py --enable-<language>
|
||||
```
|
||||
|
||||
Or to install all supported gagtets:
|
||||
|
||||
```
|
||||
./install_gadget.py --all
|
||||
```
|
||||
|
||||
To install everything other than TCL (because TCL is sadly not as popular as it
|
||||
should be):
|
||||
|
||||
```
|
||||
./install_gadget.py --all --disable-tcl
|
||||
```
|
||||
|
||||
See `--help` for more info.
|
||||
|
||||
## Manual gadget installation
|
||||
|
||||
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`.
|
||||
|
||||
The simplest way in practice is to install or start Visusal Studio Code and use
|
||||
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 `gagets.json`.
|
||||
|
||||
PRs are always welcome to add configuration to do this to `install_gadget.py`.
|
||||
|
||||
### The gadget directory
|
||||
|
||||
Vimspector uses the following directory by default to look for a file named
|
||||
`.gadgets.json`: `</path/to/vimspector>/gadgets/<os>`.
|
||||
|
||||
This path is exposed as the vimspector _variable_ `${gadgetDir}`. This is useful
|
||||
for configuring gadget command lines.
|
||||
|
||||
Where os is one of:
|
||||
|
||||
* `macos`
|
||||
* `linux`
|
||||
* `windows` (though note: Windows is not supported)
|
||||
|
||||
The format is the same as `.vimspector.json`, but only the `gagets` key is used:
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"adapters": {
|
||||
"vscode-cpptools": {
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
},
|
||||
"command": [
|
||||
"${gadgetDir}/vscode-cpptools/debugAdapters/OpenDebugAD7"
|
||||
],
|
||||
"name": "cppdbg"
|
||||
},
|
||||
"vscode-python": {
|
||||
"command": [
|
||||
"node",
|
||||
"${gadgetDir}/vscode-python/out/client/debugger/debugAdapter/main.js"
|
||||
],
|
||||
"name": "vscode-python"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The gadget file is automatically written by `install_gadget.py`.
|
||||
|
||||
# About
|
||||
|
||||
## Background
|
||||
|
||||
The motivation is that debugging in Vim is a pretty horrible experience,
|
||||
particularly if you use multiple languages. With pyclewn no more and the
|
||||
|
|
@ -69,9 +300,36 @@ experience in Vim for multiple languages, by leveraging the debug adapters that
|
|||
are being built for Visual Studio Code.
|
||||
|
||||
The ability to do remote debugging is a must. This is key to my workflow, so
|
||||
baking it in to the debugging experience is a top bill goal for the project.
|
||||
baking it in to the debugging experience is a top bill goal for the project. So
|
||||
vimspector has first-class support for executing programs remotely and attaching
|
||||
to them. This support is unique to vimspector and on top of (complementary to)
|
||||
any such support in actual debug adapters.
|
||||
|
||||
# Features and Usage
|
||||
## Status
|
||||
|
||||
Vimspector is a work in progress, and any feedback/contributions are more
|
||||
than welcome.
|
||||
|
||||
The backlog can be [viewed on Trello](https://trello.com/b/yvAKK0rD/vimspector).
|
||||
|
||||
In order to use it you have to currently:
|
||||
|
||||
- Write a mostly undocumented configuration file that contains essentially
|
||||
undocumented parameters.
|
||||
- Accept that it isn't complete yet
|
||||
- Work around some frustrating bugs in Vim
|
||||
- Ignore probably many bugs in vimspector!
|
||||
|
||||
### Experimental
|
||||
|
||||
The plugin is currently _experimental_. That means that any part of it
|
||||
can (and probably will) change, including things like:
|
||||
|
||||
- breaking changes to the configuration
|
||||
- keys, layout, functionatlity of the UI
|
||||
|
||||
If a large number of people start using it then I will do my best to
|
||||
minimise this, or at least announce on Gitter.
|
||||
|
||||
# Mappings
|
||||
|
||||
|
|
@ -89,10 +347,13 @@ That said, many people are familiar with particular debuggers, so the following
|
|||
mappings can be enabled by setting `g:vimspector_enable_mappings` to the
|
||||
specified value.
|
||||
|
||||
Please note: Currently there are no `<plug>` mappings. These will be added in
|
||||
future to make custom mappings much easier.
|
||||
|
||||
## Visual Studio / VSCode
|
||||
|
||||
To use Visual Studio-like mappings, add the following to your `vimrc` before
|
||||
loading vimspector:
|
||||
To use Visual Studio-like mappings, add the following to your `vimrc` **before
|
||||
loading vimspector**:
|
||||
|
||||
```viml
|
||||
let g:vimspector_enable_mappings = 'VISUAL_STUDIO'
|
||||
|
|
@ -116,7 +377,8 @@ If, like me, you only have 2 hands and 10 fingers, you probably don't like
|
|||
Ctrl-Shift-F keys. Also, if you're running in a terminal, there's a real
|
||||
possibility of terminfo being wrong for shifted-F-keys, particularly if your
|
||||
`TERM` is `screen-256color`. If these issues (number of hands, `TERM` variables)
|
||||
are unfixable, try the following mappings:
|
||||
are unfixable, try the following mappings, by adding the following **before
|
||||
loading vimspector**:
|
||||
|
||||
```viml
|
||||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
|
|
@ -134,7 +396,7 @@ let g:vimspector_enable_mappings = 'HUMAN'
|
|||
| `F11` | Step Into | `vimspector#StepInto()` |
|
||||
| `F12` | Step out of current function scope | `vimspector#StepOut()` |
|
||||
|
||||
|
||||
# Usage
|
||||
|
||||
## Launch and attach by PID:
|
||||
|
||||
|
|
@ -191,36 +453,24 @@ CLI for the debug adapter. Support for this varies amongt adapters.
|
|||
|
||||
NOTE: See also [Watches][#watches] above.
|
||||
|
||||
# Supported Languages
|
||||
# Debug adapter configuration
|
||||
|
||||
## Supported Languages
|
||||
|
||||
For more information on the configuration of `.vimspector.json`, take a look at
|
||||
the Getting Started section of the [Vimspector website][website].
|
||||
|
||||
Current tested with the following debug adapters.
|
||||
|
||||
Note, there is no support for installing the extension. Use VSCode to do that by
|
||||
installing it in the UI. The default extension directory is something like
|
||||
`$HOME/.vscode/extensions`.
|
||||
|
||||
Note, the launch configurations below are reverse-engineered from the
|
||||
extensions. Typically they are documented in the extension's `package.json`, but
|
||||
not always (or not completely).
|
||||
|
||||
* C++: [vscode-cpptools](https://github.com/Microsoft/vscode-cpptools)
|
||||
|
||||
Example `.vimspector.json`
|
||||
|
||||
```
|
||||
{
|
||||
"adapters": {
|
||||
"cppdbg": {
|
||||
"name": "cppdbg",
|
||||
"command": [ "<path to extension>/debugAdapters/OpenDebugAD7" ],
|
||||
"attach": {
|
||||
"pidProperty": "processId",
|
||||
"pidSelect": "ask"
|
||||
}
|
||||
},
|
||||
....
|
||||
},
|
||||
"configurations": {
|
||||
"<name>: Launch": {
|
||||
"adapter": "cppdbg",
|
||||
"adapter": "vscode-cpptools",
|
||||
"configuration": {
|
||||
"name": "<name>",
|
||||
"type": "cppdbg",
|
||||
|
|
@ -234,7 +484,7 @@ not always (or not completely).
|
|||
}
|
||||
},
|
||||
"<name>: Attach": {
|
||||
"adapter": "cppdbg",
|
||||
"adapter": "vscode-cpptools",
|
||||
"configuration": {
|
||||
"name": "<name>: Attach",
|
||||
"type": "cppdbg",
|
||||
|
|
@ -248,102 +498,13 @@ not always (or not completely).
|
|||
}
|
||||
```
|
||||
|
||||
* C++: [code=debug ](https://github.com/WebFreak001/code-debug)
|
||||
|
||||
```
|
||||
{
|
||||
"adapters": {
|
||||
"lldb-mi": {
|
||||
"name": "lldb-mi",
|
||||
"command": [
|
||||
"node",
|
||||
"<path to extension>/out/src/lldb.js"
|
||||
],
|
||||
"attach": {
|
||||
"pidProperty": "target",
|
||||
"pidSelect": "ask"
|
||||
}
|
||||
}
|
||||
...
|
||||
},
|
||||
"configurations": {
|
||||
"<name>: Launch": {
|
||||
"adapter": "lldb-mi",
|
||||
"configuration": {
|
||||
"request": "attach",
|
||||
"cwd": "<working directory>",
|
||||
"program": "<path to binary>",
|
||||
"args": [ ... ],
|
||||
"environment": [ ... ],
|
||||
"lldbmipath": "<path to a working lldb-mi>"
|
||||
}
|
||||
},
|
||||
"<name>: Attach": {
|
||||
"adapter": "lldb-mi",
|
||||
"configuration": {
|
||||
"request": "attach",
|
||||
"cwd": "<working directory>",
|
||||
"executable": "<path to binary>",
|
||||
"lldbmipath": "<path to a working lldb-mi>"
|
||||
}
|
||||
}
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
* C, C++, Rust, etc.: [CodeLLDB](https://github.com/vadimcn/vscode-lldb)
|
||||
|
||||
```
|
||||
{
|
||||
"adapters": {
|
||||
"lldb": {
|
||||
"name": "lldb",
|
||||
"command": [
|
||||
"lldb",
|
||||
"-b",
|
||||
"-O",
|
||||
"command script import '<extension path>/adapter'",
|
||||
"-O",
|
||||
"script adapter.main.run_stdio_session()"
|
||||
]
|
||||
}
|
||||
...
|
||||
},
|
||||
"configurations": {
|
||||
"<name>: Launch": {
|
||||
"adapter": "lldb",
|
||||
"configuration": {
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "<name>: Launch",
|
||||
"program": "<path to binary>",
|
||||
"args": [ .. ],
|
||||
"cwd": "<working directory>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Python: [vscode-python](https://github.com/Microsoft/vscode-python)
|
||||
|
||||
```
|
||||
{
|
||||
"adapters": {
|
||||
"python": {
|
||||
"name": "python",
|
||||
"command": [
|
||||
"node",
|
||||
"<path to extension>/out/client/debugger/debugAdapter/main.js"
|
||||
]
|
||||
}
|
||||
...
|
||||
},
|
||||
"configurations": {
|
||||
"<name>: Launch": {
|
||||
"adapter": "python",
|
||||
"adapter": "vscode-python",
|
||||
"configuration": {
|
||||
"name": "<name>: Launch",
|
||||
"type": "python",
|
||||
|
|
@ -366,9 +527,7 @@ See [my fork of TclProDebug](https://github.com/puremourning/TclProDebug) for in
|
|||
|
||||
Also the mock debugger, but that isn't actually useful.
|
||||
|
||||
# Unsupported
|
||||
|
||||
Known not to work:
|
||||
## Partially supported
|
||||
|
||||
* Java Debug Server. The [java debug server][java-debug-server] runs as a
|
||||
jdt.ls plugin, rather than a standalone debug adapter. This makes a lot
|
||||
|
|
@ -378,27 +537,17 @@ Known not to work:
|
|||
manually (however you might do so) and you can tell vimspector the port
|
||||
on which it is listening. See [this issue](https://github.com/puremourning/vimspector/issues/3)
|
||||
for more background.
|
||||
|
||||
## Unsupported
|
||||
|
||||
Known not to work:
|
||||
* C-sharp. The license appears to require that it is only used with Visual
|
||||
Studio Code.
|
||||
|
||||
# Supported Platforms
|
||||
|
||||
Currently on the author's environment which is macOS.
|
||||
|
||||
The plugin _might_ work on other UNIX-like environments but it hasn't been
|
||||
tested. It will almost certainly not work on Windows.
|
||||
|
||||
Requires:
|
||||
|
||||
- Vim 8.1 compiled with python 3 support.
|
||||
|
||||
Note the plugin uses a lot of very new Vim features (like prompt buffers), so
|
||||
I would strongly recommend a very new build of Vim.
|
||||
|
||||
# FAQ
|
||||
|
||||
1. Q: Does it work? A: Yeah, sort of. It's _incredibly_ buggy and unpolished.
|
||||
2. Q: Does it work with <insert language here>? A: Probably, but it won't
|
||||
2. Q: Does it work with _this_ language? A: Probably, but it won't
|
||||
necessarily be easy to work out what to put in the `.vimspector.json`. As you
|
||||
can see above, some of the servers aren't really editor agnostic, and require
|
||||
very-specific unique handling.
|
||||
|
|
@ -412,3 +561,4 @@ Copyright © 2018 Ben Jackson
|
|||
[ycmd]: https://github.com/Valloric/ycmd
|
||||
[gitter]: https://gitter.im/vimspector/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link
|
||||
[java-debug-server]: https://github.com/Microsoft/java-debug
|
||||
[website]: https://puremourning.github.io/vimspector-web/
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ stages:
|
|||
vmImage: 'ubuntu-16.04'
|
||||
container: 'puremourning/vimspector:test'
|
||||
steps:
|
||||
- bash: python3 install_gadget.py
|
||||
- bash: python3 install_gadget.py --all
|
||||
displayName: 'Install gadgets'
|
||||
|
||||
- bash: vim --version
|
||||
|
|
@ -61,7 +61,7 @@ stages:
|
|||
- bash: brew install macvim
|
||||
displayName: 'Install vim'
|
||||
|
||||
- bash: python3 install_gadget.py
|
||||
- bash: python3 install_gadget.py --all
|
||||
displayName: 'Install gadgets'
|
||||
|
||||
- bash: vim --version
|
||||
|
|
|
|||
281
gh-md-toc
Executable file
281
gh-md-toc
Executable file
|
|
@ -0,0 +1,281 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#
|
||||
# Steps:
|
||||
#
|
||||
# 1. Download corresponding html file for some README.md:
|
||||
# curl -s $1
|
||||
#
|
||||
# 2. Discard rows where no substring 'user-content-' (github's markup):
|
||||
# awk '/user-content-/ { ...
|
||||
#
|
||||
# 3.1 Get last number in each row like ' ... </span></a>sitemap.js</h1'.
|
||||
# It's a level of the current header:
|
||||
# substr($0, length($0), 1)
|
||||
#
|
||||
# 3.2 Get level from 3.1 and insert corresponding number of spaces before '*':
|
||||
# sprintf("%*s", substr($0, length($0), 1)*3, " ")
|
||||
#
|
||||
# 4. Find head's text and insert it inside "* [ ... ]":
|
||||
# substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5)
|
||||
#
|
||||
# 5. Find anchor and insert it inside "(...)":
|
||||
# substr($0, match($0, "href=\"[^\"]+?\" ")+6, RLENGTH-8)
|
||||
#
|
||||
|
||||
gh_toc_version="0.6.1"
|
||||
|
||||
gh_user_agent="gh-md-toc v$gh_toc_version"
|
||||
|
||||
#
|
||||
# Download rendered into html README.md by its url.
|
||||
#
|
||||
#
|
||||
gh_toc_load() {
|
||||
local gh_url=$1
|
||||
|
||||
if type curl &>/dev/null; then
|
||||
curl --user-agent "$gh_user_agent" -s "$gh_url"
|
||||
elif type wget &>/dev/null; then
|
||||
wget --user-agent="$gh_user_agent" -qO- "$gh_url"
|
||||
else
|
||||
echo "Please, install 'curl' or 'wget' and try again."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Converts local md file into html by GitHub
|
||||
#
|
||||
# ➥ curl -X POST --data '{"text": "Hello world github/linguist#1 **cool**, and #1!"}' https://api.github.com/markdown
|
||||
# <p>Hello world github/linguist#1 <strong>cool</strong>, and #1!</p>'"
|
||||
gh_toc_md2html() {
|
||||
local gh_file_md=$1
|
||||
URL=https://api.github.com/markdown/raw
|
||||
if [ ! -z "$GH_TOC_TOKEN" ]; then
|
||||
TOKEN=$GH_TOC_TOKEN
|
||||
else
|
||||
TOKEN="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/token.txt"
|
||||
fi
|
||||
if [ -f "$TOKEN" ]; then
|
||||
URL="$URL?access_token=$(cat $TOKEN)"
|
||||
fi
|
||||
# echo $URL 1>&2
|
||||
OUTPUT="$(curl -s --user-agent "$gh_user_agent" \
|
||||
--data-binary @"$gh_file_md" -H "Content-Type:text/plain" \
|
||||
$URL)"
|
||||
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "XXNetworkErrorXX"
|
||||
fi
|
||||
if [ "$(echo "${OUTPUT}" | awk '/API rate limit exceeded/')" != "" ]; then
|
||||
echo "XXRateLimitXX"
|
||||
else
|
||||
echo "${OUTPUT}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Is passed string url
|
||||
#
|
||||
gh_is_url() {
|
||||
case $1 in
|
||||
https* | http*)
|
||||
echo "yes";;
|
||||
*)
|
||||
echo "no";;
|
||||
esac
|
||||
}
|
||||
|
||||
#
|
||||
# TOC generator
|
||||
#
|
||||
gh_toc(){
|
||||
local gh_src=$1
|
||||
local gh_src_copy=$1
|
||||
local gh_ttl_docs=$2
|
||||
local need_replace=$3
|
||||
|
||||
if [ "$gh_src" = "" ]; then
|
||||
echo "Please, enter URL or local path for a README.md"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# Show "TOC" string only if working with one document
|
||||
if [ "$gh_ttl_docs" = "1" ]; then
|
||||
|
||||
echo "Table of Contents"
|
||||
echo "================="
|
||||
echo ""
|
||||
gh_src_copy=""
|
||||
|
||||
fi
|
||||
|
||||
if [ "$(gh_is_url "$gh_src")" == "yes" ]; then
|
||||
gh_toc_load "$gh_src" | gh_toc_grab "$gh_src_copy"
|
||||
if [ "${PIPESTATUS[0]}" != "0" ]; then
|
||||
echo "Could not load remote document."
|
||||
echo "Please check your url or network connectivity"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$need_replace" = "yes" ]; then
|
||||
echo
|
||||
echo "!! '$gh_src' is not a local file"
|
||||
echo "!! Can't insert the TOC into it."
|
||||
echo
|
||||
fi
|
||||
else
|
||||
local rawhtml=$(gh_toc_md2html "$gh_src")
|
||||
if [ "$rawhtml" == "XXNetworkErrorXX" ]; then
|
||||
echo "Parsing local markdown file requires access to github API"
|
||||
echo "Please make sure curl is installed and check your network connectivity"
|
||||
exit 1
|
||||
fi
|
||||
if [ "$rawhtml" == "XXRateLimitXX" ]; then
|
||||
echo "Parsing local markdown file requires access to github API"
|
||||
echo "Error: You exceeded the hourly limit. See: https://developer.github.com/v3/#rate-limiting"
|
||||
TOKEN="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/token.txt"
|
||||
echo "or place github auth token here: $TOKEN"
|
||||
exit 1
|
||||
fi
|
||||
local toc=`echo "$rawhtml" | gh_toc_grab "$gh_src_copy"`
|
||||
echo "$toc"
|
||||
if [ "$need_replace" = "yes" ]; then
|
||||
if grep -Fxq "<!--ts-->" $gh_src && grep -Fxq "<!--te-->" $gh_src; then
|
||||
echo "Found markers"
|
||||
else
|
||||
echo "You don't have <!--ts--> or <!--te--> in your file...exiting"
|
||||
exit 1
|
||||
fi
|
||||
local ts="<\!--ts-->"
|
||||
local te="<\!--te-->"
|
||||
local dt=`date +'%F_%H%M%S'`
|
||||
local ext=".orig.${dt}"
|
||||
local toc_path="${gh_src}.toc.${dt}"
|
||||
local toc_footer="<!-- Added by: `whoami`, at: `date` -->"
|
||||
# http://fahdshariff.blogspot.ru/2012/12/sed-mutli-line-replacement-between-two.html
|
||||
# clear old TOC
|
||||
sed -i${ext} "/${ts}/,/${te}/{//!d;}" "$gh_src"
|
||||
# create toc file
|
||||
echo "${toc}" > "${toc_path}"
|
||||
echo -e "\n${toc_footer}\n" >> "$toc_path"
|
||||
# insert toc file
|
||||
if [[ "`uname`" == "Darwin" ]]; then
|
||||
sed -i "" "/${ts}/r ${toc_path}" "$gh_src"
|
||||
else
|
||||
sed -i "/${ts}/r ${toc_path}" "$gh_src"
|
||||
fi
|
||||
echo
|
||||
echo "!! TOC was added into: '$gh_src'"
|
||||
echo "!! Origin version of the file: '${gh_src}${ext}'"
|
||||
echo "!! TOC added into a separate file: '${toc_path}'"
|
||||
echo
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Grabber of the TOC from rendered html
|
||||
#
|
||||
# $1 — a source url of document.
|
||||
# It's need if TOC is generated for multiple documents.
|
||||
#
|
||||
gh_toc_grab() {
|
||||
# if closed <h[1-6]> is on the new line, then move it on the prev line
|
||||
# for example:
|
||||
# was: The command <code>foo1</code>
|
||||
# </h1>
|
||||
# became: The command <code>foo1</code></h1>
|
||||
sed -e ':a' -e 'N' -e '$!ba' -e 's/\n<\/h/<\/h/g' |
|
||||
# find strings that corresponds to template
|
||||
grep -E -o '<a.*id="user-content-[^"]*".*</h[1-6]' |
|
||||
# remove code tags
|
||||
sed 's/<code>//g' | sed 's/<\/code>//g' |
|
||||
# now all rows are like:
|
||||
# <a id="user-content-..." href="..."><span ...></span></a> ... </h1
|
||||
# format result line
|
||||
# * $0 — whole string
|
||||
# * last element of each row: "</hN" where N in (1,2,3,...)
|
||||
echo -e "$(awk -v "gh_url=$1" '{
|
||||
level = substr($0, length($0), 1)
|
||||
text = substr($0, match($0, /a>.*<\/h/)+2, RLENGTH-5)
|
||||
href = substr($0, match($0, "href=\"[^\"]+?\"")+6, RLENGTH-7)
|
||||
print sprintf("%*s", level*3, " ") "* [" text "](" gh_url href ")" }' |
|
||||
sed 'y/+/ /; s/%/\\x/g')"
|
||||
}
|
||||
|
||||
#
|
||||
# Returns filename only from full path or url
|
||||
#
|
||||
gh_toc_get_filename() {
|
||||
echo "${1##*/}"
|
||||
}
|
||||
|
||||
#
|
||||
# Options hendlers
|
||||
#
|
||||
gh_toc_app() {
|
||||
local need_replace="no"
|
||||
|
||||
if [ "$1" = '--help' ] || [ $# -eq 0 ] ; then
|
||||
local app_name=$(basename "$0")
|
||||
echo "GitHub TOC generator ($app_name): $gh_toc_version"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $app_name [--insert] src [src] Create TOC for a README file (url or local path)"
|
||||
echo " $app_name - Create TOC for markdown from STDIN"
|
||||
echo " $app_name --help Show help"
|
||||
echo " $app_name --version Show version"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$1" = '--version' ]; then
|
||||
echo "$gh_toc_version"
|
||||
echo
|
||||
echo "os: `lsb_release -d | cut -f 2`"
|
||||
echo "kernel: `cat /proc/version`"
|
||||
echo "shell: `$SHELL --version`"
|
||||
echo
|
||||
for tool in curl wget grep awk sed; do
|
||||
printf "%-5s: " $tool
|
||||
echo `$tool --version | head -n 1`
|
||||
done
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$1" = "-" ]; then
|
||||
if [ -z "$TMPDIR" ]; then
|
||||
TMPDIR="/tmp"
|
||||
elif [ -n "$TMPDIR" -a ! -d "$TMPDIR" ]; then
|
||||
mkdir -p "$TMPDIR"
|
||||
fi
|
||||
local gh_tmp_md
|
||||
gh_tmp_md=$(mktemp $TMPDIR/tmp.XXXXXX)
|
||||
while read input; do
|
||||
echo "$input" >> "$gh_tmp_md"
|
||||
done
|
||||
gh_toc_md2html "$gh_tmp_md" | gh_toc_grab ""
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$1" = '--insert' ]; then
|
||||
need_replace="yes"
|
||||
shift
|
||||
fi
|
||||
|
||||
for md in "$@"
|
||||
do
|
||||
echo ""
|
||||
gh_toc "$md" "$#" "$need_replace"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Created by [gh-md-toc](https://github.com/ekalinin/github-markdown-toc)"
|
||||
}
|
||||
|
||||
#
|
||||
# Entry point
|
||||
#
|
||||
gh_toc_app "$@"
|
||||
|
|
@ -20,6 +20,7 @@ try:
|
|||
except ImportError:
|
||||
import urllib2
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import os
|
||||
import collections
|
||||
|
|
@ -41,6 +42,7 @@ from vimspector import install
|
|||
|
||||
GADGETS = {
|
||||
'vscode-cpptools': {
|
||||
'language': 'c',
|
||||
'download': {
|
||||
'url': ( 'https://github.com/Microsoft/vscode-cpptools/releases/download/'
|
||||
'${version}/${file_name}' ),
|
||||
|
|
@ -76,6 +78,7 @@ GADGETS = {
|
|||
},
|
||||
},
|
||||
'vscode-python': {
|
||||
'language': 'python',
|
||||
'download': {
|
||||
'url': ( 'https://github.com/Microsoft/vscode-python/releases/download/'
|
||||
'${version}/${file_name}' ),
|
||||
|
|
@ -97,6 +100,7 @@ GADGETS = {
|
|||
},
|
||||
},
|
||||
'tclpro': {
|
||||
'language': 'tcl',
|
||||
'repo': {
|
||||
'url': 'https://github.com/puremourning/TclProDebug',
|
||||
'ref': 'master',
|
||||
|
|
@ -104,6 +108,7 @@ GADGETS = {
|
|||
'do': lambda name, root: InstallTclProDebug( name, root )
|
||||
},
|
||||
'vscode-mono-debug': {
|
||||
'language': 'csharp',
|
||||
'enabled': False,
|
||||
'download': {
|
||||
'url': 'https://marketplace.visualstudio.com/_apis/public/gallery/'
|
||||
|
|
@ -119,6 +124,7 @@ GADGETS = {
|
|||
}
|
||||
},
|
||||
'vscode-bash-debug': {
|
||||
'language': 'bash',
|
||||
'download': {
|
||||
'url': ( 'https://github.com/rogalmic/vscode-bash-debug/releases/'
|
||||
'download/${version}/${file_name}' ),
|
||||
|
|
@ -325,12 +331,42 @@ gadget_dir = install.GetGadgetDir( os.path.dirname( __file__ ), OS )
|
|||
print( 'OS = ' + OS )
|
||||
print( 'gadget_dir = ' + gadget_dir )
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument( '--all',
|
||||
action = 'store_true',
|
||||
help = 'Enable all completers' )
|
||||
|
||||
for name, gadget in GADGETS.items():
|
||||
if not gadget.get( 'enabled', True ):
|
||||
continue
|
||||
|
||||
parser.add_argument(
|
||||
'--enable-' + gadget[ 'language' ],
|
||||
action = 'store_true',
|
||||
help = 'Install the {} debug adapter for {} support'.format(
|
||||
name,
|
||||
gadget[ 'language' ] ) )
|
||||
|
||||
parser.add_argument(
|
||||
'--disable-' + gadget[ 'language' ],
|
||||
action = 'store_true',
|
||||
help = 'Don\t install the {} debug adapter for {} support '
|
||||
'(when supplying --all)'.format( name, gadget[ 'language' ] ) )
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
failed = []
|
||||
all_adapters = {}
|
||||
for name, gadget in GADGETS.items():
|
||||
if not gadget.get( 'enabled', True ):
|
||||
continue
|
||||
|
||||
if not args.all and not getattr( args, 'enable_' + gadget[ 'language' ] ):
|
||||
continue
|
||||
|
||||
if getattr( args, 'disable_' + gadget[ 'language' ] ):
|
||||
continue
|
||||
|
||||
try:
|
||||
v = {}
|
||||
v.update( gadget.get( 'all', {} ) )
|
||||
|
|
@ -384,5 +420,3 @@ with open( install.GetGadgetConfigFile( os.path.dirname( __file__ ) ),
|
|||
if failed:
|
||||
raise RuntimeError( 'Failed to install gadgets: {}'.format(
|
||||
','.join( failed ) ) )
|
||||
|
||||
|
||||
|
|
|
|||
4
support/doc/example_vimrc.vim
Normal file
4
support/doc/example_vimrc.vim
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
let g:vimspector_enable_mappings = 'HUMAN'
|
||||
packadd! vimspector
|
||||
syntax enable
|
||||
filetype plugin indent on
|
||||
Loading…
Add table
Add a link
Reference in a new issue