mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-11-08 23:38:20 +03:00
Start work on connecting CSI callbacks
This commit is contained in:
parent
e50fc2067c
commit
d0c2821339
@ -313,6 +313,7 @@ void screen_reverse_index(Screen *self);
|
||||
void screen_index(Screen *self);
|
||||
void screen_reset(Screen *self);
|
||||
void screen_set_tab_stop(Screen *self);
|
||||
void screen_insert_characters(Screen *self, unsigned int count);
|
||||
#define DECLARE_CH_SCREEN_HANDLER(name) void screen_##name(Screen *screen, uint8_t ch);
|
||||
DECLARE_CH_SCREEN_HANDLER(bell)
|
||||
DECLARE_CH_SCREEN_HANDLER(backspace)
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "data-types.h"
|
||||
#include "control-codes.h"
|
||||
|
||||
@ -214,6 +215,26 @@ HANDLER(esc) {
|
||||
// }}}
|
||||
|
||||
// Parse CSI {{{
|
||||
|
||||
#define MAX_PARAMS 8
|
||||
|
||||
static inline unsigned int fill_params(Screen *screen, unsigned int *params, unsigned int expect) {
|
||||
unsigned int start_pos = 1, i = 1, pi = 0;
|
||||
uint8_t ch;
|
||||
screen->parser_buf[screen->parser_buf_pos++] = ';';
|
||||
|
||||
while (pi < MIN(MAX_PARAMS, expect) && i < PARSER_BUF_SZ - 1) {
|
||||
ch = screen->parser_buf[i++];
|
||||
if (ch == 0 || ch == ';') {
|
||||
if (start_pos < i - 1) {
|
||||
params[pi++] = atoi((const char *)screen->parser_buf + start_pos);
|
||||
}
|
||||
start_pos = i;
|
||||
}
|
||||
}
|
||||
return pi;
|
||||
}
|
||||
|
||||
HANDLER(csi) {
|
||||
#define CALL_BASIC_HANDLER(name) REPORT_COMMAND(screen, ch); name(screen, ch); break;
|
||||
#define HANDLE_BASIC_CH \
|
||||
@ -232,8 +253,17 @@ HANDLER(csi) {
|
||||
case NUL: \
|
||||
case DEL: \
|
||||
break; // no-op
|
||||
#define CALL_CSI_HANDLER1(name) \
|
||||
if (fill_params(screen, params, 1) != 1) { REPORT_ERROR("Expected parameter for CSI escape sequence: %s missing", #name); } \
|
||||
else { \
|
||||
REPORT_COMMAND(name, params[0]); \
|
||||
screen_insert_characters(screen, params[0]); \
|
||||
} \
|
||||
SET_STATE(NORMAL_STATE); \
|
||||
break;
|
||||
|
||||
uint8_t ch = buf[(*pos)++];
|
||||
unsigned int params[MAX_PARAMS];
|
||||
switch(screen->parser_buf_pos) {
|
||||
case 0: // CSI starting
|
||||
screen->parser_buf[0] = 0;
|
||||
@ -250,9 +280,9 @@ HANDLER(csi) {
|
||||
break;
|
||||
HANDLE_BASIC_CH
|
||||
default:
|
||||
REPORT_ERROR("%s%d", "Invalid first character for CSI: ", (int)ch);
|
||||
REPORT_ERROR("Invalid first character for CSI: 0x%x", ch);
|
||||
SET_STATE(NORMAL_STATE);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default: // CSI started
|
||||
@ -264,12 +294,21 @@ HANDLER(csi) {
|
||||
SET_STATE(NORMAL_STATE);
|
||||
} else screen->parser_buf[screen->parser_buf_pos++] = ch;
|
||||
break;
|
||||
HANDLE_BASIC_CH
|
||||
default:
|
||||
REPORT_ERROR("Invalid character for CSI: 0x%x", ch);
|
||||
SET_STATE(NORMAL_STATE);
|
||||
break;
|
||||
case ICH:
|
||||
CALL_CSI_HANDLER1(screen_insert_characters);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#undef CALL_BASIC_HANDLER
|
||||
#undef HANDLE_BASIC_CH
|
||||
#undef CALL_CSI_HANDLER1
|
||||
}
|
||||
#undef MAX_PARAMS
|
||||
// }}}
|
||||
|
||||
// Parse OSC {{{
|
||||
|
@ -55,3 +55,14 @@ class TestScreen(BaseTest):
|
||||
pb('\033x', 'Unknown char in escape_dispatch: %d' % ord('x'))
|
||||
pb('\033c123', 'screen_reset')
|
||||
self.ae(str(s.line(0)), '123 ')
|
||||
|
||||
def test_csi_codes(self):
|
||||
s = self.create_screen()
|
||||
pb = partial(self.parse_buytes_dump, s)
|
||||
pb('abcde')
|
||||
s.cursor_back(5)
|
||||
pb('x\033[2@y', ('screen_insert_characters', 2))
|
||||
self.ae(str(s.line(0)), 'xy bc')
|
||||
pb('x\033[2;3@y', ('screen_insert_characters', 2))
|
||||
pb('x\033[@y', 'Invalid first character for CSI: 0x%x' % ord('@'))
|
||||
s.reset()
|
||||
|
Loading…
Reference in New Issue
Block a user