More typing work

This commit is contained in:
Kovid Goyal 2020-03-04 06:10:57 +05:30
parent 5730ce5f53
commit a4cc10c41b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
12 changed files with 340 additions and 65 deletions

View File

@ -77,10 +77,11 @@ function, telling kitty what kind of input your kitten would like. For example:
# in handle_result, STDIN is for the kitty process itself, rather
# than the kitten process and should not be read from.
from kittens.tui.handler import result_handler
@result_handler(type_of_input='text')
def handle_result(args, stdin_data, target_window_id, boss):
pass
handle_result.type_of_input = 'text'
This will send the plain text of the active window to the kitten's
:file:`STDIN`. For text with formatting escape codes, use ``ansi``
@ -106,6 +107,8 @@ Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
def main(args):
pass
from kittens.tui.handler import result_handler
@result_handler(no_ui=True)
def handle_result(args, answer, target_window_id, boss):
tab = boss.active_tab
if tab is not None:
@ -114,8 +117,6 @@ Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py`
else:
tab.goto_layout('stack')
handle_result.no_ui = True
Now in kitty.conf add::

View File

@ -9,6 +9,7 @@
from kitty.constants import cache_dir
from ..tui.operations import alternate_screen, styled
from ..tui.handler import result_handler
readline = None
@ -108,6 +109,7 @@ def main(args):
return ans
@result_handler()
def handle_result(args, data, target_window_id, boss):
if 'response' in data:
func, *args = data['items']

View File

@ -423,6 +423,7 @@ def main(args=sys.argv):
if __name__ == '__main__':
main()
elif __name__ == '__doc__':
sys.cli_docs['usage'] = usage
sys.cli_docs['options'] = options_spec
sys.cli_docs['help_text'] = help_text
cd = sys.cli_docs # type: ignore
cd['usage'] = usage
cd['options'] = options_spec
cd['help_text'] = help_text

View File

@ -13,7 +13,7 @@
try:
from enum import IntFlag
except ImportError:
from enum import IntEnum as IntFlag
from enum import IntEnum as IntFlag # type: ignore
class BorderColor(IntFlag):

View File

@ -5,9 +5,10 @@
# Utils {{{
import os
from gettext import gettext as _
from typing import Mapping, Union
from . import fast_data_types as defines
from .conf.definition import option_func
from .conf.definition import Option, Shortcut, option_func
from .conf.utils import (
choices, positive_float, positive_int, to_bool, to_cmdline, to_color,
to_color_or_none, unit_float
@ -54,7 +55,7 @@ def uniq(vals, result_type=list):
# Groups {{{
all_options = {}
all_options: Mapping[str, Union[Option, Shortcut]] = {}
o, k, g, all_groups = option_func(all_options, {
@ -475,11 +476,11 @@ def scrollback_pager_history_size(x):
:code:`url_style` can be one of: none, single, double, curly'''))
def url_style(x):
return url_style.map.get(x, url_style.map['curly'])
def url_style(x: str) -> int:
return url_style_map.get(x, url_style_map['curly'])
url_style.map = dict(
url_style_map = dict(
((v, i) for i, v in enumerate('none single double curly'.split()))
)
@ -1415,4 +1416,4 @@ def macos_option_as_alt(x):
# }}}
# }}}
type_map = {o.name: o.option_type for o in all_options.values() if hasattr(o, 'option_type')}
type_map = {o.name: o.option_type for o in all_options.values() if isinstance(o, Option)}

View File

@ -1,8 +1,115 @@
from typing import Callable, Mapping, Optional, Tuple
from collections import namedtuple
from typing import (
Any, Callable, List, Mapping, NewType, Optional, Tuple, Union
)
from kitty.cli import Namespace
GLFW_IBEAM_CURSOR: int
CURSOR_BEAM: int
CURSOR_BLOCK: int
CURSOR_UNDERLINE: int
DECAWM: int
BGIMAGE_PROGRAM: int
BLIT_PROGRAM: int
CELL_BG_PROGRAM: int
CELL_FG_PROGRAM: int
CELL_PROGRAM: int
CELL_SPECIAL_PROGRAM: int
CSI: int
DCS: int
DECORATION: int
DIM: int
GRAPHICS_ALPHA_MASK_PROGRAM: int
GRAPHICS_PREMULT_PROGRAM: int
GRAPHICS_PROGRAM: int
MARK: int
MARK_MASK: int
OSC: int
REVERSE: int
SCROLL_FULL: int
SCROLL_LINE: int
SCROLL_PAGE: int
STRIKETHROUGH: int
TINT_PROGRAM: int
FC_MONO: int = 100
FC_DUAL: int
FC_WEIGHT_REGULAR: int
FC_WEIGHT_BOLD: int
FC_SLANT_ROMAN: int
FC_SLANT_ITALIC: int
BORDERS_PROGRAM: int
def default_color_table() -> Tuple[int, ...]:
pass
FontConfigPattern = Mapping[str, Union[str, int, bool, float]]
def fc_list(spacing: int = -1, allow_bitmapped_fonts: bool = False) -> Tuple[FontConfigPattern, ...]:
pass
def fc_match(
family: Optional[str] = None,
bold: bool = False,
italic: bool = False,
spacing: int = FC_MONO,
allow_bitmapped_fonts: bool = False,
size_in_pts: float = 0.,
dpi: float = 0.
) -> FontConfigPattern:
pass
def coretext_all_fonts() -> Tuple[Mapping[str, Any], ...]:
pass
def add_timer(callback: Callable[[int], None], interval: float, repeats: bool = True) -> int:
pass
def monitor_pid(pid: int) -> None:
pass
def add_window(os_window_id: int, tab_id: int, title: str) -> int:
pass
def compile_program(which: int, vertex_shader: str, fragment_shader: str) -> int:
pass
def init_cell_program() -> None:
pass
def set_titlebar_color(os_window_id: int, color: int) -> bool:
pass
def add_borders_rect(os_window_id: int, tab_id: int, left: int, top: int, right: int, bottom: int, color: int) -> None:
pass
def init_borders_program() -> None:
pass
def os_window_has_background_image(os_window_id: int) -> bool:
pass
def dbus_send_notification(app_name: str, icon: str, summary: str, body: str, action_name: str, timeout: int = -1) -> int:
pass
def cocoa_send_notification(identifier: Optional[str], title: str, informative_text: str, path_to_img: Optional[str], subtitle: Optional[str] = None) -> None:
pass
def create_os_window(
@ -18,6 +125,14 @@ def create_os_window(
pass
def update_window_title(os_window_id: int, tab_id: int, window_id: int, title: str) -> None:
pass
def update_window_visibility(os_window_id: int, tab_id: int, window_id: int, window_idx: int, visible: bool) -> None:
pass
def set_options(
opts: Namespace,
is_wayland: bool = False,
@ -130,7 +245,7 @@ def background_opacity_of(os_window_id: int) -> Optional[float]:
pass
def read_command_response(fd: int, timeout: float, list) -> None:
def read_command_response(fd: int, timeout: float, list: List) -> None:
pass
@ -142,6 +257,154 @@ def is_emoji_presentation_base(code: int) -> bool:
pass
def x11_window_id(os_window_id: int) -> int:
pass
def swap_tabs(os_window_id: int, a: int, b: int) -> None:
pass
def set_active_tab(os_window_id: int, a: int) -> None:
pass
def ring_bell() -> None:
pass
def remove_window(os_window_id: int, tab_id: int, window_id: int) -> None:
pass
def remove_tab(os_window_id: int, tab_id: int) -> None:
pass
def pt_to_px(pt: float, os_window_id: int = 0) -> float:
pass
def next_window_id() -> int:
pass
def mark_tab_bar_dirty(os_window_id: int) -> None:
pass
def detach_window(os_window_id: int, tab_id: int, window_id: int) -> None:
pass
def attach_window(os_window_id: int, tab_id: int, window_id: int) -> None:
pass
def add_tab(os_window_id: int) -> int:
pass
def cell_size_for_window(os_window_id: int) -> Tuple[int, int]:
pass
Region = namedtuple('Region', 'left top right bottom width height')
def viewport_for_window(os_window_id: int) -> Tuple[Region, Region, int, int, int, int]:
pass
TermiosPtr = NewType('TermiosPtr', int)
def raw_tty(fd: int, termios_ptr: TermiosPtr) -> None:
pass
def close_tty(fd: int, termios_ptr: TermiosPtr) -> None:
pass
def normal_tty(fd: int, termios_ptr: TermiosPtr) -> None:
pass
def open_tty(read_with_timeout: bool = False) -> Tuple[int, TermiosPtr]:
pass
def parse_input_from_terminal(
text_callback: Callable[[str], None],
dcs_callback: Callable[[str], None],
csi_callback: Callable[[str], None],
osc_callback: Callable[[str], None],
pm_callback: Callable[[str], None],
apc_callback: Callable[[str], None],
data: str,
in_bracketed_paste: bool
):
pass
class Line:
pass
def test_shape(line: Line, path: Optional[str] = None, index: int = 0) -> List[Tuple[int, int, int, Tuple[int, ...]]]:
pass
def test_render_line(line: Line) -> None:
pass
def sprite_map_set_limits(w: int, h: int) -> None:
pass
def set_send_sprite_to_gpu(func: Callable[[int, int, int, bytes], None]) -> None:
pass
def set_font_data(
box_drawing_func: Callable[[int, int, int, float], Tuple[int, Union[bytearray, bytes]]],
prerender_func: Callable[[int, int, int, int, int, float, float, float, float], Tuple[int, ...]],
descriptor_for_idx: Callable[[int], Tuple[dict, bool, bool]],
bold: int, italic: int, bold_italic: int, num_symbol_fonts: int,
symbol_maps: Tuple[Tuple[int, int, int], ...],
font_sz_in_pts: float,
font_feature_settings: Mapping[str, Tuple[bytes, ...]]
):
pass
def get_fallback_font(text: str, bold: bool, italic: bool):
pass
def create_test_font_group(sz: float, dpix: float, dpiy: float) -> Tuple[int, int]:
pass
class Screen:
pass
def set_tab_bar_render_data(os_window_id: int, xstart: float, ystart: float, dx: float, dy: float, screen: Screen) -> None:
pass
def set_window_render_data(
os_window_id: int, tab_id: int, window_id: int, window_idx: int,
xstart: float, ystart: float, dx: float, dy: float,
screen: Screen,
left: int, top: int, right: int, bottom: int
):
pass
class ChildMonitor:
def __init__(

View File

@ -152,7 +152,7 @@ fc_match(PyObject UNUSED *self, PyObject *args) {
FcPattern *pat = NULL;
PyObject *ans = NULL;
if (!PyArg_ParseTuple(args, "|zppppdd", &family, &bold, &italic, &spacing, &allow_bitmapped_fonts, &size_in_pts, &dpi)) return NULL;
if (!PyArg_ParseTuple(args, "|zppipdd", &family, &bold, &italic, &spacing, &allow_bitmapped_fonts, &size_in_pts, &dpi)) return NULL;
pat = FcPatternCreate();
if (pat == NULL) return PyErr_NoMemory();

View File

@ -10,6 +10,8 @@
import math
from functools import partial as p
from itertools import repeat
from typing import cast, Callable
scale = (0.001, 1, 1.5, 2)
_dpi = 96.0
@ -638,24 +640,24 @@ def quad(buf, width, height, x=0, y=0):
for ch, c in zip('╭╮╯╰', '┌┐┘└'):
box_chars[ch] = [p(corner, which=c)] # TODO: Make these rounded
for i, (a, b, c, d) in enumerate((
for i, (a_, b_, c_, d_) in enumerate((
(t, t, t, t), (f, t, t, t), (t, f, t, t), (f, f, t, t), (t, t, f, t), (t, t, t, f), (t, t, f, f),
(f, t, f, t), (t, f, f, t), (f, t, t, f), (t, f, t, f), (f, f, f, t), (f, f, t, f), (f, t, f, f),
(t, f, f, f), (f, f, f, f)
)):
box_chars[chr(ord('') + i)] = [p(cross, a=a, b=b, c=c, d=d)]
box_chars[chr(ord('') + i)] = [p(cross, a=a_, b=b_, c=c_, d=d_)]
for starts, func, pattern in (
('├┤', vert_t, ((t, t, t), (t, f, t), (f, t, t), (t, t, f), (f, t, f), (f, f, t), (t, f, f), (f, f, f))),
('┬┴', horz_t, ((t, t, t), (f, t, t), (t, f, t), (f, f, t), (t, t, f), (f, t, f), (t, f, f), (f, f, f))),
):
for start in starts:
for i, (a, b, c) in enumerate(pattern):
box_chars[chr(ord(start) + i)] = [p(func, which=start, a=a, b=b, c=c)]
for i, (a_, b_, c_) in enumerate(pattern):
box_chars[chr(ord(start) + i)] = [p(func, which=start, a=a_, b=b_, c=c_)]
for chars, func in (('╒╕╘╛', dvcorner), ('╓╖╙╜', dhcorner), ('╔╗╚╝', dcorner), ('╟╢╤╧', dpip)):
for chars, func_ in (('╒╕╘╛', dvcorner), ('╓╖╙╜', dhcorner), ('╔╗╚╝', dcorner), ('╟╢╤╧', dpip)):
for ch in chars:
box_chars[ch] = [p(func, which=ch)]
box_chars[ch] = [p(cast(Callable, func_), which=ch)]
def render_box_char(ch, buf, width, height, dpi=96.0):

View File

@ -2,6 +2,7 @@
# vim:fileencoding=utf-8
# License: GPLv3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
from typing import Mapping
from .constants import is_macos, logo_png_file
@ -25,8 +26,8 @@ def notify(
from .fast_data_types import dbus_send_notification
from .constants import get_boss
alloc_map = {}
identifier_map = {}
alloc_map: Mapping[int, str] = {}
identifier_map: Mapping[str, int] = {}
def dbus_notification_created(alloc_id, notification_id):
identifier = alloc_map.pop(alloc_id, None)

View File

@ -749,7 +749,6 @@ end:
if (fragment_shader_id != 0) glDeleteShader(fragment_shader_id);
if (PyErr_Occurred()) { glDeleteProgram(program->id); program->id = 0; return NULL;}
return Py_BuildValue("I", program->id);
Py_RETURN_NONE;
}
#define PYWRAP0(name) static PyObject* py##name(PYNOARG)

View File

@ -3,6 +3,7 @@
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
from collections import namedtuple
from typing import Set
from .config import build_ansi_color_table
from .constants import WindowGeometry
@ -26,7 +27,7 @@ def as_rgb(x):
return (x << 8) | 2
template_failures = set()
template_failures: Set[str] = set()
def draw_title(draw_data, screen, tab, index):

View File

@ -57,51 +57,55 @@ def calculate_gl_geometry(window_geometry, viewport_width, viewport_height, cell
return ScreenGeometry(xstart, ystart, window_geometry.xnum, window_geometry.ynum, dx, dy)
def load_shader_programs(semi_transparent=False):
compile_program(BLIT_PROGRAM, *load_shaders('blit'))
v, f = load_shaders('cell')
class LoadShaderPrograms:
for which, p in {
'SIMPLE': CELL_PROGRAM,
'BACKGROUND': CELL_BG_PROGRAM,
'SPECIAL': CELL_SPECIAL_PROGRAM,
'FOREGROUND': CELL_FG_PROGRAM,
}.items():
vv, ff = v.replace('WHICH_PROGRAM', which), f.replace('WHICH_PROGRAM', which)
for gln, pyn in {
'REVERSE_SHIFT': REVERSE,
'STRIKE_SHIFT': STRIKETHROUGH,
'DIM_SHIFT': DIM,
'DECORATION_SHIFT': DECORATION,
'MARK_SHIFT': MARK,
'MARK_MASK': MARK_MASK,
use_selection_fg = True
def __call__(self, semi_transparent=False):
compile_program(BLIT_PROGRAM, *load_shaders('blit'))
v, f = load_shaders('cell')
for which, p in {
'SIMPLE': CELL_PROGRAM,
'BACKGROUND': CELL_BG_PROGRAM,
'SPECIAL': CELL_SPECIAL_PROGRAM,
'FOREGROUND': CELL_FG_PROGRAM,
}.items():
vv = vv.replace('{{{}}}'.format(gln), str(pyn), 1)
if semi_transparent:
vv = vv.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
ff = ff.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
if not load_shader_programs.use_selection_fg:
vv = vv.replace('#define USE_SELECTION_FG', '#define DONT_USE_SELECTION_FG')
ff = ff.replace('#define USE_SELECTION_FG', '#define DONT_USE_SELECTION_FG')
compile_program(p, vv, ff)
vv, ff = v.replace('WHICH_PROGRAM', which), f.replace('WHICH_PROGRAM', which)
for gln, pyn in {
'REVERSE_SHIFT': REVERSE,
'STRIKE_SHIFT': STRIKETHROUGH,
'DIM_SHIFT': DIM,
'DECORATION_SHIFT': DECORATION,
'MARK_SHIFT': MARK,
'MARK_MASK': MARK_MASK,
}.items():
vv = vv.replace('{{{}}}'.format(gln), str(pyn), 1)
if semi_transparent:
vv = vv.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
ff = ff.replace('#define NOT_TRANSPARENT', '#define TRANSPARENT')
if not load_shader_programs.use_selection_fg:
vv = vv.replace('#define USE_SELECTION_FG', '#define DONT_USE_SELECTION_FG')
ff = ff.replace('#define USE_SELECTION_FG', '#define DONT_USE_SELECTION_FG')
compile_program(p, vv, ff)
v, f = load_shaders('graphics')
for which, p in {
'SIMPLE': GRAPHICS_PROGRAM,
'PREMULT': GRAPHICS_PREMULT_PROGRAM,
'ALPHA_MASK': GRAPHICS_ALPHA_MASK_PROGRAM,
}.items():
ff = f.replace('ALPHA_TYPE', which)
compile_program(p, v, ff)
v, f = load_shaders('graphics')
for which, p in {
'SIMPLE': GRAPHICS_PROGRAM,
'PREMULT': GRAPHICS_PREMULT_PROGRAM,
'ALPHA_MASK': GRAPHICS_ALPHA_MASK_PROGRAM,
}.items():
ff = f.replace('ALPHA_TYPE', which)
compile_program(p, v, ff)
v, f = load_shaders('bgimage')
compile_program(BGIMAGE_PROGRAM, v, f)
v, f = load_shaders('tint')
compile_program(TINT_PROGRAM, v, f)
init_cell_program()
v, f = load_shaders('bgimage')
compile_program(BGIMAGE_PROGRAM, v, f)
v, f = load_shaders('tint')
compile_program(TINT_PROGRAM, v, f)
init_cell_program()
load_shader_programs.use_selection_fg = True
load_shader_programs = LoadShaderPrograms()
def setup_colors(screen, opts):