Repository: mitmproxy/mitmproxy

Issue:
Mitmproxy crashes, when trying to add something to options, which are supported by specific command
##### Steps to reproduce the problem:

1. Run mitmproxy.
2. Press `:`
3. Enter one of these commands: `view.order.options`, `console.edit.focus.options`, `console.flowview.mode.options`, `console.layout.options`, `console.bodyview.options`, `console.key.contexts`. Press `enter`.
You will see something like:
![image](https://user-images.githubusercontent.com/20267977/37864892-7f9be626-2f7d-11e8-9e10-5da3b65011dc.png)

4. Press `a` button twice.

The traceback appears:
```
Traceback (most recent call last):
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/master.py", line 227, in run
    self.loop.run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 286, in run
    self._run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 384, in _run
    self.event_loop.run()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 788, in run
    self._loop()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 825, in _loop
    self._watch_files[fd]()
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 404, in <lambda>
    event_loop, callback, self.get_available_raw_input())
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/raw_display.py", line 502, in parse_input
    callback(processed, processed_codes)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 411, in _update
    self.process_input(keys)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/main_loop.py", line 511, in process_input
    k = self._topmost_widget.keypress(self.screen_size, k)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/window.py", line 309, in keypress
    k = super().keypress(size, k)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1131, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/window.py", line 44, in keypress
    ret = super().keypress(size, key)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1131, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 595, in keypress
    *self.calculate_padding_filler(size, True)), key)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1590, in keypress
    key = self.focus.keypress(tsize, key)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 2271, in keypress
    key = w.keypress((mc,) + size[1:], key)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/decoration.py", line 386, in keypress
    return self._original_widget.keypress((maxcol, self.height), key)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/grideditor/base.py", line 342, in keypress
    self._w.keypress(size, key)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/container.py", line 1131, in keypress
    return self.body.keypress( (maxcol, remaining), key )
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/listbox.py", line 999, in keypress
    key = focus_widget.keypress((maxcol,),key)
  File "/home/kajoj/Mitmproxy/mitmproxy/mitmproxy/tools/console/grideditor/base.py", line 107, in keypress
    k = self.edit_col.keypress((w,), k)
  File "/home/kajoj/Mitmproxy/mitmproxy/venv/lib/python3.5/site-packages/urwid/widget.py", line 1772, in <lambda>
    keypress = property(lambda self:get_delegate(self).keypress)
AttributeError: 'Text' object has no attribute 'keypress'
```

##### System information

Mitmproxy: 4.0.0.dev154 (commit f34932c) 
Python:    3.5.2
OpenSSL:   OpenSSL 1.1.0g  2 Nov 2017
Platform:  Linux-4.4.0-116-generic-x86_64-with-Ubuntu-16.04-xenial




Discussion:
I am debugging this right now. Hope to provide some more insights in a while :)
Now, I actually have some more insights. The fact is, I believe the editor keybindings shouldn't be passed as commands when the focus is on a DataViewer widget, like in the case of the commands listed above. To make things clear, I'll post some screenshots of debugging (sorry for the unnecessary info on screen :P)

- state of `edit_col` and `editor` in comparison between "Edit cookies" and `console.key.contexts` editors:
 
`console.key.contexts`:
![image](https://user-images.githubusercontent.com/25264901/38165193-037a6d7c-3510-11e8-9f0a-d0f015d8e554.png)


Edit Cookies:
![image](https://user-images.githubusercontent.com/25264901/38165198-0fb040bc-3510-11e8-9124-0251cafdbd89.png)


Now, `edit_col` {Display} object calls `keypress()` on its topmost widget, which is {Text}...thus the bug.

This is not limited to adding.

Deleting rows with `d` or editing in external editors with `e` does not trigger any bug, but (as expected) changes are not persistent, to reflect the fact that editing those fields is not expected.

After delete with `d` and edit with `e`:
![image](https://user-images.githubusercontent.com/25264901/38165203-321f2b0e-3510-11e8-9b18-9d42b1d08cf4.png)

After view refresh (q and :console.key.contexts):
![image](https://user-images.githubusercontent.com/25264901/38165209-5f152ad2-3510-11e8-98c4-da180af6d85f.png)


Those keybindings should not be in that view scope. Is anyone working on it? 
@madt1m I think nobody works on it :) 
Take it, if you want.

Resolving patch:
diff --git a/mitmproxy/tools/console/keymap.py b/mitmproxy/tools/console/keymap.py
--- a/mitmproxy/tools/console/keymap.py
+++ b/mitmproxy/tools/console/keymap.py
@@ -6,6 +6,7 @@
 Contexts = {
     "chooser",
     "commands",
+    "dataviewer",
     "eventlog",
     "flowlist",
     "flowview",
diff --git a/mitmproxy/tools/console/overlay.py b/mitmproxy/tools/console/overlay.py
--- a/mitmproxy/tools/console/overlay.py
+++ b/mitmproxy/tools/console/overlay.py
@@ -179,7 +179,7 @@ def layout_popping(self):
 
 
 class DataViewerOverlay(urwid.WidgetWrap, layoutwidget.LayoutWidget):
-    keyctx = "grideditor"
+    keyctx = "dataviewer"
 
     def __init__(self, master, vals):
         """


Test patch: