mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-23 08:11:00 +00:00
console: grideditor keybindings for r, R and e
This commit is contained in:
parent
f804495fd8
commit
d7cc7e62a2
@ -1,15 +1,11 @@
|
|||||||
import abc
|
import abc
|
||||||
import copy
|
import copy
|
||||||
from typing import Any
|
import os
|
||||||
from typing import Callable
|
import typing
|
||||||
from typing import Container
|
|
||||||
from typing import Iterable
|
|
||||||
from typing import Optional
|
|
||||||
from typing import Sequence
|
|
||||||
from typing import Tuple
|
|
||||||
from typing import Set # noqa
|
|
||||||
|
|
||||||
import urwid
|
import urwid
|
||||||
|
|
||||||
|
from mitmproxy.utils import strutils
|
||||||
|
from mitmproxy import exceptions
|
||||||
from mitmproxy.tools.console import common
|
from mitmproxy.tools.console import common
|
||||||
from mitmproxy.tools.console import signals
|
from mitmproxy.tools.console import signals
|
||||||
from mitmproxy.tools.console import layoutwidget
|
from mitmproxy.tools.console import layoutwidget
|
||||||
@ -24,6 +20,21 @@ FOOTER_EDITING = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def read_file(filename: str, escaped: bool) -> typing.AnyStr:
|
||||||
|
filename = os.path.expanduser(filename)
|
||||||
|
try:
|
||||||
|
with open(filename, "r" if escaped else "rb") as f:
|
||||||
|
d = f.read()
|
||||||
|
except IOError as v:
|
||||||
|
raise exceptions.CommandError(v)
|
||||||
|
if escaped:
|
||||||
|
try:
|
||||||
|
d = strutils.escaped_str_to_bytes(d)
|
||||||
|
except ValueError:
|
||||||
|
raise exceptions.CommandError("Invalid Python-style string encoding.")
|
||||||
|
return d
|
||||||
|
|
||||||
|
|
||||||
class Cell(urwid.WidgetWrap):
|
class Cell(urwid.WidgetWrap):
|
||||||
def get_data(self):
|
def get_data(self):
|
||||||
"""
|
"""
|
||||||
@ -51,10 +62,10 @@ class Column(metaclass=abc.ABCMeta):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def blank(self) -> Any:
|
def blank(self) -> typing.Any:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def keypress(self, key: str, editor: "GridEditor") -> Optional[str]:
|
def keypress(self, key: str, editor: "GridEditor") -> typing.Optional[str]:
|
||||||
return key
|
return key
|
||||||
|
|
||||||
|
|
||||||
@ -62,10 +73,10 @@ class GridRow(urwid.WidgetWrap):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
focused: Optional[int],
|
focused: typing.Optional[int],
|
||||||
editing: bool,
|
editing: bool,
|
||||||
editor: "GridEditor",
|
editor: "GridEditor",
|
||||||
values: Tuple[Iterable[bytes], Container[int]]
|
values: typing.Tuple[typing.Iterable[bytes], typing.Container[int]]
|
||||||
) -> None:
|
) -> None:
|
||||||
self.focused = focused
|
self.focused = focused
|
||||||
self.editor = editor
|
self.editor = editor
|
||||||
@ -118,7 +129,7 @@ class GridWalker(urwid.ListWalker):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
lst: Iterable[list],
|
lst: typing.Iterable[list],
|
||||||
editor: "GridEditor"
|
editor: "GridEditor"
|
||||||
) -> None:
|
) -> None:
|
||||||
self.lst = [(i, set()) for i in lst] # type: Sequence[Tuple[Any, Set]]
|
self.lst = [(i, set()) for i in lst] # type: Sequence[Tuple[Any, Set]]
|
||||||
@ -262,8 +273,8 @@ class BaseGridEditor(urwid.WidgetWrap):
|
|||||||
master: "mitmproxy.tools.console.master.ConsoleMaster",
|
master: "mitmproxy.tools.console.master.ConsoleMaster",
|
||||||
title,
|
title,
|
||||||
columns,
|
columns,
|
||||||
value: Any,
|
value: typing.Any,
|
||||||
callback: Callable[..., None],
|
callback: typing.Callable[..., None],
|
||||||
*cb_args,
|
*cb_args,
|
||||||
**cb_kwargs
|
**cb_kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -352,20 +363,20 @@ class BaseGridEditor(urwid.WidgetWrap):
|
|||||||
elif column.keypress(key, self) and not self.handle_key(key):
|
elif column.keypress(key, self) and not self.handle_key(key):
|
||||||
return self._w.keypress(size, key)
|
return self._w.keypress(size, key)
|
||||||
|
|
||||||
def data_out(self, data: Sequence[list]) -> Any:
|
def data_out(self, data: typing.Sequence[list]) -> typing.Any:
|
||||||
"""
|
"""
|
||||||
Called on raw list data, before data is returned through the
|
Called on raw list data, before data is returned through the
|
||||||
callback.
|
callback.
|
||||||
"""
|
"""
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def data_in(self, data: Any) -> Iterable[list]:
|
def data_in(self, data: typing.Any) -> typing.Iterable[list]:
|
||||||
"""
|
"""
|
||||||
Called to prepare provided data.
|
Called to prepare provided data.
|
||||||
"""
|
"""
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def is_error(self, col: int, val: Any) -> Optional[str]:
|
def is_error(self, col: int, val: typing.Any) -> typing.Optional[str]:
|
||||||
"""
|
"""
|
||||||
Return None, or a string error message.
|
Return None, or a string error message.
|
||||||
"""
|
"""
|
||||||
@ -415,6 +426,19 @@ class BaseGridEditor(urwid.WidgetWrap):
|
|||||||
def cmd_delete(self):
|
def cmd_delete(self):
|
||||||
self.walker.delete_focus()
|
self.walker.delete_focus()
|
||||||
|
|
||||||
|
def cmd_read_file(self, path):
|
||||||
|
self.walker.set_current_value(read_file(path, False))
|
||||||
|
|
||||||
|
def cmd_read_file_escaped(self, path):
|
||||||
|
self.walker.set_current_value(read_file(path, True))
|
||||||
|
|
||||||
|
def cmd_spawn_editor(self):
|
||||||
|
o = self.walker.get_current_value()
|
||||||
|
if o is not None:
|
||||||
|
n = self.master.spawn_editor(o)
|
||||||
|
n = strutils.clean_hanging_newline(n)
|
||||||
|
self.walker.set_current_value(n)
|
||||||
|
|
||||||
|
|
||||||
class GridEditor(BaseGridEditor):
|
class GridEditor(BaseGridEditor):
|
||||||
title = None # type: str
|
title = None # type: str
|
||||||
@ -424,8 +448,8 @@ class GridEditor(BaseGridEditor):
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
master: "mitmproxy.tools.console.master.ConsoleMaster",
|
master: "mitmproxy.tools.console.master.ConsoleMaster",
|
||||||
value: Any,
|
value: typing.Any,
|
||||||
callback: Callable[..., None],
|
callback: typing.Callable[..., None],
|
||||||
*cb_args,
|
*cb_args,
|
||||||
**cb_kwargs
|
**cb_kwargs
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -480,7 +504,7 @@ class FocusEditor(urwid.WidgetWrap, layoutwidget.LayoutWidget):
|
|||||||
def focus_changed(self):
|
def focus_changed(self):
|
||||||
if self.master.view.focus.flow:
|
if self.master.view.focus.flow:
|
||||||
self._w = BaseGridEditor(
|
self._w = BaseGridEditor(
|
||||||
self.master.view.focus.flow,
|
self.master,
|
||||||
self.title,
|
self.title,
|
||||||
self.columns,
|
self.columns,
|
||||||
self.get_data(self.master.view.focus.flow),
|
self.get_data(self.master.view.focus.flow),
|
||||||
|
@ -1,34 +1,9 @@
|
|||||||
import os
|
|
||||||
from typing import Callable, Optional
|
|
||||||
|
|
||||||
import urwid
|
import urwid
|
||||||
from mitmproxy.tools.console import signals
|
from mitmproxy.tools.console import signals
|
||||||
from mitmproxy.tools.console.grideditor import base
|
from mitmproxy.tools.console.grideditor import base
|
||||||
from mitmproxy.utils import strutils
|
from mitmproxy.utils import strutils
|
||||||
|
|
||||||
|
|
||||||
def read_file(filename: str, callback: Callable[..., None], escaped: bool) -> Optional[str]:
|
|
||||||
if not filename:
|
|
||||||
return None
|
|
||||||
|
|
||||||
filename = os.path.expanduser(filename)
|
|
||||||
try:
|
|
||||||
with open(filename, "r" if escaped else "rb") as f:
|
|
||||||
d = f.read()
|
|
||||||
except IOError as v:
|
|
||||||
return str(v)
|
|
||||||
|
|
||||||
if escaped:
|
|
||||||
try:
|
|
||||||
d = strutils.escaped_str_to_bytes(d)
|
|
||||||
except ValueError:
|
|
||||||
return "Invalid Python-style string encoding."
|
|
||||||
# TODO: Refactor the status_prompt_path signal so that we
|
|
||||||
# can raise exceptions here and return the content instead.
|
|
||||||
callback(d)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class Column(base.Column):
|
class Column(base.Column):
|
||||||
def Display(self, data):
|
def Display(self, data):
|
||||||
return Display(data)
|
return Display(data)
|
||||||
@ -40,29 +15,7 @@ class Column(base.Column):
|
|||||||
return b""
|
return b""
|
||||||
|
|
||||||
def keypress(self, key, editor):
|
def keypress(self, key, editor):
|
||||||
if key == "r":
|
if key in ["enter"]:
|
||||||
if editor.walker.get_current_value() is not None:
|
|
||||||
signals.status_prompt_path.send(
|
|
||||||
self,
|
|
||||||
prompt="Read file",
|
|
||||||
callback=read_file,
|
|
||||||
args=(editor.walker.set_current_value, True)
|
|
||||||
)
|
|
||||||
elif key == "R":
|
|
||||||
if editor.walker.get_current_value() is not None:
|
|
||||||
signals.status_prompt_path.send(
|
|
||||||
self,
|
|
||||||
prompt="Read unescaped file",
|
|
||||||
callback=read_file,
|
|
||||||
args=(editor.walker.set_current_value, False)
|
|
||||||
)
|
|
||||||
elif key == "e":
|
|
||||||
o = editor.walker.get_current_value()
|
|
||||||
if o is not None:
|
|
||||||
n = editor.master.spawn_editor(o)
|
|
||||||
n = strutils.clean_hanging_newline(n)
|
|
||||||
editor.walker.set_current_value(n)
|
|
||||||
elif key in ["enter"]:
|
|
||||||
editor.walker.start_edit()
|
editor.walker.start_edit()
|
||||||
else:
|
else:
|
||||||
return key
|
return key
|
||||||
|
@ -356,6 +356,28 @@ class ConsoleAddon:
|
|||||||
"""
|
"""
|
||||||
self._grideditor().cmd_delete()
|
self._grideditor().cmd_delete()
|
||||||
|
|
||||||
|
@command.command("console.grideditor.readfile")
|
||||||
|
def grideditor_readfile(self, path: str) -> None:
|
||||||
|
"""
|
||||||
|
Read a file into the currrent cell.
|
||||||
|
"""
|
||||||
|
self._grideditor().cmd_read_file(path)
|
||||||
|
|
||||||
|
@command.command("console.grideditor.readfile_escaped")
|
||||||
|
def grideditor_readfile_escaped(self, path: str) -> None:
|
||||||
|
"""
|
||||||
|
Read a file containing a Python-style escaped stringinto the
|
||||||
|
currrent cell.
|
||||||
|
"""
|
||||||
|
self._grideditor().cmd_read_file_escaped(path)
|
||||||
|
|
||||||
|
@command.command("console.grideditor.editor")
|
||||||
|
def grideditor_editor(self) -> None:
|
||||||
|
"""
|
||||||
|
Spawn an external editor on the current cell.
|
||||||
|
"""
|
||||||
|
self._grideditor().cmd_spawn_editor()
|
||||||
|
|
||||||
@command.command("console.flowview.mode.set")
|
@command.command("console.flowview.mode.set")
|
||||||
def flowview_mode_set(self) -> None:
|
def flowview_mode_set(self) -> None:
|
||||||
"""
|
"""
|
||||||
@ -514,6 +536,9 @@ def default_keymap(km):
|
|||||||
km.add("A", "console.grideditor.insert", ["grideditor"])
|
km.add("A", "console.grideditor.insert", ["grideditor"])
|
||||||
km.add("tab", "console.grideditor.next", ["grideditor"])
|
km.add("tab", "console.grideditor.next", ["grideditor"])
|
||||||
km.add("d", "console.grideditor.delete", ["grideditor"])
|
km.add("d", "console.grideditor.delete", ["grideditor"])
|
||||||
|
km.add("r", "console.command console.grideditor.readfile", ["grideditor"])
|
||||||
|
km.add("R", "console.command console.grideditor.readfile_escaped", ["grideditor"])
|
||||||
|
km.add("e", "console.grideditor.editor", ["grideditor"])
|
||||||
|
|
||||||
|
|
||||||
class ConsoleMaster(master.Master):
|
class ConsoleMaster(master.Master):
|
||||||
|
Loading…
Reference in New Issue
Block a user