aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/platform/openbsd.py1
-rw-r--r--mitmproxy/tools/console/commands.py4
-rw-r--r--mitmproxy/tools/console/defaultkeys.py7
-rw-r--r--mitmproxy/tools/console/eventlog.py8
-rw-r--r--mitmproxy/tools/console/flowlist.py2
-rw-r--r--mitmproxy/tools/console/flowview.py4
-rw-r--r--mitmproxy/tools/console/grideditor/base.py49
-rw-r--r--mitmproxy/tools/console/grideditor/col_bytes.py2
-rw-r--r--mitmproxy/tools/console/grideditor/col_subgrid.py2
-rw-r--r--mitmproxy/tools/console/grideditor/editors.py17
-rw-r--r--mitmproxy/tools/console/help.py19
-rw-r--r--mitmproxy/tools/console/keymap.py1
-rw-r--r--mitmproxy/tools/console/master.py28
-rw-r--r--mitmproxy/tools/console/options.py6
-rw-r--r--mitmproxy/tools/console/overlay.py17
-rw-r--r--mitmproxy/tools/console/select.py120
-rw-r--r--mitmproxy/tools/console/signals.py8
-rw-r--r--mitmproxy/tools/console/statusbar.py17
-rw-r--r--mitmproxy/tools/console/tabs.py4
19 files changed, 70 insertions, 246 deletions
diff --git a/mitmproxy/platform/openbsd.py b/mitmproxy/platform/openbsd.py
index e8f5ff8e..302dc11b 100644
--- a/mitmproxy/platform/openbsd.py
+++ b/mitmproxy/platform/openbsd.py
@@ -1,2 +1,3 @@
+
def original_addr(csock):
return csock.getsockname()
diff --git a/mitmproxy/tools/console/commands.py b/mitmproxy/tools/console/commands.py
index 7f680c72..e4535314 100644
--- a/mitmproxy/tools/console/commands.py
+++ b/mitmproxy/tools/console/commands.py
@@ -99,7 +99,7 @@ class CommandsList(urwid.ListBox):
super().__init__(self.walker)
def keypress(self, size, key):
- if key == "enter":
+ if key == "m_select":
foc, idx = self.get_focus()
signals.status_prompt_command.send(partial=foc.cmd.path + " ")
elif key == "m_start":
@@ -148,7 +148,7 @@ class Commands(urwid.Pile, layoutwidget.LayoutWidget):
self.master = master
def keypress(self, size, key):
- if key == "tab":
+ if key == "m_next":
self.focus_position = (
self.focus_position + 1
) % len(self.widget_list)
diff --git a/mitmproxy/tools/console/defaultkeys.py b/mitmproxy/tools/console/defaultkeys.py
index 2a442fbf..d5b868d0 100644
--- a/mitmproxy/tools/console/defaultkeys.py
+++ b/mitmproxy/tools/console/defaultkeys.py
@@ -17,6 +17,8 @@ def map(km):
km.add("j", "console.nav.down", ["global"], "Down")
km.add("l", "console.nav.right", ["global"], "Right")
km.add("h", "console.nav.left", ["global"], "Left")
+ km.add("tab", "console.nav.next", ["global"], "Next")
+ km.add("enter", "console.nav.select", ["global"], "Select")
km.add(" ", "console.nav.pagedown", ["global"], "Page down")
km.add("ctrl f", "console.nav.pagedown", ["global"], "Page down")
km.add("ctrl b", "console.nav.pageup", ["global"], "Page up")
@@ -78,7 +80,6 @@ def map(km):
["flowlist", "flowview"],
"Run a script on this flow"
)
- km.add("enter", "console.view.flow @focus", ["flowlist"], "View this flow")
km.add(
"e",
@@ -105,7 +106,6 @@ def map(km):
)
km.add("p", "view.focus.prev", ["flowview"], "Go to previous flow")
km.add("m", "console.flowview.mode.set", ["flowview"], "Set flow view mode")
- km.add("tab", "console.nav.right", ["flowview"], "Go to next tab")
km.add(
"z",
"console.choose \"Part\" request,response "
@@ -121,7 +121,6 @@ def map(km):
km.add("a", "console.grideditor.add", ["grideditor"], "Add a row after cursor")
km.add("A", "console.grideditor.insert", ["grideditor"], "Insert a row before cursor")
- km.add("tab", "console.grideditor.next", ["grideditor"], "Go to next field")
km.add("d", "console.grideditor.delete", ["grideditor"], "Delete this row")
km.add(
"r",
@@ -136,3 +135,5 @@ def map(km):
"Read a Python-style escaped string from file"
)
km.add("e", "console.grideditor.editor", ["grideditor"], "Edit in external editor")
+
+ km.add("z", "console.eventlog.clear", ["eventlog"], "Clear")
diff --git a/mitmproxy/tools/console/eventlog.py b/mitmproxy/tools/console/eventlog.py
index 1e56a05a..5fdada9f 100644
--- a/mitmproxy/tools/console/eventlog.py
+++ b/mitmproxy/tools/console/eventlog.py
@@ -18,16 +18,14 @@ class EventLog(urwid.ListBox, layoutwidget.LayoutWidget):
self.master = master
urwid.ListBox.__init__(self, self.walker)
signals.sig_add_log.connect(self.sig_add_log)
+ signals.sig_clear_log.connect(self.sig_clear_log)
def set_focus(self, index):
if 0 <= index < len(self.walker):
super().set_focus(index)
def keypress(self, size, key):
- if key == "z":
- self.clear_events()
- key = None
- elif key == "m_end":
+ if key == "m_end":
self.set_focus(len(self.walker) - 1)
elif key == "m_start":
self.set_focus(0)
@@ -45,5 +43,5 @@ class EventLog(urwid.ListBox, layoutwidget.LayoutWidget):
if self.master.options.console_focus_follow:
self.walker.set_focus(len(self.walker) - 1)
- def clear_events(self):
+ def sig_clear_log(self, sender):
self.walker[:] = []
diff --git a/mitmproxy/tools/console/flowlist.py b/mitmproxy/tools/console/flowlist.py
index 715ecb84..f00ed9fa 100644
--- a/mitmproxy/tools/console/flowlist.py
+++ b/mitmproxy/tools/console/flowlist.py
@@ -82,6 +82,8 @@ class FlowListBox(urwid.ListBox, layoutwidget.LayoutWidget):
self.master.commands.call("view.go 0")
elif key == "m_end":
self.master.commands.call("view.go -1")
+ elif key == "m_select":
+ self.master.commands.call("console.view.flow @focus")
return urwid.ListBox.keypress(self, size, key)
def view_changed(self):
diff --git a/mitmproxy/tools/console/flowview.py b/mitmproxy/tools/console/flowview.py
index dc846b7a..651c4330 100644
--- a/mitmproxy/tools/console/flowview.py
+++ b/mitmproxy/tools/console/flowview.py
@@ -194,10 +194,6 @@ class FlowDetails(tabs.Tabs):
]
return searchable.Searchable(txt)
- def keypress(self, size, key):
- key = super().keypress(size, key)
- return self._w.keypress(size, key)
-
class FlowView(urwid.Frame, layoutwidget.LayoutWidget):
keyctx = "flowview"
diff --git a/mitmproxy/tools/console/grideditor/base.py b/mitmproxy/tools/console/grideditor/base.py
index 87172eb4..cdda3def 100644
--- a/mitmproxy/tools/console/grideditor/base.py
+++ b/mitmproxy/tools/console/grideditor/base.py
@@ -6,19 +6,10 @@ import urwid
from mitmproxy.utils import strutils
from mitmproxy import exceptions
-from mitmproxy.tools.console import common
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import layoutwidget
import mitmproxy.tools.console.master # noqa
-FOOTER = [
- ('heading_key', "enter"), ":edit ",
- ('heading_key', "q"), ":back ",
-]
-FOOTER_EDITING = [
- ('heading_key', "esc"), ":stop editing ",
-]
-
def read_file(filename: str, escaped: bool) -> typing.AnyStr:
filename = os.path.expanduser(filename)
@@ -197,12 +188,10 @@ class GridWalker(urwid.ListWalker):
self.edit_row = GridRow(
self.focus_col, True, self.editor, self.lst[self.focus]
)
- signals.footer_help.send(self, helptext=FOOTER_EDITING)
self._modified()
def stop_edit(self):
if self.edit_row:
- signals.footer_help.send(self, helptext=FOOTER)
try:
val = self.edit_row.edit_col.get_data()
except ValueError:
@@ -262,7 +251,6 @@ class GridListBox(urwid.ListBox):
FIRST_WIDTH_MAX = 40
-FIRST_WIDTH_MIN = 20
class BaseGridEditor(urwid.WidgetWrap):
@@ -315,7 +303,6 @@ class BaseGridEditor(urwid.WidgetWrap):
w = urwid.Frame(self.lb, header=h)
super().__init__(w)
- signals.footer_help.send(self, helptext="")
self.show_empty_msg()
def layout_popping(self):
@@ -344,7 +331,7 @@ class BaseGridEditor(urwid.WidgetWrap):
def keypress(self, size, key):
if self.walker.edit_row:
- if key in ["esc"]:
+ if key == "esc":
self.walker.stop_edit()
elif key == "tab":
pf, pfc = self.walker.focus, self.walker.focus_col
@@ -358,6 +345,8 @@ class BaseGridEditor(urwid.WidgetWrap):
column = self.columns[self.walker.focus_col]
if key == "m_start":
self.walker.set_focus(0)
+ elif key == "m_next":
+ self.walker.tab_next()
elif key == "m_end":
self.walker.set_focus(len(self.walker.lst) - 1)
elif key == "left":
@@ -389,38 +378,6 @@ class BaseGridEditor(urwid.WidgetWrap):
def handle_key(self, key):
return False
- def make_help(self):
- text = [
- urwid.Text([("text", "Editor control:\n")])
- ]
- keys = [
- ("A", "insert row before cursor"),
- ("a", "add row after cursor"),
- ("d", "delete row"),
- ("e", "spawn external editor on current field"),
- ("q", "save changes and exit editor"),
- ("r", "read value from file"),
- ("R", "read unescaped value from file"),
- ("esc", "save changes and exit editor"),
- ("tab", "next field"),
- ("enter", "edit field"),
- ]
- text.extend(
- common.format_keyvals(keys, key="key", val="text", indent=4)
- )
- text.append(
- urwid.Text(
- [
- "\n",
- ("text", "Values are escaped Python-style strings.\n"),
- ]
- )
- )
- return text
-
- def cmd_next(self):
- self.walker.tab_next()
-
def cmd_add(self):
self.walker.add()
diff --git a/mitmproxy/tools/console/grideditor/col_bytes.py b/mitmproxy/tools/console/grideditor/col_bytes.py
index 227eb525..da10cbaf 100644
--- a/mitmproxy/tools/console/grideditor/col_bytes.py
+++ b/mitmproxy/tools/console/grideditor/col_bytes.py
@@ -15,7 +15,7 @@ class Column(base.Column):
return b""
def keypress(self, key, editor):
- if key in ["enter"]:
+ if key in ["m_select"]:
editor.walker.start_edit()
else:
return key
diff --git a/mitmproxy/tools/console/grideditor/col_subgrid.py b/mitmproxy/tools/console/grideditor/col_subgrid.py
index 4db37462..95995cd2 100644
--- a/mitmproxy/tools/console/grideditor/col_subgrid.py
+++ b/mitmproxy/tools/console/grideditor/col_subgrid.py
@@ -26,7 +26,7 @@ class Column(base.Column):
expire=1000
)
return
- elif key in ["enter"]:
+ elif key == "m_select":
editor.master.view_grideditor(
self.subeditor(
editor.master,
diff --git a/mitmproxy/tools/console/grideditor/editors.py b/mitmproxy/tools/console/grideditor/editors.py
index c6592960..074cdb77 100644
--- a/mitmproxy/tools/console/grideditor/editors.py
+++ b/mitmproxy/tools/console/grideditor/editors.py
@@ -1,8 +1,5 @@
-import urwid
-
from mitmproxy import exceptions
-from mitmproxy.tools.console import common
from mitmproxy.tools.console import layoutwidget
from mitmproxy.tools.console.grideditor import base
from mitmproxy.tools.console.grideditor import col_text
@@ -32,20 +29,6 @@ class HeaderEditor(base.FocusEditor):
col_bytes.Column("Value")
]
- def make_help(self):
- h = super().make_help()
- text = [
- urwid.Text([("text", "Special keys:\n")])
- ]
- keys = [
- ]
- text.extend(
- common.format_keyvals(keys, key="key", val="text", indent=4)
- )
- text.append(urwid.Text([("text", "\n")]))
- text.extend(h)
- return text
-
class RequestHeaderEditor(HeaderEditor):
title = "Edit Request Headers"
diff --git a/mitmproxy/tools/console/help.py b/mitmproxy/tools/console/help.py
index 959f7763..439289f6 100644
--- a/mitmproxy/tools/console/help.py
+++ b/mitmproxy/tools/console/help.py
@@ -6,6 +6,21 @@ from mitmproxy.tools.console import layoutwidget
from mitmproxy.tools.console import tabs
+class CListBox(urwid.ListBox):
+ def __init__(self, contents):
+ self.length = len(contents)
+ contents = contents[:] + [urwid.Text(["\n"])] * 5
+ super().__init__(contents)
+
+ def keypress(self, size, key):
+ if key == "m_end":
+ self.set_focus(self.length - 1)
+ elif key == "m_start":
+ self.set_focus(0)
+ else:
+ return super().keypress(size, key)
+
+
class HelpView(tabs.Tabs, layoutwidget.LayoutWidget):
title = "Help"
keyctx = "help"
@@ -54,7 +69,7 @@ class HelpView(tabs.Tabs, layoutwidget.LayoutWidget):
text.extend(self.format_keys(self.master.keymap.list("global")))
- return urwid.ListBox(text)
+ return CListBox(text)
def filtexp_title(self):
return "Filter Expressions"
@@ -83,7 +98,7 @@ class HelpView(tabs.Tabs, layoutwidget.LayoutWidget):
text.extend(
common.format_keyvals(examples, key="key", val="text", indent=4)
)
- return urwid.ListBox(text)
+ return CListBox(text)
def layout_pushed(self, prev):
"""
diff --git a/mitmproxy/tools/console/keymap.py b/mitmproxy/tools/console/keymap.py
index 343c46a6..b904f706 100644
--- a/mitmproxy/tools/console/keymap.py
+++ b/mitmproxy/tools/console/keymap.py
@@ -6,6 +6,7 @@ from mitmproxy.tools.console import commandeditor
SupportedContexts = {
"chooser",
"commands",
+ "eventlog",
"flowlist",
"flowview",
"global",
diff --git a/mitmproxy/tools/console/master.py b/mitmproxy/tools/console/master.py
index cf145c70..ce4e4d9d 100644
--- a/mitmproxy/tools/console/master.py
+++ b/mitmproxy/tools/console/master.py
@@ -131,6 +131,20 @@ class ConsoleAddon:
"""
self.master.inject_key("m_end")
+ @command.command("console.nav.next")
+ def nav_next(self) -> None:
+ """
+ Go to the next navigatable item.
+ """
+ self.master.inject_key("m_next")
+
+ @command.command("console.nav.select")
+ def nav_select(self) -> None:
+ """
+ Select a navigable item for viewing or editing.
+ """
+ self.master.inject_key("m_select")
+
@command.command("console.nav.up")
def nav_up(self) -> None:
"""
@@ -343,13 +357,6 @@ class ConsoleAddon:
"""
self._grideditor().cmd_insert()
- @command.command("console.grideditor.next")
- def grideditor_next(self) -> None:
- """
- Go to next cell.
- """
- self._grideditor().cmd_next()
-
@command.command("console.grideditor.delete")
def grideditor_delete(self) -> None:
"""
@@ -419,6 +426,13 @@ class ConsoleAddon:
]
)
+ @command.command("console.eventlog.clear")
+ def eventlog_clear(self) -> None:
+ """
+ Clear the event log.
+ """
+ signals.sig_clear_log.send(self)
+
def running(self):
self.started = True
diff --git a/mitmproxy/tools/console/options.py b/mitmproxy/tools/console/options.py
index 89656a18..4d55aeec 100644
--- a/mitmproxy/tools/console/options.py
+++ b/mitmproxy/tools/console/options.py
@@ -176,8 +176,10 @@ class OptionsList(urwid.ListBox):
except exceptions.OptionsError as v:
signals.status_message.send(message=str(v))
self.walker.stop_editing()
+ return None
elif key == "esc":
self.walker.stop_editing()
+ return None
else:
if key == "m_start":
self.set_focus(0)
@@ -185,7 +187,7 @@ class OptionsList(urwid.ListBox):
elif key == "m_end":
self.set_focus(len(self.walker.opts) - 1)
self.walker._modified()
- elif key == "enter":
+ elif key == "m_select":
foc, idx = self.get_focus()
if foc.opt.typespec == bool:
self.master.options.toggler(foc.opt.name)()
@@ -261,7 +263,7 @@ class Options(urwid.Pile, layoutwidget.LayoutWidget):
return foc.opt.name
def keypress(self, size, key):
- if key == "tab":
+ if key == "m_next":
self.focus_position = (
self.focus_position + 1
) % len(self.widget_list)
diff --git a/mitmproxy/tools/console/overlay.py b/mitmproxy/tools/console/overlay.py
index fecc7706..7072d00e 100644
--- a/mitmproxy/tools/console/overlay.py
+++ b/mitmproxy/tools/console/overlay.py
@@ -2,7 +2,6 @@ import math
import urwid
-from mitmproxy.tools.console import common
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import grideditor
from mitmproxy.tools.console import layoutwidget
@@ -116,20 +115,13 @@ class Chooser(urwid.WidgetWrap, layoutwidget.LayoutWidget):
def keypress(self, size, key):
key = self.master.keymap.handle("chooser", key)
- if key == "enter":
+ if key == "m_select":
self.callback(self.choices[self.walker.index])
signals.pop_view_state.send(self)
+ elif key == "esc":
+ signals.pop_view_state.send(self)
return super().keypress(size, key)
- def make_help(self):
- text = []
- keys = [
- ("enter", "choose option"),
- ("esc", "exit chooser"),
- ]
- text.extend(common.format_keyvals(keys, key="key", val="text", indent=4))
- return text
-
class OptionsOverlay(urwid.WidgetWrap, layoutwidget.LayoutWidget):
keyctx = "grideditor"
@@ -151,9 +143,6 @@ class OptionsOverlay(urwid.WidgetWrap, layoutwidget.LayoutWidget):
)
self.width = math.ceil(cols * 0.8)
- def make_help(self):
- return self.ge.make_help()
-
def key_responder(self):
return self.ge.key_responder()
diff --git a/mitmproxy/tools/console/select.py b/mitmproxy/tools/console/select.py
deleted file mode 100644
index f7e5d950..00000000
--- a/mitmproxy/tools/console/select.py
+++ /dev/null
@@ -1,120 +0,0 @@
-import urwid
-
-from mitmproxy.tools.console import common
-
-
-class _OptionWidget(urwid.WidgetWrap):
-
- def __init__(self, option, text, shortcut, active, focus):
- self.option = option
- textattr = "text"
- keyattr = "key"
- if focus and active:
- textattr = "option_active_selected"
- keyattr = "option_selected_key"
- elif focus:
- textattr = "option_selected"
- keyattr = "option_selected_key"
- elif active:
- textattr = "option_active"
- if shortcut:
- text = common.highlight_key(
- text,
- shortcut,
- textattr = textattr,
- keyattr = keyattr
- )
- opt = urwid.Text(text, align="left")
- opt = urwid.AttrWrap(opt, textattr)
- opt = urwid.Padding(opt, align = "center", width = 40)
- urwid.WidgetWrap.__init__(self, opt)
-
- def keypress(self, size, key):
- return key
-
- def selectable(self):
- return True
-
-
-class OptionWalker(urwid.ListWalker):
-
- def __init__(self, options):
- urwid.ListWalker.__init__(self)
- self.options = options
- self.focus = 0
-
- def set_focus(self, pos):
- self.focus = pos
-
- def get_focus(self):
- return self.options[self.focus].render(True), self.focus
-
- def get_next(self, pos):
- if pos >= len(self.options) - 1:
- return None, None
- return self.options[pos + 1].render(False), pos + 1
-
- def get_prev(self, pos):
- if pos <= 0:
- return None, None
- return self.options[pos - 1].render(False), pos - 1
-
-
-class Heading:
-
- def __init__(self, text):
- self.text = text
-
- def render(self, focus):
- opt = urwid.Text("\n" + self.text, align="left")
- opt = urwid.AttrWrap(opt, "title")
- opt = urwid.Padding(opt, align = "center", width = 40)
- return opt
-
-
-def _neg(*args):
- return False
-
-
-class Option:
-
- def __init__(self, text, shortcut, getstate=None, activate=None):
- self.text = text
- self.shortcut = shortcut
- self.getstate = getstate or _neg
- self.activate = activate or _neg
-
- def render(self, focus):
- return _OptionWidget(
- self,
- self.text,
- self.shortcut,
- self.getstate(),
- focus)
-
-
-class Select(urwid.ListBox):
-
- def __init__(self, options):
- self.walker = OptionWalker(options)
- urwid.ListBox.__init__(
- self,
- self.walker
- )
- self.options = options
- self.keymap = {}
- for i in options:
- if hasattr(i, "shortcut") and i.shortcut:
- if i.shortcut in self.keymap:
- raise ValueError("Duplicate shortcut key: %s" % i.shortcut)
- self.keymap[i.shortcut] = i
-
- def keypress(self, size, key):
- if key == "enter" or key == " ":
- self.get_focus()[0].option.activate()
- return None
- if key in self.keymap:
- self.keymap[key].activate()
- self.set_focus(self.options.index(self.keymap[key]))
- return None
- return super().keypress(size, key)
diff --git a/mitmproxy/tools/console/signals.py b/mitmproxy/tools/console/signals.py
index 5cbbd875..49115a5d 100644
--- a/mitmproxy/tools/console/signals.py
+++ b/mitmproxy/tools/console/signals.py
@@ -1,6 +1,9 @@
import blinker
-# Show a status message in the action bar
+# Clear the eventlog
+sig_clear_log = blinker.Signal()
+
+# Add an entry to the eventlog
sig_add_log = blinker.Signal()
@@ -33,9 +36,6 @@ call_in = blinker.Signal()
# Focus the body, footer or header of the main window
focus = blinker.Signal()
-# Set the mini help text in the footer of the main window
-footer_help = blinker.Signal()
-
# Fired when settings change
update_settings = blinker.Signal()
diff --git a/mitmproxy/tools/console/statusbar.py b/mitmproxy/tools/console/statusbar.py
index a4308848..a37ecbd8 100644
--- a/mitmproxy/tools/console/statusbar.py
+++ b/mitmproxy/tools/console/statusbar.py
@@ -3,7 +3,6 @@ import os.path
import urwid
from mitmproxy.tools.console import common
-from mitmproxy.tools.console import pathedit
from mitmproxy.tools.console import signals
from mitmproxy.tools.console import commandeditor
import mitmproxy.tools.console.master # noqa
@@ -39,16 +38,12 @@ class ActionBar(urwid.WidgetWrap):
self.clear()
signals.status_message.connect(self.sig_message)
signals.status_prompt.connect(self.sig_prompt)
- signals.status_prompt_path.connect(self.sig_path_prompt)
signals.status_prompt_onekey.connect(self.sig_prompt_onekey)
signals.status_prompt_command.connect(self.sig_prompt_command)
- self.last_path = ""
-
self.prompting = None
self.onekey = False
- self.pathprompt = False
def sig_message(self, sender, message, expire=1):
if self.prompting:
@@ -74,15 +69,6 @@ class ActionBar(urwid.WidgetWrap):
self._w = commandeditor.CommandEdit(partial)
self.prompting = commandeditor.CommandExecutor(self.master)
- def sig_path_prompt(self, sender, prompt, callback, args=()):
- signals.focus.send(self, section="footer")
- self._w = pathedit.PathEdit(
- self.prep_prompt(prompt),
- os.path.dirname(self.last_path)
- )
- self.pathprompt = True
- self.prompting = PromptPath(callback, args)
-
def sig_prompt_onekey(self, sender, prompt, keys, callback, args=()):
"""
Keys are a set of (word, key) tuples. The appropriate key in the
@@ -128,13 +114,10 @@ class ActionBar(urwid.WidgetWrap):
def prompt_done(self):
self.prompting = None
self.onekey = False
- self.pathprompt = False
signals.status_message.send(message="")
signals.focus.send(self, section="body")
def prompt_execute(self, txt):
- if self.pathprompt:
- self.last_path = txt
p = self.prompting
self.prompt_done()
msg = p(txt)
diff --git a/mitmproxy/tools/console/tabs.py b/mitmproxy/tools/console/tabs.py
index 93d6909e..77873086 100644
--- a/mitmproxy/tools/console/tabs.py
+++ b/mitmproxy/tools/console/tabs.py
@@ -35,7 +35,9 @@ class Tabs(urwid.WidgetWrap):
def keypress(self, size, key):
n = len(self.tabs)
- if key == "right":
+ if key == "m_next":
+ self.change_tab((self.tab_offset + 1) % n)
+ elif key == "right":
self.change_tab((self.tab_offset + 1) % n)
elif key == "left":
self.change_tab((self.tab_offset - 1) % n)