mirror of
https://github.com/kovidgoyal/kitty.git
synced 2024-09-21 11:39:57 +03:00
Simplify implementation of REP
Also make it align more with the standard by using the actual last drawn graphics character rather than the character before the cursor
This commit is contained in:
parent
8f58140419
commit
b3ed4c3f40
@ -192,7 +192,7 @@ handle_normal_mode_char(Screen *screen, uint32_t ch, PyObject DUMP_UNUSED *dump_
|
||||
break; // no-op
|
||||
default:
|
||||
REPORT_DRAW(ch);
|
||||
screen_draw(screen, ch);
|
||||
screen_draw(screen, ch, true);
|
||||
break;
|
||||
}
|
||||
#undef CALL_SCREEN_HANDLER
|
||||
|
@ -149,6 +149,7 @@ void
|
||||
screen_reset(Screen *self) {
|
||||
if (self->linebuf == self->alt_linebuf) screen_toggle_screen_buffer(self, true, true);
|
||||
if (self->overlay_line.is_active) deactivate_overlay_line(self);
|
||||
self->last_graphic_char = 0;
|
||||
self->main_savepoint.is_valid = false;
|
||||
self->alt_savepoint.is_valid = false;
|
||||
linebuf_clear(self->linebuf, BLANK_CHAR);
|
||||
@ -503,7 +504,7 @@ draw_combining_char(Screen *self, char_type ch) {
|
||||
}
|
||||
|
||||
void
|
||||
screen_draw(Screen *self, uint32_t och) {
|
||||
screen_draw(Screen *self, uint32_t och, bool from_input_stream) {
|
||||
if (is_ignored_char(och)) return;
|
||||
if (!self->has_activity_since_last_focus && !self->has_focus) {
|
||||
self->has_activity_since_last_focus = true;
|
||||
@ -523,6 +524,7 @@ screen_draw(Screen *self, uint32_t och) {
|
||||
if (char_width == 0) return;
|
||||
char_width = 1;
|
||||
}
|
||||
if (from_input_stream) self->last_graphic_char = ch;
|
||||
if (UNLIKELY(self->columns - self->cursor->x < (unsigned int)char_width)) {
|
||||
if (self->modes.mDECAWM) {
|
||||
screen_carriage_return(self);
|
||||
@ -568,7 +570,7 @@ screen_draw_overlay_text(Screen *self, const char *utf8_text) {
|
||||
switch(decode_utf8(&state, &codepoint, *(utf8_text++))) {
|
||||
case UTF8_ACCEPT:
|
||||
before = self->cursor->x;
|
||||
screen_draw(self, codepoint);
|
||||
screen_draw(self, codepoint, false);
|
||||
self->overlay_line.xnum += self->cursor->x - before;
|
||||
break;
|
||||
case UTF8_REJECT:
|
||||
@ -1328,22 +1330,10 @@ screen_insert_characters(Screen *self, unsigned int count) {
|
||||
|
||||
void
|
||||
screen_repeat_character(Screen *self, unsigned int count) {
|
||||
const unsigned int top = 0, bottom = self->lines ? self->lines - 1 : 0;
|
||||
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)) {
|
||||
if (self->last_graphic_char) {
|
||||
if (count == 0) count = 1;
|
||||
unsigned int num = MIN(count, CSI_REP_MAX_REPETITIONS);
|
||||
while (num-- > 0) screen_draw(self, ch);
|
||||
while (num-- > 0) screen_draw(self, self->last_graphic_char, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2142,7 +2132,7 @@ draw(Screen *self, PyObject *src) {
|
||||
int kind = PyUnicode_KIND(src);
|
||||
void *buf = PyUnicode_DATA(src);
|
||||
Py_ssize_t sz = PyUnicode_GET_LENGTH(src);
|
||||
for (Py_ssize_t i = 0; i < sz; i++) screen_draw(self, PyUnicode_READ(kind, buf, i));
|
||||
for (Py_ssize_t i = 0; i < sz; i++) screen_draw(self, PyUnicode_READ(kind, buf, i), true);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,7 @@ typedef struct {
|
||||
hyperlink_id_type active_hyperlink_id;
|
||||
HYPERLINK_POOL_HANDLE hyperlink_pool;
|
||||
ANSIBuf as_ansi_buf;
|
||||
char_type last_graphic_char;
|
||||
} Screen;
|
||||
|
||||
|
||||
@ -143,7 +144,7 @@ void screen_cursor_position(Screen*, unsigned int, unsigned int);
|
||||
void screen_cursor_back(Screen *self, unsigned int count/*=1*/, int move_direction/*=-1*/);
|
||||
void screen_erase_in_line(Screen *, unsigned int, bool);
|
||||
void screen_erase_in_display(Screen *, unsigned int, bool);
|
||||
void screen_draw(Screen *screen, uint32_t codepoint);
|
||||
void screen_draw(Screen *screen, uint32_t codepoint, bool);
|
||||
void screen_ensure_bounds(Screen *self, bool use_margins, bool cursor_was_within_margins);
|
||||
void screen_toggle_screen_buffer(Screen *self, bool, bool);
|
||||
void screen_normal_keypad_mode(Screen *self);
|
||||
|
@ -93,6 +93,17 @@ def test_draw_char(self):
|
||||
self.ae(str(s.line(4)), 'a\u0306b1\u030623')
|
||||
self.ae((s.cursor.x, s.cursor.y), (2, 4))
|
||||
|
||||
def test_rep(self):
|
||||
s = self.create_screen()
|
||||
s.draw('a')
|
||||
parse_bytes(s, b'\x1b[b')
|
||||
self.ae(str(s.line(0)), 'aa')
|
||||
parse_bytes(s, b'\x1b[3b')
|
||||
self.ae(str(s.line(0)), 'a'*5)
|
||||
s.draw(' ')
|
||||
parse_bytes(s, b'\x1b[3b')
|
||||
self.ae(str(s.line(1)), ' '*4)
|
||||
|
||||
def test_emoji_skin_tone_modifiers(self):
|
||||
s = self.create_screen()
|
||||
q = chr(0x1f469) + chr(0x1f3fd)
|
||||
|
Loading…
Reference in New Issue
Block a user