From be44a22903d4bbf8993c440d45cb99e0c28570dc Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Wed, 5 Aug 2020 22:19:38 +0100 Subject: [PATCH] Allow coercing a type in vimspector config Initially I considered using #i, #s, etc. to coerce to specific types, but then it wasn't clear of the semantics (particularly for bool, where JSON bool true/false, Python bool True/False). But it turns out that we can just coerce any key from a JSON string. Users can _probably_ type JSON strings for most things, or use variables to run scripts to generate them, this allows essentially complete flexibility to define the data types needed to populate the launch spec. The purpose of this is to allow some level of automated setup by requesting data from the user and then (subsequently) saving the flattneed config to the vimspector config file. --- python3/vimspector/utils.py | 24 +++++++++++++++++-- .../python/simple_python/.vimspector.json | 6 +++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/python3/vimspector/utils.py b/python3/vimspector/utils.py index 9381407..02b0c85 100644 --- a/python3/vimspector/utils.py +++ b/python3/vimspector/utils.py @@ -24,6 +24,7 @@ import subprocess import shlex import collections import re +import typing LOG_FILE = os.path.expanduser( os.path.join( '~', '.vimspector.log' ) ) @@ -540,14 +541,30 @@ def ExpandReferencesInString( orig_s, return s +def CoerceType( mapping: typing.Dict[ str, typing.Any ], key: str ): + DICT_TYPES = { + 'json': json.loads, + } + + parts = key.split( '#' ) + if len( parts ) > 1 and parts[ -1 ] in DICT_TYPES.keys(): + value = mapping.pop( key ) + + new_type = parts[ -1 ] + key = '#'.join( parts[ 0 : -1 ] ) + + mapping[ key ] = DICT_TYPES[ new_type ]( value ) + + # TODO: Should we just run the substitution on the whole JSON string instead? # That woul dallow expansion in bool and number values, such as ports etc. ? def ExpandReferencesInDict( obj, mapping, calculus, user_choices ): - for k in obj.keys(): + for k in list( obj.keys() ): obj[ k ] = ExpandReferencesInObject( obj[ k ], mapping, calculus, user_choices ) + CoerceType( obj, k ) def ParseVariables( variables_list, @@ -560,9 +577,10 @@ def ParseVariables( variables_list, if not isinstance( variables_list, list ): variables_list = [ variables_list ] + variables: typing.Dict[ str, typing.Any ] for variables in variables_list: new_mapping.update( new_variables ) - for n, v in variables.items(): + for n, v in list( variables.items() ): if isinstance( v, dict ): if 'shell' in v: new_v = v.copy() @@ -597,6 +615,8 @@ def ParseVariables( variables_list, calculus, user_choices ) + CoerceType( new_variables, n ) + return new_variables diff --git a/support/test/python/simple_python/.vimspector.json b/support/test/python/simple_python/.vimspector.json index 6a1b838..a25a75b 100644 --- a/support/test/python/simple_python/.vimspector.json +++ b/support/test/python/simple_python/.vimspector.json @@ -57,8 +57,10 @@ "type": "python", "cwd": "${workspaceRoot}", "program": "${program:${file\\}}", - "stopOnEntry": false, - "console": "integratedTerminal" + "stopOnEntry#json": "${StopOnEntry:true}", + "console": "integratedTerminal", + "args#json": "${args:[]}", + "env#json": "${env:{\\}}" }, "breakpoints": { "exception": {