<commit_before>from __future__ import absolute_import, print_function, division

import urwid

from mitmproxy.console 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)<commit_msg>Fix console search on Python 3<commit_after>from __future__ import absolute_import, print_function, division

import urwid

from mitmproxy.console 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 = range(len(self.body) - 1, -1, -1)
        else:
            rng = range(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)
{'fraction_non_alphanumeric': 0.09707742266279268, 'fraction_numerical': 0.0035891300632370535, 'mean_word_length': 1.6527651858567542, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2112701', 'n_tokens_mistral': 1725, 'n_tokens_neox': 1640, 'n_words': 376}