codekingpro/portable-devtools
114k
1import urwid2 3from mitmproxy.tools.console import signals4 5 6class Highlight(urwid.AttrMap):7 def __init__(self, t):8 urwid.AttrMap.__init__(9 self,10 urwid.Text(t.text),11 "focusfield",12 )13 self.backup = t14 15 16class Searchable(urwid.ListBox):17 def __init__(self, contents):18 self.walker = urwid.SimpleFocusListWalker(contents)19 urwid.ListBox.__init__(self, self.walker)20 self.search_offset = 021 self.current_highlight = None22 self.search_term = None23 self.last_search = None24 25 def keypress(self, size, key: str):26 if key == "/":27 signals.status_prompt.send(28 prompt="Search for", text="", callback=self.set_search29 )30 elif key == "n":31 self.find_next(False)32 elif key == "N":33 self.find_next(True)34 elif key == "m_start":35 self.set_focus(0)36 self.walker._modified()37 elif key == "m_end":38 self.set_focus(len(self.walker) - 1)39 self.walker._modified()40 else:41 return super().keypress(size, key)42 43 def set_search(self, text):44 self.last_search = text45 self.search_term = text or None46 self.find_next(False)47 48 def set_highlight(self, offset):49 if self.current_highlight is not None:50 old = self.body[self.current_highlight]51 self.body[self.current_highlight] = old.backup52 if offset is None:53 self.current_highlight = None54 else:55 self.body[offset] = Highlight(self.body[offset])56 self.current_highlight = offset57 58 def get_text(self, w):59 if isinstance(w, urwid.Text):60 return w.text61 elif isinstance(w, Highlight):62 return w.backup.text63 else:64 return None65 66 def find_next(self, backwards: bool):67 if not self.search_term:68 if self.last_search:69 self.search_term = self.last_search70 else:71 self.set_highlight(None)72 return73 # Start search at focus + 174 if backwards:75 rng = range(len(self.body) - 1, -1, -1)76 else:77 rng = range(1, len(self.body) + 1)78 for i in rng:79 off = (self.focus_position + i) % len(self.body)80 w = self.body[off]81 txt = self.get_text(w)82 if txt and self.search_term in txt:83 self.set_highlight(off)84 self.set_focus(off, coming_from="above")85 self.body._modified()86 return87 else:88 self.set_highlight(None)89 signals.status_message.send(message="Search not found.", expire=1)90 