aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@corte.si>2017-05-02 10:37:11 +1200
committerAldo Cortesi <aldo@corte.si>2017-05-02 12:18:24 +1200
commit9e58c36639f7faa327ec10bdc8ab8f68e7118bf0 (patch)
treed8e9c092c6ce8200b838e5bc829283d363d7c27b
parent8d29492960a89078ad2743e648afa08a3c71ebc1 (diff)
downloadmitmproxy-9e58c36639f7faa327ec10bdc8ab8f68e7118bf0.tar.gz
mitmproxy-9e58c36639f7faa327ec10bdc8ab8f68e7118bf0.tar.bz2
mitmproxy-9e58c36639f7faa327ec10bdc8ab8f68e7118bf0.zip
console: globally respected nav commands
Use this to bind nav keys with commands throughout.
-rw-r--r--mitmproxy/addons/view.py2
-rw-r--r--mitmproxy/tools/console/commands.py7
-rw-r--r--mitmproxy/tools/console/common.py14
-rw-r--r--mitmproxy/tools/console/flowlist.py13
-rw-r--r--mitmproxy/tools/console/flowview.py1
-rw-r--r--mitmproxy/tools/console/grideditor/base.py10
-rw-r--r--mitmproxy/tools/console/help.py11
-rw-r--r--mitmproxy/tools/console/keymap.py1
-rw-r--r--mitmproxy/tools/console/master.py81
-rw-r--r--mitmproxy/tools/console/options.py5
-rw-r--r--mitmproxy/tools/console/overlay.py5
-rw-r--r--mitmproxy/tools/console/searchable.py4
-rw-r--r--mitmproxy/tools/console/select.py1
-rw-r--r--mitmproxy/tools/console/tabs.py4
-rw-r--r--mitmproxy/tools/console/window.py2
-rw-r--r--test/mitmproxy/addons/test_view.py1
16 files changed, 110 insertions, 52 deletions
diff --git a/mitmproxy/addons/view.py b/mitmproxy/addons/view.py
index c7bced94..dd579585 100644
--- a/mitmproxy/addons/view.py
+++ b/mitmproxy/addons/view.py
@@ -353,6 +353,8 @@ class View(collections.Sequence):
the view, negative from the end of the view, so that 0 is the first
flow, -1 is the last flow.
"""
+ if len(self) == 0:
+ return
if dst < 0:
dst = len(self) + dst
if dst < 0:
diff --git a/mitmproxy/tools/console/commands.py b/mitmproxy/tools/console/commands.py
index 84455a88..76827a99 100644
--- a/mitmproxy/tools/console/commands.py
+++ b/mitmproxy/tools/console/commands.py
@@ -120,6 +120,12 @@ class CommandsList(urwid.ListBox):
if key == "enter":
foc, idx = self.get_focus()
signals.status_prompt_command.send(partial=foc.cmd.path + " ")
+ elif key == "m_start":
+ self.set_focus(0)
+ self.walker._modified()
+ elif key == "m_end":
+ self.set_focus(len(self.walker.cmds) - 1)
+ self.walker._modified()
return super().keypress(size, key)
@@ -159,7 +165,6 @@ class Commands(urwid.Pile):
self.master = master
def keypress(self, size, key):
- key = common.shortcuts(key)
if key == "tab":
self.focus_position = (
self.focus_position + 1
diff --git a/mitmproxy/tools/console/common.py b/mitmproxy/tools/console/common.py
index 58129bd0..de024d1a 100644
--- a/mitmproxy/tools/console/common.py
+++ b/mitmproxy/tools/console/common.py
@@ -77,20 +77,6 @@ def format_keyvals(lst, key="key", val="text", indent=0):
return ret
-def shortcuts(k):
- if k == " ":
- k = "page down"
- elif k == "ctrl f":
- k = "page down"
- elif k == "ctrl b":
- k = "page up"
- elif k == "j":
- k = "down"
- elif k == "k":
- k = "up"
- return k
-
-
def fcol(s, attr):
s = str(s)
return (
diff --git a/mitmproxy/tools/console/flowlist.py b/mitmproxy/tools/console/flowlist.py
index b14d27e7..8e28ff0f 100644
--- a/mitmproxy/tools/console/flowlist.py
+++ b/mitmproxy/tools/console/flowlist.py
@@ -58,13 +58,12 @@ class LogBufferBox(urwid.ListBox):
super().set_focus(index)
def keypress(self, size, key):
- key = common.shortcuts(key)
if key == "z":
self.master.clear_events()
key = None
- elif key == "G":
+ elif key == "m_end":
self.set_focus(len(self.master.logbuffer) - 1)
- elif key == "g":
+ elif key == "m_start":
self.set_focus(0)
return urwid.ListBox.keypress(self, size, key)
@@ -136,8 +135,7 @@ class FlowItem(urwid.WidgetWrap):
return True
def keypress(self, xxx_todo_changeme, key):
- (maxcol,) = xxx_todo_changeme
- return common.shortcuts(key)
+ return key
class FlowListWalker(urwid.ListWalker):
@@ -183,7 +181,10 @@ class FlowListBox(urwid.ListBox):
super().__init__(FlowListWalker(master))
def keypress(self, size, key):
- key = common.shortcuts(key)
+ if key == "m_start":
+ self.master.commands.call("view.go 0")
+ elif key == "m_end":
+ self.master.commands.call("view.go -1")
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 c564ce5a..00951610 100644
--- a/mitmproxy/tools/console/flowview.py
+++ b/mitmproxy/tools/console/flowview.py
@@ -271,7 +271,6 @@ class FlowDetails(tabs.Tabs):
def keypress(self, size, key):
key = super().keypress(size, key)
- key = common.shortcuts(key)
return self._w.keypress(size, key)
diff --git a/mitmproxy/tools/console/grideditor/base.py b/mitmproxy/tools/console/grideditor/base.py
index fa7f0439..35ae655f 100644
--- a/mitmproxy/tools/console/grideditor/base.py
+++ b/mitmproxy/tools/console/grideditor/base.py
@@ -253,6 +253,7 @@ FIRST_WIDTH_MIN = 20
class BaseGridEditor(urwid.WidgetWrap):
+
def __init__(
self,
master: "mitmproxy.tools.console.master.ConsoleMaster",
@@ -345,15 +346,14 @@ class BaseGridEditor(urwid.WidgetWrap):
self._w.keypress(size, key)
return None
- key = common.shortcuts(key)
column = self.columns[self.walker.focus_col]
- if key == "g":
+ if key == "m_start":
self.walker.set_focus(0)
- elif key == "G":
+ elif key == "m_end":
self.walker.set_focus(len(self.walker.lst) - 1)
- elif key in ["h", "left"]:
+ elif key == "left":
self.walker.left()
- elif key in ["l", "right"]:
+ elif key == "right":
self.walker.right()
elif key == "tab":
self.walker.tab_next()
diff --git a/mitmproxy/tools/console/help.py b/mitmproxy/tools/console/help.py
index 33418624..ec0c95d9 100644
--- a/mitmproxy/tools/console/help.py
+++ b/mitmproxy/tools/console/help.py
@@ -4,7 +4,6 @@ import urwid
from mitmproxy import flowfilter
from mitmproxy.tools.console import common
-from mitmproxy.tools.console import signals
from mitmproxy import version
@@ -85,14 +84,8 @@ class HelpView(urwid.ListBox):
return text
def keypress(self, size, key):
- key = common.shortcuts(key)
- if key == "q":
- signals.pop_view_state.send(self)
- return None
- elif key == "?":
- key = None
- elif key == "g":
+ if key == "m_start":
self.set_focus(0)
- elif key == "G":
+ elif key == "m_end":
self.set_focus(len(self.body.contents))
return urwid.ListBox.keypress(self, size, key)
diff --git a/mitmproxy/tools/console/keymap.py b/mitmproxy/tools/console/keymap.py
index 3b22d530..62e2dcfb 100644
--- a/mitmproxy/tools/console/keymap.py
+++ b/mitmproxy/tools/console/keymap.py
@@ -4,6 +4,7 @@ from mitmproxy.tools.console import commandeditor
SupportedContexts = {
+ "chooser",
"commands",
"flowlist",
"flowview",
diff --git a/mitmproxy/tools/console/master.py b/mitmproxy/tools/console/master.py
index 115785d3..3f46c5e3 100644
--- a/mitmproxy/tools/console/master.py
+++ b/mitmproxy/tools/console/master.py
@@ -83,6 +83,62 @@ class ConsoleAddon:
self.master = master
self.started = False
+ @command.command("console.nav.start")
+ def nav_start(self) -> None:
+ """
+ Go to the start of a list or scrollable.
+ """
+ self.master.inject_key("m_start")
+
+ @command.command("console.nav.end")
+ def nav_end(self) -> None:
+ """
+ Go to the end of a list or scrollable.
+ """
+ self.master.inject_key("m_end")
+
+ @command.command("console.nav.up")
+ def nav_up(self) -> None:
+ """
+ Go up.
+ """
+ self.master.inject_key("up")
+
+ @command.command("console.nav.down")
+ def nav_down(self) -> None:
+ """
+ Go down.
+ """
+ self.master.inject_key("down")
+
+ @command.command("console.nav.pageup")
+ def nav_pageup(self) -> None:
+ """
+ Go up.
+ """
+ self.master.inject_key("page up")
+
+ @command.command("console.nav.pagedown")
+ def nav_pagedown(self) -> None:
+ """
+ Go down.
+ """
+ self.master.inject_key("page down")
+
+ @command.command("console.nav.left")
+ def nav_left(self) -> None:
+ """
+ Go left.
+ """
+ self.master.inject_key("left")
+
+ @command.command("console.nav.right")
+ def nav_right(self) -> None:
+ """
+ Go right.
+ """
+ self.master.inject_key("right")
+
@command.command("console.choose")
def console_choose(
self, prompt: str, choices: typing.Sequence[str], *cmd: typing.Sequence[str]
@@ -101,7 +157,7 @@ class ConsoleAddon:
except exceptions.CommandError as e:
signals.status_message.send(message=str(e))
- self.master.overlay(overlay.Chooser(prompt, choices, "", callback))
+ self.master.overlay(overlay.Chooser(self.master, prompt, choices, "", callback))
ctx.log.info(choices)
@command.command("console.choose.cmd")
@@ -124,7 +180,7 @@ class ConsoleAddon:
except exceptions.CommandError as e:
signals.status_message.send(message=str(e))
- self.master.overlay(overlay.Chooser(prompt, choices, "", callback))
+ self.master.overlay(overlay.Chooser(self.master, prompt, choices, "", callback))
ctx.log.info(choices)
@command.command("console.command")
@@ -246,7 +302,7 @@ class ConsoleAddon:
signals.status_message.send(message=str(e))
opts = [i.name.lower() for i in contentviews.views]
- self.master.overlay(overlay.Chooser("Mode", opts, "", callback))
+ self.master.overlay(overlay.Chooser(self.master, "Mode", opts, "", callback))
@command.command("console.flowview.mode")
def flowview_mode(self) -> str:
@@ -288,6 +344,17 @@ def default_keymap(km):
km.add("O", "console.view.options", ["global"])
km.add("Q", "console.exit", ["global"])
km.add("q", "console.view.pop", ["global"])
+
+ km.add("g", "console.nav.start", ["global"])
+ km.add("G", "console.nav.end", ["global"])
+ km.add("k", "console.nav.up", ["global"])
+ km.add("j", "console.nav.down", ["global"])
+ km.add("l", "console.nav.right", ["global"])
+ km.add("h", "console.nav.left", ["global"])
+ km.add(" ", "console.nav.pagedown", ["global"])
+ km.add("ctrl f", "console.nav.pagedown", ["global"])
+ km.add("ctrl b", "console.nav.pageup", ["global"])
+
km.add("i", "console.command set intercept=", ["global"])
km.add("W", "console.command set save_stream_file=", ["global"])
@@ -308,9 +375,7 @@ def default_keymap(km):
)
km.add("f", "console.command set view_filter=", ["flowlist"])
km.add("F", "set console_focus_follow=toggle", ["flowlist"])
- km.add("g", "view.go 0", ["flowlist"])
- km.add("G", "view.go -1", ["flowlist"])
- km.add("l", "console.command cut.clip ", ["flowlist", "flowview"])
+ km.add("ctrl l", "console.command cut.clip ", ["flowlist", "flowview"])
km.add("L", "console.command view.load ", ["flowlist"])
km.add("m", "flow.mark.toggle @focus", ["flowlist"])
km.add("M", "view.marked.toggle", ["flowlist"])
@@ -361,6 +426,7 @@ def default_keymap(km):
)
km.add("p", "view.focus.prev", ["flowview"])
km.add("m", "console.flowview.mode.set", ["flowview"])
+ km.add("tab", "console.nav.right", ["flowview"])
km.add(
"z",
"console.choose \"Part\" request,response "
@@ -523,6 +589,9 @@ class ConsoleMaster(master.Master):
self.loop.draw_screen()
self.loop.set_alarm_in(0.01, self.ticker)
+ def inject_key(self, key):
+ self.loop.process_input([key])
+
def run(self):
self.ui = urwid.raw_display.Screen()
self.ui.set_terminal_properties(256)
diff --git a/mitmproxy/tools/console/options.py b/mitmproxy/tools/console/options.py
index 68967f91..03b54f36 100644
--- a/mitmproxy/tools/console/options.py
+++ b/mitmproxy/tools/console/options.py
@@ -214,10 +214,10 @@ class OptionsList(urwid.ListBox):
foc.opt.name,
self.master.options.default(foc.opt.name)
)
- elif key == "g":
+ elif key == "m_start":
self.set_focus(0)
self.walker._modified()
- elif key == "G":
+ elif key == "m_end":
self.set_focus(len(self.walker.opts) - 1)
self.walker._modified()
elif key == "l":
@@ -299,7 +299,6 @@ class Options(urwid.Pile):
self.master = master
def keypress(self, size, key):
- key = common.shortcuts(key)
if key == "tab":
self.focus_position = (
self.focus_position + 1
diff --git a/mitmproxy/tools/console/overlay.py b/mitmproxy/tools/console/overlay.py
index 7e05fe81..2fa6aa46 100644
--- a/mitmproxy/tools/console/overlay.py
+++ b/mitmproxy/tools/console/overlay.py
@@ -80,7 +80,8 @@ class ChooserListWalker(urwid.ListWalker):
class Chooser(urwid.WidgetWrap):
- def __init__(self, title, choices, current, callback):
+ def __init__(self, master, title, choices, current, callback):
+ self.master = master
self.choices = choices
self.callback = callback
choicewidth = max([len(i) for i in choices])
@@ -103,7 +104,7 @@ class Chooser(urwid.WidgetWrap):
return True
def keypress(self, size, key):
- key = common.shortcuts(key)
+ key = self.master.keymap.handle("chooser", key)
if key == "enter":
self.callback(self.choices[self.walker.index])
signals.pop_view_state.send(self)
diff --git a/mitmproxy/tools/console/searchable.py b/mitmproxy/tools/console/searchable.py
index bb19135f..f2bb5612 100644
--- a/mitmproxy/tools/console/searchable.py
+++ b/mitmproxy/tools/console/searchable.py
@@ -35,10 +35,10 @@ class Searchable(urwid.ListBox):
self.find_next(False)
elif key == "N":
self.find_next(True)
- elif key == "g":
+ elif key == "m_start":
self.set_focus(0)
self.walker._modified()
- elif key == "G":
+ elif key == "m_end":
self.set_focus(len(self.walker) - 1)
self.walker._modified()
else:
diff --git a/mitmproxy/tools/console/select.py b/mitmproxy/tools/console/select.py
index a990dff8..f7e5d950 100644
--- a/mitmproxy/tools/console/select.py
+++ b/mitmproxy/tools/console/select.py
@@ -113,7 +113,6 @@ class Select(urwid.ListBox):
if key == "enter" or key == " ":
self.get_focus()[0].option.activate()
return None
- key = common.shortcuts(key)
if key in self.keymap:
self.keymap[key].activate()
self.set_focus(self.options.index(self.keymap[key]))
diff --git a/mitmproxy/tools/console/tabs.py b/mitmproxy/tools/console/tabs.py
index 4f5f270a..93d6909e 100644
--- a/mitmproxy/tools/console/tabs.py
+++ b/mitmproxy/tools/console/tabs.py
@@ -35,9 +35,9 @@ class Tabs(urwid.WidgetWrap):
def keypress(self, size, key):
n = len(self.tabs)
- if key in ["tab", "l"]:
+ if key == "right":
self.change_tab((self.tab_offset + 1) % n)
- elif key == "h":
+ elif key == "left":
self.change_tab((self.tab_offset - 1) % n)
return self._w.keypress(size, key)
diff --git a/mitmproxy/tools/console/window.py b/mitmproxy/tools/console/window.py
index ed29465e..63f189ec 100644
--- a/mitmproxy/tools/console/window.py
+++ b/mitmproxy/tools/console/window.py
@@ -76,6 +76,8 @@ class Window(urwid.Frame):
self.call(self.focus, "view_popping")
def push(self, wname):
+ if self.primary_stack and self.primary_stack[-1] == wname:
+ return
self.primary_stack.append(wname)
self.body = urwid.AttrWrap(
self.windows[wname], "background"
diff --git a/test/mitmproxy/addons/test_view.py b/test/mitmproxy/addons/test_view.py
index ef969d1d..6da13650 100644
--- a/test/mitmproxy/addons/test_view.py
+++ b/test/mitmproxy/addons/test_view.py
@@ -221,6 +221,7 @@ def test_resolve():
def test_movement():
v = view.View()
with taddons.context():
+ v.go(0)
v.add([
tflow.tflow(),
tflow.tflow(),