Merge pull request #136 from puremourning/json-comments
Support c-style comments in JSON
This commit is contained in:
commit
03d97dc58f
10 changed files with 145 additions and 16 deletions
|
|
@ -609,6 +609,11 @@ the Getting Started section of the [Vimspector website][website].
|
||||||
For full explanation, including how to use variables, substitutions and how to
|
For full explanation, including how to use variables, substitutions and how to
|
||||||
specify exception breakpoints, see [the docs][vimspector-ref].
|
specify exception breakpoints, see [the docs][vimspector-ref].
|
||||||
|
|
||||||
|
The JSON configuration file allows C-style comments:
|
||||||
|
|
||||||
|
* `// comment to end of line ...`
|
||||||
|
* `/* inline comment ... */`
|
||||||
|
|
||||||
Current tested with the following debug adapters.
|
Current tested with the following debug adapters.
|
||||||
|
|
||||||
## C, C++, Rust, etc.
|
## C, C++, Rust, etc.
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ stages:
|
||||||
env:
|
env:
|
||||||
VIMSPECTOR_MIMODE: gdb
|
VIMSPECTOR_MIMODE: gdb
|
||||||
VIMSPECTOR_TEST_STDOUT: true
|
VIMSPECTOR_TEST_STDOUT: true
|
||||||
VIMSPECTOR_MI_DEBUGGER: ""
|
VIMSPECTOR_MI_DEBUGGER: gdb
|
||||||
|
|
||||||
- bash: ./make_package linux $(Build.SourceVersion)
|
- bash: ./make_package linux $(Build.SourceVersion)
|
||||||
displayName: 'Package'
|
displayName: 'Package'
|
||||||
|
|
|
||||||
|
|
@ -110,14 +110,15 @@ But for now, consider the following example snippet:
|
||||||
{
|
{
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"example-debug-configuration": {
|
"example-debug-configuration": {
|
||||||
|
// This is a single-line comment explaining the purpose
|
||||||
"adapter": "example-adapter-name",
|
"adapter": "example-adapter-name",
|
||||||
"variables": {
|
"variables": {
|
||||||
"SecretToken": {
|
"SecretToken": { // Variables should start with upper-case letters
|
||||||
"shell" : [ "cat", "${HOME}/.secret_token" ]
|
"shell" : [ "cat", "${HOME}/.secret_token" ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"request": "launch",
|
"request": "launch" /* or it could be "attach" */,
|
||||||
"program": [
|
"program": [
|
||||||
"${fileBasenameNoExtension}",
|
"${fileBasenameNoExtension}",
|
||||||
"-c", "configuration_file.cfg",
|
"-c", "configuration_file.cfg",
|
||||||
|
|
@ -364,6 +365,25 @@ The following variables are provided:
|
||||||
* `${fileExtname}` - the current opened file's extension
|
* `${fileExtname}` - the current opened file's extension
|
||||||
* `${cwd}` - the current working directory of the active window on launch
|
* `${cwd}` - the current working directory of the active window on launch
|
||||||
|
|
||||||
|
## Appendix: Configuration file format
|
||||||
|
|
||||||
|
The configuration files are text files which must be UTF-8 encoded. They
|
||||||
|
contain a single JSON object, along with optional comments.
|
||||||
|
|
||||||
|
Comments are "c-style", i.e.:
|
||||||
|
|
||||||
|
* `// single line comment ...`
|
||||||
|
* `/* inline comment */`
|
||||||
|
|
||||||
|
There is much debate about whether JSON files should contain comments. I have
|
||||||
|
added them because they are useful in the context of configuration files.
|
||||||
|
Unforutnately this may mean your editor doesn't like them (they are strictly
|
||||||
|
invalid JSON) so it's up to you if you use them.
|
||||||
|
|
||||||
|
Technically, Vimspector uses [JSON
|
||||||
|
minify](https://github.com/getify/JSON.minify) to strip comments before parsing
|
||||||
|
the JSON.
|
||||||
|
|
||||||
## Appendix: Editor configuration
|
## Appendix: Editor configuration
|
||||||
|
|
||||||
If you would like some assistance with writing the JSON files, and your editor
|
If you would like some assistance with writing the JSON files, and your editor
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ sys.path.insert( 1, os.path.join( os.path.dirname( __file__ ),
|
||||||
'python3' ) )
|
'python3' ) )
|
||||||
|
|
||||||
from vimspector import install, installer
|
from vimspector import install, installer
|
||||||
|
from vimspector.vendor.json_minify import minify
|
||||||
|
|
||||||
GADGETS = {
|
GADGETS = {
|
||||||
'vscode-cpptools': {
|
'vscode-cpptools': {
|
||||||
|
|
@ -634,7 +635,7 @@ for custom_file_name in functools.reduce( operator.add,
|
||||||
args.custom_gadget_file,
|
args.custom_gadget_file,
|
||||||
custom_files ):
|
custom_files ):
|
||||||
with open( custom_file_name, 'r' ) as custom_file:
|
with open( custom_file_name, 'r' ) as custom_file:
|
||||||
CUSTOM_GADGETS.update( json.load( custom_file ) )
|
CUSTOM_GADGETS.update( json.loads( minify( custom_file.read() ) ) )
|
||||||
|
|
||||||
|
|
||||||
failed = []
|
failed = []
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ from vimspector import ( breakpoints,
|
||||||
stack_trace,
|
stack_trace,
|
||||||
utils,
|
utils,
|
||||||
variables )
|
variables )
|
||||||
|
from vimspector.vendor.json_minify import minify
|
||||||
|
|
||||||
VIMSPECTOR_HOME = os.path.abspath( os.path.join( os.path.dirname( __file__ ),
|
VIMSPECTOR_HOME = os.path.abspath( os.path.join( os.path.dirname( __file__ ),
|
||||||
'..',
|
'..',
|
||||||
|
|
@ -96,7 +97,8 @@ class DebugSession( object ):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
with open( gadget_config_file, 'r' ) as f:
|
with open( gadget_config_file, 'r' ) as f:
|
||||||
adapters.update( json.load( f ).get( 'adapters' ) or {} )
|
a = json.loads( minify( f.read() ) ).get( 'adapters' ) or {}
|
||||||
|
adapters.update( a )
|
||||||
|
|
||||||
for launch_config_file in PathsToAllConfigFiles( VIMSPECTOR_HOME,
|
for launch_config_file in PathsToAllConfigFiles( VIMSPECTOR_HOME,
|
||||||
current_file,
|
current_file,
|
||||||
|
|
@ -106,7 +108,7 @@ class DebugSession( object ):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
with open( launch_config_file, 'r' ) as f:
|
with open( launch_config_file, 'r' ) as f:
|
||||||
database = json.load( f )
|
database = json.loads( minify( f.read() ) )
|
||||||
adapters.update( database.get( 'adapters' ) or {} )
|
adapters.update( database.get( 'adapters' ) or {} )
|
||||||
configurations.update( database.get( 'configurations' or {} ) )
|
configurations.update( database.get( 'configurations' or {} ) )
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,7 @@ def MakeSymlink( in_folder, link, pointing_to ):
|
||||||
else:
|
else:
|
||||||
os.symlink( pointing_to_relative, link_path )
|
os.symlink( pointing_to_relative, link_path )
|
||||||
|
|
||||||
|
|
||||||
def CloneRepoTo( url, ref, destination ):
|
def CloneRepoTo( url, ref, destination ):
|
||||||
RemoveIfExists( destination )
|
RemoveIfExists( destination )
|
||||||
git_in_repo = [ 'git', '-C', destination ]
|
git_in_repo = [ 'git', '-C', destination ]
|
||||||
|
|
|
||||||
97
python3/vimspector/vendor/json_minify.py
vendored
Normal file
97
python3/vimspector/vendor/json_minify.py
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
# Copyright © 2020 Kyle Simpson <getify@gmail.com>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
# a copy of this software and associated documentation files (the "Software"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
|
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
||||||
|
# OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""A port of the `JSON-minify` utility to the Python language.
|
||||||
|
|
||||||
|
Based on JSON.minify.js: https://github.com/getify/JSON.minify
|
||||||
|
|
||||||
|
Contributers:
|
||||||
|
- Gerald Storer
|
||||||
|
- Contributed original version
|
||||||
|
- Felipe Machado
|
||||||
|
- Performance optimization
|
||||||
|
- Pradyun S. Gedam
|
||||||
|
- Conditions and variable names changed
|
||||||
|
- Reformatted tests and moved to separate file
|
||||||
|
- Made into a PyPI Package
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
# Vimspector modification: strip_space defaults to False; we don't actually want
|
||||||
|
# to minify - we just want to strip comments.
|
||||||
|
def minify(string, strip_space=False):
|
||||||
|
tokenizer = re.compile('"|(/\*)|(\*/)|(//)|\n|\r')
|
||||||
|
end_slashes_re = re.compile(r'(\\)*$')
|
||||||
|
|
||||||
|
in_string = False
|
||||||
|
in_multi = False
|
||||||
|
in_single = False
|
||||||
|
|
||||||
|
new_str = []
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
for match in re.finditer(tokenizer, string):
|
||||||
|
|
||||||
|
if not (in_multi or in_single):
|
||||||
|
tmp = string[index:match.start()]
|
||||||
|
if not in_string and strip_space:
|
||||||
|
# replace white space as defined in standard
|
||||||
|
tmp = re.sub('[ \t\n\r]+', '', tmp)
|
||||||
|
new_str.append(tmp)
|
||||||
|
elif not strip_space:
|
||||||
|
# Replace comments with white space so that the JSON parser reports
|
||||||
|
# the correct column numbers on parsing errors.
|
||||||
|
new_str.append(' ' * (match.start() - index))
|
||||||
|
|
||||||
|
index = match.end()
|
||||||
|
val = match.group()
|
||||||
|
|
||||||
|
if val == '"' and not (in_multi or in_single):
|
||||||
|
escaped = end_slashes_re.search(string, 0, match.start())
|
||||||
|
|
||||||
|
# start of string or unescaped quote character to end string
|
||||||
|
if not in_string or (escaped is None or len(escaped.group()) % 2 == 0): # noqa
|
||||||
|
in_string = not in_string
|
||||||
|
index -= 1 # include " character in next catch
|
||||||
|
elif not (in_string or in_multi or in_single):
|
||||||
|
if val == '/*':
|
||||||
|
in_multi = True
|
||||||
|
elif val == '//':
|
||||||
|
in_single = True
|
||||||
|
elif val == '*/' and in_multi and not (in_string or in_single):
|
||||||
|
in_multi = False
|
||||||
|
if not strip_space:
|
||||||
|
new_str.append(' ' * len(val))
|
||||||
|
elif val in '\r\n' and not (in_multi or in_string) and in_single:
|
||||||
|
in_single = False
|
||||||
|
elif not ((in_multi or in_single) or (val in ' \r\n\t' and strip_space)): # noqa
|
||||||
|
new_str.append(val)
|
||||||
|
|
||||||
|
if not strip_space:
|
||||||
|
if val in '\r\n':
|
||||||
|
new_str.append(val)
|
||||||
|
elif in_multi or in_single:
|
||||||
|
new_str.append(' ' * len(val))
|
||||||
|
|
||||||
|
new_str.append(string[index:])
|
||||||
|
return ''.join(new_str)
|
||||||
19
run_tests
19
run_tests
|
|
@ -23,23 +23,24 @@ fi
|
||||||
if [ -z "$VIMSPECTOR_MIMODE" ]; then
|
if [ -z "$VIMSPECTOR_MIMODE" ]; then
|
||||||
if which lldb >/dev/null 2>&1; then
|
if which lldb >/dev/null 2>&1; then
|
||||||
export VIMSPECTOR_MIMODE=lldb
|
export VIMSPECTOR_MIMODE=lldb
|
||||||
|
|
||||||
|
if [ -z "${VIMSPECTOR_MI_DEBUGGER}" ]; then
|
||||||
|
if which lldb-mi >/dev/null 2>&1; then
|
||||||
|
export VIMSPECTOR_MI_DEBUGGER=lldb-mi
|
||||||
|
else
|
||||||
|
echo "Couldn't guess VIMSPECTOR_MI_DEBUGGER. Need lldb-mi in path"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
elif which gdb >/dev/null 2>&1; then
|
elif which gdb >/dev/null 2>&1; then
|
||||||
export VIMSPECTOR_MIMODE=gdb
|
export VIMSPECTOR_MIMODE=gdb
|
||||||
|
export VIMSPECTOR_MI_DEBUGGER=gdb
|
||||||
else
|
else
|
||||||
echo "Couldn't guess VIMSPECTOR_MIMODE. Need lldb or gdb in path"
|
echo "Couldn't guess VIMSPECTOR_MIMODE. Need lldb or gdb in path"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "${VIMSPECTOR_MI_DEBUGGER}" ]; then
|
|
||||||
if which lldb-mi >/dev/null 2>&1; then
|
|
||||||
export VIMSPECTOR_MI_DEBUGGER=lldb-mi
|
|
||||||
else
|
|
||||||
echo "Couldn't guess VIMSPECTOR_MI_DEBUGGER. Need lldb-mi in path"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Testing with:"
|
echo "Testing with:"
|
||||||
echo " * VIMSPECTOR_MIMODE=$VIMSPECTOR_MIMODE"
|
echo " * VIMSPECTOR_MIMODE=$VIMSPECTOR_MIMODE"
|
||||||
echo " * VIMSPECTOR_MI_DEBUGGER=${VIMSPECTOR_MI_DEBUGGER}"
|
echo " * VIMSPECTOR_MI_DEBUGGER=${VIMSPECTOR_MI_DEBUGGER}"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"configurations": {
|
"configurations": {
|
||||||
|
// This is a comment.
|
||||||
"run legacy vscode-python": {
|
"run legacy vscode-python": {
|
||||||
"adapter": "vscode-python",
|
"adapter": "vscode-python" /* coment goes here too */,
|
||||||
"configuration": {
|
"configuration": {
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"type": "python",
|
"type": "python",
|
||||||
|
|
|
||||||
1
tox.ini
1
tox.ini
|
|
@ -1,3 +1,4 @@
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore = E111,E114,E121,E125,E126,E127,E128,E129,E131,E133,E201,E202,E203,E211,E221,E222,E241,E251,E261,E303,E402,W503,W504
|
ignore = E111,E114,E121,E125,E126,E127,E128,E129,E131,E133,E201,E202,E203,E211,E221,E222,E241,E251,E261,E303,E402,W503,W504
|
||||||
max-line-length = 80
|
max-line-length = 80
|
||||||
|
exclude = python3/vimspector/vendor
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue