Start work on option to modify font characteristics

Implement parsing of the option
This commit is contained in:
Kovid Goyal
2022-07-15 08:54:53 +05:30
parent 0a2ba3fb66
commit ee931a17b0
6 changed files with 95 additions and 3 deletions

View File

@@ -1,7 +1,8 @@
try:
from typing import TypedDict
from typing import TypedDict, NamedTuple
except ImportError:
TypedDict = dict
from enum import Enum, auto
class ListedFont(TypedDict):
@@ -21,3 +22,27 @@ class FontFeature:
def __repr__(self) -> str:
return repr(self.name)
class ModificationType(Enum):
underline_position = auto()
underline_thickness = auto()
strikethrough_position = auto()
strikethrough_thickness = auto()
size = auto()
class ModificationUnit(Enum):
pt = auto()
percent = auto()
class ModificationValue(NamedTuple):
val: float
unit: ModificationUnit
class FontModification(NamedTuple):
mod_type: ModificationType
mod_value: ModificationValue
font_name: str = ''

View File

@@ -216,6 +216,20 @@ You can do this with e.g.::
'''
)
opt('+modify_font', '',
option_type='modify_font',
add_to_default=False,
long_text='''
Modify font characteristics such as the position or thickness of the underline and strikethrough.
The modifications can be either plain numbers, in which case they are interpreted as
pts, or percentages, in which case they are interpreted as a percentage of the original value.
For example::
modify_font underline_position -2
modify_font underline_thickness 150%
modify_font strikethrough_thickness 50%
''')
opt('box_drawing_scale', '0.001, 1, 1.5, 2',
option_type='box_drawing_scale',
long_text='''

View File

@@ -12,7 +12,7 @@ from kitty.options.utils import (
cursor_text_color, deprecated_hide_window_decorations_aliases,
deprecated_macos_show_window_title_in_menubar_alias, deprecated_send_text, disable_ligatures,
edge_width, env, font_features, hide_window_decorations, macos_option_as_alt, macos_titlebar_color,
narrow_symbols, optional_edge_width, parse_map, parse_mouse_map, paste_actions,
modify_font, narrow_symbols, optional_edge_width, parse_map, parse_mouse_map, paste_actions,
resize_draw_strategy, scrollback_lines, scrollback_pager_history_size, shell_integration,
store_multiple, symbol_map, tab_activity_symbol, tab_bar_edge, tab_bar_margin_height,
tab_bar_min_tabs, tab_fade, tab_font_style, tab_separator, tab_title_template, titlebar_color,
@@ -1096,6 +1096,10 @@ class Parser:
def mark3_foreground(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['mark3_foreground'] = to_color(val)
def modify_font(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
for k, v in modify_font(val):
ans["modify_font"][k] = v
def mouse_hide_wait(self, val: str, ans: typing.Dict[str, typing.Any]) -> None:
ans['mouse_hide_wait'] = float(val)
@@ -1364,6 +1368,7 @@ def create_result_dict() -> typing.Dict[str, typing.Any]:
'exe_search_path': {},
'font_features': {},
'kitten_alias': {},
'modify_font': {},
'narrow_symbols': {},
'symbol_map': {},
'watcher': {},

View File

@@ -393,6 +393,7 @@ option_names = ( # {{{
'mark2_foreground',
'mark3_background',
'mark3_foreground',
'modify_font',
'mouse_hide_wait',
'mouse_map',
'narrow_symbols',
@@ -612,6 +613,7 @@ class Options:
exe_search_path: typing.Dict[str, str] = {}
font_features: typing.Dict[str, typing.Tuple[kitty.fonts.FontFeature, ...]] = {}
kitten_alias: typing.Dict[str, str] = {}
modify_font: typing.Dict[str, kitty.fonts.FontModification] = {}
narrow_symbols: typing.Dict[typing.Tuple[int, int], int] = {}
symbol_map: typing.Dict[typing.Tuple[int, int], str] = {}
watcher: typing.Dict[str, str] = {}
@@ -731,6 +733,7 @@ defaults.env = {}
defaults.exe_search_path = {}
defaults.font_features = {}
defaults.kitten_alias = {}
defaults.modify_font = {}
defaults.narrow_symbols = {}
defaults.symbol_map = {}
defaults.watcher = {}

View File

@@ -20,7 +20,10 @@ from kitty.constants import is_macos
from kitty.fast_data_types import (
CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE, Color
)
from kitty.fonts import FontFeature
from kitty.fonts import (
FontFeature, FontModification, ModificationType, ModificationUnit,
ModificationValue
)
from kitty.key_names import (
character_key_name_aliases, functional_key_name_aliases,
get_key_name_lookup
@@ -797,6 +800,41 @@ def font_features(val: str) -> Iterable[Tuple[str, Tuple[FontFeature, ...]]]:
yield parts[0], tuple(features)
def modify_font(val: str) -> Iterable[Tuple[str, FontModification]]:
parts = val.split()
pos, plen = 0, len(parts)
if plen < 2:
log_error(f"Ignoring invalid modify_font: {val}")
return
mtype: Optional[ModificationType] = getattr(ModificationType, parts[pos], None)
if mtype is None:
log_error(f"Ignoring invalid modify_font with unknown modification type: {parts[pos]}")
return
pos += 1
font_name = ''
if mtype is ModificationType.size:
font_name = parts[pos]
pos += 1
if plen - pos < 1:
log_error(f"Ignoring invalid modify_font: {val}")
return
sz = parts[pos]
pos += 1
munit = ModificationUnit.pt
if sz.endswith('%'):
munit = ModificationUnit.percent
sz = sz[:-1]
try:
mvalue = float(sz)
except Exception:
log_error(f'Ignoring modify_font with invalid size: {sz}')
return
key = mtype.name
if font_name:
key += f':{font_name}'
yield key, FontModification(mtype, ModificationValue(mvalue, munit), font_name)
def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
val = val.strip()
if val:

View File

@@ -23,6 +23,7 @@ class TestConfParsing(BaseTest):
from kitty.config import load_config, defaults
from kitty.constants import is_macos
from kitty.options.utils import to_modifiers
from kitty.fonts import FontModification, ModificationType, ModificationValue, ModificationUnit
bad_lines = []
def p(*lines, bad_line_num=0):
@@ -55,6 +56,12 @@ class TestConfParsing(BaseTest):
self.assertFalse(bad_lines)
opts = p('pointer_shape_when_grabbed XXX', bad_line_num=1)
self.ae(opts.pointer_shape_when_grabbed, defaults.pointer_shape_when_grabbed)
opts = p('modify_font underline_position -2', 'modify_font underline_thickness 150%', 'modify_font size Test -1')
self.ae(opts.modify_font, {
'underline_position': FontModification(ModificationType.underline_position, ModificationValue(-2., ModificationUnit.pt)),
'underline_thickness': FontModification(ModificationType.underline_thickness, ModificationValue(150, ModificationUnit.percent)),
'size:Test': FontModification(ModificationType.size, ModificationValue(-1., ModificationUnit.pt), 'Test'),
})
# test the aliasing options
opts = p('env A=1', 'env B=x$A', 'env C=', 'env D', 'clear_all_shortcuts y', 'kitten_alias a b --moo', 'map f1 kitten a arg')