def on_keypress(self, evt): if evt.key == "ESC": remove_child(self.parent, self) if self.file_menu and has_child(self.container, self.file_menu): self.file_menu.close() evt.stop_propagation() elif evt.key in [ "LEFT_ARROW", "RIGHT_ARROW", "UP_ARROW", "DOWN_ARROW", "\r" ]: # route these events to the menu fire_event(self.file_menu, evt) else: query = self.text_field.get_text() self.file_menu.remove_items() if len(query) > 0: matches = [] for file in self.files: filename = self.get_filename(file) if fuzzy_contain(filename, query): result = fuzzy_match_5(filename, query) matches.append((file, result)) else: matches = [] if len(matches) > 0: for code_file, result in sorted(matches, key=lambda m: m[1][0], reverse=True): filename = self.get_filename(code_file) match_positions = result[1] filename_display = sstring("") last_idx = -1 for pos in match_positions: filename_display += sstring(filename[last_idx + 1:pos]) filename_display += sstring(filename[pos], [BRIGHT_MAGENTA, BOLD]) last_idx = pos filename_display += sstring(filename[last_idx + 1:]) self.file_menu.add_item( MenuItem(filename_display, self.on_file_selected, key=code_file["id"])) x, y = self.region.offset width, height = self.size cwidth, cheight = self.container.size self.file_menu.layout( BoxConstraints(min_width=width, max_width=width, max_height=cheight)) if not has_child(self.container, self.file_menu): add_child(self.container, self.file_menu, abs_pos=(x, y + height - 1), abs_size=self.file_menu.size) else: if has_child(self.container, self.file_menu): remove_child(self.container, self.file_menu)
def print_variables(grouped): for key, value in grouped.items(): # print("key", key) if isinstance(value, dict): print("%s = %s" % (key, sstring(display_dict(value), [YELLOW])), end=" ") else: print("%s = %r" % (key, sstring(str(value), [YELLOW])), end=" ")
def test_print(): buf = TermBuffer((10, 10)) buf.print_at(1, 2, "hello") assert buf.lines[0] == sstring(10 * " ") assert buf.lines[1] == sstring(10 * " ") assert buf.lines[2] == sstring(" hello ") for line in buf.lines[3:]: assert line == sstring(10 * " ")
def test_strike_through_group(): a_string = sstring("Hello", RED) b_string = sstring("World", YELLOW) c_string = sstring(a_string + b_string, [UNDERLINE], strike_through=True) print("strike through group", c_string) assert str( c_string ) == '\x1b[4m\x1b[31mH̶e̶l̶l̶o̶\x1b[0m\x1b[4m\x1b[33mW̶o̶r̶l̶d̶\x1b[0m' assert repr(c_string) == '<4m-><31m>Hello</31m><33m>World</33m></4m->'
def test_multiple_codes_group(): a_string = sstring("Hello", RED) b_string = sstring("World", YELLOW) c_string = sstring(a_string + b_string, [UNDERLINE, REVERSED]) print("multiple codes group", c_string) assert repr(c_string) == "<4m,7m><31m>Hello</31m><33m>World</33m></4m,7m>" assert str( c_string ) == '\x1b[4m\x1b[7m\x1b[31mHello\x1b[0m\x1b[4m\x1b[7m\x1b[33mWorld\x1b[0m'
def draw_gutter(self): width, height = self.size offsetx, offsety = self.offset gutter_width = self.get_gutter_width() for i in range(height): line_no = offsety + i + 1 line_no_display = sstring( str(line_no).rjust(gutter_width - 1), [CYAN] ) + sstring("│") self.region.draw(0, i, line_no_display)
def test_clear_rect(): buf = TermBuffer((10, 10)) for i in range(10): buf.print_at(0, i, "helloworld") buf.clear_rect(2, 2, 6, 6) assert buf.lines[0] == sstring("helloworld") assert buf.lines[1] == sstring("helloworld") assert buf.lines[8] == sstring("helloworld") assert buf.lines[9] == sstring("helloworld") for line in buf.lines[2:8]: assert line == sstring("he ld")
def test_concat(): a_string = sstring("Hello", RED) b_string = sstring(" World", YELLOW) c_string = a_string + b_string assert len(c_string) == len(a_string) + len(b_string) assert len(c_string) == 11 assert repr(c_string) == "<31m>Hello</31m><33m> World</33m>" assert str(c_string) == '\x1b[31mHello\x1b[0m\x1b[33m World\x1b[0m' d_string = c_string + sstring(" and you", "34m") assert repr( d_string) == "<31m>Hello</31m><33m> World</33m><34m> and you</34m>" assert len(d_string) == 19
def test_nesting(): a_string = sstring("Hello") b_string = sstring(" World", YELLOW) c_string = sstring( sstring("+") + a_string + b_string + sstring("+"), UNDERLINE) print("nested", c_string) assert str( c_string ) == '\x1b[4m+Hello\x1b[0m\x1b[4m\x1b[33m World\x1b[0m\x1b[4m+\x1b[0m' assert len(c_string) == len(a_string) + len(b_string) + 2 print("nested", repr(c_string)) assert repr(c_string) == "<4m>+Hello<33m> World</33m>+</4m>"
def test_slice_group(): a_string = sstring("Hello", RED) b_string = sstring("World", YELLOW) c_string = a_string + b_string slice1 = c_string[0:3] assert repr(slice1) == "<31m>Hel</31m>" slice2 = c_string[0:5] assert repr(slice2) == "<31m>Hello</31m>" slice3 = c_string[3:7] assert repr(slice3) == "<31m>lo</31m><33m>Wo</33m>" slice4 = c_string[6:8] assert repr(slice4) == "<33m>or</33m>" slice5 = c_string[8:] assert repr(slice5) == "<33m>ld</33m>"
def paint(self): xoffset = self.region.offset[0] - self.region.origin[0] yoffset = self.region.offset[1] - self.region.origin[1] width = self.size[0] height = self.region.size[1] prev_snapshot = None next_snapshot = None last_filename = None prev_level = -1 for i in range(height): snapshot_id = i + yoffset + 1 snapshot = self.cache.get_snapshot(snapshot_id) if snapshot is None: break code_file, line = self.get_file_and_line_for_snapshot(snapshot) line = line.lstrip() filename = code_file["file_path"].split("/")[-1] prefix, level = self.calculate_prefix(snapshot) if prev_level > level: line = "⏎ " + line line_display = prefix + line if last_filename != filename: line_display += " (%s)" % filename last_filename = filename if self.current_snapshot_id == snapshot_id: line_display = sstring(line_display.ljust(width), [REVERSED]) prev_level = level self.region.draw(-xoffset, yoffset + i, line_display)
def print_at(self, x, y, string): width, height = self.size if isinstance(string, str): string = sstring(string) line = self.lines[y] if x < 0: pre = sstring("") else: pre = line[0:x] post = line[x + len(string):] str_len = width - len(pre) - len(post) if len(string) > str_len: low = 0 if x >= 0 else -x high = low + str_len string = string[low:high] new_line = pre + string + post self.lines[y] = new_line
def test_equality(): assert sstring("Hello") == sstring("Hello") assert sstring("Hello", RED) == sstring("Hello", RED) a_string = sstring("Hello", BG_YELLOW) b_string = sstring(" World", BG_MAGENTA) c_string = a_string + b_string d_string = a_string + b_string assert c_string == d_string assert sstring(a_string) == a_string assert sstring(d_string) == d_string
def update_status(self): message = "Step %d of %d: %s() line %d" % ( self.snapshot["id"], self.last_snapshot["id"], self.fun_code["name"], self.snapshot["line_no"], ) if self.error: message += ", Error: %s" % self.error["message"] self.status_bar.set_text(sstring(message, [REVERSED]))
def test_ljust_rjust_center_group(): a_string = sstring("Hello", BG_YELLOW) b_string = sstring(" World", BG_MAGENTA) c_string = a_string + b_string print("ljust", c_string.ljust(15)) assert repr(c_string.ljust( 15)) == "<43m>Hello</43m><45m> World</45m><45m> </45m>" assert repr(c_string.ljust( 15, '-')) == "<43m>Hello</43m><45m> World</45m><45m>----</45m>" print("ljust short", c_string.ljust(5)) print("ljust short", repr(c_string.ljust(5))) assert repr(c_string.ljust(5)) == repr(c_string) print("rjust", c_string.rjust(15)) assert repr(c_string.rjust( 15)) == "<43m> </43m><43m>Hello</43m><45m> World</45m>" print("center", c_string.center(15)) assert repr(c_string.center( 15)) == "<43m> </43m><43m>Hello</43m><45m> World</45m><45m> </45m>"
def paint(self): width, height = self.size xoffset = self.region.offset[0] - self.region.origin[0] yoffset = self.region.offset[1] - self.region.origin[1] snapshots = self.snapshots[yoffset:yoffset + height] for i, snapshot in enumerate(snapshots): line_display = sstring("%d: " % snapshot["id"]) fun_call = self.cache.get_fun_call(snapshot["fun_call_id"]) fun_code = self.cache.get_fun_code(fun_call["fun_code_id"]) locals_id = fun_call["locals"] var_values = self.value_fetcher.get_values_by_varnames( locals_id, self.vars, snapshot["id"]) attrs = {} for var_value in var_values: attrs[var_value["key"]] = self.value_fetcher.fetch_value( var_value["value"], snapshot["id"], 2) selected_attrs = {} for key in self.attrs_to_use: key_parts = key.split(".")[2:] curr_attrs = attrs for part in key_parts: if curr_attrs and part in curr_attrs: curr_attrs = curr_attrs[part] else: curr_attrs = None selected_attrs[key] = curr_attrs display_grouped = group_attributes(selected_attrs) for key, value in display_grouped.items(): line_display += self.display_value(key, value) if self.current_snapshot_id == snapshot["id"]: line_display = sstring(line_display.ljust(width), [REVERSED]) self.region.draw(-xoffset, yoffset + i, line_display)
def test_slice(): a_string = sstring("Hello world", RED) slice1 = a_string[1:4] assert repr(slice1) == "<31m>ell</31m>" assert len(slice1) == 3 slice2 = a_string[6:] assert repr(slice2) == "<31m>world</31m>" assert len(slice2) == 5 slice3 = a_string[:5] assert repr(slice3) == "<31m>Hello</31m>" assert len(slice3) == 5 slice4 = a_string[0:] assert repr(slice4) == "<31m>Hello world</31m>" assert len(slice4) == 11
def draw_scroll_bars(self): region = self.region width, height = self.size content_width, content_height = self.content.size offsetx, offsety = self.offset vscroll = height < content_height hscroll = width < content_width if vscroll: vscroll_offset_percent = offsety / content_height vscroll_visible_percent = height / content_height vscroll_knob_offset = round(vscroll_offset_percent * height) vscroll_scroll_knob_height = round(vscroll_visible_percent * height) for i in range(height): if i < vscroll_knob_offset: region.draw(width - 1, i, "┃") elif i >= vscroll_knob_offset + vscroll_scroll_knob_height: region.draw(width - 1, i, "┃") else: region.draw(width - 1, i, sstring(" ", REVERSED)) if hscroll: if vscroll: hscroll_width = width - 1 else: hscroll_width = width hscroll_offset_percent = offsetx / content_width hscroll_visible_percent = width / content_width hscroll_knob_offset = round(hscroll_offset_percent * width) hscroll_scroll_knob_width = round(hscroll_visible_percent * hscroll_width) region.draw(0, height - 1, "━" * hscroll_knob_offset) region.draw(hscroll_knob_offset, height - 1, sstring(" " * hscroll_scroll_knob_width, REVERSED)) region.draw( hscroll_knob_offset + hscroll_scroll_knob_width, height - 1, "━" * (hscroll_width - (hscroll_knob_offset + hscroll_scroll_knob_width)) )
def __init__(self, cache, navigator, container): self.snapshot = None self.cache = cache self.nav = navigator self.container = container self.code_lines_pane = CodeLinesPane(self.cache) self.scroll_view = ScrollView(self.code_lines_pane, line_numbers=True) self.vbox = VBox() self.toolbar = HBox() self.init_menu() add_child(self.toolbar, self.file_menu_button) self.hits_button = Text(sstring(" Show hits ", [BG_BLUE])) add_listener(self.hits_button, "click", self.hits_button_clicked) add_child(self.toolbar, self.hits_button) add_child(self.vbox, self.toolbar) add_child(self.vbox, self.scroll_view, stretch="both") add_child(self, self.vbox)
def main(): ui = WindowManager() box = VBox(same_item_width=True) add_child(box, Text("sum = 0"), stretch="x") add_child(box, Text("while n < 0:"), stretch="x") add_child(box, Text(sstring(" sum += n", REVERSED)), stretch="x") add_child(box, Text(" n += 1"), stretch="x") win1 = Window("Debugger", box) ui.add_window(win1, abs_pos=(2, 2), abs_size=(20, 10)) box2 = VBox(same_item_width=True) add_child(box2, Text("Hello, world!"), stretch="x") win2 = Window("Program", box2) ui.add_window(win2, abs_pos=(24, 15)) run(ui)
def update_view_menu_items(self): if self.win_manager.has_window(self.code_win): self.code_view_menu_item.label = sstring("✓ Code") else: self.code_view_menu_item.label = sstring(" Code") if self.win_manager.has_window(self.stack_win): self.variables_view_menu_item.label = sstring("✓ Variables") else: self.variables_view_menu_item.label = sstring(" Variables") if self.win_manager.has_window(self.timeline_win): self.timeline_view_menu_item.label = sstring("✓ Timeline") else: self.timeline_view_menu_item.label = sstring(" Timeline")
def test(): test_basic() test_multiple_control_codes() test_len() test_concat() test_index() test_slice() test_complex_control_code() test_strike_through() test_ljust() test_rjust() test_center() test_index_group() test_slice_group() test_multiple_codes_group() test_strike_through_group() test_ljust_rjust_center_group() test_nesting() test_equality() print(sstring("ok", [GREEN]))
def main(): def on_keypress(evt): if evt.key == "q": quit() ui = VBox() hbox = HBox() field = TextField(placeholder="What to do?", width=20) button = Text(sstring("Add", [REVERSED])) add_listener(field, "keypress", on_keypress) add_child(hbox, field, stretch="x") add_child(hbox, button) add_child(ui, Border(hbox), stretch="x") list_ui = VBox() add_child(ui, Border(list_ui), stretch="x") add_child(list_ui, Text("Water plants")) add_child(list_ui, Text("Do homework")) add_child(list_ui, Text("Make dinner")) run(ui)
def paint(self): file_lines = self.cache.get_code_lines(self.code_file["id"]) lines_hit = self.cache.get_code_file_lines_hit(self.code_file["id"]) if file_lines is None: return width, height = self.size gutter_width = len(str(len(file_lines) + 1)) xoffset = self.region.offset[0] - self.region.origin[0] yoffset = self.region.offset[1] - self.region.origin[1] display_lines = file_lines[yoffset:yoffset + height] for i, line in enumerate(display_lines): line = line.replace("\t", " ") lineno = yoffset + i + 1 line_display = line.ljust(width) styles = [] if lineno in lines_hit: if self.current_line == lineno: styles.append(BG_WHITE) styles.append(BLACK) else: styles.append(RED) line_display = sstring(line_display, styles) self.region.draw(-xoffset, yoffset + i, line_display)
def init_ui(self): self.ui = VBox() self.content = Board() self.init_menu_bar() self.status_bar = Text(sstring("", [REVERSED])) add_child(self.ui, self.menu_bar, stretch="x") add_child(self.ui, self.content, stretch="both") add_child(self.ui, self.status_bar, stretch="x") add_listener(self.ui, "keypress", self.on_keypress) add_listener(self.ui, "goto_snapshot", self.on_goto_snapshot) self.win_manager = WindowManager() add_child(self.content, self.win_manager, stretch="both") termsize = os.get_terminal_size() self.init_code_pane(termsize) self.init_stack_pane(termsize) self.init_timeline() add_listener(self.win_manager, "add_window", self.on_add_window) add_listener(self.win_manager, "close_window", self.on_close_window)
def paint(self): region = self.region width, height = self.size text = self.text use_placeholder = self.placeholder and len(text) == 0 if use_placeholder: text = self.placeholder display_text = "".join(text[self.offset:]).ljust(width)[0:width] background = "48;5;242m" placeholder_color = "38;5;246m" cursor_background = "44m" if has_focus(self): cursor = self.cursor - self.offset before_cursor = display_text[0:cursor] cursor_char = display_text[cursor] after_cursor = display_text[cursor + 1:] region.draw(0, 0, sstring(before_cursor, background)) if use_placeholder: region.draw( cursor, 0, sstring(cursor_char, [placeholder_color, cursor_background])) else: region.draw(cursor, 0, sstring(cursor_char, cursor_background)) if use_placeholder: region.draw( cursor + 1, 0, sstring(after_cursor, [placeholder_color, background])) else: region.draw(cursor + 1, 0, sstring(after_cursor, background)) else: if use_placeholder: region.draw( 0, 0, sstring(display_text, [placeholder_color, background])) else: region.draw(0, 0, sstring(display_text, background))
def paint(self, region, pos): self.pos = pos for i in range(0, 10): for j in range(0, 12): region.draw(i, j, sstring("%d" % i, color256(i)))
def on_checkbox_clicked(self, evt): self.checked = not self.checked display = "☐ " if not self.checked else "☑ " self.check_box.set_text(display) self.label.set_text(sstring(self.text, strike_through=self.checked))
def paint(self): width, height = self.size display = self.label.ljust(width) if self.highlighted: display = sstring(display, BG_BRIGHT_CYAN) self.region.draw(0, 0, display)
def __init__(self, size): self.size = size width, height = self.size self.lines = [sstring(" " * width) for i in range(height)]