Calculate variables on-demand; add an unused-local-port variable-function
This commit is contained in:
parent
85667a5bac
commit
044804ca20
2 changed files with 71 additions and 32 deletions
|
|
@ -177,43 +177,53 @@ class DebugSession( object ):
|
||||||
return [ '', '' ]
|
return [ '', '' ]
|
||||||
return os.path.splitext( p )
|
return os.path.splitext( p )
|
||||||
|
|
||||||
self._variables = {
|
variables = {
|
||||||
'dollar': '$', # HACK. Hote '$$' also works.
|
'dollar': '$', # HACK. Hote '$$' also works.
|
||||||
'workspaceRoot': self._workspace_root,
|
'workspaceRoot': self._workspace_root,
|
||||||
'workspaceFolder': self._workspace_root,
|
'workspaceFolder': self._workspace_root,
|
||||||
'gadgetDir': install.GetGadgetDir( VIMSPECTOR_HOME, install.GetOS() ),
|
|
||||||
'file': current_file,
|
'file': current_file,
|
||||||
'relativeFile': relpath( current_file, self._workspace_root ),
|
}
|
||||||
'fileBasename': os.path.basename( current_file ),
|
|
||||||
|
calculus = {
|
||||||
|
'gadgetDir': lambda: install.GetGadgetDir( VIMSPECTOR_HOME,
|
||||||
|
install.GetOS() ),
|
||||||
|
'relativeFile': lambda: relpath( current_file,
|
||||||
|
self._workspace_root ),
|
||||||
|
'fileBasename': lambda: os.path.basename( current_file ),
|
||||||
'fileBasenameNoExtension':
|
'fileBasenameNoExtension':
|
||||||
splitext( os.path.basename( current_file ) )[ 0 ],
|
lambda: splitext( os.path.basename( current_file ) )[ 0 ],
|
||||||
'fileDirname': os.path.dirname( current_file ),
|
'fileDirname': lambda: os.path.dirname( current_file ),
|
||||||
'fileExtname': splitext( os.path.basename( current_file ) )[ 1 ],
|
'fileExtname': lambda: splitext( os.path.basename( current_file ) )[ 1 ],
|
||||||
# NOTE: this is the window-local cwd for the current window, *not* Vim's
|
# NOTE: this is the window-local cwd for the current window, *not* Vim's
|
||||||
# working directory.
|
# working directory.
|
||||||
'cwd': os.getcwd(),
|
'cwd': os.getcwd,
|
||||||
|
'unusedLocalPort': utils.GetUnusedLocalPort,
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pretend that vars passed to the launch command were typed in by the user
|
# Pretend that vars passed to the launch command were typed in by the user
|
||||||
# (they may have been in theory)
|
# (they may have been in theory)
|
||||||
USER_CHOICES.update( launch_variables )
|
USER_CHOICES.update( launch_variables )
|
||||||
self._variables.update( launch_variables )
|
variables.update( launch_variables )
|
||||||
|
|
||||||
self._variables.update(
|
variables.update(
|
||||||
utils.ParseVariables( adapter.get( 'variables', {} ),
|
utils.ParseVariables( adapter.get( 'variables', {} ),
|
||||||
self._variables,
|
variables,
|
||||||
|
calculus,
|
||||||
USER_CHOICES ) )
|
USER_CHOICES ) )
|
||||||
self._variables.update(
|
variables.update(
|
||||||
utils.ParseVariables( configuration.get( 'variables', {} ),
|
utils.ParseVariables( configuration.get( 'variables', {} ),
|
||||||
self._variables,
|
variables,
|
||||||
|
calculus,
|
||||||
USER_CHOICES ) )
|
USER_CHOICES ) )
|
||||||
|
|
||||||
|
|
||||||
utils.ExpandReferencesInDict( configuration,
|
utils.ExpandReferencesInDict( configuration,
|
||||||
self._variables,
|
variables,
|
||||||
|
calculus,
|
||||||
USER_CHOICES )
|
USER_CHOICES )
|
||||||
utils.ExpandReferencesInDict( adapter,
|
utils.ExpandReferencesInDict( adapter,
|
||||||
self._variables,
|
variables,
|
||||||
|
calculus,
|
||||||
USER_CHOICES )
|
USER_CHOICES )
|
||||||
|
|
||||||
if not adapter:
|
if not adapter:
|
||||||
|
|
|
||||||
|
|
@ -345,9 +345,9 @@ def IsCurrent( window, buf ):
|
||||||
return vim.current.window == window and vim.current.window.buffer == buf
|
return vim.current.window == window and vim.current.window.buffer == buf
|
||||||
|
|
||||||
|
|
||||||
def ExpandReferencesInObject( obj, mapping, user_choices ):
|
def ExpandReferencesInObject( obj, mapping, calculus, user_choices ):
|
||||||
if isinstance( obj, dict ):
|
if isinstance( obj, dict ):
|
||||||
ExpandReferencesInDict( obj, mapping, user_choices )
|
ExpandReferencesInDict( obj, mapping, calculus, user_choices )
|
||||||
elif isinstance( obj, list ):
|
elif isinstance( obj, list ):
|
||||||
j_offset = 0
|
j_offset = 0
|
||||||
obj_copy = list( obj )
|
obj_copy = list( obj )
|
||||||
|
|
@ -360,6 +360,7 @@ def ExpandReferencesInObject( obj, mapping, user_choices ):
|
||||||
# *${something} - expand list in place
|
# *${something} - expand list in place
|
||||||
value = ExpandReferencesInString( obj_copy[ i ][ 1: ],
|
value = ExpandReferencesInString( obj_copy[ i ][ 1: ],
|
||||||
mapping,
|
mapping,
|
||||||
|
calculus,
|
||||||
user_choices )
|
user_choices )
|
||||||
obj.pop( j )
|
obj.pop( j )
|
||||||
j_offset -= 1
|
j_offset -= 1
|
||||||
|
|
@ -369,14 +370,18 @@ def ExpandReferencesInObject( obj, mapping, user_choices ):
|
||||||
else:
|
else:
|
||||||
obj[ j ] = ExpandReferencesInObject( obj_copy[ i ],
|
obj[ j ] = ExpandReferencesInObject( obj_copy[ i ],
|
||||||
mapping,
|
mapping,
|
||||||
|
calculus,
|
||||||
user_choices )
|
user_choices )
|
||||||
elif isinstance( obj, str ):
|
elif isinstance( obj, str ):
|
||||||
obj = ExpandReferencesInString( obj, mapping, user_choices )
|
obj = ExpandReferencesInString( obj, mapping, calculus, user_choices )
|
||||||
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def ExpandReferencesInString( orig_s, mapping, user_choices ):
|
def ExpandReferencesInString( orig_s,
|
||||||
|
mapping,
|
||||||
|
calculus,
|
||||||
|
user_choices ):
|
||||||
s = os.path.expanduser( orig_s )
|
s = os.path.expanduser( orig_s )
|
||||||
s = os.path.expandvars( s )
|
s = os.path.expandvars( s )
|
||||||
|
|
||||||
|
|
@ -393,6 +398,10 @@ def ExpandReferencesInString( orig_s, mapping, user_choices ):
|
||||||
# HACK: This is seemingly the only way to get the key. str( e ) returns
|
# HACK: This is seemingly the only way to get the key. str( e ) returns
|
||||||
# the key surrounded by '' for unknowable reasons.
|
# the key surrounded by '' for unknowable reasons.
|
||||||
key = e.args[ 0 ]
|
key = e.args[ 0 ]
|
||||||
|
|
||||||
|
if key in calculus:
|
||||||
|
mapping[ key ] = calculus[ key ]()
|
||||||
|
else:
|
||||||
default_value = user_choices.get( key, None )
|
default_value = user_choices.get( key, None )
|
||||||
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
mapping[ key ] = AskForInput( 'Enter value for {}: '.format( key ),
|
||||||
default_value )
|
default_value )
|
||||||
|
|
@ -412,12 +421,18 @@ def ExpandReferencesInString( orig_s, mapping, user_choices ):
|
||||||
|
|
||||||
# TODO: Should we just run the substitution on the whole JSON string instead?
|
# 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. ?
|
# That woul dallow expansion in bool and number values, such as ports etc. ?
|
||||||
def ExpandReferencesInDict( obj, mapping, user_choices ):
|
def ExpandReferencesInDict( obj, mapping, calculus, user_choices ):
|
||||||
for k in obj.keys():
|
for k in obj.keys():
|
||||||
obj[ k ] = ExpandReferencesInObject( obj[ k ], mapping, user_choices )
|
obj[ k ] = ExpandReferencesInObject( obj[ k ],
|
||||||
|
mapping,
|
||||||
|
calculus,
|
||||||
|
user_choices )
|
||||||
|
|
||||||
|
|
||||||
def ParseVariables( variables_list, mapping, user_choices ):
|
def ParseVariables( variables_list,
|
||||||
|
mapping,
|
||||||
|
calculus,
|
||||||
|
user_choices ):
|
||||||
new_variables = {}
|
new_variables = {}
|
||||||
new_mapping = mapping.copy()
|
new_mapping = mapping.copy()
|
||||||
|
|
||||||
|
|
@ -431,7 +446,10 @@ def ParseVariables( variables_list, mapping, user_choices ):
|
||||||
if 'shell' in v:
|
if 'shell' in v:
|
||||||
new_v = v.copy()
|
new_v = v.copy()
|
||||||
# Bit of a hack. Allows environment variables to be used.
|
# Bit of a hack. Allows environment variables to be used.
|
||||||
ExpandReferencesInDict( new_v, new_mapping, user_choices )
|
ExpandReferencesInDict( new_v,
|
||||||
|
new_mapping,
|
||||||
|
calculus,
|
||||||
|
user_choices )
|
||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env.update( new_v.get( 'env' ) or {} )
|
env.update( new_v.get( 'env' ) or {} )
|
||||||
|
|
@ -455,6 +473,7 @@ def ParseVariables( variables_list, mapping, user_choices ):
|
||||||
else:
|
else:
|
||||||
new_variables[ n ] = ExpandReferencesInObject( v,
|
new_variables[ n ] = ExpandReferencesInObject( v,
|
||||||
mapping,
|
mapping,
|
||||||
|
calculus,
|
||||||
user_choices )
|
user_choices )
|
||||||
|
|
||||||
return new_variables
|
return new_variables
|
||||||
|
|
@ -575,3 +594,13 @@ def GetVimspectorBase():
|
||||||
return base.decode( 'utf-8' )
|
return base.decode( 'utf-8' )
|
||||||
else:
|
else:
|
||||||
return base
|
return base
|
||||||
|
|
||||||
|
|
||||||
|
def GetUnusedLocalPort():
|
||||||
|
import socket
|
||||||
|
sock = socket.socket()
|
||||||
|
# This tells the OS to give us any free port in the range [1024 - 65535]
|
||||||
|
sock.bind( ( '', 0 ) )
|
||||||
|
port = sock.getsockname()[ 1 ]
|
||||||
|
sock.close()
|
||||||
|
return port
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue