Skip to content

Interface addons #248

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions doc/Vdebug.txt
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,8 @@ the current debugger status, connection details and a help message.

This shows the current position of the debugger. The file will automatically
change as the debugger pauses in different parts of the code, and the current
line is shown with a "->" sign in the margin.
line is shown centered vertically in the source window, with a "->" sign
in the margin.

Don't edit the contents of the file when in debug mode, and especially don't
edit without saving - this causes problems when swapping between files.
Expand Down Expand Up @@ -472,8 +473,8 @@ strings to indicate relationships. The compact version has a variable on each
line, and works better for smaller screens. To set this option, see
|VdebugOptions-watch_window_style|.

The watch window automatically updates every time the debugger pauses, so
nothing needs to be done on your part.
The watch window automatically updates every time the debugger pauses,
or a stack jump is made on the stack window (see next topic).

You can also see variables from different contexts. For example, PHP has normal
context variables and global variables, and the debugging engine differentiates
Expand All @@ -498,7 +499,12 @@ below show the path the script has taken.
Like the watch window, the stack will update automatically every time the
debugger pauses. You can jump to a place in the stack by putting your cursor
over a line and pressing <enter> (<cr>) or by double clicking with your mouse
(if you have mouse support enabled).
(if you have mouse support enabled). The watch window will be updated
with the file name and line number of the file in the current stack
depth (i.e. the index in the stack activated by <enter> ou double
click - the "stack jump"), and the stack window and the source window
will have a "#>" sign in their left margin marking the current stack
depth and the corresponding source line number, respectively.

------------------------------------------------------------------------------
4.2.4 The status window *VdebugStatusWindow*
Expand Down
58 changes: 51 additions & 7 deletions plugin/python/vdebug/dbgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import vdebug.log
import base64
import time
import re

""" Response objects for the DBGP module."""

Expand Down Expand Up @@ -119,9 +120,31 @@ def __init__(self,response,cmd,cmd_args,api):
Response.__init__(self,response,cmd,cmd_args,api)
self.properties = []

def get_page(self, cmd_args):
opts = re.compile('-p (\d+)')
page = None
result = opts.search(cmd_args)
if result != None:
page = int(result.group(1))
return page

def show_children(self):
return self.cmd == 'property_get'

def get_context(self):
page = self.get_page(self.cmd_args)
for c in list(self.as_xml()):
self.create_properties(ContextProperty(c))
self.create_properties(ContextProperty(c, init_children=self.show_children()))
if page == 0:
""" Loop through pages 2 to num_pages """
for p in xrange(1, self.properties[0].num_pages):
nth_cmd_args = self.cmd_args.replace('-p ' + str(page), '-p ' + str(p))
nth_prop = self.api.send_cmd(self.cmd, nth_cmd_args, ContextGetResponse)
""" First row is duplicated on pages > 0 so delete it """
nth_page = nth_prop.get_context()
del nth_page[0]

self.properties.extend(nth_page)

return self.properties

Expand Down Expand Up @@ -335,22 +358,22 @@ def stack_get(self):
"""
return self.send_cmd('stack_get','',StackGetResponse)

def context_get(self,context = 0):
def context_get(self,context = 0, depth = 0):
"""Get the context variables.
"""
return self.send_cmd('context_get',\
'-c %i' % int(context),\
'-c %i -d %i' % (int(context), int(depth)),\
ContextGetResponse)

def context_names(self):
"""Get the context types.
"""
return self.send_cmd('context_names','',ContextNamesResponse)

def property_get(self,name):
def property_get(self,name, depth = 0, page = 0):
"""Get a property.
"""
return self.send_cmd('property_get','-n %s -d 0' % name,ContextGetResponse)
return self.send_cmd('property_get','-n %s -d %i -p %i' % (name, int(depth), int(page)),ContextGetResponse)

def detach(self):
"""Tell the debugger to detach itself from this
Expand Down Expand Up @@ -525,8 +548,11 @@ class ContextProperty:

ns = '{urn:debugger_protocol_v1}'

def __init__(self,node,parent = None,depth = 0):
def __init__(self,node,parent = None,depth = 0, init_children = True):
self.parent = parent
""" Every child property will have a zero-based page property set """
if self.parent:
self.page = parent.page
self.__determine_type(node)
self._determine_displayname(node)
self.encoding = node.get('encoding')
Expand All @@ -538,7 +564,8 @@ def __init__(self,node,parent = None,depth = 0):

self._determine_children(node)
self.__determine_value(node)
self.__init_children(node)
if init_children:
self.__init_children(node)
if self.type == 'scalar':
self.size = len(self.value) - 2

