We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
WebSocket view jumps to top on new message
The WebSocket view keeps jumping to the top every time a new message arrives. This makes it basically impossible to work with while the connection is open. I hold down arrow -> it scrolls a bit -> message arrives -> I'm back at the top

_Originally posted by @Prinzhorn in https://github.com/mitmproxy/mitmproxy/issues/4486#issuecomment-796578909_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mitmproxy/tools/console/searchable.py`
Content:
```
1 import urwid
2 
3 from mitmproxy.tools.console import signals
4 
5 
6 class Highlight(urwid.AttrMap):
7 
8     def __init__(self, t):
9         urwid.AttrMap.__init__(
10             self,
11             urwid.Text(t.text),
12             "focusfield",
13         )
14         self.backup = t
15 
16 
17 class Searchable(urwid.ListBox):
18 
19     def __init__(self, contents):
20         self.walker = urwid.SimpleFocusListWalker(contents)
21         urwid.ListBox.__init__(self, self.walker)
22         self.search_offset = 0
23         self.current_highlight = None
24         self.search_term = None
25         self.last_search = None
26 
27     def keypress(self, size, key):
28         if key == "/":
29             signals.status_prompt.send(
30                 prompt = "Search for",
31                 text = "",
32                 callback = self.set_search
33             )
34         elif key == "n":
35             self.find_next(False)
36         elif key == "N":
37             self.find_next(True)
38         elif key == "m_start":
39             self.set_focus(0)
40             self.walker._modified()
41         elif key == "m_end":
42             self.set_focus(len(self.walker) - 1)
43             self.walker._modified()
44         else:
45             return super().keypress(size, key)
46 
47     def set_search(self, text):
48         self.last_search = text
49         self.search_term = text or None
50         self.find_next(False)
51 
52     def set_highlight(self, offset):
53         if self.current_highlight is not None:
54             old = self.body[self.current_highlight]
55             self.body[self.current_highlight] = old.backup
56         if offset is None:
57             self.current_highlight = None
58         else:
59             self.body[offset] = Highlight(self.body[offset])
60             self.current_highlight = offset
61 
62     def get_text(self, w):
63         if isinstance(w, urwid.Text):
64             return w.text
65         elif isinstance(w, Highlight):
66             return w.backup.text
67         else:
68             return None
69 
70     def find_next(self, backwards):
71         if not self.search_term:
72             if self.last_search:
73                 self.search_term = self.last_search
74             else:
75                 self.set_highlight(None)
76                 return
77         # Start search at focus + 1
78         if backwards:
79             rng = range(len(self.body) - 1, -1, -1)
80         else:
81             rng = range(1, len(self.body) + 1)
82         for i in rng:
83             off = (self.focus_position + i) % len(self.body)
84             w = self.body[off]
85             txt = self.get_text(w)
86             if txt and self.search_term in txt:
87                 self.set_highlight(off)
88                 self.set_focus(off, coming_from="above")
89                 self.body._modified()
90                 return
91         else:
92             self.set_highlight(None)
93             signals.status_message.send(message="Search not found.", expire=1)
94
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mitmproxy/tools/console/searchable.py b/mitmproxy/tools/console/searchable.py
--- a/mitmproxy/tools/console/searchable.py
+++ b/mitmproxy/tools/console/searchable.py
@@ -19,6 +19,7 @@
     def __init__(self, contents):
         self.walker = urwid.SimpleFocusListWalker(contents)
         urwid.ListBox.__init__(self, self.walker)
+        self.set_focus(len(self.walker) - 1)
         self.search_offset = 0
         self.current_highlight = None
         self.search_term = None

{"golden_diff": "diff --git a/mitmproxy/tools/console/searchable.py b/mitmproxy/tools/console/searchable.py\n--- a/mitmproxy/tools/console/searchable.py\n+++ b/mitmproxy/tools/console/searchable.py\n@@ -19,6 +19,7 @@\n     def __init__(self, contents):\n         self.walker = urwid.SimpleFocusListWalker(contents)\n         urwid.ListBox.__init__(self, self.walker)\n+        self.set_focus(len(self.walker) - 1)\n         self.search_offset = 0\n         self.current_highlight = None\n         self.search_term = None\n", "issue": "WebSocket view jumps to top on new message\nThe WebSocket view keeps jumping to the top every time a new message arrives. This makes it basically impossible to work with while the connection is open. I hold down arrow -> it scrolls a bit -> message arrives -> I'm back at the top\r\n\r\n_Originally posted by @Prinzhorn in https://github.com/mitmproxy/mitmproxy/issues/4486#issuecomment-796578909_\n", "before_files": [{"content": "import urwid\n\nfrom mitmproxy.tools.console import signals\n\n\nclass Highlight(urwid.AttrMap):\n\n    def __init__(self, t):\n        urwid.AttrMap.__init__(\n            self,\n            urwid.Text(t.text),\n            \"focusfield\",\n        )\n        self.backup = t\n\n\nclass Searchable(urwid.ListBox):\n\n    def __init__(self, contents):\n        self.walker = urwid.SimpleFocusListWalker(contents)\n        urwid.ListBox.__init__(self, self.walker)\n        self.search_offset = 0\n        self.current_highlight = None\n        self.search_term = None\n        self.last_search = None\n\n    def keypress(self, size, key):\n        if key == \"/\":\n            signals.status_prompt.send(\n                prompt = \"Search for\",\n                text = \"\",\n                callback = self.set_search\n            )\n        elif key == \"n\":\n            self.find_next(False)\n        elif key == \"N\":\n            self.find_next(True)\n        elif key == \"m_start\":\n            self.set_focus(0)\n            self.walker._modified()\n        elif key == \"m_end\":\n            self.set_focus(len(self.walker) - 1)\n            self.walker._modified()\n        else:\n            return super().keypress(size, key)\n\n    def set_search(self, text):\n        self.last_search = text\n        self.search_term = text or None\n        self.find_next(False)\n\n    def set_highlight(self, offset):\n        if self.current_highlight is not None:\n            old = self.body[self.current_highlight]\n            self.body[self.current_highlight] = old.backup\n        if offset is None:\n            self.current_highlight = None\n        else:\n            self.body[offset] = Highlight(self.body[offset])\n            self.current_highlight = offset\n\n    def get_text(self, w):\n        if isinstance(w, urwid.Text):\n            return w.text\n        elif isinstance(w, Highlight):\n            return w.backup.text\n        else:\n            return None\n\n    def find_next(self, backwards):\n        if not self.search_term:\n            if self.last_search:\n                self.search_term = self.last_search\n            else:\n                self.set_highlight(None)\n                return\n        # Start search at focus + 1\n        if backwards:\n            rng = range(len(self.body) - 1, -1, -1)\n        else:\n            rng = range(1, len(self.body) + 1)\n        for i in rng:\n            off = (self.focus_position + i) % len(self.body)\n            w = self.body[off]\n            txt = self.get_text(w)\n            if txt and self.search_term in txt:\n                self.set_highlight(off)\n                self.set_focus(off, coming_from=\"above\")\n                self.body._modified()\n                return\n        else:\n            self.set_highlight(None)\n            signals.status_message.send(message=\"Search not found.\", expire=1)\n", "path": "mitmproxy/tools/console/searchable.py"}], "after_files": [{"content": "import urwid\n\nfrom mitmproxy.tools.console import signals\n\n\nclass Highlight(urwid.AttrMap):\n\n    def __init__(self, t):\n        urwid.AttrMap.__init__(\n            self,\n            urwid.Text(t.text),\n            \"focusfield\",\n        )\n        self.backup = t\n\n\nclass Searchable(urwid.ListBox):\n\n    def __init__(self, contents):\n        self.walker = urwid.SimpleFocusListWalker(contents)\n        urwid.ListBox.__init__(self, self.walker)\n        self.set_focus(len(self.walker) - 1)\n        self.search_offset = 0\n        self.current_highlight = None\n        self.search_term = None\n        self.last_search = None\n\n    def keypress(self, size, key):\n        if key == \"/\":\n            signals.status_prompt.send(\n                prompt = \"Search for\",\n                text = \"\",\n                callback = self.set_search\n            )\n        elif key == \"n\":\n            self.find_next(False)\n        elif key == \"N\":\n            self.find_next(True)\n        elif key == \"m_start\":\n            self.set_focus(0)\n            self.walker._modified()\n        elif key == \"m_end\":\n            self.set_focus(len(self.walker) - 1)\n            self.walker._modified()\n        else:\n            return super().keypress(size, key)\n\n    def set_search(self, text):\n        self.last_search = text\n        self.search_term = text or None\n        self.find_next(False)\n\n    def set_highlight(self, offset):\n        if self.current_highlight is not None:\n            old = self.body[self.current_highlight]\n            self.body[self.current_highlight] = old.backup\n        if offset is None:\n            self.current_highlight = None\n        else:\n            self.body[offset] = Highlight(self.body[offset])\n            self.current_highlight = offset\n\n    def get_text(self, w):\n        if isinstance(w, urwid.Text):\n            return w.text\n        elif isinstance(w, Highlight):\n            return w.backup.text\n        else:\n            return None\n\n    def find_next(self, backwards):\n        if not self.search_term:\n            if self.last_search:\n                self.search_term = self.last_search\n            else:\n                self.set_highlight(None)\n                return\n        # Start search at focus + 1\n        if backwards:\n            rng = range(len(self.body) - 1, -1, -1)\n        else:\n            rng = range(1, len(self.body) + 1)\n        for i in rng:\n            off = (self.focus_position + i) % len(self.body)\n            w = self.body[off]\n            txt = self.get_text(w)\n            if txt and self.search_term in txt:\n                self.set_highlight(off)\n                self.set_focus(off, coming_from=\"above\")\n                self.body._modified()\n                return\n        else:\n            self.set_highlight(None)\n            signals.status_message.send(message=\"Search not found.\", expire=1)\n", "path": "mitmproxy/tools/console/searchable.py"}]}