aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@corte.si>2017-12-20 10:32:38 +1300
committerGitHub <noreply@github.com>2017-12-20 10:32:38 +1300
commit91b9ca8675b876e38e98649484c16a412fa39eeb (patch)
tree39337e31da2cc291e2fc4265f0d860771a0a7de5
parent4f32b835f7d81250adc339a9f715bb3851e1f3da (diff)
parent79ca2c843718c56ff7428f50faf1e155f500e3b3 (diff)
downloadmitmproxy-91b9ca8675b876e38e98649484c16a412fa39eeb.tar.gz
mitmproxy-91b9ca8675b876e38e98649484c16a412fa39eeb.tar.bz2
mitmproxy-91b9ca8675b876e38e98649484c16a412fa39eeb.zip
Merge pull request #2715 from cortesi/fancycommander2
commander: palette entries, highlight errors
-rw-r--r--mitmproxy/command.py2
-rw-r--r--mitmproxy/tools/console/commander/commander.py23
-rw-r--r--mitmproxy/tools/console/palettes.py20
-rw-r--r--mitmproxy/types.py18
-rw-r--r--test/mitmproxy/test_command.py79
-rw-r--r--test/mitmproxy/test_types.py9
6 files changed, 144 insertions, 7 deletions
diff --git a/mitmproxy/command.py b/mitmproxy/command.py
index e01c767c..e1e56d3a 100644
--- a/mitmproxy/command.py
+++ b/mitmproxy/command.py
@@ -172,7 +172,7 @@ class CommandManager(mitmproxy.types._CommandBase):
if parts[i] in self.commands:
params[:] = self.commands[parts[i]].paramtypes
else:
- typ = str
+ typ = mitmproxy.types.Unknown
to = mitmproxy.types.CommandTypes.get(typ, None)
valid = False
diff --git a/mitmproxy/tools/console/commander/commander.py b/mitmproxy/tools/console/commander/commander.py
index 125bb76f..30e8b13b 100644
--- a/mitmproxy/tools/console/commander/commander.py
+++ b/mitmproxy/tools/console/commander/commander.py
@@ -69,14 +69,29 @@ class CommandBuffer():
self._cursor = x
def render(self):
- parts, _ = self.master.commands.parse_partial(self.text)
+ """
+ This function is somewhat tricky - in order to make the cursor
+ position valid, we have to make sure there is a
+ character-for-character offset match in the rendered output, up
+ to the cursor. Beyond that, we can add stuff.
+ """
+ parts, remhelp = self.master.commands.parse_partial(self.text)
ret = []
for p in parts:
- if p.type == mitmproxy.types.Cmd and p.valid:
- ret.append(("title", p.value))
+ if p.valid:
+ if p.type == mitmproxy.types.Cmd:
+ ret.append(("commander_command", p.value))
+ else:
+ ret.append(("text", p.value))
+ elif p.value:
+ ret.append(("commander_invalid", p.value))
else:
- ret.append(("text", p.value))
+ ret.append(("text", ""))
+ ret.append(("text", " "))
+ if remhelp:
ret.append(("text", " "))
+ for v in remhelp:
+ ret.append(("commander_hint", "%s " % v))
return ret
def flatten(self, txt):
diff --git a/mitmproxy/tools/console/palettes.py b/mitmproxy/tools/console/palettes.py
index 7fbdcfd8..465fd574 100644
--- a/mitmproxy/tools/console/palettes.py
+++ b/mitmproxy/tools/console/palettes.py
@@ -32,6 +32,9 @@ class Palette:
# Grid Editor
'focusfield', 'focusfield_error', 'field_error', 'editfield',
+
+ # Commander
+ 'commander_command', 'commander_invalid', 'commander_hint'
]
high = None # type: typing.Mapping[str, typing.Sequence[str]]
@@ -117,6 +120,11 @@ class LowDark(Palette):
focusfield_error = ('dark red', 'light gray'),
field_error = ('dark red', 'default'),
editfield = ('white', 'default'),
+
+
+ commander_command = ('white,bold', 'default'),
+ commander_invalid = ('light red', 'default'),
+ commander_hint = ('dark gray', 'default'),
)
@@ -183,6 +191,10 @@ class LowLight(Palette):
focusfield_error = ('dark red', 'light gray'),
field_error = ('dark red', 'black'),
editfield = ('black', 'default'),
+
+ commander_command = ('dark magenta', 'default'),
+ commander_invalid = ('light red', 'default'),
+ commander_hint = ('light gray', 'default'),
)
@@ -267,6 +279,10 @@ class SolarizedLight(LowLight):
focusfield_error = (sol_red, sol_base2),
field_error = (sol_red, 'default'),
editfield = (sol_base01, 'default'),
+
+ commander_command = (sol_cyan, 'default'),
+ commander_invalid = (sol_orange, 'default'),
+ commander_hint = (sol_base1, 'default'),
)
@@ -317,6 +333,10 @@ class SolarizedDark(LowDark):
focusfield_error = (sol_red, sol_base02),
field_error = (sol_red, 'default'),
editfield = (sol_base1, 'default'),
+
+ commander_command = (sol_blue, 'default'),
+ commander_invalid = (sol_orange, 'default'),
+ commander_hint = (sol_base00, 'default'),
)
diff --git a/mitmproxy/types.py b/mitmproxy/types.py
index bdbd3924..8ae8b309 100644
--- a/mitmproxy/types.py
+++ b/mitmproxy/types.py
@@ -18,6 +18,10 @@ class Arg(str):
pass
+class Unknown(str):
+ pass
+
+
class CutSpec(typing.Sequence[str]):
pass
@@ -116,6 +120,20 @@ class _StrType(_BaseType):
return isinstance(val, str)
+class _UnknownType(_BaseType):
+ typ = Unknown
+ display = "unknown"
+
+ def completion(self, manager: _CommandBase, t: type, s: str) -> typing.Sequence[str]:
+ return []
+
+ def parse(self, manager: _CommandBase, t: type, s: str) -> str:
+ return s
+
+ def is_valid(self, manager: _CommandBase, typ: typing.Any, val: typing.Any) -> bool:
+ return False
+
+
class _IntType(_BaseType):
typ = int
display = "int"
diff --git a/test/mitmproxy/test_command.py b/test/mitmproxy/test_command.py
index 25df2e61..c777192d 100644
--- a/test/mitmproxy/test_command.py
+++ b/test/mitmproxy/test_command.py
@@ -23,6 +23,10 @@ class TAddon:
def cmd3(self, foo: int) -> int:
return foo
+ @command.command("cmd4")
+ def cmd4(self, a: int, b: str, c: mitmproxy.types.Path) -> str:
+ return "ok"
+
@command.command("subcommand")
def subcommand(self, cmd: mitmproxy.types.Cmd, *args: mitmproxy.types.Arg) -> str:
return "ok"
@@ -46,6 +50,10 @@ class TAddon:
def path(self, arg: mitmproxy.types.Path) -> None:
pass
+ @command.command("flow")
+ def flow(self, f: flow.Flow, s: str) -> None:
+ pass
+
class TestCommand:
def test_varargs(self):
@@ -78,8 +86,12 @@ class TestCommand:
[
"foo bar",
[
- command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = False),
- command.ParseResult(value = "bar", type = str, valid = True)
+ command.ParseResult(
+ value = "foo", type = mitmproxy.types.Cmd, valid = False
+ ),
+ command.ParseResult(
+ value = "bar", type = mitmproxy.types.Unknown, valid = False
+ )
],
[],
],
@@ -136,6 +148,69 @@ class TestCommand:
],
[]
],
+ [
+ "cmd4",
+ [
+ command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
+ ],
+ ["int", "str", "path"]
+ ],
+ [
+ "cmd4 ",
+ [
+ command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "", type = int, valid = False),
+ ],
+ ["str", "path"]
+ ],
+ [
+ "cmd4 1",
+ [
+ command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "1", type = int, valid = True),
+ ],
+ ["str", "path"]
+ ],
+ [
+ "cmd4 1",
+ [
+ command.ParseResult(value = "cmd4", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "1", type = int, valid = True),
+ ],
+ ["str", "path"]
+ ],
+ [
+ "flow",
+ [
+ command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
+ ],
+ ["flow", "str"]
+ ],
+ [
+ "flow ",
+ [
+ command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "", type = flow.Flow, valid = False),
+ ],
+ ["str"]
+ ],
+ [
+ "flow x",
+ [
+ command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "x", type = flow.Flow, valid = False),
+ ],
+ ["str"]
+ ],
+ [
+ "flow x ",
+ [
+ command.ParseResult(value = "flow", type = mitmproxy.types.Cmd, valid = True),
+ command.ParseResult(value = "x", type = flow.Flow, valid = False),
+ command.ParseResult(value = "", type = str, valid = True),
+ ],
+ []
+ ],
]
with taddons.context() as tctx:
tctx.master.addons.add(TAddon())
diff --git a/test/mitmproxy/test_types.py b/test/mitmproxy/test_types.py
index 29e86203..72492fa9 100644
--- a/test/mitmproxy/test_types.py
+++ b/test/mitmproxy/test_types.py
@@ -43,6 +43,15 @@ def test_str():
assert b.parse(tctx.master.commands, str, "foo") == "foo"
+def test_unknown():
+ with taddons.context() as tctx:
+ b = mitmproxy.types._UnknownType()
+ assert b.is_valid(tctx.master.commands, mitmproxy.types.Unknown, "foo") is False
+ assert b.is_valid(tctx.master.commands, mitmproxy.types.Unknown, 1) is False
+ assert b.completion(tctx.master.commands, mitmproxy.types.Unknown, "") == []
+ assert b.parse(tctx.master.commands, mitmproxy.types.Unknown, "foo") == "foo"
+
+
def test_int():
with taddons.context() as tctx:
b = mitmproxy.types._IntType()