From 0cdab6be4ef4fd6c2c54db2d80be77d549c3b8f5 Mon Sep 17 00:00:00 2001 From: Ben Jackson Date: Thu, 25 Mar 2021 22:08:31 +0000 Subject: [PATCH] React to the debugpyAttach event and try and start a new session; this gets tripped up by the _vimspector.Variables (etc) buffers already existing. Probably need to add the sesssion ID to the buffer name --- autoload/vimspector/internal/state.vim | 8 ++-- python3/vimspector/custom/python.py | 46 +++++++++++++++++++ python3/vimspector/debug_session.py | 7 +-- python3/vimspector/gadgets.py | 3 +- python3/vimspector/session_manager.py | 12 ++++- .../python/multiprocessing/.vimspector.json | 24 ++++++++++ .../multiprocessing/multiprocessing_test.py | 27 +++++++++++ 7 files changed, 117 insertions(+), 10 deletions(-) create mode 100644 python3/vimspector/custom/python.py create mode 100644 support/test/python/multiprocessing/.vimspector.json create mode 100644 support/test/python/multiprocessing/multiprocessing_test.py diff --git a/autoload/vimspector/internal/state.vim b/autoload/vimspector/internal/state.vim index e628eaa..1c0458f 100644 --- a/autoload/vimspector/internal/state.vim +++ b/autoload/vimspector/internal/state.vim @@ -27,12 +27,10 @@ endif function! vimspector#internal#state#Reset() abort try py3 import vim - py3 _vimspector_session_manager = __import__( + py3 _vimspector_session = __import__( \ "vimspector", - \ fromlist=[ "session_manager" ] ).session_manager.SessionManager() - - py3 _vimspector_session = _vimspector_session_manager = - \ _vimspector_session_manager.NewSession( vim.eval( 's:prefix' ) ) + \ fromlist=[ "session_manager" ] ).session_manager.Get().NewSession( + \ vim.eval( 's:prefix' ) ) catch /.*/ echohl WarningMsg echom 'Exception while loading vimspector:' v:exception diff --git a/python3/vimspector/custom/python.py b/python3/vimspector/custom/python.py new file mode 100644 index 0000000..8f6f578 --- /dev/null +++ b/python3/vimspector/custom/python.py @@ -0,0 +1,46 @@ +# vimspector - A multi-language debugging system for Vim +# Copyright 2021 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.debug_session import DebugSession +from vimspector import session_manager + +from typing import Sequence + + +class Debugpy( object ): + parent: DebugSession + sessions: Sequence[ DebugSession ] + + def __init__( self, debug_session: DebugSession ): + self.parent = debug_session + + + def OnEvent_debugpyAttach( self, message ): + # Debugpy sends us the contents of a launch request that we should use. We + # probaly just jave to guess the rest + launch_argyments = message[ 'body' ] + session = session_manager.Get().NewSession( self.parent._api_prefix ) + + # Inject the launch config (HACK!). This will actually mean that the + # configuration passed below is ignored. + session._launch_config = launch_argyments + + # FIXME: We probably do need to add a StartWithLauncArguments and somehow + # tell the new session that it shoud not support "Restart" requests ? + # + # In fact, what even would Reset do... ? + session._StartWithConfiguration( self.parent._configuration, + self.parent._adapter ) + diff --git a/python3/vimspector/debug_session.py b/python3/vimspector/debug_session.py index 7b1916d..f80c217 100644 --- a/python3/vimspector/debug_session.py +++ b/python3/vimspector/debug_session.py @@ -1190,9 +1190,10 @@ class DebugSession( object ): self._on_init_complete_handlers = [] self._logger.debug( "LAUNCH!" ) - self._launch_config = {} - self._launch_config.update( self._adapter.get( 'configuration', {} ) ) - self._launch_config.update( self._configuration[ 'configuration' ] ) + if self._launch_config is None: + self._launch_config = {} + self._launch_config.update( self._adapter.get( 'configuration', {} ) ) + self._launch_config.update( self._configuration[ 'configuration' ] ) request = self._configuration.get( 'remote-request', diff --git a/python3/vimspector/gadgets.py b/python3/vimspector/gadgets.py index 528f60c..5524899 100644 --- a/python3/vimspector/gadgets.py +++ b/python3/vimspector/gadgets.py @@ -136,7 +136,8 @@ GADGETS = { # doesn't support the custom messages) # https://github.com/puremourning/vimspector/issues/141 "subProcess": False, - } + }, + 'custom_handler': 'vimspector.custom.python.Debugpy' } }, }, diff --git a/python3/vimspector/session_manager.py b/python3/vimspector/session_manager.py index 25a6f85..e48f03d 100644 --- a/python3/vimspector/session_manager.py +++ b/python3/vimspector/session_manager.py @@ -15,6 +15,9 @@ from vimspector.debug_session import DebugSession +# Singleton +_session_manager = None + class SessionManager: next_session_id = 0 @@ -41,6 +44,13 @@ class SessionManager: def GetSession( self, session_id ): return self.sessions.get( session_id ) - def CurrentSession( self ): return self.GetSession( self.current_session ) + + +def Get(): + global _session_manager + if _session_manager is None: + _session_manager = SessionManager() + + return _session_manager diff --git a/support/test/python/multiprocessing/.vimspector.json b/support/test/python/multiprocessing/.vimspector.json new file mode 100644 index 0000000..66272e3 --- /dev/null +++ b/support/test/python/multiprocessing/.vimspector.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://puremourning.github.io/vimspector/schema/vimspector.schema.json", + "configurations": { + "run": { + "adapter": "debugpy", + "configuration": { + "request": "launch", + "type": "python", + "cwd": "${workspaceRoot}", + "program": "${file}", + "stopOnEntry": false, + "console": "integratedTerminal", + "subProcess": true + }, + "breakpoints": { + "exception": { + "raised": "N", + "uncaught": "Y", + "userUnhandled": "" + } + } + } + } +} diff --git a/support/test/python/multiprocessing/multiprocessing_test.py b/support/test/python/multiprocessing/multiprocessing_test.py new file mode 100644 index 0000000..1a4d0a7 --- /dev/null +++ b/support/test/python/multiprocessing/multiprocessing_test.py @@ -0,0 +1,27 @@ +import time +import multiprocessing as mp + + +def First(): + for _ in range( 100 ): + print( "in first" ) + time.sleep( 0.1 ) + + +def Second(): + for _ in range( 100 ): + print( "in second" ) + time.sleep( 0.1 ) + + +print( "main" ) +p1 = mp.Process( target=First ) +p2 = mp.Process( target=Second ) + +p1.start() +p2.start() + +p1.join() +p2.join() + +print( "Done" )