aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/libmproxy/console/searchable.py
diff options
context:
space:
mode:
Diffstat (limited to 'mitmproxy/libmproxy/console/searchable.py')
-rw-r--r--mitmproxy/libmproxy/console/searchable.py93
1 files changed, 93 insertions, 0 deletions
diff --git a/mitmproxy/libmproxy/console/searchable.py b/mitmproxy/libmproxy/console/searchable.py
new file mode 100644
index 00000000..cff1f0a1
--- /dev/null
+++ b/mitmproxy/libmproxy/console/searchable.py
@@ -0,0 +1,93 @@
+import urwid
+
+from . import signals
+
+
+class Highlight(urwid.AttrMap):
+
+ def __init__(self, t):
+ urwid.AttrMap.__init__(
+ self,
+ urwid.Text(t.text),
+ "focusfield",
+ )
+ self.backup = t
+
+
+class Searchable(urwid.ListBox):
+
+ def __init__(self, state, contents):
+ self.walker = urwid.SimpleFocusListWalker(contents)
+ urwid.ListBox.__init__(self, self.walker)
+ self.state = state
+ self.search_offset = 0
+ self.current_highlight = None
+ self.search_term = None
+
+ def keypress(self, size, key):
+ if key == "/":
+ signals.status_prompt.send(
+ prompt = "Search for",
+ text = "",
+ callback = self.set_search
+ )
+ elif key == "n":
+ self.find_next(False)
+ elif key == "N":
+ self.find_next(True)
+ elif key == "g":
+ self.set_focus(0)
+ self.walker._modified()
+ elif key == "G":
+ self.set_focus(len(self.walker) - 1)
+ self.walker._modified()
+ else:
+ return super(self.__class__, self).keypress(size, key)
+
+ def set_search(self, text):
+ self.state.last_search = text
+ self.search_term = text or None
+ self.find_next(False)
+
+ def set_highlight(self, offset):
+ if self.current_highlight is not None:
+ old = self.body[self.current_highlight]
+ self.body[self.current_highlight] = old.backup
+ if offset is None:
+ self.current_highlight = None
+ else:
+ self.body[offset] = Highlight(self.body[offset])
+ self.current_highlight = offset
+
+ def get_text(self, w):
+ if isinstance(w, urwid.Text):
+ return w.text
+ elif isinstance(w, Highlight):
+ return w.backup.text
+ else:
+ return None
+
+ def find_next(self, backwards):
+ if not self.search_term:
+ if self.state.last_search:
+ self.search_term = self.state.last_search
+ else:
+ self.set_highlight(None)
+ return
+ # Start search at focus + 1
+ if backwards:
+ rng = xrange(len(self.body) - 1, -1, -1)
+ else:
+ rng = xrange(1, len(self.body) + 1)
+ for i in rng:
+ off = (self.focus_position + i) % len(self.body)
+ w = self.body[off]
+ txt = self.get_text(w)
+ if txt and self.search_term in txt:
+ self.set_highlight(off)
+ self.set_focus(off, coming_from="above")
+ self.body._modified()
+ return
+ else:
+ self.set_highlight(None)
+ signals.status_message.send(message="Search not found.", expire=1)