Provide support for CSI REP control code
This commit is contained in:
parent
3d32202b3a
commit
9fe631ee3f
@ -188,6 +188,9 @@
|
||||
// *Horizontal position relative*: Same as :data:`CUF`.
|
||||
#define HPR 'a'
|
||||
|
||||
// Repeat the preceding graphic character Ps times.
|
||||
#define REP 'b'
|
||||
|
||||
// *Device Attributes*.
|
||||
#define DA 'c'
|
||||
|
||||
|
||||
@ -550,6 +550,11 @@ left_shift(Line *self, PyObject *args) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
line_get_char(Line *self, unsigned int at) {
|
||||
return self->cpu_cells[at].ch;
|
||||
}
|
||||
|
||||
void
|
||||
line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor, bool UNUSED is_second) {
|
||||
if (cursor == NULL) {
|
||||
|
||||
@ -57,6 +57,7 @@ line_reset_cells(Line *line, index_type start, index_type num, GPUCell *gpu_cell
|
||||
typedef Line*(get_line_func)(void *, int);
|
||||
void line_clear_text(Line *self, unsigned int at, unsigned int num, char_type ch);
|
||||
void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char);
|
||||
uint32_t line_get_char(Line *self, unsigned int at);
|
||||
void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *, bool);
|
||||
void line_right_shift(Line *, unsigned int , unsigned int );
|
||||
void line_add_combining_char(Line *, uint32_t , unsigned int );
|
||||
|
||||
@ -652,6 +652,8 @@ dispatch_csi(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
||||
case ICH:
|
||||
NO_MODIFIERS(end_modifier, ' ', "Shift left escape code not implemented");
|
||||
CALL_CSI_HANDLER1(screen_insert_characters, 1);
|
||||
case REP:
|
||||
CALL_CSI_HANDLER1(screen_repeat_character, 1);
|
||||
case CUU:
|
||||
NO_MODIFIERS(end_modifier, ' ', "Shift right escape code not implemented");
|
||||
CALL_CSI_HANDLER1(screen_cursor_up2, 1);
|
||||
|
||||
@ -1251,6 +1251,25 @@ screen_insert_characters(Screen *self, unsigned int count) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
screen_repeat_character(Screen *self, unsigned int count) {
|
||||
unsigned int top = self->margin_top, bottom = self->margin_bottom;
|
||||
unsigned int x = self->cursor->x;
|
||||
if (count == 0) count = 1;
|
||||
if (top <= self->cursor->y && self->cursor->y <= bottom && x > 0) {
|
||||
unsigned int num = MIN(count, self->columns - x);
|
||||
linebuf_init_line(self->linebuf, self->cursor->y);
|
||||
uint32_t ch = line_get_char(self->linebuf->line, x - 1);
|
||||
if (is_ignored_char(ch) || is_combining_char(ch)) {
|
||||
return;
|
||||
}
|
||||
while (num > 0) {
|
||||
screen_draw(self, ch);
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
screen_delete_characters(Screen *self, unsigned int count) {
|
||||
// Delete characters, later characters are moved left
|
||||
|
||||
@ -165,6 +165,7 @@ void screen_cursor_up1(Screen *self, unsigned int count/*=1*/);
|
||||
void screen_cursor_to_line(Screen *screen, unsigned int line);
|
||||
void screen_insert_lines(Screen *self, unsigned int count/*=1*/);
|
||||
void screen_delete_lines(Screen *self, unsigned int count/*=1*/);
|
||||
void screen_repeat_character(Screen *self, unsigned int count);
|
||||
void screen_delete_characters(Screen *self, unsigned int count);
|
||||
void screen_erase_characters(Screen *self, unsigned int count);
|
||||
void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
|
||||
|
||||
@ -177,6 +177,25 @@ class TestParser(BaseTest):
|
||||
pb('\033[3 A', ('Shift right escape code not implemented',))
|
||||
pb('\033[3;4 S', ('Select presentation directions escape code not implemented',))
|
||||
|
||||
def test_csi_code_rep(self):
|
||||
s = self.create_screen(8)
|
||||
pb = partial(self.parse_bytes_dump, s)
|
||||
pb('\033[1b', ('screen_repeat_character', 1))
|
||||
self.ae(str(s.line(0)), '')
|
||||
pb('x\033[7b', 'x', ('screen_repeat_character', 7))
|
||||
self.ae(str(s.line(0)), 'xxxxxxxx')
|
||||
pb('\033[1;3H', ('screen_cursor_position', 1, 3))
|
||||
pb('\033[byz\033[b', ('screen_repeat_character', 1), 'yz', ('screen_repeat_character', 1))
|
||||
# repeat 'x' at 3, then 'yz' at 4-5, then repeat 'z' at 6
|
||||
self.ae(str(s.line(0)), 'xxxyzzxx')
|
||||
s.reset()
|
||||
pb(' \033[3b', ' ', ('screen_repeat_character', 3))
|
||||
self.ae(str(s.line(0)), ' ')
|
||||
s.reset()
|
||||
pb('\t\033[b', ('screen_tab',), ('screen_repeat_character', 1))
|
||||
self.ae(str(s.line(0)), '\t')
|
||||
s.reset()
|
||||
|
||||
def test_osc_codes(self):
|
||||
s = self.create_screen()
|
||||
pb = partial(self.parse_bytes_dump, s)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user