Have the save/restore colors escape codes also save restore the ANSI color table
This commit is contained in:
parent
c3c5a5446f
commit
e97f1a4310
@ -180,23 +180,24 @@ rectangular region of the screen from (3, 4) to (10, 11), you use::
|
|||||||
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
|
<ESC>[2*x<ESC>[4;3;11;10;44$r<ESC>[*x
|
||||||
|
|
||||||
|
|
||||||
Saving and restoring the default foreground/background/selection/cursor colors
|
Saving and restoring colors
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
|
|
||||||
It is often useful for a full screen application with its own color themes
|
It is often useful for a full screen application with its own color themes to
|
||||||
to set the default foreground, background, selection and cursor colors. This
|
set the default foreground, background, selection and cursor colors and the
|
||||||
allows for various performance optimizations when drawing the screen. The
|
ANSI color table. This allows for various performance optimizations when
|
||||||
problem is that if the user previously used the escape codes to change these
|
drawing the screen. The problem is that if the user previously used the escape
|
||||||
colors herself, then running the full screen application will lose her
|
codes to change these colors herself, then running the full screen application
|
||||||
changes even after it exits. To avoid this, kitty introduces a new pair of
|
will lose her changes even after it exits. To avoid this, kitty introduces a
|
||||||
*OSC* escape codes to push and pop the current color values from a stack::
|
new pair of *OSC* escape codes to push and pop the current color values from a
|
||||||
|
stack::
|
||||||
|
|
||||||
<ESC>]30001<ESC>\ # push onto stack
|
<ESC>]30001<ESC>\ # push onto stack
|
||||||
<ESC>]30101<ESC>\ # pop from stack
|
<ESC>]30101<ESC>\ # pop from stack
|
||||||
|
|
||||||
These escape codes save/restore the so called *dynamic colors*, default
|
These escape codes save/restore the colors, default
|
||||||
background, default foreground, selection background, selection foreground and
|
background, default foreground, selection background, selection foreground and
|
||||||
cursor color.
|
cursor color and the 256 colors of the ANSI color table.
|
||||||
|
|
||||||
|
|
||||||
Pasting to clipboard
|
Pasting to clipboard
|
||||||
|
|||||||
@ -318,19 +318,56 @@ copy_color_table_to_buffer(ColorProfile *self, color_type *buf, int offset, size
|
|||||||
self->dirty = false;
|
self->dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
colorprofile_push_dynamic_colors(ColorProfile *self) {
|
push_onto_color_stack_at(ColorProfile *self, unsigned int i) {
|
||||||
if (self->dynamic_color_stack_idx >= arraysz(self->dynamic_color_stack)) {
|
self->color_stack[i].dynamic_colors = self->overridden;
|
||||||
memmove(self->dynamic_color_stack, self->dynamic_color_stack + 1, sizeof(self->dynamic_color_stack) - sizeof(self->dynamic_color_stack[0]));
|
self->color_stack[i].valid = true;
|
||||||
self->dynamic_color_stack_idx = arraysz(self->dynamic_color_stack) - 1;
|
memcpy(self->color_stack[i].color_table, self->color_table, sizeof(self->color_stack->color_table));
|
||||||
}
|
|
||||||
self->dynamic_color_stack[self->dynamic_color_stack_idx++] = self->overridden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
colorprofile_pop_dynamic_colors(ColorProfile *self) {
|
copy_from_color_stack_at(ColorProfile *self, unsigned int i) {
|
||||||
if (!self->dynamic_color_stack_idx) return;
|
self->overridden = self->color_stack[i].dynamic_colors;
|
||||||
self->overridden = self->dynamic_color_stack[--(self->dynamic_color_stack_idx)];
|
memcpy(self->color_table, self->color_stack[i].color_table, sizeof(self->color_table));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
colorprofile_push_colors(ColorProfile *self, unsigned int idx) {
|
||||||
|
if (idx == 0) {
|
||||||
|
for (unsigned i = 0; i < arraysz(self->color_stack); i++) {
|
||||||
|
if (!self->color_stack[i].valid) {
|
||||||
|
push_onto_color_stack_at(self, i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memmove(self->color_stack, self->color_stack + 1, sizeof(self->color_stack) - sizeof(self->color_stack[0]));
|
||||||
|
push_onto_color_stack_at(self, arraysz(self->color_stack) - 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (idx < arraysz(self->color_stack)) {
|
||||||
|
push_onto_color_stack_at(self, idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
colorprofile_pop_colors(ColorProfile *self, unsigned int idx) {
|
||||||
|
if (idx == 0) {
|
||||||
|
for (unsigned i = arraysz(self->color_stack) - 1; i-- > 0; ) {
|
||||||
|
if (self->color_stack[i].valid) {
|
||||||
|
copy_from_color_stack_at(self, i);
|
||||||
|
self->color_stack[i].valid = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (idx < arraysz(self->color_stack)) {
|
||||||
|
copy_from_color_stack_at(self, idx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
|
|||||||
@ -237,14 +237,20 @@ typedef struct {
|
|||||||
color_type default_fg, default_bg, cursor_color, cursor_text_color, cursor_text_uses_bg, highlight_fg, highlight_bg;
|
color_type default_fg, default_bg, cursor_color, cursor_text_color, cursor_text_uses_bg, highlight_fg, highlight_bg;
|
||||||
} DynamicColor;
|
} DynamicColor;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
DynamicColor dynamic_colors;
|
||||||
|
uint32_t color_table[256];
|
||||||
|
bool valid;
|
||||||
|
} ColorStackEntry;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
|
||||||
bool dirty;
|
bool dirty;
|
||||||
uint32_t color_table[256];
|
uint32_t color_table[256];
|
||||||
uint32_t orig_color_table[256];
|
uint32_t orig_color_table[256];
|
||||||
DynamicColor dynamic_color_stack[10];
|
ColorStackEntry color_stack[16];
|
||||||
size_t dynamic_color_stack_idx;
|
|
||||||
DynamicColor configured, overridden;
|
DynamicColor configured, overridden;
|
||||||
color_type mark_foregrounds[MARK_MASK+1], mark_backgrounds[MARK_MASK+1];
|
color_type mark_foregrounds[MARK_MASK+1], mark_backgrounds[MARK_MASK+1];
|
||||||
} ColorProfile;
|
} ColorProfile;
|
||||||
@ -304,8 +310,8 @@ bool set_iutf8(int, bool);
|
|||||||
color_type colorprofile_to_color(ColorProfile *self, color_type entry, color_type defval);
|
color_type colorprofile_to_color(ColorProfile *self, color_type entry, color_type defval);
|
||||||
float cursor_text_as_bg(ColorProfile *self);
|
float cursor_text_as_bg(ColorProfile *self);
|
||||||
void copy_color_table_to_buffer(ColorProfile *self, color_type *address, int offset, size_t stride);
|
void copy_color_table_to_buffer(ColorProfile *self, color_type *address, int offset, size_t stride);
|
||||||
void colorprofile_push_dynamic_colors(ColorProfile*);
|
bool colorprofile_push_colors(ColorProfile*, unsigned int);
|
||||||
void colorprofile_pop_dynamic_colors(ColorProfile*);
|
bool colorprofile_pop_colors(ColorProfile*, unsigned int);
|
||||||
|
|
||||||
void set_mouse_cursor(MouseShape);
|
void set_mouse_cursor(MouseShape);
|
||||||
void enter_event(void);
|
void enter_event(void);
|
||||||
|
|||||||
@ -414,11 +414,11 @@ dispatch_osc(Screen *screen, PyObject DUMP_UNUSED *dump_callback) {
|
|||||||
END_DISPATCH
|
END_DISPATCH
|
||||||
case 30001:
|
case 30001:
|
||||||
REPORT_COMMAND(screen_push_dynamic_colors);
|
REPORT_COMMAND(screen_push_dynamic_colors);
|
||||||
screen_push_dynamic_colors(screen);
|
screen_push_colors(screen, 0);
|
||||||
break;
|
break;
|
||||||
case 30101:
|
case 30101:
|
||||||
REPORT_COMMAND(screen_pop_dynamic_colors);
|
REPORT_COMMAND(screen_pop_dynamic_colors);
|
||||||
screen_pop_dynamic_colors(screen);
|
screen_pop_colors(screen, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
REPORT_ERROR("Unknown OSC code: %u", code);
|
REPORT_ERROR("Unknown OSC code: %u", code);
|
||||||
|
|||||||
@ -1594,13 +1594,13 @@ screen_handle_cmd(Screen *self, PyObject *cmd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_push_dynamic_colors(Screen *self) {
|
screen_push_colors(Screen *self, unsigned int idx) {
|
||||||
colorprofile_push_dynamic_colors(self->color_profile);
|
colorprofile_push_colors(self->color_profile, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
screen_pop_dynamic_colors(Screen *self) {
|
screen_pop_colors(Screen *self, unsigned int idx) {
|
||||||
colorprofile_pop_dynamic_colors(self->color_profile);
|
colorprofile_pop_colors(self->color_profile, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@ -179,8 +179,8 @@ 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);
|
||||||
void screen_change_charset(Screen *, uint32_t to);
|
void screen_change_charset(Screen *, uint32_t to);
|
||||||
void screen_handle_cmd(Screen *, PyObject *cmd);
|
void screen_handle_cmd(Screen *, PyObject *cmd);
|
||||||
void screen_push_dynamic_colors(Screen *);
|
void screen_push_colors(Screen *, unsigned int);
|
||||||
void screen_pop_dynamic_colors(Screen *);
|
void screen_pop_colors(Screen *, unsigned int);
|
||||||
void screen_handle_print(Screen *, PyObject *cmd);
|
void screen_handle_print(Screen *, PyObject *cmd);
|
||||||
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
|
void screen_designate_charset(Screen *, uint32_t which, uint32_t as);
|
||||||
void screen_use_latin1(Screen *, bool);
|
void screen_use_latin1(Screen *, bool);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user