From 341fa53ef5adf8df0b43b2643f5a24fd3639fb2c Mon Sep 17 00:00:00 2001 From: Rocco Caputo Date: Wed, 18 Mar 2020 21:32:32 -0400 Subject: [PATCH] Highlight Variables that have changed since the last render. I like how Registers highlight changes and thought it would be nice to also have that for Variables. The implementation ended up being more invasive than initially expected because of how the Variables class is used to display variables for other views. --- .gdbinit | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/.gdbinit b/.gdbinit index 4ddc693..e431a04 100644 --- a/.gdbinit +++ b/.gdbinit @@ -1484,12 +1484,15 @@ A value of 0 uses the whole height.''', class Variables(Dashboard.Module): '''Show arguments and locals of the selected frame.''' + def __init__(self): + self.previous_values = {} + def label(self): return 'Variables' def lines(self, term_width, term_height, style_changed): return Variables.format_frame( - gdb.selected_frame(), self.show_arguments, self.show_locals, self.compact, self.align) + gdb.selected_frame(), self.show_arguments, self.show_locals, self.compact, self.align, self) def attributes(self): return { @@ -1518,7 +1521,7 @@ class Variables(Dashboard.Module): } @staticmethod - def format_frame(frame, show_arguments, show_locals, compact, align): + def format_frame(frame, show_arguments, show_locals, compact, align, myself): out = [] # fetch frame arguments and locals decorator = gdb.FrameDecorator.FrameDecorator(frame) @@ -1527,7 +1530,7 @@ class Variables(Dashboard.Module): def prefix(line): return Stack.format_line('arg', line) frame_args = decorator.frame_args() - args_lines = Variables.fetch(frame, frame_args, compact, align) + args_lines = Variables.fetch(frame, frame_args, compact, align, myself) if args_lines: if compact: args_line = separator.join(args_lines) @@ -1539,7 +1542,7 @@ class Variables(Dashboard.Module): def prefix(line): return Stack.format_line('loc', line) frame_locals = decorator.frame_locals() - locals_lines = Variables.fetch(frame, frame_locals, compact, align) + locals_lines = Variables.fetch(frame, frame_locals, compact, align, myself) if locals_lines: if compact: locals_line = separator.join(locals_lines) @@ -1550,16 +1553,21 @@ class Variables(Dashboard.Module): return out @staticmethod - def fetch(frame, data, compact, align): + def fetch(frame, data, compact, align, myself): lines = [] name_width = 0 if align and not compact: name_width = max(len(str(elem.sym)) for elem in data) if data else 0 for elem in data or []: - name = ansi(elem.sym, R.style_high) + ' ' * (name_width - len(str(elem.sym))) + raw_name = str(elem.sym) + name = ansi(elem.sym, R.style_high) + ' ' * (name_width - len(raw_name)) equal = ansi('=', R.style_low) value = format_value(elem.sym.value(frame), compact) - lines.append('{} {} {}'.format(name, equal, value)) + changed = myself and (myself.previous_values.get(raw_name, '') != value) + if myself: + myself.previous_values[raw_name] = value + style = R.style_selected_1 if changed else '' + lines.append('{} {} {}'.format(name, equal, ansi(value, style))) return lines class Stack(Dashboard.Module): @@ -1596,7 +1604,7 @@ Optionally list the frame arguments and locals too.''' frame_lines = [] frame_lines.append('[{}] {}'.format(frame_id, info)) # add frame arguments and locals - variables = Variables.format_frame(frame, self.show_arguments, self.show_locals, self.compact, self.align) + variables = Variables.format_frame(frame, self.show_arguments, self.show_locals, self.compact, self.align, False) frame_lines.extend(variables) # add frame frames.append(frame_lines)