Start work on option to modify font characteristics
Implement parsing of the option
This commit is contained in:
@@ -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 = ''
|
||||
|
||||
@@ -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='''
|
||||
|
||||
7
kitty/options/parse.py
generated
7
kitty/options/parse.py
generated
@@ -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': {},
|
||||
|
||||
3
kitty/options/types.py
generated
3
kitty/options/types.py
generated
@@ -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 = {}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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')
|
||||
|
||||
Reference in New Issue
Block a user