Expand Down Expand Up @@ -606,6 +633,23 @@ def _determine_children(self,node):
children = int(children)
self.num_declared_children = children
self.has_children = children > 0
""" If the current element has children, initialize page properties """
self.page = None
self.pagesize = None
self.num_pages = 0
if self.has_children:
self.page = node.get('page')
self.pagesize = node.get('pagesize')
if self.page == None or self.pagesize == None:
self.page = 0
self.pagesize = 0
self.num_pages = 0
else:
self.page = int(self.page)
self.pagesize = int(self.pagesize)
self.num_pages = self.num_declared_children / self.pagesize
if (self.num_declared_children % self.pagesize):
self.num_pages += 1
self.children = []

def __init_children(self,node):
Expand Down
22 changes: 13 additions & 9 deletions plugin/python/vdebug/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,20 +131,23 @@ class StackWindowLineSelectEvent(Event):
"""Move the the currently selected file and line in the stack window
"""
def execute(self,runner):
lineno = vim.current.window.cursor[0]
stacklineno = vim.current.window.cursor[0]

vdebug.log.Log("User action in stack window, line %s" % lineno,\
vdebug.log.Log("User action in stack window, line %s" % stacklineno,\
vdebug.log.Logger.DEBUG)
line = runner.ui.stackwin.buffer[lineno-1]
if line.find(" @ ") == -1:
return False
filename_pos = line.find(" @ ") + 3
file_and_line = line[filename_pos:]
file_and_line = runner.ui.stackwin.get_file_and_line(stacklineno)
line_pos = file_and_line.rfind(":")
file = vdebug.util.LocalFilePath(file_and_line[:line_pos])

""" Setting stack depth and current file_and_line in runner """
runner.set_context_stack_info(stacklineno - 1, file_and_line)

lineno = file_and_line[line_pos+1:]
runner.ui.sourcewin.set_file(file)
runner.ui.sourcewin.set_line(lineno)
runner.ui.sourcewin.place_stack_sign(lineno)
runner.ui.stackwin.place_stack_sign(stacklineno)
runner.get_context(0)

class WatchWindowPropertyGetEvent(Event):
"""Open a tree node in the watch window.
Expand All @@ -159,10 +162,11 @@ def execute(self,runner):

eq_index = line.find('=')
if eq_index == -1:
raise EventError("Cannot read the selected property")
return

name = line[pointer_index+step:eq_index-1]
context_res = runner.api.property_get(name)
""" Refactoring property_get with multiple pages """
context_res = runner.property_get(name)
rend = vdebug.ui.vimui.ContextGetResponseRenderer(context_res)
output = rend.render(pointer_index - 1)
if vdebug.opts.Options.get('watch_window_style') == 'expanded':
Expand Down
28 changes: 24 additions & 4 deletions plugin/python/vdebug/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ def open(self):
status = self.api.step_into()
else:
status = self.api.run()

""" Updating stack on open, for watchwin correct title """
if status in ["running", "break"]:
self.update_stack()
self.set_context_stack_info(0)
self.refresh(status)
except Exception:
self.close()
Expand All @@ -95,7 +100,7 @@ def save_code(self,code):
return code

def refresh(self,status):
"""The main action performed after a deubugger step.
"""The main action performed after a debugger step.

Updates the status window, current stack, source
file and line and watch window."""
Expand Down Expand Up @@ -128,6 +133,11 @@ def refresh(self,status):
self.cur_file,\
self.cur_lineno)

""" Removing stack signs """
self.ui.stackwin.remove_stack_sign()
self.ui.sourcewin.remove_stack_sign()
self.set_context_stack_info(0)

if self.saved_code != '':
self.eval(self.saved_code)
else:
Expand All @@ -138,14 +148,15 @@ def get_context(self,context_id = 0):
self.ui.tracewin.clean()
name = self.context_names[context_id]
vdebug.log.Log("Getting %s variables" % name)
context_res = self.api.context_get(context_id)
context_res = self.api.context_get(context_id, self.context_stack_depth)

rend = vdebug.ui.vimui.ContextGetResponseRenderer(\
context_res,"%s at %s:%s" \
%(name,self.ui.sourcewin.file,self.cur_lineno),\
context_res,"%s at %s" \
%(name, self.context_file_and_line),\
self.context_names, context_id)

self.ui.watchwin.accept_renderer(rend)
self.ui.watchwin.open_child_properties(self)

if self.ui.tracewin.is_tracing():
try:
Expand All @@ -157,6 +168,8 @@ def get_context(self,context_id = 0):
except vdebug.dbgp.EvalError:
self.ui.tracewin.render_in_error_case()

def property_get(self, name):
return self.api.property_get(name, self.context_stack_depth)

