import os import re import socket import sys import time import traceback import urllib.parse as urllib import vim from . import dbgp from . import error from . import log from . import opts class ExceptionHandler: """ Exception handlers """ def __init__(self, session_handler): self._session_handler = session_handler self.readable_errors = (error.EventError, error.BreakpointError, error.LogError, error.NoConnectionError, error.ModifiedBufferError) def exception_to_string(self, e): if isinstance(e, self.readable_errors): return str(e) return str(sys.exc_info()[0]) def handle_timeout(self): """Handle a timeout, which is pretty normal. """ self._session_handler.stop() self._session_handler.ui().say("No connection was made") def handle_interrupt(self): """Handle a user interrupt, which is pretty normal. """ self._session_handler.stop() self._session_handler.ui().say("Connection cancelled") def handle_socket_end(self): """Handle a socket closing, which is pretty normal. """ self._session_handler.ui().say( "Connection to the debugger has been closed" ) self._session_handler.stop() def handle_vim_error(self, e): """Handle a VIM error. This should NOT occur under normal circumstances. """ self._session_handler.ui().error("A Vim error occured: %s\n%s" % (e, traceback.format_exc())) def handle_readable_error(self, e): """Simply print an error, since it is human readable enough. """ self._session_handler.ui().error(str(e)) def handle_dbgp_error(self, e): """Simply print an error, since it is human readable enough. """ self._session_handler.ui().error(str(e.args[0])) def handle_general_exception(self): """Handle an unknown error of any kind. """ self._session_handler.ui().error("An error occured: %s\n%s" % ( sys.exc_info()[0], traceback.format_exc(5))) def handle(self, e): """Switch on the exception type to work out how to handle it. """ if isinstance(e, dbgp.TimeoutError): self.handle_timeout() elif isinstance(e, error.UserInterrupt): try: self.handle_interrupt() except Exception as e: pass elif isinstance(e, self.readable_errors): self.handle_readable_error(e) elif isinstance(e, dbgp.DBGPError): self.handle_dbgp_error(e) elif isinstance(e, (EOFError, socket.error)): self.handle_socket_end() elif isinstance(e, KeyboardInterrupt): print("Keyboard interrupt - debugging session cancelled") try: self._session_handler.stop() except Exception as e: pass else: self.handle_general_exception() class Keymapper: """Map and unmap key commands for the Vim user interface. """ exclude = ["run", "close", "set_breakpoint", "enable_breakpoint", "disable_breakpoint", "toggle_breakpoint" "eval_visual"] def __init__(self): self.is_mapped = False self._reload_keys() self.existing = [] def run_key(self): return self.keymaps['run'] def close_key(self): return self.keymaps['close'] def map(self): log.Log("keymapper: map", log.Logger.DEBUG) if self.is_mapped: return self._store_old_map() self._reload_keys() for func in self.keymaps: if func not in self.exclude: key = self.keymaps[func] map_cmd = "noremap %s%s :python3 debugger.%s()" % ( self.leader, key, func) vim.command(map_cmd) self.is_mapped = True def reload(self): log.Log("keymapper: reload", log.Logger.DEBUG) self.is_mapped = False self.map() def _reload_keys(self): log.Log("keymapper: reload_keys", log.Logger.DEBUG) self.keymaps = vim.eval("g:vdebug_keymap") self.leader = vim.eval("g:vdebug_leader_key") def _store_old_map(self): log.Log("keymapper: store_old_map", log.Logger.DEBUG) vim.command('let tempfile=tempname()') tempfile = vim.eval("tempfile") vim.command('mkexrc! %s' % (tempfile)) regex = re.compile(r'^([nvxsoilc]|)(nore)?map!?') split_regex = re.compile(r'\s+') keys = {v for k, v in self.keymaps.items() if k not in self.exclude} special = {"", "", "", "