Implement control code to change colors
This commit is contained in:
parent
3031d41e72
commit
abd09464f0
@ -20,7 +20,7 @@ import glfw_constants
|
||||
from .constants import appname
|
||||
from .char_grid import CharGrid
|
||||
from .keys import interpret_text_event, interpret_key_event, get_shortcut
|
||||
from .utils import sanitize_title
|
||||
from .utils import sanitize_title, parse_color_set
|
||||
from .fast_data_types import (
|
||||
BRACKETED_PASTE_START, BRACKETED_PASTE_END, Screen, read_bytes_dump, read_bytes
|
||||
)
|
||||
@ -274,8 +274,27 @@ class Boss(Thread):
|
||||
code += 1
|
||||
self.queue_action(self.apply_change_colors)
|
||||
|
||||
def refresh(self):
|
||||
self.screen.mark_as_dirty()
|
||||
self.wakeup()
|
||||
|
||||
def set_color_table_color(self, code, value):
|
||||
print(11111111, code, value)
|
||||
if code == 4:
|
||||
for c, val in parse_color_set(value):
|
||||
self.char_grid.color_profile.set_color(c, val)
|
||||
self.refresh()
|
||||
elif code == 104:
|
||||
if not value.strip():
|
||||
self.char_grid.color_profile.reset_color_table()
|
||||
else:
|
||||
for c in value.split(';'):
|
||||
try:
|
||||
c = int(c)
|
||||
except Exception:
|
||||
continue
|
||||
if 0 <= c <= 255:
|
||||
self.char_grid.color_profile.reset_color(c)
|
||||
self.refresh()
|
||||
|
||||
def apply_change_colors(self):
|
||||
self.char_grid.change_colors(self.pending_color_changes)
|
||||
|
||||
@ -7,10 +7,10 @@ from ctypes import c_uint, addressof, memmove, sizeof
|
||||
from queue import Queue, Empty
|
||||
from threading import Lock
|
||||
|
||||
from .config import build_ansi_color_table, to_color
|
||||
from .config import build_ansi_color_table
|
||||
from .fonts import set_font_family
|
||||
from .shaders import Sprites, ShaderProgram
|
||||
from .utils import get_logical_dpi
|
||||
from .utils import get_logical_dpi, to_color
|
||||
from .fast_data_types import (
|
||||
glBlendFunc, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, glClear,
|
||||
GL_COLOR_BUFFER_BIT, glClearColor, glViewport, glUniform2ui, glUniform4f,
|
||||
|
||||
@ -106,6 +106,32 @@ as_color(ColorProfile *self, PyObject *val) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
reset_color_table(ColorProfile *self) {
|
||||
#define reset_color_table_doc "Reset all customized colors back to defaults"
|
||||
memcpy(self->color_table, self->orig_color_table, sizeof(FG_BG_256));
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
reset_color(ColorProfile *self, PyObject *val) {
|
||||
#define reset_color_doc "Reset the specified color"
|
||||
uint8_t i = PyLong_AsUnsignedLong(val) & 0xff;
|
||||
self->color_table[i] = self->orig_color_table[i];
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
set_color(ColorProfile *self, PyObject *args) {
|
||||
#define set_color_doc "Set the specified color"
|
||||
unsigned char i;
|
||||
unsigned long val;
|
||||
if (!PyArg_ParseTuple(args, "Bk", &i, &val)) return NULL;
|
||||
self->color_table[i] = val;
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
to_color(ColorProfile *self, uint32_t entry, uint32_t defval) {
|
||||
unsigned int t = entry & 0xFF, r;
|
||||
@ -125,7 +151,10 @@ to_color(ColorProfile *self, uint32_t entry, uint32_t defval) {
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
METHOD(update_ansi_color_table, METH_O)
|
||||
METHOD(reset_color_table, METH_NOARGS)
|
||||
METHOD(as_color, METH_O)
|
||||
METHOD(reset_color, METH_O)
|
||||
METHOD(set_color, METH_VARARGS)
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
171
kitty/config.py
171
kitty/config.py
@ -9,178 +9,9 @@ from collections import namedtuple
|
||||
import glfw_constants as glfw
|
||||
|
||||
from .fast_data_types import CURSOR_BLOCK, CURSOR_BEAM, CURSOR_UNDERLINE
|
||||
from .utils import to_color
|
||||
|
||||
key_pat = re.compile(r'([a-zA-Z][a-zA-Z0-9_-]*)\s+(.+)$')
|
||||
# Color definitions {{{
|
||||
color_pat = re.compile(r'^#([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$')
|
||||
color_names = {
|
||||
'aliceblue': 'f0f8ff',
|
||||
'antiquewhite': 'faebd7',
|
||||
'aqua': '00ffff',
|
||||
'aquamarine': '7fffd4',
|
||||
'azure': 'f0ffff',
|
||||
'beige': 'f5f5dc',
|
||||
'bisque': 'ffe4c4',
|
||||
'black': '000000',
|
||||
'blanchedalmond': 'ffebcd',
|
||||
'blue': '0000ff',
|
||||
'blueviolet': '8a2be2',
|
||||
'brown': 'a52a2a',
|
||||
'burlywood': 'deb887',
|
||||
'cadetblue': '5f9ea0',
|
||||
'chartreuse': '7fff00',
|
||||
'chocolate': 'd2691e',
|
||||
'coral': 'ff7f50',
|
||||
'cornflowerblue': '6495ed',
|
||||
'cornsilk': 'fff8dc',
|
||||
'crimson': 'dc143c',
|
||||
'cyan': '00ffff',
|
||||
'darkblue': '00008b',
|
||||
'darkcyan': '008b8b',
|
||||
'darkgoldenrod': 'b8860b',
|
||||
'darkgray': 'a9a9a9',
|
||||
'darkgrey': 'a9a9a9',
|
||||
'darkgreen': '006400',
|
||||
'darkkhaki': 'bdb76b',
|
||||
'darkmagenta': '8b008b',
|
||||
'darkolivegreen': '556b2f',
|
||||
'darkorange': 'ff8c00',
|
||||
'darkorchid': '9932cc',
|
||||
'darkred': '8b0000',
|
||||
'darksalmon': 'e9967a',
|
||||
'darkseagreen': '8fbc8f',
|
||||
'darkslateblue': '483d8b',
|
||||
'darkslategray': '2f4f4f',
|
||||
'darkslategrey': '2f4f4f',
|
||||
'darkturquoise': '00ced1',
|
||||
'darkviolet': '9400d3',
|
||||
'deeppink': 'ff1493',
|
||||
'deepskyblue': '00bfff',
|
||||
'dimgray': '696969',
|
||||
'dimgrey': '696969',
|
||||
'dodgerblue': '1e90ff',
|
||||
'firebrick': 'b22222',
|
||||
'floralwhite': 'fffaf0',
|
||||
'forestgreen': '228b22',
|
||||
'fuchsia': 'ff00ff',
|
||||
'gainsboro': 'dcdcdc',
|
||||
'ghostwhite': 'f8f8ff',
|
||||
'gold': 'ffd700',
|
||||
'goldenrod': 'daa520',
|
||||
'gray': '808080',
|
||||
'grey': '808080',
|
||||
'green': '008000',
|
||||
'greenyellow': 'adff2f',
|
||||
'honeydew': 'f0fff0',
|
||||
'hotpink': 'ff69b4',
|
||||
'indianred': 'cd5c5c',
|
||||
'indigo': '4b0082',
|
||||
'ivory': 'fffff0',
|
||||
'khaki': 'f0e68c',
|
||||
'lavender': 'e6e6fa',
|
||||
'lavenderblush': 'fff0f5',
|
||||
'lawngreen': '7cfc00',
|
||||
'lemonchiffon': 'fffacd',
|
||||
'lightblue': 'add8e6',
|
||||
'lightcoral': 'f08080',
|
||||
'lightcyan': 'e0ffff',
|
||||
'lightgoldenrodyellow': 'fafad2',
|
||||
'lightgray': 'd3d3d3',
|
||||
'lightgrey': 'd3d3d3',
|
||||
'lightgreen': '90ee90',
|
||||
'lightpink': 'ffb6c1',
|
||||
'lightsalmon': 'ffa07a',
|
||||
'lightseagreen': '20b2aa',
|
||||
'lightskyblue': '87cefa',
|
||||
'lightslategray': '778899',
|
||||
'lightslategrey': '778899',
|
||||
'lightsteelblue': 'b0c4de',
|
||||
'lightyellow': 'ffffe0',
|
||||
'lime': '00ff00',
|
||||
'limegreen': '32cd32',
|
||||
'linen': 'faf0e6',
|
||||
'magenta': 'ff00ff',
|
||||
'maroon': '800000',
|
||||
'mediumaquamarine': '66cdaa',
|
||||
'mediumblue': '0000cd',
|
||||
'mediumorchid': 'ba55d3',
|
||||
'mediumpurple': '9370db',
|
||||
'mediumseagreen': '3cb371',
|
||||
'mediumslateblue': '7b68ee',
|
||||
'mediumspringgreen': '00fa9a',
|
||||
'mediumturquoise': '48d1cc',
|
||||
'mediumvioletred': 'c71585',
|
||||
'midnightblue': '191970',
|
||||
'mintcream': 'f5fffa',
|
||||
'mistyrose': 'ffe4e1',
|
||||
'moccasin': 'ffe4b5',
|
||||
'navajowhite': 'ffdead',
|
||||
'navy': '000080',
|
||||
'oldlace': 'fdf5e6',
|
||||
'olive': '808000',
|
||||
'olivedrab': '6b8e23',
|
||||
'orange': 'ffa500',
|
||||
'orangered': 'ff4500',
|
||||
'orchid': 'da70d6',
|
||||
'palegoldenrod': 'eee8aa',
|
||||
'palegreen': '98fb98',
|
||||
'paleturquoise': 'afeeee',
|
||||
'palevioletred': 'db7093',
|
||||
'papayawhip': 'ffefd5',
|
||||
'peachpuff': 'ffdab9',
|
||||
'per': 'cd853f',
|
||||
'pink': 'ffc0cb',
|
||||
'plum': 'dda0dd',
|
||||
'powderblue': 'b0e0e6',
|
||||
'purple': '800080',
|
||||
'red': 'ff0000',
|
||||
'rosybrown': 'bc8f8f',
|
||||
'royalblue': '4169e1',
|
||||
'saddlebrown': '8b4513',
|
||||
'salmon': 'fa8072',
|
||||
'sandybrown': 'f4a460',
|
||||
'seagreen': '2e8b57',
|
||||
'seashell': 'fff5ee',
|
||||
'sienna': 'a0522d',
|
||||
'silver': 'c0c0c0',
|
||||
'skyblue': '87ceeb',
|
||||
'slateblue': '6a5acd',
|
||||
'slategray': '708090',
|
||||
'slategrey': '708090',
|
||||
'snow': 'fffafa',
|
||||
'springgreen': '00ff7f',
|
||||
'steelblue': '4682b4',
|
||||
'tan': 'd2b48c',
|
||||
'teal': '008080',
|
||||
'thistle': 'd8bfd8',
|
||||
'tomato': 'ff6347',
|
||||
'turquoise': '40e0d0',
|
||||
'violet': 'ee82ee',
|
||||
'wheat': 'f5deb3',
|
||||
'white': 'ffffff',
|
||||
'whitesmoke': 'f5f5f5',
|
||||
'yellow': 'ffff00',
|
||||
'yellowgreen': '9acd32',
|
||||
}
|
||||
Color = namedtuple('Color', 'red green blue')
|
||||
# }}}
|
||||
|
||||
|
||||
def to_color(raw, validate=False):
|
||||
x = raw.strip().lower()
|
||||
m = color_pat.match(x)
|
||||
val = None
|
||||
if m is not None:
|
||||
val = m.group(1)
|
||||
if len(val) == 3:
|
||||
val = ''.join(2 * s for s in val)
|
||||
else:
|
||||
val = color_names.get(x)
|
||||
if val is None:
|
||||
if validate:
|
||||
raise ValueError('Invalid color name: {}'.format(raw))
|
||||
return
|
||||
return Color(int(val[:2], 16), int(val[2:4], 16), int(val[4:], 16))
|
||||
|
||||
|
||||
def to_font_size(x):
|
||||
|
||||
@ -53,8 +53,9 @@ void screen_reset(Screen *self) {
|
||||
cursor_reset(self->cursor);
|
||||
tracker_cursor_changed(self->change_tracker);
|
||||
screen_cursor_position(self, 1, 1);
|
||||
screen_change_default_color(self, FG, 0);
|
||||
screen_change_default_color(self, BG, 0);
|
||||
set_dynamic_color(self, 110, NULL);
|
||||
set_dynamic_color(self, 111, NULL);
|
||||
set_color_table_color(self, 104, NULL);
|
||||
tracker_update_screen(self->change_tracker);
|
||||
}
|
||||
static inline HistoryBuf* realloc_hb(HistoryBuf *old, unsigned int lines, unsigned int columns) {
|
||||
@ -173,15 +174,6 @@ screen_draw(Screen *self, uint32_t ch) {
|
||||
|
||||
// Graphics {{{
|
||||
|
||||
void screen_change_default_color(Screen *self, unsigned int which, uint32_t col) {
|
||||
if (self->callbacks == Py_None) return;
|
||||
if (col & 0xFF) PyObject_CallMethod(self->callbacks, "change_default_color", "s(III)", which == FG ? "fg" : "bg",
|
||||
(col >> 24) & 0xFF, (col >> 16) & 0xFF, (col >> 8) & 0xFF);
|
||||
else PyObject_CallMethod(self->callbacks, "change_default_color", "sO", which == FG ? "fg" : "bg", Py_None);
|
||||
if (PyErr_Occurred()) PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
void screen_alignment_display(Screen *self) {
|
||||
// http://www.vt100.net/docs/vt510-rm/DECALN.html
|
||||
screen_cursor_position(self, 1, 1);
|
||||
@ -810,12 +802,14 @@ void set_icon(Screen *self, PyObject *icon) {
|
||||
}
|
||||
|
||||
void set_dynamic_color(Screen *self, unsigned int code, PyObject *color) {
|
||||
PyObject_CallMethod(self->callbacks, "set_dynamic_color", "IO", code, color);
|
||||
if (color == NULL) PyObject_CallMethod(self->callbacks, "set_dynamic_color", "Is", code, "");
|
||||
else PyObject_CallMethod(self->callbacks, "set_dynamic_color", "IO", code, color);
|
||||
if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
|
||||
}
|
||||
|
||||
void set_color_table_color(Screen *self, unsigned int code, PyObject *color) {
|
||||
PyObject_CallMethod(self->callbacks, "set_color_table_color", "IO", code, color);
|
||||
if (color == NULL) PyObject_CallMethod(self->callbacks, "set_color_table_color", "Is", code, "");
|
||||
else PyObject_CallMethod(self->callbacks, "set_color_table_color", "IO", code, color);
|
||||
if (PyErr_Occurred()) { PyErr_Print(); PyErr_Clear(); }
|
||||
}
|
||||
|
||||
@ -1008,6 +1002,11 @@ static PyObject* is_dirty(Screen *self) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
static PyObject* mark_as_dirty(Screen *self) {
|
||||
tracker_update_screen(self->change_tracker);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject* current_char_width(Screen *self) {
|
||||
#define current_char_width_doc "The width of the character under the cursor"
|
||||
unsigned long ans = 1;
|
||||
@ -1063,6 +1062,7 @@ static PyMethodDef methods[] = {
|
||||
MND(index, METH_NOARGS)
|
||||
MND(reverse_index, METH_NOARGS)
|
||||
MND(is_dirty, METH_NOARGS)
|
||||
MND(mark_as_dirty, METH_NOARGS)
|
||||
MND(resize, METH_VARARGS)
|
||||
MND(set_scroll_cell_data, METH_VARARGS)
|
||||
{"update_cell_data", (PyCFunction)screen_update_cell_data, METH_VARARGS, ""},
|
||||
|
||||
193
kitty/utils.py
193
kitty/utils.py
@ -5,6 +5,7 @@
|
||||
import re
|
||||
import subprocess
|
||||
import ctypes
|
||||
from collections import namedtuple
|
||||
from contextlib import contextmanager
|
||||
from functools import lru_cache
|
||||
from time import monotonic
|
||||
@ -56,3 +57,195 @@ def get_dpi():
|
||||
dpiy = vmode.height / (height / 25.4)
|
||||
get_dpi.ans = {'physical': (dpix, dpiy), 'logical': get_logical_dpi()}
|
||||
return get_dpi.ans
|
||||
|
||||
# Color names {{{
|
||||
|
||||
|
||||
color_pat = re.compile(r'^#([a-fA-F0-9]{3}|[a-fA-F0-9]{6})$')
|
||||
color_pat2 = re.compile(r'rgb:([a-f0-9]{2})/([a-f0-9]{2})/([a-f0-9]{2})$', re.IGNORECASE)
|
||||
|
||||
color_names = {
|
||||
'aliceblue': 'f0f8ff',
|
||||
'antiquewhite': 'faebd7',
|
||||
'aqua': '00ffff',
|
||||
'aquamarine': '7fffd4',
|
||||
'azure': 'f0ffff',
|
||||
'beige': 'f5f5dc',
|
||||
'bisque': 'ffe4c4',
|
||||
'black': '000000',
|
||||
'blanchedalmond': 'ffebcd',
|
||||
'blue': '0000ff',
|
||||
'blueviolet': '8a2be2',
|
||||
'brown': 'a52a2a',
|
||||
'burlywood': 'deb887',
|
||||
'cadetblue': '5f9ea0',
|
||||
'chartreuse': '7fff00',
|
||||
'chocolate': 'd2691e',
|
||||
'coral': 'ff7f50',
|
||||
'cornflowerblue': '6495ed',
|
||||
'cornsilk': 'fff8dc',
|
||||
'crimson': 'dc143c',
|
||||
'cyan': '00ffff',
|
||||
'darkblue': '00008b',
|
||||
'darkcyan': '008b8b',
|
||||
'darkgoldenrod': 'b8860b',
|
||||
'darkgray': 'a9a9a9',
|
||||
'darkgrey': 'a9a9a9',
|
||||
'darkgreen': '006400',
|
||||
'darkkhaki': 'bdb76b',
|
||||
'darkmagenta': '8b008b',
|
||||
'darkolivegreen': '556b2f',
|
||||
'darkorange': 'ff8c00',
|
||||
'darkorchid': '9932cc',
|
||||
'darkred': '8b0000',
|
||||
'darksalmon': 'e9967a',
|
||||
'darkseagreen': '8fbc8f',
|
||||
'darkslateblue': '483d8b',
|
||||
'darkslategray': '2f4f4f',
|
||||
'darkslategrey': '2f4f4f',
|
||||
'darkturquoise': '00ced1',
|
||||
'darkviolet': '9400d3',
|
||||
'deeppink': 'ff1493',
|
||||
'deepskyblue': '00bfff',
|
||||
'dimgray': '696969',
|
||||
'dimgrey': '696969',
|
||||
'dodgerblue': '1e90ff',
|
||||
'firebrick': 'b22222',
|
||||
'floralwhite': 'fffaf0',
|
||||
'forestgreen': '228b22',
|
||||
'fuchsia': 'ff00ff',
|
||||
'gainsboro': 'dcdcdc',
|
||||
'ghostwhite': 'f8f8ff',
|
||||
'gold': 'ffd700',
|
||||
'goldenrod': 'daa520',
|
||||
'gray': '808080',
|
||||
'grey': '808080',
|
||||
'green': '008000',
|
||||
'greenyellow': 'adff2f',
|
||||
'honeydew': 'f0fff0',
|
||||
'hotpink': 'ff69b4',
|
||||
'indianred': 'cd5c5c',
|
||||
'indigo': '4b0082',
|
||||
'ivory': 'fffff0',
|
||||
'khaki': 'f0e68c',
|
||||
'lavender': 'e6e6fa',
|
||||
'lavenderblush': 'fff0f5',
|
||||
'lawngreen': '7cfc00',
|
||||
'lemonchiffon': 'fffacd',
|
||||
'lightblue': 'add8e6',
|
||||
'lightcoral': 'f08080',
|
||||
'lightcyan': 'e0ffff',
|
||||
'lightgoldenrodyellow': 'fafad2',
|
||||
'lightgray': 'd3d3d3',
|
||||
'lightgrey': 'd3d3d3',
|
||||
'lightgreen': '90ee90',
|
||||
'lightpink': 'ffb6c1',
|
||||
'lightsalmon': 'ffa07a',
|
||||
'lightseagreen': '20b2aa',
|
||||
'lightskyblue': '87cefa',
|
||||
'lightslategray': '778899',
|
||||
'lightslategrey': '778899',
|
||||
'lightsteelblue': 'b0c4de',
|
||||
'lightyellow': 'ffffe0',
|
||||
'lime': '00ff00',
|
||||
'limegreen': '32cd32',
|
||||
'linen': 'faf0e6',
|
||||
'magenta': 'ff00ff',
|
||||
'maroon': '800000',
|
||||
'mediumaquamarine': '66cdaa',
|
||||
'mediumblue': '0000cd',
|
||||
'mediumorchid': 'ba55d3',
|
||||
'mediumpurple': '9370db',
|
||||
'mediumseagreen': '3cb371',
|
||||
'mediumslateblue': '7b68ee',
|
||||
'mediumspringgreen': '00fa9a',
|
||||
'mediumturquoise': '48d1cc',
|
||||
'mediumvioletred': 'c71585',
|
||||
'midnightblue': '191970',
|
||||
'mintcream': 'f5fffa',
|
||||
'mistyrose': 'ffe4e1',
|
||||
'moccasin': 'ffe4b5',
|
||||
'navajowhite': 'ffdead',
|
||||
'navy': '000080',
|
||||
'oldlace': 'fdf5e6',
|
||||
'olive': '808000',
|
||||
'olivedrab': '6b8e23',
|
||||
'orange': 'ffa500',
|
||||
'orangered': 'ff4500',
|
||||
'orchid': 'da70d6',
|
||||
'palegoldenrod': 'eee8aa',
|
||||
'palegreen': '98fb98',
|
||||
'paleturquoise': 'afeeee',
|
||||
'palevioletred': 'db7093',
|
||||
'papayawhip': 'ffefd5',
|
||||
'peachpuff': 'ffdab9',
|
||||
'per': 'cd853f',
|
||||
'pink': 'ffc0cb',
|
||||
'plum': 'dda0dd',
|
||||
'powderblue': 'b0e0e6',
|
||||
'purple': '800080',
|
||||
'red': 'ff0000',
|
||||
'rosybrown': 'bc8f8f',
|
||||
'royalblue': '4169e1',
|
||||
'saddlebrown': '8b4513',
|
||||
'salmon': 'fa8072',
|
||||
'sandybrown': 'f4a460',
|
||||
'seagreen': '2e8b57',
|
||||
'seashell': 'fff5ee',
|
||||
'sienna': 'a0522d',
|
||||
'silver': 'c0c0c0',
|
||||
'skyblue': '87ceeb',
|
||||
'slateblue': '6a5acd',
|
||||
'slategray': '708090',
|
||||
'slategrey': '708090',
|
||||
'snow': 'fffafa',
|
||||
'springgreen': '00ff7f',
|
||||
'steelblue': '4682b4',
|
||||
'tan': 'd2b48c',
|
||||
'teal': '008080',
|
||||
'thistle': 'd8bfd8',
|
||||
'tomato': 'ff6347',
|
||||
'turquoise': '40e0d0',
|
||||
'violet': 'ee82ee',
|
||||
'wheat': 'f5deb3',
|
||||
'white': 'ffffff',
|
||||
'whitesmoke': 'f5f5f5',
|
||||
'yellow': 'ffff00',
|
||||
'yellowgreen': '9acd32',
|
||||
}
|
||||
Color = namedtuple('Color', 'red green blue')
|
||||
# }}}
|
||||
|
||||
|
||||
def to_color(raw, validate=False):
|
||||
x = raw.strip().lower()
|
||||
m = color_pat.match(x)
|
||||
val = None
|
||||
if m is not None:
|
||||
val = m.group(1)
|
||||
if len(val) == 3:
|
||||
val = ''.join(2 * s for s in val)
|
||||
else:
|
||||
m = color_pat2.match(x)
|
||||
if m is not None:
|
||||
val = m.group(1) + m.group(2) + m.group(3)
|
||||
else:
|
||||
val = color_names.get(x)
|
||||
if val is None:
|
||||
if validate:
|
||||
raise ValueError('Invalid color name: {}'.format(raw))
|
||||
return
|
||||
return Color(int(val[:2], 16), int(val[2:4], 16), int(val[4:], 16))
|
||||
|
||||
|
||||
def parse_color_set(raw):
|
||||
parts = raw.split(';')
|
||||
for c, spec in [parts[i:i + 2] for i in range(0, len(parts), 2)]:
|
||||
try:
|
||||
c = int(c)
|
||||
if c < 0 or c > 255:
|
||||
raise IndexError('Out of bounds')
|
||||
r, g, b = to_color(spec)
|
||||
yield c, r << 16 | g << 8 | b
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
@ -7,6 +7,34 @@ from unittest import TestCase
|
||||
from kitty.fast_data_types import LineBuf, Cursor, Screen, HistoryBuf
|
||||
|
||||
|
||||
class Callbacks:
|
||||
|
||||
def __init__(self):
|
||||
self.clear()
|
||||
|
||||
def write_to_child(self, data):
|
||||
self.wtcbuf += data
|
||||
|
||||
def title_changed(self, data):
|
||||
self.titlebuf += data
|
||||
|
||||
def icon_changed(self, data):
|
||||
self.iconbuf += data
|
||||
|
||||
def set_dynamic_color(self, code, data):
|
||||
self.colorbuf += data or ''
|
||||
|
||||
def set_color_table_color(self, code, data):
|
||||
self.ctbuf += ''
|
||||
|
||||
def request_capabilities(self, q):
|
||||
self.qbuf += q
|
||||
|
||||
def clear(self):
|
||||
self.wtcbuf = b''
|
||||
self.iconbuf = self.titlebuf = self.colorbuf = self.qbuf = self.ctbuf = ''
|
||||
|
||||
|
||||
def filled_line_buf(ynum=5, xnum=5, cursor=Cursor()):
|
||||
ans = LineBuf(ynum, xnum)
|
||||
cursor.x = 0
|
||||
@ -38,7 +66,7 @@ class BaseTest(TestCase):
|
||||
ae = TestCase.assertEqual
|
||||
|
||||
def create_screen(self, cols=5, lines=5, scrollback=5):
|
||||
return Screen(None, lines, cols, scrollback)
|
||||
return Screen(Callbacks(), lines, cols, scrollback)
|
||||
|
||||
def assertEqualAttributes(self, c1, c2):
|
||||
x1, y1, c1.x, c1.y = c1.x, c1.y, 0, 0
|
||||
|
||||
@ -15,31 +15,6 @@ class CmdDump(list):
|
||||
self.append(a)
|
||||
|
||||
|
||||
class Callbacks:
|
||||
|
||||
def __init__(self):
|
||||
self.clear()
|
||||
|
||||
def write_to_child(self, data):
|
||||
self.wtcbuf += data
|
||||
|
||||
def title_changed(self, data):
|
||||
self.titlebuf += data
|
||||
|
||||
def icon_changed(self, data):
|
||||
self.iconbuf += data
|
||||
|
||||
def set_dynamic_color(self, code, data):
|
||||
self.colorbuf += data
|
||||
|
||||
def request_capabilities(self, q):
|
||||
self.qbuf += q
|
||||
|
||||
def clear(self):
|
||||
self.wtcbuf = b''
|
||||
self.iconbuf = self.titlebuf = self.colorbuf = self.qbuf = ''
|
||||
|
||||
|
||||
class TestParser(BaseTest):
|
||||
|
||||
def parse_bytes_dump(self, s, x, *cmds):
|
||||
@ -131,8 +106,7 @@ class TestParser(BaseTest):
|
||||
pb('\033[38;2;1;2;3;48;2;7;8;9m', ('select_graphic_rendition', 10))
|
||||
self.ae(s.cursor.fg, 1 << 24 | 2 << 16 | 3 << 8 | 2)
|
||||
self.ae(s.cursor.bg, 7 << 24 | 8 << 16 | 9 << 8 | 2)
|
||||
c = Callbacks()
|
||||
s.callbacks = c
|
||||
c = s.callbacks
|
||||
pb('\033[5n', ('report_device_status', 5, 0))
|
||||
self.ae(c.wtcbuf, b'\033[0n')
|
||||
c.clear()
|
||||
@ -153,8 +127,7 @@ class TestParser(BaseTest):
|
||||
def test_osc_codes(self):
|
||||
s = self.create_screen()
|
||||
pb = partial(self.parse_bytes_dump, s)
|
||||
c = Callbacks()
|
||||
s.callbacks = c
|
||||
c = s.callbacks
|
||||
pb('a\033]2;xyz\x9cbcde', 'a', ('set_title', 'xyz'), 'bcde')
|
||||
self.ae(str(s.line(0)), 'abcde')
|
||||
self.ae(c.titlebuf, 'xyz')
|
||||
@ -171,7 +144,6 @@ class TestParser(BaseTest):
|
||||
|
||||
def test_dcs_codes(self):
|
||||
s = self.create_screen()
|
||||
s.callbacks = Callbacks()
|
||||
pb = partial(self.parse_bytes_dump, s)
|
||||
pb('a\033P+q436f\x9cbcde', 'a', ('screen_request_capabilities', '436f'), 'bcde')
|
||||
self.ae(str(s.line(0)), 'abcde')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user