def toggle_breakpoint_window(self):
"""Open or close the breakpoint window.
Expand Down Expand Up @@ -345,6 +358,13 @@ def update_stack(self):
renderer = vdebug.ui.vimui.StackGetResponseRenderer(res)
self.ui.stackwin.accept_renderer(renderer)
return res

def set_context_stack_info(self, stack_depth, file_and_line = ''):
""" stack_depth parameter is zero-based """
self.context_stack_depth = stack_depth
if (file_and_line == ''):
file_and_line = self.ui.stackwin.get_file_and_line(stack_depth + 1)
self.context_file_and_line = file_and_line

def detach(self):
"""Detach the debugger engine, and allow it to continue execution.
Expand Down
51 changes: 49 additions & 2 deletions plugin/python/vdebug/ui/vimui.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import vim
import vdebug.log
import vdebug.opts
import vdebug.event

class Ui(vdebug.ui.interface.Ui):
"""Ui layer which manages the Vim windows.
Expand Down Expand Up @@ -218,6 +219,7 @@ class SourceWindow(vdebug.ui.interface.Window):
file = None
pointer_sign_id = '6145'
breakpoint_sign_id = '6146'
stack_sign_id = '6147'

def __init__(self,ui,winno):
self.winno = str(winno)
Expand All @@ -244,7 +246,8 @@ def set_file(self,file):

def set_line(self,lineno):
self.focus()
vim.command("normal %sgg" % str(lineno))
""" Centering display vertically on lineno """
vim.command("normal %szz" % str(lineno))

def get_file(self):
self.focus()
Expand All @@ -265,6 +268,17 @@ def place_pointer(self,line):
def remove_pointer(self):
vim.command('sign unplace %s' % self.pointer_sign_id)

def place_stack_sign(self, line):
self.remove_stack_sign()
vdebug.log.Log("Placing stack sign on line "+str(line),\
vdebug.log.Logger.INFO)
vim.command('sign place '+self.stack_sign_id+\
' name=stack line='+str(line)+\
' file='+self.file)

def remove_stack_sign(self):
vim.command('sign unplace %s' % self.stack_sign_id)

class Window(vdebug.ui.interface.Window):
name = "WINDOW"
open_cmd = "new"
Expand All @@ -279,6 +293,9 @@ def __init__(self,ui,open_cmd):
def getwinnr(self):
return int(vim.eval("bufwinnr('"+self.name+"')"))

def focus(self):
vim.command(str(self.getwinnr())+"wincmd w")

def set_height(self,height):
height = int(height)
minheight = int(vim.eval("&winminheight"))
Expand Down Expand Up @@ -431,6 +448,7 @@ def write(self, msg, return_focus = True):

class StackWindow(Window):
name = "DebuggerStack"
stack_sign_id = '6148'

def on_create(self):
self.command('inoremap <buffer> <cr> <esc>'+\
Expand All @@ -447,6 +465,24 @@ def on_create(self):
def write(self, msg, return_focus = True):
Window.write(self, msg, after="normal gg")

def place_stack_sign(self, line):
self.remove_stack_sign()
self.focus()
vim.command('sign place ' + self.stack_sign_id +\
' name=stack' +\
' line=' + str(line) +\
' buffer=' + vim.eval("bufnr('%')"))

def remove_stack_sign(self):
vim.command('sign unplace %s' % self.stack_sign_id)

def get_file_and_line(self, stacklineno):
line = self.buffer[stacklineno - 1]
if line.find(" @ ") == -1:
return False
filename_pos = line.find(" @ ") + 3
return line[filename_pos:]

class WatchWindow(Window):
name = "DebuggerWatch"

Expand All @@ -465,6 +501,17 @@ def on_create(self):
def write(self, msg, return_focus = True):
Window.write(self, msg, after="normal gg")

def open_child_properties(self, runner):
self.focus()
last_line_idx = int(vim.eval("line('$')")) - 1
first_line_idx = -1
for idx in xrange(last_line_idx, first_line_idx, -1):
self.command('normal ' + str(idx+1) + 'G')
line = vim.current.buffer[idx]
if line.startswith(' ' + vdebug.opts.Options.get('marker_closed_tree')):
vdebug.event.WatchWindowPropertyGetEvent().execute(runner)
self.command('normal gg')

class StatusWindow(Window):
name = "DebuggerStatus"

Expand Down Expand Up @@ -540,7 +587,7 @@ def render(self):
%{'num':s.get('level'),'where':where,\
'file':str(file.as_local()),'line':s.get('lineno')}
string += line + "\n"
return string
return string[:-1]


class ContextGetResponseRenderer(ResponseRenderer):
Expand Down
Loading