mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-26 18:18:25 +00:00
Merge pull request #2715 from cortesi/fancycommander2
commander: palette entries, highlight errors
This commit is contained in:
commit
91b9ca8675
@ -172,7 +172,7 @@ class CommandManager(mitmproxy.types._CommandBase):
|
|||||||
if parts[i] in self.commands:
|
if parts[i] in self.commands:
|
||||||
params[:] = self.commands[parts[i]].paramtypes
|
params[:] = self.commands[parts[i]].paramtypes
|
||||||
else:
|
else:
|
||||||
typ = str
|
typ = mitmproxy.types.Unknown
|
||||||
|
|
||||||
to = mitmproxy.types.CommandTypes.get(typ, None)
|
to = mitmproxy.types.CommandTypes.get(typ, None)
|
||||||
valid = False
|
valid = False
|
||||||
|
@ -69,14 +69,29 @@ class CommandBuffer():
|
|||||||
self._cursor = x
|
self._cursor = x
|
||||||
|
|
||||||
def render(self):
|
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 = []
|
ret = []
|
||||||
for p in parts:
|
for p in parts:
|
||||||
if p.type == mitmproxy.types.Cmd and p.valid:
|
if p.valid:
|
||||||
ret.append(("title", p.value))
|
if p.type == mitmproxy.types.Cmd:
|
||||||
|
ret.append(("commander_command", p.value))
|
||||||
else:
|
else:
|
||||||
ret.append(("text", p.value))
|
ret.append(("text", p.value))
|
||||||
|
elif p.value:
|
||||||
|
ret.append(("commander_invalid", p.value))
|
||||||
|
else:
|
||||||
|
ret.append(("text", ""))
|
||||||
ret.append(("text", " "))
|
ret.append(("text", " "))
|
||||||
|
if remhelp:
|
||||||
|
ret.append(("text", " "))
|
||||||
|
for v in remhelp:
|
||||||
|
ret.append(("commander_hint", "%s " % v))
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def flatten(self, txt):
|
def flatten(self, txt):
|
||||||
|
@ -32,6 +32,9 @@ class Palette:
|
|||||||
|
|
||||||
# Grid Editor
|
# Grid Editor
|
||||||
'focusfield', 'focusfield_error', 'field_error', 'editfield',
|
'focusfield', 'focusfield_error', 'field_error', 'editfield',
|
||||||
|
|
||||||
|
# Commander
|
||||||
|
'commander_command', 'commander_invalid', 'commander_hint'
|
||||||
]
|
]
|
||||||
high = None # type: typing.Mapping[str, typing.Sequence[str]]
|
high = None # type: typing.Mapping[str, typing.Sequence[str]]
|
||||||
|
|
||||||
@ -117,6 +120,11 @@ class LowDark(Palette):
|
|||||||
focusfield_error = ('dark red', 'light gray'),
|
focusfield_error = ('dark red', 'light gray'),
|
||||||
field_error = ('dark red', 'default'),
|
field_error = ('dark red', 'default'),
|
||||||
editfield = ('white', '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'),
|
focusfield_error = ('dark red', 'light gray'),
|
||||||
field_error = ('dark red', 'black'),
|
field_error = ('dark red', 'black'),
|
||||||
editfield = ('black', 'default'),
|
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),
|
focusfield_error = (sol_red, sol_base2),
|
||||||
field_error = (sol_red, 'default'),
|
field_error = (sol_red, 'default'),
|
||||||
editfield = (sol_base01, '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),
|
focusfield_error = (sol_red, sol_base02),
|
||||||
field_error = (sol_red, 'default'),
|
field_error = (sol_red, 'default'),
|
||||||
editfield = (sol_base1, 'default'),
|
editfield = (sol_base1, 'default'),
|
||||||
|
|
||||||
|
commander_command = (sol_blue, 'default'),
|
||||||
|
commander_invalid = (sol_orange, 'default'),
|
||||||
|
commander_hint = (sol_base00, 'default'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ class Arg(str):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Unknown(str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class CutSpec(typing.Sequence[str]):
|
class CutSpec(typing.Sequence[str]):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -116,6 +120,20 @@ class _StrType(_BaseType):
|
|||||||
return isinstance(val, str)
|
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):
|
class _IntType(_BaseType):
|
||||||
typ = int
|
typ = int
|
||||||
display = "int"
|
display = "int"
|
||||||
|
@ -23,6 +23,10 @@ class TAddon:
|
|||||||
def cmd3(self, foo: int) -> int:
|
def cmd3(self, foo: int) -> int:
|
||||||
return foo
|
return foo
|
||||||
|
|
||||||
|
@command.command("cmd4")
|
||||||
|
def cmd4(self, a: int, b: str, c: mitmproxy.types.Path) -> str:
|
||||||
|
return "ok"
|
||||||
|
|
||||||
@command.command("subcommand")
|
@command.command("subcommand")
|
||||||
def subcommand(self, cmd: mitmproxy.types.Cmd, *args: mitmproxy.types.Arg) -> str:
|
def subcommand(self, cmd: mitmproxy.types.Cmd, *args: mitmproxy.types.Arg) -> str:
|
||||||
return "ok"
|
return "ok"
|
||||||
@ -46,6 +50,10 @@ class TAddon:
|
|||||||
def path(self, arg: mitmproxy.types.Path) -> None:
|
def path(self, arg: mitmproxy.types.Path) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@command.command("flow")
|
||||||
|
def flow(self, f: flow.Flow, s: str) -> None:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TestCommand:
|
class TestCommand:
|
||||||
def test_varargs(self):
|
def test_varargs(self):
|
||||||
@ -78,8 +86,12 @@ class TestCommand:
|
|||||||
[
|
[
|
||||||
"foo bar",
|
"foo bar",
|
||||||
[
|
[
|
||||||
command.ParseResult(value = "foo", type = mitmproxy.types.Cmd, valid = False),
|
command.ParseResult(
|
||||||
command.ParseResult(value = "bar", type = str, valid = True)
|
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:
|
with taddons.context() as tctx:
|
||||||
tctx.master.addons.add(TAddon())
|
tctx.master.addons.add(TAddon())
|
||||||
|
@ -43,6 +43,15 @@ def test_str():
|
|||||||
assert b.parse(tctx.master.commands, str, "foo") == "foo"
|
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():
|
def test_int():
|
||||||
with taddons.context() as tctx:
|
with taddons.context() as tctx:
|
||||||
b = mitmproxy.types._IntType()
|
b = mitmproxy.types._IntType()
|
||||||
|
Loading…
Reference in New Issue
Block a user