1# Register a gdb pretty printer for UGrid instances. Usage:
2#
3# - start gdb
4# - run `source contrib/gdb/nvim-gdb-pretty-printers.py`
5# - when a `UGrid` pointer can be evaluated in the current frame, just print
6#   it's value normally: `p *grid` (assuming `grid` is the variable name
7#   holding the pointer)
8# - highlighting can be activated by setting the NVIM_GDB_HIGHLIGHT_UGRID
9#   environment variable(only xterm-compatible terminals supported). This
10#   can be done while gdb is running through the python interface:
11#   `python os.environ['NVIM_GDB_HIGHLIGHT_UGRID'] = '1'`
12import os
13import gdb
14import gdb.printing
15
16
17SGR0 = '\x1b(B\x1b[m'
18
19
20def get_color_code(bg, color_num):
21    if color_num < 16:
22        prefix = 3
23        if color_num > 7:
24            prefix = 9
25        if bg:
26            prefix += 1
27        color_num %= 8
28    else:
29        prefix = '48;5;' if bg else '38;5;'
30    return '\x1b[{0}{1}m'.format(prefix, color_num)
31
32
33def highlight(attrs):
34    fg, bg = [int(attrs['foreground']), int(attrs['background'])]
35    rv = [SGR0]  # start with sgr0
36    if fg != -1:
37        rv.append(get_color_code(False, fg))
38    if bg != -1:
39        rv.append(get_color_code(True, bg))
40    if bool(attrs['bold']):
41        rv.append('\x1b[1m')
42    if bool(attrs['italic']):
43        rv.append('\x1b[3m')
44    if bool(attrs['undercurl']) or bool(attrs['underline']):
45        rv.append('\x1b[4m')
46    if bool(attrs['reverse']):
47        rv.append('\x1b[7m')
48    return ''.join(rv)
49
50
51class UGridPrinter(object):
52    def __init__(self, val):
53        self.val = val
54
55    def to_string(self):
56        do_hl = (os.getenv('NVIM_GDB_HIGHLIGHT_UGRID') and
57                 os.getenv('NVIM_GDB_HIGHLIGHT_UGRID') != '0')
58        grid = self.val
59        height = int(grid['height'])
60        width = int(grid['width'])
61        delimiter = '-' * (width + 2)
62        rows = [delimiter]
63        for row in range(height):
64            cols = []
65            if do_hl:
66                cols.append(SGR0)
67            curhl = None
68            for col in range(width):
69                cell = grid['cells'][row][col]
70                if do_hl:
71                    hl = highlight(cell['attrs'])
72                    if hl != curhl:
73                        cols.append(hl)
74                        curhl = hl
75                cols.append(cell['data'].string('utf-8'))
76            if do_hl:
77                cols.append(SGR0)
78            rows.append('|' + ''.join(cols) + '|')
79        rows.append(delimiter)
80        return '\n' + '\n'.join(rows)
81
82    def display_hint(self):
83        return 'hint'
84
85
86def pretty_printers():
87    pp = gdb.printing.RegexpCollectionPrettyPrinter('nvim')
88    pp.add_printer('UGrid', '^ugrid$', UGridPrinter)
89    return pp
90
91
92gdb.printing.register_pretty_printer(gdb, pretty_printers(), replace=True)
93