aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/console/searchable.py
diff options
context:
space:
mode:
authorJim Shaver <dcypherd@gmail.com>2015-06-23 21:48:05 -0500
committerJim Shaver <dcypherd@gmail.com>2015-06-23 21:48:05 -0500
commit080e4534253338c94e6d8c86cb3679ff15410f85 (patch)
tree6322fb822332b4135f0ff14de8c2d7137016f734 /libmproxy/console/searchable.py
parentdb5c0b210b0133d7cd58124c727dbc24480e2568 (diff)
parent074d8d7c7463cdb1f0a90e165a4b3ada3554b4c2 (diff)
downloadmitmproxy-080e4534253338c94e6d8c86cb3679ff15410f85.tar.gz
mitmproxy-080e4534253338c94e6d8c86cb3679ff15410f85.tar.bz2
mitmproxy-080e4534253338c94e6d8c86cb3679ff15410f85.zip
Merge branch 'master' into hardfailvenv
Conflicts: dev
Diffstat (limited to 'libmproxy/console/searchable.py')
-rw-r--r--libmproxy/console/searchable.py91
1 files changed, 91 insertions, 0 deletions
diff --git a/libmproxy/console/searchable.py b/libmproxy/console/searchable.py
new file mode 100644
index 00000000..627d595d
--- /dev/null
+++ b/libmproxy/console/searchable.py
@@ -0,0 +1,91 @@
+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)