def __init__(self, dbg, stdin, stdout, term_size):
    FrameVarInfoKeeper.__init__(self)
    self.debugger = dbg
    from urwid import AttrMap
    from pudb.ui_tools import SearchController
    self.search_controller = SearchController(self)
    self.last_module_filter = ''

    def move_up(w, size, key):
        w.keypress(size, 'up')

    def move_down(w, size, key):
        w.keypress(size, 'down')

    def move_left(w, size, key):
        w.keypress(size, 'left')

    def move_right(w, size, key):
        w.keypress(size, 'right')

    def page_up(w, size, key):
        w.keypress(size, 'page up')

    def page_down(w, size, key):
        w.keypress(size, 'page down')

    def move_home(w, size, key):
        w.keypress(size, 'home')

    def move_end(w, size, key):
        w.keypress(size, 'end')

    def add_vi_nav_keys(widget):
        widget.listen('k', move_up)
        widget.listen('j', move_down)
        widget.listen('h', move_left)
        widget.listen('l', move_right)
        widget.listen('ctrl b', page_up)
        widget.listen('ctrl f', page_down)
        widget.listen('ctrl u', page_up)
        widget.listen('ctrl d', page_down)
        widget.listen('g', move_home)
        widget.listen('G', move_end)

    def add_help_keys(widget, helpfunc):
        widget.listen('f1', helpfunc)
        widget.listen('?', helpfunc)
    self.source = urwid.SimpleListWalker([])
    self.source_list = urwid.ListBox(self.source)
    self.source_sigwrap = SignalWrap(self.source_list)
    self.source_attr = urwid.AttrMap(self.source_sigwrap, 'source')
    self.source_hscroll_start = 0
    self.cmdline_history = []
    self.cmdline_history_position = (- 1)
    self.cmdline_contents = urwid.SimpleFocusListWalker([])
    self.cmdline_list = urwid.ListBox(self.cmdline_contents)
    self.cmdline_edit = urwid.Edit([('command line prompt', '>>> ')])
    cmdline_edit_attr = urwid.AttrMap(self.cmdline_edit, 'command line edit')
    self.cmdline_edit_sigwrap = SignalWrap(cmdline_edit_attr, is_preemptive=True)

    def clear_cmdline_history(btn):
        del self.cmdline_contents[:]
    self.cmdline_edit_bar = urwid.Columns([self.cmdline_edit_sigwrap, ('fixed', 10, AttrMap(urwid.Button('Clear', clear_cmdline_history), 'command line clear button', 'command line focused button'))])
    self.cmdline_pile = urwid.Pile([('flow', urwid.Text('Command line: [Ctrl-X]')), ('weight', 1, urwid.AttrMap(self.cmdline_list, 'command line output')), ('flow', self.cmdline_edit_bar)])
    self.cmdline_sigwrap = SignalWrap(urwid.AttrMap(self.cmdline_pile, None, 'focused sidebar'))
    self.cmdline_on = (not CONFIG['hide_cmdline_win'])
    self.cmdline_weight = 1
    self.lhs_col = urwid.Pile([('weight', 5, self.source_attr), ('weight', (self.cmdline_weight if self.cmdline_on else 0), self.cmdline_sigwrap)])
    self.locals = urwid.SimpleListWalker([])
    self.var_list = SignalWrap(urwid.ListBox(self.locals))
    self.stack_walker = urwid.SimpleListWalker([])
    self.stack_list = SignalWrap(urwid.ListBox(self.stack_walker))
    self.bp_walker = urwid.SimpleListWalker([])
    self.bp_list = SignalWrap(urwid.ListBox(self.bp_walker))
    self.rhs_col = urwid.Pile([('weight', float(CONFIG['variables_weight']), AttrMap(urwid.Pile([('flow', urwid.Text(make_hotkey_markup('_Variables:'))), AttrMap(self.var_list, 'variables')]), None, 'focused sidebar')), ('weight', float(CONFIG['stack_weight']), AttrMap(urwid.Pile([('flow', urwid.Text(make_hotkey_markup('_Stack:'))), AttrMap(self.stack_list, 'stack')]), None, 'focused sidebar')), ('weight', float(CONFIG['breakpoints_weight']), AttrMap(urwid.Pile([('flow', urwid.Text(make_hotkey_markup('_Breakpoints:'))), AttrMap(self.bp_list, 'breakpoint')]), None, 'focused sidebar'))])
    self.rhs_col_sigwrap = SignalWrap(self.rhs_col)

    def helpside(w, size, key):
        help((((HELP_HEADER + HELP_SIDE) + HELP_MAIN) + HELP_LICENSE))
    add_vi_nav_keys(self.rhs_col_sigwrap)
    add_help_keys(self.rhs_col_sigwrap, helpside)
    self.columns = urwid.Columns([('weight', 1, self.lhs_col), ('weight', float(CONFIG['sidebar_width']), self.rhs_col_sigwrap)], dividechars=1)
    self.caption = urwid.Text('')
    header = urwid.AttrMap(self.caption, 'header')
    self.top = SignalWrap(urwid.Frame(urwid.AttrMap(self.columns, 'background'), header))

    def change_rhs_box(name, index, direction, w, size, key):
        from pudb.settings import save_config
        weight = self.rhs_col.item_types[index][1]
        if (direction < 0):
            if (weight > (1 / 5)):
                weight /= 1.25
        elif (weight < 5):
            weight *= 1.25
        CONFIG[(name + '_weight')] = weight
        save_config(CONFIG)
        self.rhs_col.item_types[index] = ('weight', weight)
        self.rhs_col._invalidate()

    def get_inspect_info(id_path, read_only=False):
        return self.get_frame_var_info(read_only).get_inspect_info(id_path, read_only)

    def collapse_current(var, pos, iinfo):
        if iinfo.show_detail:
            iinfo.show_detail = False
        elif (var.parent is not None):
            p_iinfo = get_inspect_info(var.parent.id_path)
            p_iinfo.show_detail = False
            return self.locals.index(var.parent)
        return None

    def change_var_state(w, size, key):
        (var, pos) = self.var_list._w.get_focus()
        if (var is None):
            return
        iinfo = get_inspect_info(var.id_path)
        focus_index = None
        if ((key == 'enter') or (key == '\\') or (key == ' ')):
            iinfo.show_detail = (not iinfo.show_detail)
        elif (key == 'h'):
            focus_index = collapse_current(var, pos, iinfo)
        elif (key == 'l'):
            iinfo.show_detail = True
        elif (key == 'd'):
            iinfo.display_type = 'default'
        elif (key == 't'):
            iinfo.display_type = 'type'
        elif (key == 'r'):
            iinfo.display_type = 'repr'
        elif (key == 's'):
            iinfo.display_type = 'str'
        elif (key == 'i'):
            iinfo.display_type = 'id'
        elif (key == 'c'):
            iinfo.display_type = CONFIG['custom_stringifier']
        elif (key == 'H'):
            iinfo.highlighted = (not iinfo.highlighted)
        elif (key == '@'):
            iinfo.repeated_at_top = (not iinfo.repeated_at_top)
        elif (key == '*'):
            levels = ['public', 'private', 'all', 'public']
            iinfo.access_level = levels[(levels.index(iinfo.access_level) + 1)]
        elif (key == 'w'):
            iinfo.wrap = (not iinfo.wrap)
        elif (key == 'm'):
            iinfo.show_methods = (not iinfo.show_methods)
        self.update_var_view(focus_index=focus_index)

    def edit_inspector_detail(w, size, key):
        (var, pos) = self.var_list._w.get_focus()
        if (var is None):
            return
        fvi = self.get_frame_var_info(read_only=False)
        iinfo = fvi.get_inspect_info(var.id_path, read_only=False)
        buttons = [('OK', True), ('Cancel', False)]
        if (var.watch_expr is not None):
            watch_edit = urwid.Edit([('label', 'Watch expression: ')], var.watch_expr.expression)
            id_segment = [urwid.AttrMap(watch_edit, 'value'), urwid.Text('')]
            buttons.extend([None, ('Delete', 'del')])
            title = 'Watch Expression Options'
        else:
            id_segment = [labelled_value('Identifier Path: ', var.id_path), urwid.Text('')]
            title = 'Variable Inspection Options'
        rb_grp_show = []
        rb_show_default = urwid.RadioButton(rb_grp_show, 'Default', (iinfo.display_type == 'default'))
        rb_show_type = urwid.RadioButton(rb_grp_show, 'Show type()', (iinfo.display_type == 'type'))
        rb_show_repr = urwid.RadioButton(rb_grp_show, 'Show repr()', (iinfo.display_type == 'repr'))
        rb_show_str = urwid.RadioButton(rb_grp_show, 'Show str()', (iinfo.display_type == 'str'))
        rb_show_id = urwid.RadioButton(rb_grp_show, 'Show id()', (iinfo.display_type == 'id'))
        rb_show_custom = urwid.RadioButton(rb_grp_show, 'Show custom (set in prefs)', (iinfo.display_type == CONFIG['custom_stringifier']))
        rb_grp_access = []
        rb_access_public = urwid.RadioButton(rb_grp_access, 'Public members', (iinfo.access_level == 'public'))
        rb_access_private = urwid.RadioButton(rb_grp_access, 'Public and private members', (iinfo.access_level == 'private'))
        rb_access_all = urwid.RadioButton(rb_grp_access, 'All members (including __dunder__)', (iinfo.access_level == 'all'))
        wrap_checkbox = urwid.CheckBox('Line Wrap', iinfo.wrap)
        expanded_checkbox = urwid.CheckBox('Expanded', iinfo.show_detail)
        highlighted_checkbox = urwid.CheckBox('Highlighted', iinfo.highlighted)
        repeated_at_top_checkbox = urwid.CheckBox('Repeated at top', iinfo.repeated_at_top)
        show_methods_checkbox = urwid.CheckBox('Show methods', iinfo.show_methods)
        lb = urwid.ListBox(urwid.SimpleListWalker((((((id_segment + rb_grp_show) + [urwid.Text('')]) + rb_grp_access) + [urwid.Text('')]) + [wrap_checkbox, expanded_checkbox, highlighted_checkbox, repeated_at_top_checkbox, show_methods_checkbox])))
        result = self.dialog(lb, buttons, title=title)
        if (result is True):
            iinfo.show_detail = expanded_checkbox.get_state()
            iinfo.wrap = wrap_checkbox.get_state()
            iinfo.highlighted = highlighted_checkbox.get_state()
            iinfo.repeated_at_top = repeated_at_top_checkbox.get_state()
            iinfo.show_methods = show_methods_checkbox.get_state()
            if rb_show_default.get_state():
                iinfo.display_type = 'default'
            elif rb_show_type.get_state():
                iinfo.display_type = 'type'
            elif rb_show_repr.get_state():
                iinfo.display_type = 'repr'
            elif rb_show_str.get_state():
                iinfo.display_type = 'str'
            elif rb_show_id.get_state():
                iinfo.display_type = 'id'
            elif rb_show_custom.get_state():
                iinfo.display_type = CONFIG['custom_stringifier']
            if rb_access_public.get_state():
                iinfo.access_level = 'public'
            elif rb_access_private.get_state():
                iinfo.access_level = 'private'
            elif rb_access_all.get_state():
                iinfo.access_level = 'all'
            if (var.watch_expr is not None):
                var.watch_expr.expression = watch_edit.get_edit_text()
        elif (result == 'del'):
            for (i, watch_expr) in enumerate(fvi.watches):
                if (watch_expr is var.watch_expr):
                    del fvi.watches[i]
        self.update_var_view()

    def insert_watch(w, size, key):
        watch_edit = urwid.Edit([('label', 'Watch expression: ')])
        if self.dialog(urwid.ListBox(urwid.SimpleListWalker([urwid.AttrMap(watch_edit, 'value')])), [('OK', True), ('Cancel', False)], title='Add Watch Expression'):
            from pudb.var_view import WatchExpression
            we = WatchExpression(watch_edit.get_edit_text())
            fvi = self.get_frame_var_info(read_only=False)
            fvi.watches.append(we)
            self.update_var_view()
    self.var_list.listen('\\', change_var_state)
    self.var_list.listen(' ', change_var_state)
    self.var_list.listen('h', change_var_state)
    self.var_list.listen('l', change_var_state)
    self.var_list.listen('d', change_var_state)
    self.var_list.listen('t', change_var_state)
    self.var_list.listen('r', change_var_state)
    self.var_list.listen('s', change_var_state)
    self.var_list.listen('i', change_var_state)
    self.var_list.listen('c', change_var_state)
    self.var_list.listen('H', change_var_state)
    self.var_list.listen('@', change_var_state)
    self.var_list.listen('*', change_var_state)
    self.var_list.listen('w', change_var_state)
    self.var_list.listen('m', change_var_state)
    self.var_list.listen('enter', change_var_state)
    self.var_list.listen('e', edit_inspector_detail)
    self.var_list.listen('n', insert_watch)
    self.var_list.listen('insert', insert_watch)
    self.var_list.listen('[', partial(change_rhs_box, 'variables', 0, (- 1)))
    self.var_list.listen(']', partial(change_rhs_box, 'variables', 0, 1))

    def examine_frame(w, size, key):
        (_, pos) = self.stack_list._w.get_focus()
        self.debugger.set_frame_index(self.translate_ui_stack_index(pos))
    self.stack_list.listen('enter', examine_frame)

    def open_file_editor(file_name, line_number):
        file_changed = False
        try:
            original_modification_time = os.path.getmtime(file_name)
            self.screen.stop()
            filename_edited = self.debugger.open_file_to_edit(file_name, line_number)
            self.screen.start()
            new_modification_time = os.path.getmtime(file_name)
            file_changed = ((new_modification_time - original_modification_time) > 0)
        except Exception:
            from traceback import format_exception
            self.message(('Exception happened when trying to edit the file:\n\n%s' % ''.join(format_exception(*sys.exc_info()))), title='File Edit Error')
            return
        if file_changed:
            self.message(f'''File is changed, but the execution is continued with the 'old' codebase.
Changed file: {filename_edited}

Please quit and restart to see changes''', title='File is changed')

    def open_editor_on_stack_frame(w, size, key):
        (_, pos) = self.stack_list._w.get_focus()
        index = self.translate_ui_stack_index(pos)
        (curframe, line_number) = self.debugger.stack[index]
        file_name = curframe.f_code.co_filename
        open_file_editor(file_name, line_number)
    self.stack_list.listen('ctrl e', open_editor_on_stack_frame)

    def move_stack_top(w, size, key):
        self.debugger.set_frame_index((len(self.debugger.stack) - 1))

    def move_stack_up(w, size, key):
        self.debugger.move_up_frame()

    def move_stack_down(w, size, key):
        self.debugger.move_down_frame()
    self.stack_list.listen('H', move_stack_top)
    self.stack_list.listen('u', move_stack_up)
    self.stack_list.listen('d', move_stack_down)
    self.stack_list.listen('[', partial(change_rhs_box, 'stack', 1, (- 1)))
    self.stack_list.listen(']', partial(change_rhs_box, 'stack', 1, 1))

    def save_breakpoints(w, size, key):
        self.debugger.save_breakpoints()

    def delete_breakpoint(w, size, key):
        bp_source_identifier = self.source_code_provider.get_source_identifier()
        if (bp_source_identifier is None):
            self.message('Cannot currently delete a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')
        bp_list = self._get_bp_list()
        if bp_list:
            (_, pos) = self.bp_list._w.get_focus()
            bp = bp_list[pos]
            if ((bp_source_identifier == bp.file) and ((bp.line - 1) < len(self.source))):
                self.source[(bp.line - 1)].set_breakpoint(False)
            err = self.debugger.clear_break(bp.file, bp.line)
            if err:
                self.message(('Error clearing breakpoint:\n' + err))
            else:
                self.update_breakpoints()

    def enable_disable_breakpoint(w, size, key):
        (bp_entry, pos) = self.bp_list._w.get_focus()
        if (bp_entry is None):
            return
        bp = self._get_bp_list()[pos]
        bp.enabled = (not bp.enabled)
        sline = self.source[(bp.line - 1)]
        sline.set_breakpoint(bp.enabled)
        self.update_breakpoints()

    def examine_breakpoint(w, size, key):
        (bp_entry, pos) = self.bp_list._w.get_focus()
        if (bp_entry is None):
            return
        bp = self._get_bp_list()[pos]
        if (bp.cond is None):
            cond = ''
        else:
            cond = str(bp.cond)
        enabled_checkbox = urwid.CheckBox('Enabled', bp.enabled)
        cond_edit = urwid.Edit([('label', 'Condition:               ')], cond)
        ign_count_edit = urwid.IntEdit([('label', 'Ignore the next N times: ')], bp.ignore)
        lb = urwid.ListBox(urwid.SimpleListWalker([labelled_value('File: ', bp.file), labelled_value('Line: ', bp.line), labelled_value('Hits: ', bp.hits), urwid.Text(''), enabled_checkbox, urwid.AttrMap(cond_edit, 'value', 'value'), urwid.AttrMap(ign_count_edit, 'value', 'value')]))
        result = self.dialog(lb, [('OK', True), ('Cancel', False), None, ('Delete', 'del'), ('Location', 'loc')], title='Edit Breakpoint')
        if (result is True):
            bp.enabled = enabled_checkbox.get_state()
            bp.ignore = int(ign_count_edit.value())
            cond = cond_edit.get_edit_text()
            if cond:
                bp.cond = cond
            else:
                bp.cond = None
        elif (result == 'loc'):
            self.show_line(bp.line, FileSourceCodeProvider(self.debugger, bp.file))
            self.columns.set_focus(0)
        elif (result == 'del'):
            bp_source_identifier = self.source_code_provider.get_source_identifier()
            if (bp_source_identifier is None):
                self.message('Cannot currently delete a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')
            if (bp_source_identifier == bp.file):
                self.source[(bp.line - 1)].set_breakpoint(False)
            err = self.debugger.clear_break(bp.file, bp.line)
            if err:
                self.message(('Error clearing breakpoint:\n' + err))
            else:
                self.update_breakpoints()

    def show_breakpoint(w, size, key):
        (bp_entry, pos) = self.bp_list._w.get_focus()
        if (bp_entry is not None):
            bp = self._get_bp_list()[pos]
            self.show_line(bp.line, FileSourceCodeProvider(self.debugger, bp.file))
    self.bp_list.listen('enter', show_breakpoint)
    self.bp_list.listen('d', delete_breakpoint)
    self.bp_list.listen('s', save_breakpoints)
    self.bp_list.listen('e', examine_breakpoint)
    self.bp_list.listen('b', enable_disable_breakpoint)
    self.bp_list.listen('H', move_stack_top)
    self.bp_list.listen('[', partial(change_rhs_box, 'breakpoints', 2, (- 1)))
    self.bp_list.listen(']', partial(change_rhs_box, 'breakpoints', 2, 1))

    def end():
        self.debugger.save_breakpoints()
        self.quit_event_loop = True

    def next_line(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_next(self.debugger.curframe)
            end()

    def step(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_step()
            end()

    def finish(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_return(self.debugger.curframe)
            end()

    def cont(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_continue()
            end()

    def run_to_cursor(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            (sline, pos) = self.source.get_focus()
            lineno = (pos + 1)
            bp_source_identifier = self.source_code_provider.get_source_identifier()
            if (bp_source_identifier is None):
                self.message('Cannot currently set a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')
            from pudb.lowlevel import get_breakpoint_invalid_reason
            invalid_reason = get_breakpoint_invalid_reason(bp_source_identifier, lineno)
            if (invalid_reason is not None):
                self.message(('Cannot run to the line you indicated, for the following reason:\n\n' + invalid_reason))
            else:
                err = self.debugger.set_break(bp_source_identifier, (pos + 1), temporary=True)
                if err:
                    self.message(('Error dealing with breakpoint:\n' + err))
                self.debugger.set_continue()
                end()

    def go_to_line(w, size, key):
        (_, line) = self.source.get_focus()
        lineno_edit = urwid.IntEdit([('label', 'Go to Line   :')], None)
        if self.dialog(urwid.ListBox(urwid.SimpleListWalker([labelled_value('File :', self.source_code_provider.identifier()), labelled_value('Current Line :', (line + 1)), urwid.AttrMap(lineno_edit, 'value')])), [('OK', True), ('Cancel', False)], title='Go to Line Number'):
            lineno = min(max(0, (int(lineno_edit.value()) - 1)), (len(self.source) - 1))
            self.source.set_focus(lineno)

    def scroll_left(w, size, key):
        self.source_hscroll_start = max(0, (self.source_hscroll_start - 4))
        for sl in self.source:
            sl._invalidate()

    def scroll_right(w, size, key):
        self.source_hscroll_start += 4
        for sl in self.source:
            sl._invalidate()

    def search(w, size, key):
        self.search_controller.open_search_ui()

    def search_next(w, size, key):
        self.search_controller.perform_search(dir=1, update_search_start=True)

    def search_previous(w, size, key):
        self.search_controller.perform_search(dir=(- 1), update_search_start=True)

    def toggle_breakpoint(w, size, key):
        bp_source_identifier = self.source_code_provider.get_source_identifier()
        if bp_source_identifier:
            (sline, pos) = self.source.get_focus()
            lineno = (pos + 1)
            existing_breaks = self.debugger.get_breaks(bp_source_identifier, lineno)
            if existing_breaks:
                err = None
                for bp in existing_breaks:
                    if (not bp.enabled):
                        bp.enable()
                        sline.set_breakpoint(True)
                        break
                else:
                    err = self.debugger.clear_break(bp_source_identifier, lineno)
                    sline.set_breakpoint(False)
            else:
                file_lineno = (bp_source_identifier, lineno)
                if (file_lineno in self.debugger.set_traces):
                    self.debugger.set_traces[file_lineno] = (not self.debugger.set_traces[file_lineno])
                    sline.set_breakpoint(self.debugger.set_traces[file_lineno])
                    return
                from pudb.lowlevel import get_breakpoint_invalid_reason
                invalid_reason = get_breakpoint_invalid_reason(bp_source_identifier, (pos + 1))
                if (invalid_reason is not None):
                    do_set = (not self.dialog(urwid.ListBox(urwid.SimpleListWalker([urwid.Text(('The breakpoint you just set may be invalid, for the following reason:\n\n' + invalid_reason))])), [('Cancel', True), ('Set Anyway', False)], title='Possibly Invalid Breakpoint', focus_buttons=True))
                else:
                    do_set = True
                if do_set:
                    err = self.debugger.set_break(bp_source_identifier, (pos + 1))
                    sline.set_breakpoint(True)
                else:
                    err = None
            if err:
                self.message(('Error dealing with breakpoint:\n' + err))
            self.update_breakpoints()
        else:
            self.message('Cannot currently set a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')

    def pick_module(w, size, key):
        from os.path import splitext
        import sys

        def mod_exists(mod):
            if (not hasattr(mod, '__file__')):
                return False
            if (mod.__file__ is None):
                return False
            filename = mod.__file__
            (base, ext) = splitext(filename)
            ext = ext.lower()
            from os.path import exists
            if (ext == '.pyc'):
                return exists((base + '.py'))
            else:
                return (ext == '.py')
        new_mod_text = SelectableText('-- update me --')
        new_mod_entry = urwid.AttrMap(new_mod_text, None, 'focused selectable')

        def build_filtered_mod_list(filt_string=''):
            modules = sorted((name for (name, mod) in list(sys.modules.items()) if mod_exists(mod)))
            result = [urwid.AttrMap(SelectableText(mod), None, 'focused selectable') for mod in modules if (filt_string in mod)]
            new_mod_text.set_text(("<<< IMPORT MODULE '%s' >>>" % filt_string))
            result.append(new_mod_entry)
            return result

        def show_mod(mod):
            filename = self.debugger.canonic(mod.__file__)
            (base, ext) = splitext(filename)
            if (ext == '.pyc'):
                ext = '.py'
                filename = (base + '.py')
            self.set_source_code_provider(FileSourceCodeProvider(self.debugger, filename))
            self.source_list.set_focus(0)

        class FilterEdit(urwid.Edit):

            def keypress(self, size, key):
                result = urwid.Edit.keypress(self, size, key)
                if (result is None):
                    mod_list[:] = build_filtered_mod_list(self.get_edit_text())
                return result
        filt_edit = FilterEdit([('label', 'Filter: ')], self.last_module_filter)
        mod_list = urwid.SimpleListWalker(build_filtered_mod_list(filt_edit.get_edit_text()))
        lb = urwid.ListBox(mod_list)
        w = urwid.Pile([('flow', urwid.AttrMap(filt_edit, 'value')), ('fixed', 1, urwid.SolidFill()), urwid.AttrMap(lb, 'selectable')])
        while True:
            result = self.dialog(w, [('OK', True), ('Cancel', False), ('Reload', 'reload')], title='Pick Module')
            self.last_module_filter = filt_edit.get_edit_text()
            if (result is True):
                (widget, pos) = lb.get_focus()
                if (widget is new_mod_entry):
                    new_mod_name = filt_edit.get_edit_text()
                    try:
                        __import__(str(new_mod_name))
                    except Exception:
                        from traceback import format_exception
                        self.message("Could not import module '{}':\n\n{}".format(new_mod_name, ''.join(format_exception(*sys.exc_info()))), title='Import Error')
                    else:
                        show_mod(__import__(str(new_mod_name)))
                        break
                else:
                    show_mod(sys.modules[widget.base_widget.get_text()[0]])
                    break
            elif (result is False):
                break
            elif (result == 'reload'):
                (widget, pos) = lb.get_focus()
                if (widget is not new_mod_entry):
                    mod_name = widget.base_widget.get_text()[0]
                    mod = sys.modules[mod_name]
                    import importlib
                    importlib.reload(mod)
                    self.message(("'%s' was successfully reloaded." % mod_name))
                    if (self.source_code_provider is not None):
                        self.source_code_provider.clear_cache()
                    self.set_source_code_provider(self.source_code_provider, force_update=True)
                    (_, pos) = self.stack_list._w.get_focus()
                    self.debugger.set_frame_index(self.translate_ui_stack_index(pos))

    def helpmain(w, size, key):
        help((((HELP_HEADER + HELP_MAIN) + HELP_SIDE) + HELP_LICENSE))
    self.source_sigwrap.listen('n', next_line)
    self.source_sigwrap.listen('s', step)
    self.source_sigwrap.listen('f', finish)
    self.source_sigwrap.listen('r', finish)
    self.source_sigwrap.listen('c', cont)
    self.source_sigwrap.listen('t', run_to_cursor)
    self.source_sigwrap.listen('L', go_to_line)
    self.source_sigwrap.listen('/', search)
    self.source_sigwrap.listen(',', search_previous)
    self.source_sigwrap.listen('.', search_next)
    self.source_sigwrap.listen('b', toggle_breakpoint)
    self.source_sigwrap.listen('m', pick_module)
    self.source_sigwrap.listen('H', move_stack_top)
    self.source_sigwrap.listen('u', move_stack_up)
    self.source_sigwrap.listen('d', move_stack_down)
    self.source_sigwrap.listen('h', scroll_left)
    self.source_sigwrap.listen('l', scroll_right)
    add_vi_nav_keys(self.source_sigwrap)
    add_help_keys(self.source_sigwrap, helpmain)

    def cmdline_get_namespace():
        curframe = self.debugger.curframe
        from pudb.shell import SetPropagatingDict
        return SetPropagatingDict([curframe.f_locals, curframe.f_globals], curframe.f_locals)

    def cmdline_tab_complete(w, size, key):
        try:
            from jedi import Interpreter
        except ImportError:
            self.add_cmdline_content('Tab completion requires jedi to be installed. ', 'command line error')
            return
        import jedi
        from distutils.version import LooseVersion
        if (LooseVersion(jedi.__version__) < LooseVersion('0.16.0')):
            self.add_cmdline_content('jedi 0.16.0 is required for Tab completion', 'command line error')
        text = self.cmdline_edit.edit_text
        pos = self.cmdline_edit.edit_pos
        chopped_text = text[:pos]
        suffix = text[pos:]
        try:
            completions = Interpreter(chopped_text, [cmdline_get_namespace()]).complete()
        except Exception as e:
            self.add_cmdline_content(("Could not tab complete (Jedi error: '%s')" % e), 'command line error')
            return
        full_completions = [i.name_with_symbols for i in completions]
        chopped_completions = [i.complete for i in completions]

        def common_prefix(a, b):
            for (i, (a_i, b_i)) in enumerate(zip(a, b)):
                if (a_i != b_i):
                    return a[:i]
            return a[:max(len(a), len(b))]
        common_compl_prefix = None
        for completion in chopped_completions:
            if (common_compl_prefix is None):
                common_compl_prefix = completion
            else:
                common_compl_prefix = common_prefix(common_compl_prefix, completion)
        completed_chopped_text = common_compl_prefix
        if (completed_chopped_text is None):
            return
        if ((len(completed_chopped_text) == 0) and (len(completions) > 1)):
            self.add_cmdline_content('   '.join(full_completions), 'command line output')
            return
        self.cmdline_edit.edit_text = ((chopped_text + completed_chopped_text) + suffix)
        self.cmdline_edit.edit_pos = (len(chopped_text) + len(completed_chopped_text))

    def cmdline_append_newline(w, size, key):
        self.cmdline_edit.insert_text('\n')

    def cmdline_exec(w, size, key):
        cmd = self.cmdline_edit.get_edit_text()
        if (not cmd):
            return
        self.add_cmdline_content(('>>> ' + cmd), 'command line input')
        if ((not self.cmdline_history) or (cmd != self.cmdline_history[(- 1)])):
            self.cmdline_history.append(cmd)
        self.cmdline_history_position = (- 1)
        prev_sys_stdin = sys.stdin
        prev_sys_stdout = sys.stdout
        prev_sys_stderr = sys.stderr
        from io import StringIO
        sys.stdin = None
        sys.stderr = sys.stdout = StringIO()
        try:
            eval(compile(cmd, '<pudb command line>', 'single'), cmdline_get_namespace())
        except Exception:
            (tp, val, tb) = sys.exc_info()
            import traceback
            tblist = traceback.extract_tb(tb)
            del tblist[:1]
            tb_lines = traceback.format_list(tblist)
            if tb_lines:
                tb_lines.insert(0, 'Traceback (most recent call last):\n')
            tb_lines[len(tb_lines):] = traceback.format_exception_only(tp, val)
            self.add_cmdline_content(''.join(tb_lines), 'command line error')
        else:
            self.cmdline_edit.set_edit_text('')
        finally:
            if sys.stdout.getvalue():
                self.add_cmdline_content(sys.stdout.getvalue(), 'command line output')
            sys.stdin = prev_sys_stdin
            sys.stdout = prev_sys_stdout
            sys.stderr = prev_sys_stderr

    def cmdline_history_browse(direction):
        if (self.cmdline_history_position == (- 1)):
            self.cmdline_history_position = len(self.cmdline_history)
        self.cmdline_history_position += direction
        if (0 <= self.cmdline_history_position < len(self.cmdline_history)):
            self.cmdline_edit.edit_text = self.cmdline_history[self.cmdline_history_position]
        else:
            self.cmdline_history_position = (- 1)
            self.cmdline_edit.edit_text = ''
        self.cmdline_edit.edit_pos = len(self.cmdline_edit.edit_text)

    def cmdline_history_prev(w, size, key):
        cmdline_history_browse((- 1))

    def cmdline_history_next(w, size, key):
        cmdline_history_browse(1)

    def cmdline_start_of_line(w, size, key):
        self.cmdline_edit.edit_pos = 0

    def cmdline_end_of_line(w, size, key):
        self.cmdline_edit.edit_pos = len(self.cmdline_edit.edit_text)

    def cmdline_del_word(w, size, key):
        pos = self.cmdline_edit.edit_pos
        (before, after) = (self.cmdline_edit.edit_text[:pos], self.cmdline_edit.edit_text[pos:])
        before = before[::(- 1)]
        before = before.lstrip()
        i = 0
        while (i < len(before)):
            if (not before[i].isspace()):
                i += 1
            else:
                break
        self.cmdline_edit.edit_text = (before[i:][::(- 1)] + after)
        self.cmdline_edit.edit_post = len(before[i:])

    def cmdline_del_to_start_of_line(w, size, key):
        pos = self.cmdline_edit.edit_pos
        self.cmdline_edit.edit_text = self.cmdline_edit.edit_text[pos:]
        self.cmdline_edit.edit_pos = 0

    def toggle_cmdline_focus(w, size, key):
        self.columns.set_focus(self.lhs_col)
        if (self.lhs_col.get_focus() is self.cmdline_sigwrap):
            if CONFIG['hide_cmdline_win']:
                self.set_cmdline_state(False)
            self.lhs_col.set_focus((self.search_controller.search_AttrMap if self.search_controller.search_box else self.source_attr))
        else:
            if CONFIG['hide_cmdline_win']:
                self.set_cmdline_state(True)
            self.cmdline_pile.set_focus(self.cmdline_edit_bar)
            self.lhs_col.set_focus(self.cmdline_sigwrap)
    self.cmdline_edit_sigwrap.listen('tab', cmdline_tab_complete)
    self.cmdline_edit_sigwrap.listen('ctrl v', cmdline_append_newline)
    self.cmdline_edit_sigwrap.listen('enter', cmdline_exec)
    self.cmdline_edit_sigwrap.listen('ctrl n', cmdline_history_next)
    self.cmdline_edit_sigwrap.listen('ctrl p', cmdline_history_prev)
    self.cmdline_edit_sigwrap.listen('esc', toggle_cmdline_focus)
    self.cmdline_edit_sigwrap.listen('ctrl d', toggle_cmdline_focus)
    self.cmdline_edit_sigwrap.listen('ctrl a', cmdline_start_of_line)
    self.cmdline_edit_sigwrap.listen('ctrl e', cmdline_end_of_line)
    self.cmdline_edit_sigwrap.listen('ctrl w', cmdline_del_word)
    self.cmdline_edit_sigwrap.listen('ctrl u', cmdline_del_to_start_of_line)
    self.top.listen('ctrl x', toggle_cmdline_focus)

    def set_cmdline_default_size(weight):
        self.cmdline_weight = weight
        self.set_cmdline_size()

    def max_cmdline(w, size, key):
        set_cmdline_default_size(5)

    def min_cmdline(w, size, key):
        set_cmdline_default_size((1 / 2))

    def grow_cmdline(w, size, key):
        weight = self.cmdline_weight
        if (weight < 5):
            weight *= 1.25
            set_cmdline_default_size(weight)

    def shrink_cmdline(w, size, key):
        weight = self.cmdline_weight
        if (weight > (1 / 2)):
            weight /= 1.25
            set_cmdline_default_size(weight)
    self.cmdline_sigwrap.listen('=', max_cmdline)
    self.cmdline_sigwrap.listen('+', grow_cmdline)
    self.cmdline_sigwrap.listen('_', min_cmdline)
    self.cmdline_sigwrap.listen('-', shrink_cmdline)

    def max_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = 5
        CONFIG['sidebar_width'] = weight
        save_config(CONFIG)
        self.columns.column_types[1] = ('weight', weight)
        self.columns._invalidate()

    def min_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = (1 / 5)
        CONFIG['sidebar_width'] = weight
        save_config(CONFIG)
        self.columns.column_types[1] = ('weight', weight)
        self.columns._invalidate()

    def grow_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = self.columns.column_types[1][1]
        if (weight < 5):
            weight *= 1.25
            CONFIG['sidebar_width'] = weight
            save_config(CONFIG)
            self.columns.column_types[1] = ('weight', weight)
            self.columns._invalidate()

    def shrink_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = self.columns.column_types[1][1]
        if (weight > (1 / 5)):
            weight /= 1.25
            CONFIG['sidebar_width'] = weight
            save_config(CONFIG)
            self.columns.column_types[1] = ('weight', weight)
            self.columns._invalidate()
    self.rhs_col_sigwrap.listen('=', max_sidebar)
    self.rhs_col_sigwrap.listen('+', grow_sidebar)
    self.rhs_col_sigwrap.listen('_', min_sidebar)
    self.rhs_col_sigwrap.listen('-', shrink_sidebar)

    def show_output(w, size, key):
        self.screen.stop()
        input('Hit Enter to return:')
        self.screen.start()

    def reload_breakpoints_and_redisplay():
        reload_breakpoints()
        curr_line = self.current_line
        self.set_source_code_provider(self.source_code_provider, force_update=True)
        if (curr_line is not None):
            self.current_line = self.source[(int(curr_line.line_nr) - 1)]
            self.current_line.set_current(True)

    def reload_breakpoints():
        self.debugger.clear_all_breaks()
        from pudb.settings import load_breakpoints
        for bpoint_descr in load_breakpoints():
            dbg.set_break(*bpoint_descr)
        self.update_breakpoints()

    def show_traceback(w, size, key):
        if (self.current_exc_tuple is not None):
            from traceback import format_exception
            result = self.dialog(urwid.ListBox(urwid.SimpleListWalker([urwid.Text(''.join(format_exception(*self.current_exc_tuple)))])), [('Close', 'close'), ('Location', 'location')], title='Exception Viewer', focus_buttons=True, bind_enter_esc=False)
            if (result == 'location'):
                self.debugger.set_frame_index((len(self.debugger.stack) - 1))
        else:
            self.message('No exception available.')

    def run_external_cmdline(w, size, key):
        self.screen.stop()
        curframe = self.debugger.curframe
        import pudb.shell as shell
        if ((CONFIG['shell'] == 'ipython') and shell.have_ipython()):
            runner = shell.run_ipython_shell
        elif ((CONFIG['shell'] == 'ipython_kernel') and shell.have_ipython()):
            runner = shell.run_ipython_kernel
        elif ((CONFIG['shell'] == 'bpython') and shell.HAVE_BPYTHON):
            runner = shell.run_bpython_shell
        elif ((CONFIG['shell'] == 'ptpython') and shell.HAVE_PTPYTHON):
            runner = shell.run_ptpython_shell
        elif ((CONFIG['shell'] == 'ptipython') and shell.HAVE_PTIPYTHON):
            runner = shell.run_ptipython_shell
        elif (CONFIG['shell'] == 'classic'):
            runner = shell.run_classic_shell
        else:
            try:
                if (not shell.custom_shell_dict):
                    from os.path import expanduser
                    cshell_fname = expanduser(CONFIG['shell'])
                    with open(cshell_fname) as inf:
                        exec(compile(inf.read(), cshell_fname, 'exec'), shell.custom_shell_dict, shell.custom_shell_dict)
            except Exception:
                print('Error when importing custom shell:')
                from traceback import print_exc
                print_exc()
                print('Falling back to classic shell')
                runner = shell.run_classic_shell
            else:
                if ('pudb_shell' not in shell.custom_shell_dict):
                    print(('%s does not contain a function named pudb_shell at the module level.' % CONFIG['shell']))
                    print('Falling back to classic shell')
                    runner = shell.run_classic_shell
                else:
                    runner = shell.custom_shell_dict['pudb_shell']
        runner(curframe.f_globals, curframe.f_locals)
        self.screen.start()
        self.update_var_view()

    def run_cmdline(w, size, key):
        if (CONFIG['shell'] == 'internal'):
            return toggle_cmdline_focus(w, size, key)
        else:
            return run_external_cmdline(w, size, key)

    def focus_code(w, size, key):
        self.columns.set_focus(self.lhs_col)
        self.lhs_col.set_focus(self.source_attr)

    class RHColumnFocuser():

        def __init__(self, idx):
            self.idx = idx

        def __call__(subself, w, size, key):
            self.columns.set_focus(self.rhs_col_sigwrap)
            self.rhs_col.set_focus(self.rhs_col.widget_list[subself.idx])

    def quit(w, size, key):
        self.debugger.set_quit()
        end()

    def do_edit_config(w, size, key):
        self.run_edit_config()

    def redraw_screen(w, size, key):
        self.screen.clear()

    def help(pages):
        self.message(pages, title='PuDB - The Python Urwid Debugger')

    def edit_current_frame(w, size, key):
        (_, pos) = self.source.get_focus()
        source_identifier = self.source_code_provider.get_source_identifier()
        if (source_identifier is None):
            self.message('Cannot edit the current file--source code does not correspond to a file location. (perhaps this is generated code)')
        open_file_editor(source_identifier, (pos + 1))
    self.top.listen('o', show_output)
    self.top.listen('ctrl r', (lambda w, size, key: reload_breakpoints_and_redisplay()))
    self.top.listen('!', run_cmdline)
    self.top.listen('e', show_traceback)
    self.top.listen('C', focus_code)
    self.top.listen('V', RHColumnFocuser(0))
    self.top.listen('S', RHColumnFocuser(1))
    self.top.listen('B', RHColumnFocuser(2))
    self.top.listen('q', quit)
    self.top.listen('ctrl p', do_edit_config)
    self.top.listen('ctrl l', redraw_screen)
    self.top.listen('ctrl e', edit_current_frame)
    want_curses_display = ((CONFIG['display'] == 'curses') or ((CONFIG['display'] == 'auto') and (not (os.environ.get('TERM', '').startswith('xterm') or os.environ.get('TERM', '').startswith('rxvt')))))
    if (want_curses_display and (not ((stdin is not None) or (stdout is not None))) and (CursesScreen is not None)):
        self.screen = ThreadsafeCursesScreen()
    else:
        screen_kwargs = {}
        if (stdin is not None):
            screen_kwargs['input'] = stdin
        if (stdout is not None):
            screen_kwargs['output'] = stdout
        if (term_size is not None):
            screen_kwargs['term_size'] = term_size
        if screen_kwargs:
            self.screen = ThreadsafeFixedSizeRawScreen(**screen_kwargs)
        else:
            self.screen = ThreadsafeRawScreen()
    del want_curses_display
    if curses:
        try:
            curses.setupterm()
        except Exception:
            pass
        else:
            color_support = curses.tigetnum('colors')
            if ((color_support == 256) and isinstance(self.screen, RawScreen)):
                self.screen.set_terminal_properties(256)
    self.setup_palette(self.screen)
    self.show_count = 0
    self.source_code_provider = None
    self.current_line = None
    self.quit_event_loop = False
def __init__(self, dbg, stdin, stdout, term_size):
    FrameVarInfoKeeper.__init__(self)
    self.debugger = dbg
    from urwid import AttrMap
    from pudb.ui_tools import SearchController
    self.search_controller = SearchController(self)
    self.last_module_filter = 

    def move_up(w, size, key):
        w.keypress(size, 'up')

    def move_down(w, size, key):
        w.keypress(size, 'down')

    def move_left(w, size, key):
        w.keypress(size, 'left')

    def move_right(w, size, key):
        w.keypress(size, 'right')

    def page_up(w, size, key):
        w.keypress(size, 'page up')

    def page_down(w, size, key):
        w.keypress(size, 'page down')

    def move_home(w, size, key):
        w.keypress(size, 'home')

    def move_end(w, size, key):
        w.keypress(size, 'end')

    def add_vi_nav_keys(widget):
        widget.listen('k', move_up)
        widget.listen('j', move_down)
        widget.listen('h', move_left)
        widget.listen('l', move_right)
        widget.listen('ctrl b', page_up)
        widget.listen('ctrl f', page_down)
        widget.listen('ctrl u', page_up)
        widget.listen('ctrl d', page_down)
        widget.listen('g', move_home)
        widget.listen('G', move_end)

    def add_help_keys(widget, helpfunc):
        widget.listen('f1', helpfunc)
        widget.listen('?', helpfunc)
    self.source = urwid.SimpleListWalker([])
    self.source_list = urwid.ListBox(self.source)
    self.source_sigwrap = SignalWrap(self.source_list)
    self.source_attr = urwid.AttrMap(self.source_sigwrap, 'source')
    self.source_hscroll_start = 0
    self.cmdline_history = []
    self.cmdline_history_position = (- 1)
    self.cmdline_contents = urwid.SimpleFocusListWalker([])
    self.cmdline_list = urwid.ListBox(self.cmdline_contents)
    self.cmdline_edit = urwid.Edit([('command line prompt', '>>> ')])
    cmdline_edit_attr = urwid.AttrMap(self.cmdline_edit, 'command line edit')
    self.cmdline_edit_sigwrap = SignalWrap(cmdline_edit_attr, is_preemptive=True)

    def clear_cmdline_history(btn):
        del self.cmdline_contents[:]
    self.cmdline_edit_bar = urwid.Columns([self.cmdline_edit_sigwrap, ('fixed', 10, AttrMap(urwid.Button('Clear', clear_cmdline_history), 'command line clear button', 'command line focused button'))])
    self.cmdline_pile = urwid.Pile([('flow', urwid.Text('Command line: [Ctrl-X]')), ('weight', 1, urwid.AttrMap(self.cmdline_list, 'command line output')), ('flow', self.cmdline_edit_bar)])
    self.cmdline_sigwrap = SignalWrap(urwid.AttrMap(self.cmdline_pile, None, 'focused sidebar'))
    self.cmdline_on = (not CONFIG['hide_cmdline_win'])
    self.cmdline_weight = 1
    self.lhs_col = urwid.Pile([('weight', 5, self.source_attr), ('weight', (self.cmdline_weight if self.cmdline_on else 0), self.cmdline_sigwrap)])
    self.locals = urwid.SimpleListWalker([])
    self.var_list = SignalWrap(urwid.ListBox(self.locals))
    self.stack_walker = urwid.SimpleListWalker([])
    self.stack_list = SignalWrap(urwid.ListBox(self.stack_walker))
    self.bp_walker = urwid.SimpleListWalker([])
    self.bp_list = SignalWrap(urwid.ListBox(self.bp_walker))
    self.rhs_col = urwid.Pile([('weight', float(CONFIG['variables_weight']), AttrMap(urwid.Pile([('flow', urwid.Text(make_hotkey_markup('_Variables:'))), AttrMap(self.var_list, 'variables')]), None, 'focused sidebar')), ('weight', float(CONFIG['stack_weight']), AttrMap(urwid.Pile([('flow', urwid.Text(make_hotkey_markup('_Stack:'))), AttrMap(self.stack_list, 'stack')]), None, 'focused sidebar')), ('weight', float(CONFIG['breakpoints_weight']), AttrMap(urwid.Pile([('flow', urwid.Text(make_hotkey_markup('_Breakpoints:'))), AttrMap(self.bp_list, 'breakpoint')]), None, 'focused sidebar'))])
    self.rhs_col_sigwrap = SignalWrap(self.rhs_col)

    def helpside(w, size, key):
        help((((HELP_HEADER + HELP_SIDE) + HELP_MAIN) + HELP_LICENSE))
    add_vi_nav_keys(self.rhs_col_sigwrap)
    add_help_keys(self.rhs_col_sigwrap, helpside)
    self.columns = urwid.Columns([('weight', 1, self.lhs_col), ('weight', float(CONFIG['sidebar_width']), self.rhs_col_sigwrap)], dividechars=1)
    self.caption = urwid.Text()
    header = urwid.AttrMap(self.caption, 'header')
    self.top = SignalWrap(urwid.Frame(urwid.AttrMap(self.columns, 'background'), header))

    def change_rhs_box(name, index, direction, w, size, key):
        from pudb.settings import save_config
        weight = self.rhs_col.item_types[index][1]
        if (direction < 0):
            if (weight > (1 / 5)):
                weight /= 1.25
        elif (weight < 5):
            weight *= 1.25
        CONFIG[(name + '_weight')] = weight
        save_config(CONFIG)
        self.rhs_col.item_types[index] = ('weight', weight)
        self.rhs_col._invalidate()

    def get_inspect_info(id_path, read_only=False):
        return self.get_frame_var_info(read_only).get_inspect_info(id_path, read_only)

    def collapse_current(var, pos, iinfo):
        if iinfo.show_detail:
            iinfo.show_detail = False
        elif (var.parent is not None):
            p_iinfo = get_inspect_info(var.parent.id_path)
            p_iinfo.show_detail = False
            return self.locals.index(var.parent)
        return None

    def change_var_state(w, size, key):
        (var, pos) = self.var_list._w.get_focus()
        if (var is None):
            return
        iinfo = get_inspect_info(var.id_path)
        focus_index = None
        if ((key == 'enter') or (key == '\\') or (key == ' ')):
            iinfo.show_detail = (not iinfo.show_detail)
        elif (key == 'h'):
            focus_index = collapse_current(var, pos, iinfo)
        elif (key == 'l'):
            iinfo.show_detail = True
        elif (key == 'd'):
            iinfo.display_type = 'default'
        elif (key == 't'):
            iinfo.display_type = 'type'
        elif (key == 'r'):
            iinfo.display_type = 'repr'
        elif (key == 's'):
            iinfo.display_type = 'str'
        elif (key == 'i'):
            iinfo.display_type = 'id'
        elif (key == 'c'):
            iinfo.display_type = CONFIG['custom_stringifier']
        elif (key == 'H'):
            iinfo.highlighted = (not iinfo.highlighted)
        elif (key == '@'):
            iinfo.repeated_at_top = (not iinfo.repeated_at_top)
        elif (key == '*'):
            levels = ['public', 'private', 'all', 'public']
            iinfo.access_level = levels[(levels.index(iinfo.access_level) + 1)]
        elif (key == 'w'):
            iinfo.wrap = (not iinfo.wrap)
        elif (key == 'm'):
            iinfo.show_methods = (not iinfo.show_methods)
        self.update_var_view(focus_index=focus_index)

    def edit_inspector_detail(w, size, key):
        (var, pos) = self.var_list._w.get_focus()
        if (var is None):
            return
        fvi = self.get_frame_var_info(read_only=False)
        iinfo = fvi.get_inspect_info(var.id_path, read_only=False)
        buttons = [('OK', True), ('Cancel', False)]
        if (var.watch_expr is not None):
            watch_edit = urwid.Edit([('label', 'Watch expression: ')], var.watch_expr.expression)
            id_segment = [urwid.AttrMap(watch_edit, 'value'), urwid.Text()]
            buttons.extend([None, ('Delete', 'del')])
            title = 'Watch Expression Options'
        else:
            id_segment = [labelled_value('Identifier Path: ', var.id_path), urwid.Text()]
            title = 'Variable Inspection Options'
        rb_grp_show = []
        rb_show_default = urwid.RadioButton(rb_grp_show, 'Default', (iinfo.display_type == 'default'))
        rb_show_type = urwid.RadioButton(rb_grp_show, 'Show type()', (iinfo.display_type == 'type'))
        rb_show_repr = urwid.RadioButton(rb_grp_show, 'Show repr()', (iinfo.display_type == 'repr'))
        rb_show_str = urwid.RadioButton(rb_grp_show, 'Show str()', (iinfo.display_type == 'str'))
        rb_show_id = urwid.RadioButton(rb_grp_show, 'Show id()', (iinfo.display_type == 'id'))
        rb_show_custom = urwid.RadioButton(rb_grp_show, 'Show custom (set in prefs)', (iinfo.display_type == CONFIG['custom_stringifier']))
        rb_grp_access = []
        rb_access_public = urwid.RadioButton(rb_grp_access, 'Public members', (iinfo.access_level == 'public'))
        rb_access_private = urwid.RadioButton(rb_grp_access, 'Public and private members', (iinfo.access_level == 'private'))
        rb_access_all = urwid.RadioButton(rb_grp_access, 'All members (including __dunder__)', (iinfo.access_level == 'all'))
        wrap_checkbox = urwid.CheckBox('Line Wrap', iinfo.wrap)
        expanded_checkbox = urwid.CheckBox('Expanded', iinfo.show_detail)
        highlighted_checkbox = urwid.CheckBox('Highlighted', iinfo.highlighted)
        repeated_at_top_checkbox = urwid.CheckBox('Repeated at top', iinfo.repeated_at_top)
        show_methods_checkbox = urwid.CheckBox('Show methods', iinfo.show_methods)
        lb = urwid.ListBox(urwid.SimpleListWalker((((((id_segment + rb_grp_show) + [urwid.Text()]) + rb_grp_access) + [urwid.Text()]) + [wrap_checkbox, expanded_checkbox, highlighted_checkbox, repeated_at_top_checkbox, show_methods_checkbox])))
        result = self.dialog(lb, buttons, title=title)
        if (result is True):
            iinfo.show_detail = expanded_checkbox.get_state()
            iinfo.wrap = wrap_checkbox.get_state()
            iinfo.highlighted = highlighted_checkbox.get_state()
            iinfo.repeated_at_top = repeated_at_top_checkbox.get_state()
            iinfo.show_methods = show_methods_checkbox.get_state()
            if rb_show_default.get_state():
                iinfo.display_type = 'default'
            elif rb_show_type.get_state():
                iinfo.display_type = 'type'
            elif rb_show_repr.get_state():
                iinfo.display_type = 'repr'
            elif rb_show_str.get_state():
                iinfo.display_type = 'str'
            elif rb_show_id.get_state():
                iinfo.display_type = 'id'
            elif rb_show_custom.get_state():
                iinfo.display_type = CONFIG['custom_stringifier']
            if rb_access_public.get_state():
                iinfo.access_level = 'public'
            elif rb_access_private.get_state():
                iinfo.access_level = 'private'
            elif rb_access_all.get_state():
                iinfo.access_level = 'all'
            if (var.watch_expr is not None):
                var.watch_expr.expression = watch_edit.get_edit_text()
        elif (result == 'del'):
            for (i, watch_expr) in enumerate(fvi.watches):
                if (watch_expr is var.watch_expr):
                    del fvi.watches[i]
        self.update_var_view()

    def insert_watch(w, size, key):
        watch_edit = urwid.Edit([('label', 'Watch expression: ')])
        if self.dialog(urwid.ListBox(urwid.SimpleListWalker([urwid.AttrMap(watch_edit, 'value')])), [('OK', True), ('Cancel', False)], title='Add Watch Expression'):
            from pudb.var_view import WatchExpression
            we = WatchExpression(watch_edit.get_edit_text())
            fvi = self.get_frame_var_info(read_only=False)
            fvi.watches.append(we)
            self.update_var_view()
    self.var_list.listen('\\', change_var_state)
    self.var_list.listen(' ', change_var_state)
    self.var_list.listen('h', change_var_state)
    self.var_list.listen('l', change_var_state)
    self.var_list.listen('d', change_var_state)
    self.var_list.listen('t', change_var_state)
    self.var_list.listen('r', change_var_state)
    self.var_list.listen('s', change_var_state)
    self.var_list.listen('i', change_var_state)
    self.var_list.listen('c', change_var_state)
    self.var_list.listen('H', change_var_state)
    self.var_list.listen('@', change_var_state)
    self.var_list.listen('*', change_var_state)
    self.var_list.listen('w', change_var_state)
    self.var_list.listen('m', change_var_state)
    self.var_list.listen('enter', change_var_state)
    self.var_list.listen('e', edit_inspector_detail)
    self.var_list.listen('n', insert_watch)
    self.var_list.listen('insert', insert_watch)
    self.var_list.listen('[', partial(change_rhs_box, 'variables', 0, (- 1)))
    self.var_list.listen(']', partial(change_rhs_box, 'variables', 0, 1))

    def examine_frame(w, size, key):
        (_, pos) = self.stack_list._w.get_focus()
        self.debugger.set_frame_index(self.translate_ui_stack_index(pos))
    self.stack_list.listen('enter', examine_frame)

    def open_file_editor(file_name, line_number):
        file_changed = False
        try:
            original_modification_time = os.path.getmtime(file_name)
            self.screen.stop()
            filename_edited = self.debugger.open_file_to_edit(file_name, line_number)
            self.screen.start()
            new_modification_time = os.path.getmtime(file_name)
            file_changed = ((new_modification_time - original_modification_time) > 0)
        except Exception:
            from traceback import format_exception
            self.message(('Exception happened when trying to edit the file:\n\n%s' % .join(format_exception(*sys.exc_info()))), title='File Edit Error')
            return
        if file_changed:
            self.message(f'File is changed, but the execution is continued with the 'old' codebase.
Changed file: {filename_edited}

Please quit and restart to see changes', title='File is changed')

    def open_editor_on_stack_frame(w, size, key):
        (_, pos) = self.stack_list._w.get_focus()
        index = self.translate_ui_stack_index(pos)
        (curframe, line_number) = self.debugger.stack[index]
        file_name = curframe.f_code.co_filename
        open_file_editor(file_name, line_number)
    self.stack_list.listen('ctrl e', open_editor_on_stack_frame)

    def move_stack_top(w, size, key):
        self.debugger.set_frame_index((len(self.debugger.stack) - 1))

    def move_stack_up(w, size, key):
        self.debugger.move_up_frame()

    def move_stack_down(w, size, key):
        self.debugger.move_down_frame()
    self.stack_list.listen('H', move_stack_top)
    self.stack_list.listen('u', move_stack_up)
    self.stack_list.listen('d', move_stack_down)
    self.stack_list.listen('[', partial(change_rhs_box, 'stack', 1, (- 1)))
    self.stack_list.listen(']', partial(change_rhs_box, 'stack', 1, 1))

    def save_breakpoints(w, size, key):
        self.debugger.save_breakpoints()

    def delete_breakpoint(w, size, key):
        bp_source_identifier = self.source_code_provider.get_source_identifier()
        if (bp_source_identifier is None):
            self.message('Cannot currently delete a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')
        bp_list = self._get_bp_list()
        if bp_list:
            (_, pos) = self.bp_list._w.get_focus()
            bp = bp_list[pos]
            if ((bp_source_identifier == bp.file) and ((bp.line - 1) < len(self.source))):
                self.source[(bp.line - 1)].set_breakpoint(False)
            err = self.debugger.clear_break(bp.file, bp.line)
            if err:
                self.message(('Error clearing breakpoint:\n' + err))
            else:
                self.update_breakpoints()

    def enable_disable_breakpoint(w, size, key):
        (bp_entry, pos) = self.bp_list._w.get_focus()
        if (bp_entry is None):
            return
        bp = self._get_bp_list()[pos]
        bp.enabled = (not bp.enabled)
        sline = self.source[(bp.line - 1)]
        sline.set_breakpoint(bp.enabled)
        self.update_breakpoints()

    def examine_breakpoint(w, size, key):
        (bp_entry, pos) = self.bp_list._w.get_focus()
        if (bp_entry is None):
            return
        bp = self._get_bp_list()[pos]
        if (bp.cond is None):
            cond = 
        else:
            cond = str(bp.cond)
        enabled_checkbox = urwid.CheckBox('Enabled', bp.enabled)
        cond_edit = urwid.Edit([('label', 'Condition:               ')], cond)
        ign_count_edit = urwid.IntEdit([('label', 'Ignore the next N times: ')], bp.ignore)
        lb = urwid.ListBox(urwid.SimpleListWalker([labelled_value('File: ', bp.file), labelled_value('Line: ', bp.line), labelled_value('Hits: ', bp.hits), urwid.Text(), enabled_checkbox, urwid.AttrMap(cond_edit, 'value', 'value'), urwid.AttrMap(ign_count_edit, 'value', 'value')]))
        result = self.dialog(lb, [('OK', True), ('Cancel', False), None, ('Delete', 'del'), ('Location', 'loc')], title='Edit Breakpoint')
        if (result is True):
            bp.enabled = enabled_checkbox.get_state()
            bp.ignore = int(ign_count_edit.value())
            cond = cond_edit.get_edit_text()
            if cond:
                bp.cond = cond
            else:
                bp.cond = None
        elif (result == 'loc'):
            self.show_line(bp.line, FileSourceCodeProvider(self.debugger, bp.file))
            self.columns.set_focus(0)
        elif (result == 'del'):
            bp_source_identifier = self.source_code_provider.get_source_identifier()
            if (bp_source_identifier is None):
                self.message('Cannot currently delete a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')
            if (bp_source_identifier == bp.file):
                self.source[(bp.line - 1)].set_breakpoint(False)
            err = self.debugger.clear_break(bp.file, bp.line)
            if err:
                self.message(('Error clearing breakpoint:\n' + err))
            else:
                self.update_breakpoints()

    def show_breakpoint(w, size, key):
        (bp_entry, pos) = self.bp_list._w.get_focus()
        if (bp_entry is not None):
            bp = self._get_bp_list()[pos]
            self.show_line(bp.line, FileSourceCodeProvider(self.debugger, bp.file))
    self.bp_list.listen('enter', show_breakpoint)
    self.bp_list.listen('d', delete_breakpoint)
    self.bp_list.listen('s', save_breakpoints)
    self.bp_list.listen('e', examine_breakpoint)
    self.bp_list.listen('b', enable_disable_breakpoint)
    self.bp_list.listen('H', move_stack_top)
    self.bp_list.listen('[', partial(change_rhs_box, 'breakpoints', 2, (- 1)))
    self.bp_list.listen(']', partial(change_rhs_box, 'breakpoints', 2, 1))

    def end():
        self.debugger.save_breakpoints()
        self.quit_event_loop = True

    def next_line(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_next(self.debugger.curframe)
            end()

    def step(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_step()
            end()

    def finish(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_return(self.debugger.curframe)
            end()

    def cont(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            self.debugger.set_continue()
            end()

    def run_to_cursor(w, size, key):
        if self.debugger.post_mortem:
            self.message("Post-mortem mode: Can't modify state.")
        else:
            (sline, pos) = self.source.get_focus()
            lineno = (pos + 1)
            bp_source_identifier = self.source_code_provider.get_source_identifier()
            if (bp_source_identifier is None):
                self.message('Cannot currently set a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')
            from pudb.lowlevel import get_breakpoint_invalid_reason
            invalid_reason = get_breakpoint_invalid_reason(bp_source_identifier, lineno)
            if (invalid_reason is not None):
                self.message(('Cannot run to the line you indicated, for the following reason:\n\n' + invalid_reason))
            else:
                err = self.debugger.set_break(bp_source_identifier, (pos + 1), temporary=True)
                if err:
                    self.message(('Error dealing with breakpoint:\n' + err))
                self.debugger.set_continue()
                end()

    def go_to_line(w, size, key):
        (_, line) = self.source.get_focus()
        lineno_edit = urwid.IntEdit([('label', 'Go to Line   :')], None)
        if self.dialog(urwid.ListBox(urwid.SimpleListWalker([labelled_value('File :', self.source_code_provider.identifier()), labelled_value('Current Line :', (line + 1)), urwid.AttrMap(lineno_edit, 'value')])), [('OK', True), ('Cancel', False)], title='Go to Line Number'):
            lineno = min(max(0, (int(lineno_edit.value()) - 1)), (len(self.source) - 1))
            self.source.set_focus(lineno)

    def scroll_left(w, size, key):
        self.source_hscroll_start = max(0, (self.source_hscroll_start - 4))
        for sl in self.source:
            sl._invalidate()

    def scroll_right(w, size, key):
        self.source_hscroll_start += 4
        for sl in self.source:
            sl._invalidate()

    def search(w, size, key):
        self.search_controller.open_search_ui()

    def search_next(w, size, key):
        self.search_controller.perform_search(dir=1, update_search_start=True)

    def search_previous(w, size, key):
        self.search_controller.perform_search(dir=(- 1), update_search_start=True)

    def toggle_breakpoint(w, size, key):
        bp_source_identifier = self.source_code_provider.get_source_identifier()
        if bp_source_identifier:
            (sline, pos) = self.source.get_focus()
            lineno = (pos + 1)
            existing_breaks = self.debugger.get_breaks(bp_source_identifier, lineno)
            if existing_breaks:
                err = None
                for bp in existing_breaks:
                    if (not bp.enabled):
                        bp.enable()
                        sline.set_breakpoint(True)
                        break
                else:
                    err = self.debugger.clear_break(bp_source_identifier, lineno)
                    sline.set_breakpoint(False)
            else:
                file_lineno = (bp_source_identifier, lineno)
                if (file_lineno in self.debugger.set_traces):
                    self.debugger.set_traces[file_lineno] = (not self.debugger.set_traces[file_lineno])
                    sline.set_breakpoint(self.debugger.set_traces[file_lineno])
                    return
                from pudb.lowlevel import get_breakpoint_invalid_reason
                invalid_reason = get_breakpoint_invalid_reason(bp_source_identifier, (pos + 1))
                if (invalid_reason is not None):
                    do_set = (not self.dialog(urwid.ListBox(urwid.SimpleListWalker([urwid.Text(('The breakpoint you just set may be invalid, for the following reason:\n\n' + invalid_reason))])), [('Cancel', True), ('Set Anyway', False)], title='Possibly Invalid Breakpoint', focus_buttons=True))
                else:
                    do_set = True
                if do_set:
                    err = self.debugger.set_break(bp_source_identifier, (pos + 1))
                    sline.set_breakpoint(True)
                else:
                    err = None
            if err:
                self.message(('Error dealing with breakpoint:\n' + err))
            self.update_breakpoints()
        else:
            self.message('Cannot currently set a breakpoint here--source code does not correspond to a file location. (perhaps this is generated code)')

    def pick_module(w, size, key):
        from os.path import splitext
        import sys

        def mod_exists(mod):
            if (not hasattr(mod, '__file__')):
                return False
            if (mod.__file__ is None):
                return False
            filename = mod.__file__
            (base, ext) = splitext(filename)
            ext = ext.lower()
            from os.path import exists
            if (ext == '.pyc'):
                return exists((base + '.py'))
            else:
                return (ext == '.py')
        new_mod_text = SelectableText('-- update me --')
        new_mod_entry = urwid.AttrMap(new_mod_text, None, 'focused selectable')

        def build_filtered_mod_list(filt_string=):
            modules = sorted((name for (name, mod) in list(sys.modules.items()) if mod_exists(mod)))
            result = [urwid.AttrMap(SelectableText(mod), None, 'focused selectable') for mod in modules if (filt_string in mod)]
            new_mod_text.set_text(("<<< IMPORT MODULE '%s' >>>" % filt_string))
            result.append(new_mod_entry)
            return result

        def show_mod(mod):
            filename = self.debugger.canonic(mod.__file__)
            (base, ext) = splitext(filename)
            if (ext == '.pyc'):
                ext = '.py'
                filename = (base + '.py')
            self.set_source_code_provider(FileSourceCodeProvider(self.debugger, filename))
            self.source_list.set_focus(0)

        class FilterEdit(urwid.Edit):

            def keypress(self, size, key):
                result = urwid.Edit.keypress(self, size, key)
                if (result is None):
                    mod_list[:] = build_filtered_mod_list(self.get_edit_text())
                return result
        filt_edit = FilterEdit([('label', 'Filter: ')], self.last_module_filter)
        mod_list = urwid.SimpleListWalker(build_filtered_mod_list(filt_edit.get_edit_text()))
        lb = urwid.ListBox(mod_list)
        w = urwid.Pile([('flow', urwid.AttrMap(filt_edit, 'value')), ('fixed', 1, urwid.SolidFill()), urwid.AttrMap(lb, 'selectable')])
        while True:
            result = self.dialog(w, [('OK', True), ('Cancel', False), ('Reload', 'reload')], title='Pick Module')
            self.last_module_filter = filt_edit.get_edit_text()
            if (result is True):
                (widget, pos) = lb.get_focus()
                if (widget is new_mod_entry):
                    new_mod_name = filt_edit.get_edit_text()
                    try:
                        __import__(str(new_mod_name))
                    except Exception:
                        from traceback import format_exception
                        self.message("Could not import module '{}':\n\n{}".format(new_mod_name, .join(format_exception(*sys.exc_info()))), title='Import Error')
                    else:
                        show_mod(__import__(str(new_mod_name)))
                        break
                else:
                    show_mod(sys.modules[widget.base_widget.get_text()[0]])
                    break
            elif (result is False):
                break
            elif (result == 'reload'):
                (widget, pos) = lb.get_focus()
                if (widget is not new_mod_entry):
                    mod_name = widget.base_widget.get_text()[0]
                    mod = sys.modules[mod_name]
                    import importlib
                    importlib.reload(mod)
                    self.message(("'%s' was successfully reloaded." % mod_name))
                    if (self.source_code_provider is not None):
                        self.source_code_provider.clear_cache()
                    self.set_source_code_provider(self.source_code_provider, force_update=True)
                    (_, pos) = self.stack_list._w.get_focus()
                    self.debugger.set_frame_index(self.translate_ui_stack_index(pos))

    def helpmain(w, size, key):
        help((((HELP_HEADER + HELP_MAIN) + HELP_SIDE) + HELP_LICENSE))
    self.source_sigwrap.listen('n', next_line)
    self.source_sigwrap.listen('s', step)
    self.source_sigwrap.listen('f', finish)
    self.source_sigwrap.listen('r', finish)
    self.source_sigwrap.listen('c', cont)
    self.source_sigwrap.listen('t', run_to_cursor)
    self.source_sigwrap.listen('L', go_to_line)
    self.source_sigwrap.listen('/', search)
    self.source_sigwrap.listen(',', search_previous)
    self.source_sigwrap.listen('.', search_next)
    self.source_sigwrap.listen('b', toggle_breakpoint)
    self.source_sigwrap.listen('m', pick_module)
    self.source_sigwrap.listen('H', move_stack_top)
    self.source_sigwrap.listen('u', move_stack_up)
    self.source_sigwrap.listen('d', move_stack_down)
    self.source_sigwrap.listen('h', scroll_left)
    self.source_sigwrap.listen('l', scroll_right)
    add_vi_nav_keys(self.source_sigwrap)
    add_help_keys(self.source_sigwrap, helpmain)

    def cmdline_get_namespace():
        curframe = self.debugger.curframe
        from pudb.shell import SetPropagatingDict
        return SetPropagatingDict([curframe.f_locals, curframe.f_globals], curframe.f_locals)

    def cmdline_tab_complete(w, size, key):
        try:
            from jedi import Interpreter
        except ImportError:
            self.add_cmdline_content('Tab completion requires jedi to be installed. ', 'command line error')
            return
        import jedi
        from distutils.version import LooseVersion
        if (LooseVersion(jedi.__version__) < LooseVersion('0.16.0')):
            self.add_cmdline_content('jedi 0.16.0 is required for Tab completion', 'command line error')
        text = self.cmdline_edit.edit_text
        pos = self.cmdline_edit.edit_pos
        chopped_text = text[:pos]
        suffix = text[pos:]
        try:
            completions = Interpreter(chopped_text, [cmdline_get_namespace()]).complete()
        except Exception as e:
            self.add_cmdline_content(("Could not tab complete (Jedi error: '%s')" % e), 'command line error')
            return
        full_completions = [i.name_with_symbols for i in completions]
        chopped_completions = [i.complete for i in completions]

        def common_prefix(a, b):
            for (i, (a_i, b_i)) in enumerate(zip(a, b)):
                if (a_i != b_i):
                    return a[:i]
            return a[:max(len(a), len(b))]
        common_compl_prefix = None
        for completion in chopped_completions:
            if (common_compl_prefix is None):
                common_compl_prefix = completion
            else:
                common_compl_prefix = common_prefix(common_compl_prefix, completion)
        completed_chopped_text = common_compl_prefix
        if (completed_chopped_text is None):
            return
        if ((len(completed_chopped_text) == 0) and (len(completions) > 1)):
            self.add_cmdline_content('   '.join(full_completions), 'command line output')
            return
        self.cmdline_edit.edit_text = ((chopped_text + completed_chopped_text) + suffix)
        self.cmdline_edit.edit_pos = (len(chopped_text) + len(completed_chopped_text))

    def cmdline_append_newline(w, size, key):
        self.cmdline_edit.insert_text('\n')

    def cmdline_exec(w, size, key):
        cmd = self.cmdline_edit.get_edit_text()
        if (not cmd):
            return
        self.add_cmdline_content(('>>> ' + cmd), 'command line input')
        if ((not self.cmdline_history) or (cmd != self.cmdline_history[(- 1)])):
            self.cmdline_history.append(cmd)
        self.cmdline_history_position = (- 1)
        prev_sys_stdin = sys.stdin
        prev_sys_stdout = sys.stdout
        prev_sys_stderr = sys.stderr
        from io import StringIO
        sys.stdin = None
        sys.stderr = sys.stdout = StringIO()
        try:
            eval(compile(cmd, '<pudb command line>', 'single'), cmdline_get_namespace())
        except Exception:
            (tp, val, tb) = sys.exc_info()
            import traceback
            tblist = traceback.extract_tb(tb)
            del tblist[:1]
            tb_lines = traceback.format_list(tblist)
            if tb_lines:
                tb_lines.insert(0, 'Traceback (most recent call last):\n')
            tb_lines[len(tb_lines):] = traceback.format_exception_only(tp, val)
            self.add_cmdline_content(.join(tb_lines), 'command line error')
        else:
            self.cmdline_edit.set_edit_text()
        finally:
            if sys.stdout.getvalue():
                self.add_cmdline_content(sys.stdout.getvalue(), 'command line output')
            sys.stdin = prev_sys_stdin
            sys.stdout = prev_sys_stdout
            sys.stderr = prev_sys_stderr

    def cmdline_history_browse(direction):
        if (self.cmdline_history_position == (- 1)):
            self.cmdline_history_position = len(self.cmdline_history)
        self.cmdline_history_position += direction
        if (0 <= self.cmdline_history_position < len(self.cmdline_history)):
            self.cmdline_edit.edit_text = self.cmdline_history[self.cmdline_history_position]
        else:
            self.cmdline_history_position = (- 1)
            self.cmdline_edit.edit_text = 
        self.cmdline_edit.edit_pos = len(self.cmdline_edit.edit_text)

    def cmdline_history_prev(w, size, key):
        cmdline_history_browse((- 1))

    def cmdline_history_next(w, size, key):
        cmdline_history_browse(1)

    def cmdline_start_of_line(w, size, key):
        self.cmdline_edit.edit_pos = 0

    def cmdline_end_of_line(w, size, key):
        self.cmdline_edit.edit_pos = len(self.cmdline_edit.edit_text)

    def cmdline_del_word(w, size, key):
        pos = self.cmdline_edit.edit_pos
        (before, after) = (self.cmdline_edit.edit_text[:pos], self.cmdline_edit.edit_text[pos:])
        before = before[::(- 1)]
        before = before.lstrip()
        i = 0
        while (i < len(before)):
            if (not before[i].isspace()):
                i += 1
            else:
                break
        self.cmdline_edit.edit_text = (before[i:][::(- 1)] + after)
        self.cmdline_edit.edit_post = len(before[i:])

    def cmdline_del_to_start_of_line(w, size, key):
        pos = self.cmdline_edit.edit_pos
        self.cmdline_edit.edit_text = self.cmdline_edit.edit_text[pos:]
        self.cmdline_edit.edit_pos = 0

    def toggle_cmdline_focus(w, size, key):
        self.columns.set_focus(self.lhs_col)
        if (self.lhs_col.get_focus() is self.cmdline_sigwrap):
            if CONFIG['hide_cmdline_win']:
                self.set_cmdline_state(False)
            self.lhs_col.set_focus((self.search_controller.search_AttrMap if self.search_controller.search_box else self.source_attr))
        else:
            if CONFIG['hide_cmdline_win']:
                self.set_cmdline_state(True)
            self.cmdline_pile.set_focus(self.cmdline_edit_bar)
            self.lhs_col.set_focus(self.cmdline_sigwrap)
    self.cmdline_edit_sigwrap.listen('tab', cmdline_tab_complete)
    self.cmdline_edit_sigwrap.listen('ctrl v', cmdline_append_newline)
    self.cmdline_edit_sigwrap.listen('enter', cmdline_exec)
    self.cmdline_edit_sigwrap.listen('ctrl n', cmdline_history_next)
    self.cmdline_edit_sigwrap.listen('ctrl p', cmdline_history_prev)
    self.cmdline_edit_sigwrap.listen('esc', toggle_cmdline_focus)
    self.cmdline_edit_sigwrap.listen('ctrl d', toggle_cmdline_focus)
    self.cmdline_edit_sigwrap.listen('ctrl a', cmdline_start_of_line)
    self.cmdline_edit_sigwrap.listen('ctrl e', cmdline_end_of_line)
    self.cmdline_edit_sigwrap.listen('ctrl w', cmdline_del_word)
    self.cmdline_edit_sigwrap.listen('ctrl u', cmdline_del_to_start_of_line)
    self.top.listen('ctrl x', toggle_cmdline_focus)

    def set_cmdline_default_size(weight):
        self.cmdline_weight = weight
        self.set_cmdline_size()

    def max_cmdline(w, size, key):
        set_cmdline_default_size(5)

    def min_cmdline(w, size, key):
        set_cmdline_default_size((1 / 2))

    def grow_cmdline(w, size, key):
        weight = self.cmdline_weight
        if (weight < 5):
            weight *= 1.25
            set_cmdline_default_size(weight)

    def shrink_cmdline(w, size, key):
        weight = self.cmdline_weight
        if (weight > (1 / 2)):
            weight /= 1.25
            set_cmdline_default_size(weight)
    self.cmdline_sigwrap.listen('=', max_cmdline)
    self.cmdline_sigwrap.listen('+', grow_cmdline)
    self.cmdline_sigwrap.listen('_', min_cmdline)
    self.cmdline_sigwrap.listen('-', shrink_cmdline)

    def max_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = 5
        CONFIG['sidebar_width'] = weight
        save_config(CONFIG)
        self.columns.column_types[1] = ('weight', weight)
        self.columns._invalidate()

    def min_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = (1 / 5)
        CONFIG['sidebar_width'] = weight
        save_config(CONFIG)
        self.columns.column_types[1] = ('weight', weight)
        self.columns._invalidate()

    def grow_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = self.columns.column_types[1][1]
        if (weight < 5):
            weight *= 1.25
            CONFIG['sidebar_width'] = weight
            save_config(CONFIG)
            self.columns.column_types[1] = ('weight', weight)
            self.columns._invalidate()

    def shrink_sidebar(w, size, key):
        from pudb.settings import save_config
        weight = self.columns.column_types[1][1]
        if (weight > (1 / 5)):
            weight /= 1.25
            CONFIG['sidebar_width'] = weight
            save_config(CONFIG)
            self.columns.column_types[1] = ('weight', weight)
            self.columns._invalidate()
    self.rhs_col_sigwrap.listen('=', max_sidebar)
    self.rhs_col_sigwrap.listen('+', grow_sidebar)
    self.rhs_col_sigwrap.listen('_', min_sidebar)
    self.rhs_col_sigwrap.listen('-', shrink_sidebar)

    def show_output(w, size, key):
        self.screen.stop()
        input('Hit Enter to return:')
        self.screen.start()

    def reload_breakpoints_and_redisplay():
        reload_breakpoints()
        curr_line = self.current_line
        self.set_source_code_provider(self.source_code_provider, force_update=True)
        if (curr_line is not None):
            self.current_line = self.source[(int(curr_line.line_nr) - 1)]
            self.current_line.set_current(True)

    def reload_breakpoints():
        self.debugger.clear_all_breaks()
        from pudb.settings import load_breakpoints
        for bpoint_descr in load_breakpoints():
            dbg.set_break(*bpoint_descr)
        self.update_breakpoints()

    def show_traceback(w, size, key):
        if (self.current_exc_tuple is not None):
            from traceback import format_exception
            result = self.dialog(urwid.ListBox(urwid.SimpleListWalker([urwid.Text(.join(format_exception(*self.current_exc_tuple)))])), [('Close', 'close'), ('Location', 'location')], title='Exception Viewer', focus_buttons=True, bind_enter_esc=False)
            if (result == 'location'):
                self.debugger.set_frame_index((len(self.debugger.stack) - 1))
        else:
            self.message('No exception available.')

    def run_external_cmdline(w, size, key):
        self.screen.stop()
        curframe = self.debugger.curframe
        import pudb.shell as shell
        if ((CONFIG['shell'] == 'ipython') and shell.have_ipython()):
            runner = shell.run_ipython_shell
        elif ((CONFIG['shell'] == 'ipython_kernel') and shell.have_ipython()):
            runner = shell.run_ipython_kernel
        elif ((CONFIG['shell'] == 'bpython') and shell.HAVE_BPYTHON):
            runner = shell.run_bpython_shell
        elif ((CONFIG['shell'] == 'ptpython') and shell.HAVE_PTPYTHON):
            runner = shell.run_ptpython_shell
        elif ((CONFIG['shell'] == 'ptipython') and shell.HAVE_PTIPYTHON):
            runner = shell.run_ptipython_shell
        elif (CONFIG['shell'] == 'classic'):
            runner = shell.run_classic_shell
        else:
            try:
                if (not shell.custom_shell_dict):
                    from os.path import expanduser
                    cshell_fname = expanduser(CONFIG['shell'])
                    with open(cshell_fname) as inf:
                        exec(compile(inf.read(), cshell_fname, 'exec'), shell.custom_shell_dict, shell.custom_shell_dict)
            except Exception:
                print('Error when importing custom shell:')
                from traceback import print_exc
                print_exc()
                print('Falling back to classic shell')
                runner = shell.run_classic_shell
            else:
                if ('pudb_shell' not in shell.custom_shell_dict):
                    print(('%s does not contain a function named pudb_shell at the module level.' % CONFIG['shell']))
                    print('Falling back to classic shell')
                    runner = shell.run_classic_shell
                else:
                    runner = shell.custom_shell_dict['pudb_shell']
        runner(curframe.f_globals, curframe.f_locals)
        self.screen.start()
        self.update_var_view()

    def run_cmdline(w, size, key):
        if (CONFIG['shell'] == 'internal'):
            return toggle_cmdline_focus(w, size, key)
        else:
            return run_external_cmdline(w, size, key)

    def focus_code(w, size, key):
        self.columns.set_focus(self.lhs_col)
        self.lhs_col.set_focus(self.source_attr)

    class RHColumnFocuser():

        def __init__(self, idx):
            self.idx = idx

        def __call__(subself, w, size, key):
            self.columns.set_focus(self.rhs_col_sigwrap)
            self.rhs_col.set_focus(self.rhs_col.widget_list[subself.idx])

    def quit(w, size, key):
        self.debugger.set_quit()
        end()

    def do_edit_config(w, size, key):
        self.run_edit_config()

    def redraw_screen(w, size, key):
        self.screen.clear()

    def help(pages):
        self.message(pages, title='PuDB - The Python Urwid Debugger')

    def edit_current_frame(w, size, key):
        (_, pos) = self.source.get_focus()
        source_identifier = self.source_code_provider.get_source_identifier()
        if (source_identifier is None):
            self.message('Cannot edit the current file--source code does not correspond to a file location. (perhaps this is generated code)')
        open_file_editor(source_identifier, (pos + 1))
    self.top.listen('o', show_output)
    self.top.listen('ctrl r', (lambda w, size, key: reload_breakpoints_and_redisplay()))
    self.top.listen('!', run_cmdline)
    self.top.listen('e', show_traceback)
    self.top.listen('C', focus_code)
    self.top.listen('V', RHColumnFocuser(0))
    self.top.listen('S', RHColumnFocuser(1))
    self.top.listen('B', RHColumnFocuser(2))
    self.top.listen('q', quit)
    self.top.listen('ctrl p', do_edit_config)
    self.top.listen('ctrl l', redraw_screen)
    self.top.listen('ctrl e', edit_current_frame)
    want_curses_display = ((CONFIG['display'] == 'curses') or ((CONFIG['display'] == 'auto') and (not (os.environ.get('TERM', ).startswith('xterm') or os.environ.get('TERM', ).startswith('rxvt')))))
    if (want_curses_display and (not ((stdin is not None) or (stdout is not None))) and (CursesScreen is not None)):
        self.screen = ThreadsafeCursesScreen()
    else:
        screen_kwargs = {}
        if (stdin is not None):
            screen_kwargs['input'] = stdin
        if (stdout is not None):
            screen_kwargs['output'] = stdout
        if (term_size is not None):
            screen_kwargs['term_size'] = term_size
        if screen_kwargs:
            self.screen = ThreadsafeFixedSizeRawScreen(**screen_kwargs)
        else:
            self.screen = ThreadsafeRawScreen()
    del want_curses_display
    if curses:
        try:
            curses.setupterm()
        except Exception:
            pass
        else:
            color_support = curses.tigetnum('colors')
            if ((color_support == 256) and isinstance(self.screen, RawScreen)):
                self.screen.set_terminal_properties(256)
    self.setup_palette(self.screen)
    self.show_count = 0
    self.source_code_provider = None
    self.current_line = None
    self.quit_event_loop = False