diff options
author | Ike Devolder <ike.devolder@gmail.com> | 2019-07-04 23:32:08 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-07-04 23:32:08 +0200 |
commit | f16351a94bc784a7c5e20e4b1a08f2f4de34f2be (patch) | |
tree | 525d7ca4b63e58c4c6b7763b48746d9884c294d9 | |
parent | e3af9800fd19f903a96e54dd4b15886a195cc1ee (diff) | |
parent | 3223b2aea1d80d5f568be5efd32023d12cbff3c5 (diff) | |
download | vdebug-f16351a94bc784a7c5e20e4b1a08f2f4de34f2be.zip |
Merge pull request #404 from Garethp/breakpoint-toggle
Adding support for breakpoint enabling/disabling (Solve #393)
-rw-r--r-- | plugin/vdebug.vim | 6 | ||||
-rw-r--r-- | python3/vdebug/breakpoint.py | 47 | ||||
-rw-r--r-- | python3/vdebug/dbgp.py | 6 | ||||
-rw-r--r-- | python3/vdebug/debugger_interface.py | 25 | ||||
-rw-r--r-- | python3/vdebug/event.py | 116 | ||||
-rw-r--r-- | python3/vdebug/ui/vimui.py | 11 | ||||
-rw-r--r-- | python3/vdebug/util.py | 3 |
7 files changed, 210 insertions, 4 deletions
diff --git a/plugin/vdebug.vim b/plugin/vdebug.vim index 5997950..084e640 100644 --- a/plugin/vdebug.vim +++ b/plugin/vdebug.vim @@ -90,6 +90,7 @@ let g:vdebug_options_defaults = { \ 'marker_open_tree' : '▾', \ 'sign_breakpoint' : '▷', \ 'sign_current' : '▶', +\ 'sign_disabled': '▌▌', \ 'continuous_mode' : 1, \ 'background_listener' : 1, \ 'auto_start' : 1, @@ -120,7 +121,8 @@ python3 import vdebug.debugger_interface python3 debugger = vdebug.debugger_interface.DebuggerInterface() " Commands -command! -nargs=? -complete=customlist,s:BreakpointTypes Breakpoint python3 debugger.set_breakpoint(<q-args>) +command! -nargs=? -complete=customlist,s:BreakpointTypes Breakpoint python3 debugger.cycle_breakpoint(<q-args>) +command! -nargs=? -complete=customlist,s:BreakpointTypes SetBreakpoint python3 debugger.set_breakpoint(<q-args>) command! VdebugStart python3 debugger.run() command! -nargs=? BreakpointRemove python3 debugger.remove_breakpoint(<q-args>) command! BreakpointWindow python3 debugger.toggle_breakpoint_window() @@ -129,6 +131,7 @@ command! -nargs=+ -complete=customlist,s:OptionNames VdebugOpt :call Vdebug_set_ command! -nargs=+ VdebugPathMap :call Vdebug_path_map(<f-args>) command! -nargs=+ VdebugAddPathMap :call Vdebug_add_path_map(<f-args>) command! -nargs=? VdebugTrace python3 debugger.handle_trace(<q-args>) +command! -nargs=? BreakpointStatus python3 debugger.breakpoint_status(<q-args>) if hlexists('DbgCurrentLine') == 0 hi default DbgCurrentLine term=reverse ctermfg=White ctermbg=Red guifg=#ffffff guibg=#ff0000 @@ -147,6 +150,7 @@ end function! s:DefineSigns() exe 'sign define breakpt text=' . g:vdebug_options['sign_breakpoint'] . ' texthl=DbgBreakptSign linehl=DbgBreakptLine' exe 'sign define current text=' . g:vdebug_options['sign_current'] . ' texthl=DbgCurrentSign linehl=DbgCurrentLine' + exe 'sign define breakpt_dis text=' . g:vdebug_options['sign_disabled'] . ' texthl=DbgDisabledSign linehl=DbgDisabledLine' endfunction function! s:BreakpointTypes(A,L,P) diff --git a/python3/vdebug/breakpoint.py b/python3/vdebug/breakpoint.py index ccabcd9..48b529d 100644 --- a/python3/vdebug/breakpoint.py +++ b/python3/vdebug/breakpoint.py @@ -41,6 +41,33 @@ class Store: res = self.api.breakpoint_set(breakpoint.get_cmd()) breakpoint.set_debugger_id(res.get_id()) + def toggle_breakpoint_by_id(self, id): + id = str(id) + if id not in self.breakpoints: + raise error.BreakpointError("No breakpoint matching ID %s" % id) + if self.breakpoints[id].enabled: + self.disable_breakpoint_by_id(id) + else: + self.enable_breakpoint_by_id(id) + + def enable_breakpoint_by_id(self, id): + id = str(id) + if id not in self.breakpoints: + raise error.BreakpointError("No breakpoint matching ID %s" % id) + dbg_id = self.breakpoints[id].get_debugger_id() + if dbg_id is not None: + self.api.breakpoint_enable(dbg_id) + self.breakpoints[id].on_enable() + + def disable_breakpoint_by_id(self, id): + id = str(id) + if id not in self.breakpoints: + raise error.BreakpointError("No breakpoint matching ID %s" % id) + dbg_id = self.breakpoints[id].get_debugger_id() + if dbg_id is not None: + self.api.breakpoint_disable(dbg_id) + self.breakpoints[id].on_disable() + def remove_breakpoint(self, breakpoint): self.remove_breakpoint_by_id(breakpoint.get_id()) @@ -63,6 +90,13 @@ class Store: self.remove_breakpoint_by_id(id) self.breakpoints = {} + def get_breakpoint_by_id(self, id): + id = str(id) + if id not in list(self.breakpoints.keys()): + return None + + return self.breakpoints[id] + def find_breakpoint(self, file, line): found = None for bp in self.breakpoints.values(): @@ -88,6 +122,7 @@ class Breakpoint: self.id = Breakpoint.id Breakpoint.id += 1 self.ui = ui + self.enabled = True def get_id(self): return self.id @@ -101,6 +136,14 @@ class Breakpoint: def on_add(self): self.ui.register_breakpoint(self) + def on_enable(self): + self.enabled = True + self.ui.enable_breakpoint(self) + + def on_disable(self): + self.enabled = False + self.ui.disable_breakpoint(self) + def on_remove(self): self.ui.remove_breakpoint(self) @@ -188,8 +231,8 @@ class LineBreakpoint(Breakpoint): return self.file def get_cmd(self): - return '-t {} -f "{}" -n {} -s enabled'.format( - self.type, self.file.as_remote(), self.line) + return '-t {} -f "{}" -n {} -s {}'.format( + self.type, self.file.as_remote(), self.line, "enabled" if self.enabled else "disabled") class TemporaryLineBreakpoint(LineBreakpoint): diff --git a/python3/vdebug/dbgp.py b/python3/vdebug/dbgp.py index bfa2ec8..91d5912 100644 --- a/python3/vdebug/dbgp.py +++ b/python3/vdebug/dbgp.py @@ -381,6 +381,12 @@ class Api: def breakpoint_list(self): return self.send_cmd('breakpoint_list') + def breakpoint_disable(self, id): + return self.send_cmd('breakpoint_update', '-d %i -s disabled' % id, Response) + + def breakpoint_enable(self, id): + return self.send_cmd('breakpoint_update', '-d %i -s enabled' % id, Response) + def breakpoint_remove(self, id): """Remove a breakpoint by ID. diff --git a/python3/vdebug/debugger_interface.py b/python3/vdebug/debugger_interface.py index 030d508..b154291 100644 --- a/python3/vdebug/debugger_interface.py +++ b/python3/vdebug/debugger_interface.py @@ -114,6 +114,31 @@ class DebuggerInterface: """ self.session_handler.dispatch_event("set_breakpoint", args) + def cycle_breakpoint(self, args=None): + """Cycle a breakpoint between Enabled, Disabled and Removed + """ + self.session_handler.dispatch_event("cycle_breakpoint", args) + + def toggle_breakpoint(self, args=None): + """Toggle a breakpoint, specified by args + """ + self.session_handler.dispatch_event("toggle_breakpoint", args) + + def enable_breakpoint(self, args=None): + """Enable a breakpoint, specified by args + """ + self.session_handler.dispatch_event("enable_breakpoint", args) + + def disable_breakpoint(self, args=None): + """Disable a breakpoint, specified by args + """ + self.session_handler.dispatch_event("disable_breakpoint", args) + + def breakpoint_status(self, args=None): + """Either gets the status of a breakpoint or changes it + """ + self.session_handler.dispatch_event("breakpoint_status", args) + def remove_breakpoint(self, args=None): """Remove one or more breakpoints, specified by args. """ diff --git a/python3/vdebug/event.py b/python3/vdebug/event.py index 49eb893..7463f9a 100644 --- a/python3/vdebug/event.py +++ b/python3/vdebug/event.py @@ -401,6 +401,117 @@ class SetBreakpointEvent(Event): self.session_handler.breakpoints().add_breakpoint(bp) +class BreakpointStatusEvent(Event): + def parseArgs(self, args): + if args is None: + args = "" + args = args.strip() + + arg_parts = args.split(' ') + first_param = arg_parts.pop(0) + if first_param == "": + return { "id": None, "action": None } + + if first_param in ("toggle", "enable", "disable"): + return { "id": None, "action": first_param } + + if len(arg_parts) == 0: + return { "id": first_param , "action": None } + + second_param = arg_parts.pop(0) + return { "id": first_param, "action": second_param } + + def get_breakpoint(self, id): + if id is not None: + return self.session_handler.breakpoints().get_breakpoint_by_id(id) + + """ Line breakpoint """ + try: + file = self.ui.get_current_file() + line = self.ui.get_current_row() + id = self.session_handler.breakpoints().find_breakpoint(file, line) + if id is None: + return None + + return self.session_handler.breakpoints().get_breakpoint_by_id(id) + except error.FilePathError: + raise error.BreakpointError('No file, cannot set breakpoint') + + def run(self, args): + parsed_args = self.parseArgs(args) + id = parsed_args["id"] + action = parsed_args["action"] + bp = self.get_breakpoint(id) + + if bp is None: + print("No breakpoint found") + return + + if action is None: + print("enabled" if bp.enabled else "disabled") + return + + if action == "enable": + return self.dispatch("enable_breakpoint", str(bp.id)) + + if action == "disable": + return self.dispatch("disable_breakpoint", str(bp.id)) + + if action == "toggle": + return self.dispatch("toggle_breakpoint", str(bp.id)) + + +class CycleBreakpointStatusEvent(BreakpointStatusEvent): + + def run(self, args): + parsed_args = self.parseArgs(args) + id = parsed_args["id"] + bp = self.get_breakpoint(id) + + if bp is None: + self.dispatch("set_breakpoint", args) + return + + if bp is not None: + if bp.enabled: + self.session_handler.breakpoints().disable_breakpoint_by_id(bp.id) + else: + self.session_handler.breakpoints().remove_breakpoint_by_id(bp.id) + + +class ToggleBreakpointEvent(BreakpointStatusEvent): + + def run(self, args): + parsed_args = self.parseArgs(args) + id = parsed_args["id"] + bp = self.get_breakpoint(id) + + if bp is not None and bp.type == "line": + self.session_handler.breakpoints().toggle_breakpoint_by_id(bp.id) + + +class EnableBreakpointEvent(BreakpointStatusEvent): + + def run(self, args): + parsed_args = self.parseArgs(args) + id = parsed_args["id"] + bp = self.get_breakpoint(id) + + if bp is not None and bp.type == "line": + self.session_handler.breakpoints().enable_breakpoint_by_id(id) + + +class DisableBreakpointEvent(BreakpointStatusEvent): + + def run(self, args): + parsed_args = self.parseArgs(args) + id = parsed_args["id"] + bp = self.get_breakpoint(id) + + if bp is not None and bp.type == "line": + self.session_handler.breakpoints().disable_breakpoint_by_id(id) + + class RemoveBreakpointEvent(Event): def run(self, args): @@ -506,6 +617,11 @@ class Dispatcher: "eval": EvalEvent, "set_eval_expression": SetEvalExpressionEvent, "set_breakpoint": SetBreakpointEvent, + "cycle_breakpoint": CycleBreakpointStatusEvent, + "toggle_breakpoint": ToggleBreakpointEvent, + "enable_breakpoint": EnableBreakpointEvent, + "disable_breakpoint": DisableBreakpointEvent, + "breakpoint_status": BreakpointStatusEvent, "get_context": GetContextEvent, "reload_keymappings": ReloadKeymappingsEvent, "remove_breakpoint": RemoveBreakpointEvent, diff --git a/python3/vdebug/ui/vimui.py b/python3/vdebug/ui/vimui.py index 7653966..d543ad5 100644 --- a/python3/vdebug/ui/vimui.py +++ b/python3/vdebug/ui/vimui.py @@ -204,6 +204,17 @@ class Ui(interface.Ui): vim.command('sign place %s name=breakpt line=%s file=%s' % (sign_id, line, file.as_local())) + def enable_breakpoint(self, breakpoint): + self.place_breakpoint(breakpoint.id, breakpoint.file, breakpoint.line) + + def disable_breakpoint(self, breakpoint): + self.place_disabled_breakpoint(breakpoint.id, breakpoint.file, breakpoint.line) + + @staticmethod + def place_disabled_breakpoint(sign_id, file, line): + vim.command('sign place %s name=breakpt_dis line=%s file=%s' + % (sign_id, line, file.as_local())) + def remove_breakpoint(self, breakpoint): id = breakpoint.id vim.command('sign unplace %i' % id) diff --git a/python3/vdebug/util.py b/python3/vdebug/util.py index 9ee1e49..653705e 100644 --- a/python3/vdebug/util.py +++ b/python3/vdebug/util.py @@ -104,7 +104,8 @@ class Keymapper: """Map and unmap key commands for the Vim user interface. """ - exclude = ["run", "close", "set_breakpoint", "eval_visual"] + exclude = ["run", "close", "set_breakpoint", "enable_breakpoint", "disable_breakpoint", + "toggle_breakpoint" "eval_visual"] def __init__(self): self.is_mapped = False |