Make debugging kittens a little nicer

Now debug() writes to the stderr of the parent kitty process instead of
a temp file.
This commit is contained in:
Kovid Goyal 2018-05-19 16:32:08 +05:30
parent 646a349d82
commit fb57653665
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
7 changed files with 40 additions and 12 deletions

View file

@ -46,8 +46,6 @@ def create_kitten_handler(kitten, orig_args):
def set_debug(kitten):
from kittens.tui.loop import debug
path = os.path.join('/tmp', 'kitten-' + kitten)
debug.fd = open(path, 'w')
import builtins
builtins.debug = debug

View file

@ -3,16 +3,17 @@
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
from kittens.tui.operations import commander
from .operations import commander
class Handler:
image_manager_class = None
def _initialize(self, screen_size, quit_loop, wakeup, start_job, image_manager=None):
def _initialize(self, screen_size, quit_loop, wakeup, start_job, debug, image_manager=None):
self.screen_size, self.quit_loop = screen_size, quit_loop
self.wakeup = wakeup
self.debug = debug
self.start_job = start_job
self.cmd = commander(self)
self.image_manager = image_manager
@ -20,10 +21,12 @@ def _initialize(self, screen_size, quit_loop, wakeup, start_job, image_manager=N
def __enter__(self):
if self.image_manager is not None:
self.image_manager.__enter__()
self.debug.fobj = self
self.initialize()
def __exit__(self, *a):
del self.write_buf[:]
del self.debug.fobj
self.finalize()
if self.image_manager is not None:
self.image_manager.__exit__(*a)

View file

@ -31,12 +31,16 @@
def debug(*a, **kw):
fd = getattr(debug, 'fd', None)
if fd is None:
fd = debug.fd = open('/tmp/kitten-debug', 'w')
kw['file'] = fd
from base64 import standard_b64encode
buf = io.StringIO()
kw['file'] = buf
print(*a, **kw)
fd.flush()
text = buf.getvalue()
text = b'\x1bP@kitty-print|' + standard_b64encode(text.encode('utf-8')) + b'\x1b\\'
fobj = getattr(debug, 'fobj', sys.stdout.buffer)
fobj.write(text)
if hasattr(fobj, 'flush'):
fobj.flush()
def write_all(fd, data):
@ -374,7 +378,7 @@ def loop(self, handler):
image_manager = handler.image_manager_class(handler)
keep_going = True
try:
handler._initialize(screen_size(), self.quit, self.wakeup, self.start_job, image_manager)
handler._initialize(screen_size(), self.quit, self.wakeup, self.start_job, debug, image_manager)
with handler:
while keep_going:
has_data_to_write = bool(handler.write_buf)
@ -403,7 +407,7 @@ def _report_error_loop(self, tb, term_manager):
handler = UnhandledException(tb)
handler.write_buf = []
handler._term_manager = term_manager
handler._initialize(screen_size(), self.quit, self.wakeup, self.start_job)
handler._initialize(screen_size(), self.quit, self.wakeup, self.start_job, debug)
with handler:
while True:
has_data_to_write = bool(handler.write_buf)

View file

@ -769,17 +769,28 @@ dispatch_dcs(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
}
break;
case '@':
if (startswith(screen->parser_buf + 1, screen->parser_buf_pos - 2, "kitty-cmd{")) {
#define CMD_PREFIX "kitty-cmd{"
if (startswith(screen->parser_buf + 1, screen->parser_buf_pos - 2, CMD_PREFIX)) {
PyObject *cmd = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, screen->parser_buf + 10, screen->parser_buf_pos - 10);
if (cmd != NULL) {
REPORT_OSC2(screen_handle_cmd, (char)screen->parser_buf[0], cmd);
screen_handle_cmd(screen, cmd);
Py_DECREF(cmd);
} else PyErr_Clear();
#undef CMD_PREFIX
#define PRINT_PREFIX "kitty-print|"
} else if (startswith(screen->parser_buf + 1, screen->parser_buf_pos - 1, PRINT_PREFIX)) {
PyObject *msg = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, screen->parser_buf + sizeof(PRINT_PREFIX), screen->parser_buf_pos - sizeof(PRINT_PREFIX));
if (msg != NULL) {
REPORT_OSC2(screen_handle_print, (char)screen->parser_buf[0], msg);
screen_handle_print(screen, msg);
Py_DECREF(msg);
} else PyErr_Clear();
} else {
REPORT_ERROR("Unrecognized DCS @ code: 0x%x", screen->parser_buf[1]);
}
break;
#undef PRINT_PREFIX
default:
REPORT_ERROR("Unrecognized DCS code: 0x%x", screen->parser_buf[0]);
break;

View file

@ -1219,6 +1219,11 @@ screen_handle_cmd(Screen *self, PyObject *cmd) {
CALLBACK("handle_remote_cmd", "O", cmd);
}
void
screen_handle_print(Screen *self, PyObject *msg) {
CALLBACK("handle_remote_print", "O", msg);
}
void
screen_request_capabilities(Screen *self, char c, PyObject *q) {
static char buf[128];

View file

@ -138,6 +138,7 @@ void screen_erase_characters(Screen *self, unsigned int count);
void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
void screen_change_charset(Screen *, uint32_t to);
void screen_handle_cmd(Screen *, PyObject *cmd);
void screen_handle_print(Screen *, PyObject *cmd);
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
void screen_use_latin1(Screen *, bool);
void set_title(Screen *self, PyObject*);

View file

@ -328,6 +328,12 @@ def request_capabilities(self, q):
def handle_remote_cmd(self, cmd):
get_boss().handle_remote_cmd(cmd, self)
def handle_remote_print(self, msg):
from base64 import standard_b64decode
msg = standard_b64decode(msg).decode('utf-8')
print(msg, end='', file=sys.stderr)
sys.stderr.flush()
def send_cmd_response(self, response):
self.screen.send_escape_code_to_child(DCS, '@kitty-cmd' + json.dumps(response))