Merge branch 'ft/csi-code-rep' of https://github.com/keynslug/kitty
This commit is contained in:
commit
9ba808ec3c
@ -30,6 +30,8 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
|||||||
|
|
||||||
- BSD: Fix controlling terminal not being established (:pull:`2686`)
|
- BSD: Fix controlling terminal not being established (:pull:`2686`)
|
||||||
|
|
||||||
|
- Add support for the CSI REP escape code (:pull:`2702`)
|
||||||
|
|
||||||
|
|
||||||
0.17.4 [2020-05-09]
|
0.17.4 [2020-05-09]
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@ -188,6 +188,9 @@
|
|||||||
// *Horizontal position relative*: Same as :data:`CUF`.
|
// *Horizontal position relative*: Same as :data:`CUF`.
|
||||||
#define HPR 'a'
|
#define HPR 'a'
|
||||||
|
|
||||||
|
// Repeat the preceding graphic character Ps times.
|
||||||
|
#define REP 'b'
|
||||||
|
|
||||||
// *Device Attributes*.
|
// *Device Attributes*.
|
||||||
#define DA 'c'
|
#define DA 'c'
|
||||||
|
|
||||||
|
|||||||
@ -550,6 +550,13 @@ left_shift(Line *self, PyObject *args) {
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char_type
|
||||||
|
line_get_char(Line *self, index_type at) {
|
||||||
|
char_type ch = self->cpu_cells[at].ch;
|
||||||
|
if (!ch && at > 0 && (self->gpu_cells[at-1].attrs & WIDTH_MASK) > 1) ch = self->cpu_cells[at-1].ch;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor, bool UNUSED is_second) {
|
line_set_char(Line *self, unsigned int at, uint32_t ch, unsigned int width, Cursor *cursor, bool UNUSED is_second) {
|
||||||
if (cursor == NULL) {
|
if (cursor == NULL) {
|
||||||
|
|||||||
@ -69,6 +69,7 @@ left_shift_line(Line *line, index_type at, index_type num) {
|
|||||||
typedef Line*(get_line_func)(void *, int);
|
typedef Line*(get_line_func)(void *, int);
|
||||||
void line_clear_text(Line *self, unsigned int at, unsigned int num, char_type ch);
|
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);
|
void line_apply_cursor(Line *self, Cursor *cursor, unsigned int at, unsigned int num, bool clear_char);
|
||||||
|
char_type line_get_char(Line *self, index_type at);
|
||||||
void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *, bool);
|
void line_set_char(Line *, unsigned int , uint32_t , unsigned int , Cursor *, bool);
|
||||||
void line_right_shift(Line *, unsigned int , unsigned int );
|
void line_right_shift(Line *, unsigned int , unsigned int );
|
||||||
void line_add_combining_char(Line *, uint32_t , 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:
|
case ICH:
|
||||||
NO_MODIFIERS(end_modifier, ' ', "Shift left escape code not implemented");
|
NO_MODIFIERS(end_modifier, ' ', "Shift left escape code not implemented");
|
||||||
CALL_CSI_HANDLER1(screen_insert_characters, 1);
|
CALL_CSI_HANDLER1(screen_insert_characters, 1);
|
||||||
|
case REP:
|
||||||
|
CALL_CSI_HANDLER1(screen_repeat_character, 1);
|
||||||
case CUU:
|
case CUU:
|
||||||
NO_MODIFIERS(end_modifier, ' ', "Shift right escape code not implemented");
|
NO_MODIFIERS(end_modifier, ' ', "Shift right escape code not implemented");
|
||||||
CALL_CSI_HANDLER1(screen_cursor_up2, 1);
|
CALL_CSI_HANDLER1(screen_cursor_up2, 1);
|
||||||
|
|||||||
@ -28,6 +28,8 @@
|
|||||||
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
static const ScreenModes empty_modes = {0, .mDECAWM=true, .mDECTCEM=true, .mDECARM=true};
|
||||||
static Selection EMPTY_SELECTION = {{0}};
|
static Selection EMPTY_SELECTION = {{0}};
|
||||||
|
|
||||||
|
#define CSI_REP_MAX_REPETITIONS 65535u
|
||||||
|
|
||||||
// Constructor/destructor {{{
|
// Constructor/destructor {{{
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -1251,6 +1253,27 @@ 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 (x > self->columns) return;
|
||||||
|
if (x > 0) {
|
||||||
|
linebuf_init_line(self->linebuf, self->cursor->y);
|
||||||
|
} else {
|
||||||
|
if (self->cursor->y > 0) {
|
||||||
|
linebuf_init_line(self->linebuf, self->cursor->y - 1);
|
||||||
|
x = self->columns;
|
||||||
|
} else return;
|
||||||
|
}
|
||||||
|
char_type ch = line_get_char(self->linebuf->line, x-1);
|
||||||
|
if (top <= self->cursor->y && self->cursor->y <= bottom && !is_ignored_char(ch)) {
|
||||||
|
unsigned int num = MIN(count, CSI_REP_MAX_REPETITIONS);
|
||||||
|
while (num-- > 0) screen_draw(self, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_delete_characters(Screen *self, unsigned int count) {
|
screen_delete_characters(Screen *self, unsigned int count) {
|
||||||
// Delete characters, later characters are moved left
|
// 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_cursor_to_line(Screen *screen, unsigned int line);
|
||||||
void screen_insert_lines(Screen *self, unsigned int count/*=1*/);
|
void screen_insert_lines(Screen *self, unsigned int count/*=1*/);
|
||||||
void screen_delete_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_delete_characters(Screen *self, unsigned int count);
|
||||||
void screen_erase_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);
|
void screen_set_margins(Screen *self, unsigned int top, unsigned int bottom);
|
||||||
|
|||||||
@ -181,6 +181,8 @@ string_capabilities = {
|
|||||||
'kind': r'\E[1;2B',
|
'kind': r'\E[1;2B',
|
||||||
# Restore cursor
|
# Restore cursor
|
||||||
'rc': r'\E8',
|
'rc': r'\E8',
|
||||||
|
# Repeat preceding character
|
||||||
|
'rep': r'%p1%c\E[%p2%{1}%-%db',
|
||||||
# Reverse video
|
# Reverse video
|
||||||
'rev': r'\E[7m',
|
'rev': r'\E[7m',
|
||||||
# Scroll backwards the specified number of lines (reverse index)
|
# Scroll backwards the specified number of lines (reverse index)
|
||||||
@ -347,6 +349,7 @@ termcap_aliases.update({
|
|||||||
'kR': 'kri',
|
'kR': 'kri',
|
||||||
'kF': 'kind',
|
'kF': 'kind',
|
||||||
'rc': 'rc',
|
'rc': 'rc',
|
||||||
|
'rp': 'rep',
|
||||||
'mr': 'rev',
|
'mr': 'rev',
|
||||||
'sr': 'ri',
|
'sr': 'ri',
|
||||||
'SR': 'rin',
|
'SR': 'rin',
|
||||||
|
|||||||
@ -177,6 +177,25 @@ class TestParser(BaseTest):
|
|||||||
pb('\033[3 A', ('Shift right escape code not implemented',))
|
pb('\033[3 A', ('Shift right escape code not implemented',))
|
||||||
pb('\033[3;4 S', ('Select presentation directions 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):
|
def test_osc_codes(self):
|
||||||
s = self.create_screen()
|
s = self.create_screen()
|
||||||
pb = partial(self.parse_bytes_dump, s)
|
pb = partial(self.parse_bytes_dump, s)
|
||||||
|
|||||||
@ -204,6 +204,7 @@ xterm-kitty|KovIdTTY,
|
|||||||
oc=\E]104\007,
|
oc=\E]104\007,
|
||||||
op=\E[39;49m,
|
op=\E[39;49m,
|
||||||
rc=\E8,
|
rc=\E8,
|
||||||
|
rep=%p1%c\E[%p2%{1}%-%db,
|
||||||
rev=\E[7m,
|
rev=\E[7m,
|
||||||
ri=\EM,
|
ri=\EM,
|
||||||
rin=\E[%p1%dT,
|
rin=\E[%p1%dT,
|
||||||
|
|||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user