Merge branch 'refactor-fstring' of https://github.com/page-down/kitty
This commit is contained in:
commit
2e790a119a
14
.github/workflows/ci.py
vendored
14
.github/workflows/ci.py
vendored
@ -48,7 +48,7 @@ def install_deps():
|
||||
|
||||
def build_kitty():
|
||||
python = shutil.which('python3') if is_bundle else sys.executable
|
||||
cmd = '{} setup.py build --verbose'.format(python)
|
||||
cmd = f'{python} setup.py build --verbose'
|
||||
if os.environ.get('KITTY_SANITIZE') == '1':
|
||||
cmd += ' --debug --sanitize'
|
||||
run(cmd)
|
||||
@ -59,8 +59,8 @@ def test_kitty():
|
||||
|
||||
|
||||
def package_kitty():
|
||||
py = 'python3' if is_macos else 'python'
|
||||
run(py + ' setup.py linux-package --update-check-interval=0 --verbose')
|
||||
python = 'python3' if is_macos else 'python'
|
||||
run(f'{python} setup.py linux-package --update-check-interval=0 --verbose')
|
||||
if is_macos:
|
||||
run('python3 setup.py kitty.app --update-check-interval=0 --verbose')
|
||||
run('kitty.app/Contents/MacOS/kitty +runpy "from kitty.constants import *; print(kitty_exe())"')
|
||||
@ -76,11 +76,11 @@ def replace_in_file(path, src, dest):
|
||||
def setup_bundle_env():
|
||||
global SW
|
||||
os.environ['SW'] = SW = '/Users/Shared/kitty-build/sw/sw' if is_macos else os.path.join(os.environ['GITHUB_WORKSPACE'], 'sw')
|
||||
os.environ['PKG_CONFIG_PATH'] = SW + '/lib/pkgconfig'
|
||||
os.environ['PKG_CONFIG_PATH'] = os.path.join(SW, 'lib', 'pkgconfig')
|
||||
if is_macos:
|
||||
os.environ['PATH'] = '{}:{}'.format('/usr/local/opt/sphinx-doc/bin', os.environ['PATH'])
|
||||
else:
|
||||
os.environ['LD_LIBRARY_PATH'] = SW + '/lib'
|
||||
os.environ['LD_LIBRARY_PATH'] = os.path.join(SW, 'lib')
|
||||
os.environ['PYTHONHOME'] = SW
|
||||
os.environ['PATH'] = '{}:{}'.format(os.path.join(SW, 'bin'), os.environ['PATH'])
|
||||
|
||||
@ -111,7 +111,7 @@ def main():
|
||||
setup_bundle_env()
|
||||
else:
|
||||
if not is_macos and 'pythonLocation' in os.environ:
|
||||
os.environ['LD_LIBRARY_PATH'] = '{}/lib'.format(os.environ['pythonLocation'])
|
||||
os.environ['LD_LIBRARY_PATH'] = os.path.join(os.environ['pythonLocation'], 'lib')
|
||||
action = sys.argv[-1]
|
||||
if action in ('build', 'package'):
|
||||
install_deps()
|
||||
@ -122,7 +122,7 @@ def main():
|
||||
elif action == 'test':
|
||||
test_kitty()
|
||||
else:
|
||||
raise SystemExit('Unknown action: ' + action)
|
||||
raise SystemExit(f'Unknown action: {action}')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -13,7 +13,7 @@ import tempfile
|
||||
|
||||
def compile_terminfo(base):
|
||||
with tempfile.TemporaryDirectory() as tdir:
|
||||
proc = subprocess.run(['tic', '-x', '-o' + tdir, 'terminfo/kitty.terminfo'], check=True, stderr=subprocess.PIPE)
|
||||
proc = subprocess.run(['tic', '-x', f'-o{tdir}', 'terminfo/kitty.terminfo'], check=True, stderr=subprocess.PIPE)
|
||||
regex = '^"terminfo/kitty.terminfo", line [0-9]+, col [0-9]+, terminal \'xterm-kitty\': older tic versions may treat the description field as an alias$'
|
||||
for error in proc.stderr.decode('utf-8').splitlines():
|
||||
if not re.match(regex, error):
|
||||
|
||||
@ -26,7 +26,7 @@ def initialize_constants():
|
||||
kitty_constants = {}
|
||||
src = read_src_file('constants.py')
|
||||
nv = re.search(r'Version\((\d+), (\d+), (\d+)\)', src)
|
||||
kitty_constants['version'] = '%s.%s.%s' % (nv.group(1), nv.group(2), nv.group(3))
|
||||
kitty_constants['version'] = f'{nv.group(1)}.{nv.group(2)}.{nv.group(3)}'
|
||||
kitty_constants['appname'] = re.search(
|
||||
r'appname: str\s+=\s+(u{0,1})[\'"]([^\'"]+)[\'"]', src
|
||||
).group(2)
|
||||
|
||||
@ -38,7 +38,7 @@ def binary_includes():
|
||||
'ncursesw', 'readline', 'brotlicommon', 'brotlienc', 'brotlidec'
|
||||
))) + (
|
||||
get_dll_path('bz2', 2), get_dll_path('ssl', 2), get_dll_path('crypto', 2),
|
||||
get_dll_path('python' + py_ver, 2),
|
||||
get_dll_path(f'python{py_ver}', 2),
|
||||
)
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ class Env:
|
||||
def __init__(self, package_dir):
|
||||
self.base = package_dir
|
||||
self.lib_dir = j(self.base, 'lib')
|
||||
self.py_dir = j(self.lib_dir, 'python' + py_ver)
|
||||
self.py_dir = j(self.lib_dir, f'python{py_ver}')
|
||||
os.makedirs(self.py_dir)
|
||||
self.bin_dir = j(self.base, 'bin')
|
||||
self.obj_dir = mkdtemp('launchers-')
|
||||
@ -107,7 +107,7 @@ def add_ca_certs(env):
|
||||
|
||||
def copy_python(env):
|
||||
print('Copying python...')
|
||||
srcdir = j(PREFIX, 'lib/python' + py_ver)
|
||||
srcdir = j(PREFIX, f'lib/python{py_ver}')
|
||||
|
||||
for x in os.listdir(srcdir):
|
||||
y = j(srcdir, x)
|
||||
@ -187,11 +187,11 @@ def strip_files(files, argv_max=(256 * 1024)):
|
||||
|
||||
|
||||
def strip_binaries(files):
|
||||
print('Stripping %d files...' % len(files))
|
||||
print(f'Stripping {len(files)} files...')
|
||||
before = sum(os.path.getsize(x) for x in files)
|
||||
strip_files(files)
|
||||
after = sum(os.path.getsize(x) for x in files)
|
||||
print('Stripped %.1f MB' % ((before - after) / (1024 * 1024.)))
|
||||
print('Stripped {:.1f} MB'.format((before - after) / (1024 * 1024.)))
|
||||
|
||||
|
||||
def create_tarfile(env, compression_level='9'):
|
||||
@ -203,7 +203,7 @@ def create_tarfile(env, compression_level='9'):
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
os.mkdir(base)
|
||||
dist = os.path.join(base, '%s-%s-%s.tar' % (kitty_constants['appname'], kitty_constants['version'], arch))
|
||||
dist = os.path.join(base, f'{kitty_constants["appname"]}-{kitty_constants["version"]}-{arch}.tar')
|
||||
with tarfile.open(dist, mode='w', format=tarfile.PAX_FORMAT) as tf:
|
||||
cwd = os.getcwd()
|
||||
os.chdir(env.base)
|
||||
@ -213,13 +213,13 @@ def create_tarfile(env, compression_level='9'):
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
print('Compressing archive...')
|
||||
ans = dist.rpartition('.')[0] + '.txz'
|
||||
ans = f'{dist.rpartition(".")[0]}.txz'
|
||||
start_time = time.time()
|
||||
subprocess.check_call(['xz', '--threads=0', '-f', '-' + compression_level, dist])
|
||||
subprocess.check_call(['xz', '--threads=0', '-f', f'-{compression_level}', dist])
|
||||
secs = time.time() - start_time
|
||||
print('Compressed in %d minutes %d seconds' % (secs // 60, secs % 60))
|
||||
os.rename(dist + '.xz', ans)
|
||||
print('Archive %s created: %.2f MB' % (
|
||||
print('Compressed in {} minutes {} seconds'.format(secs // 60, secs % 60))
|
||||
os.rename(f'{dist}.xz', ans)
|
||||
print('Archive {} created: {:.2f} MB'.format(
|
||||
os.path.basename(ans), os.stat(ans).st_size / (1024.**2)))
|
||||
|
||||
|
||||
|
||||
@ -90,7 +90,7 @@ def strip_files(files, argv_max=(256 * 1024)):
|
||||
def files_in(folder):
|
||||
for record in os.walk(folder):
|
||||
for f in record[-1]:
|
||||
yield os.path.join(record[0], f)
|
||||
yield join(record[0], f)
|
||||
|
||||
|
||||
def expand_dirs(items, exclude=lambda x: x.endswith('.so')):
|
||||
@ -103,7 +103,7 @@ def expand_dirs(items, exclude=lambda x: x.endswith('.so')):
|
||||
|
||||
|
||||
def do_sign(app_dir):
|
||||
with current_dir(os.path.join(app_dir, 'Contents')):
|
||||
with current_dir(join(app_dir, 'Contents')):
|
||||
# Sign all .so files
|
||||
so_files = {x for x in files_in('.') if x.endswith('.so')}
|
||||
codesign(so_files)
|
||||
@ -153,7 +153,7 @@ class Freeze(object):
|
||||
self.to_strip = []
|
||||
self.warnings = []
|
||||
self.py_ver = py_ver
|
||||
self.python_stdlib = join(self.resources_dir, 'Python', 'lib', 'python' + self.py_ver)
|
||||
self.python_stdlib = join(self.resources_dir, 'Python', 'lib', f'python{self.py_ver}')
|
||||
self.site_packages = self.python_stdlib # hack to avoid needing to add site-packages to path
|
||||
self.obj_dir = mkdtemp('launchers-')
|
||||
|
||||
@ -177,7 +177,7 @@ class Freeze(object):
|
||||
self.run_tests()
|
||||
# self.run_shell()
|
||||
|
||||
ret = self.makedmg(self.build_dir, APPNAME + '-' + VERSION)
|
||||
ret = self.makedmg(self.build_dir, f'{APPNAME}-{VERSION}')
|
||||
|
||||
return ret
|
||||
|
||||
@ -186,7 +186,7 @@ class Freeze(object):
|
||||
print('\nDownloading CA certs...')
|
||||
from urllib.request import urlopen
|
||||
cdata = urlopen(kitty_constants['cacerts_url']).read()
|
||||
dest = os.path.join(self.contents_dir, 'Resources', 'cacert.pem')
|
||||
dest = join(self.contents_dir, 'Resources', 'cacert.pem')
|
||||
with open(dest, 'wb') as f:
|
||||
f.write(cdata)
|
||||
|
||||
@ -197,7 +197,7 @@ class Freeze(object):
|
||||
|
||||
@flush
|
||||
def run_tests(self):
|
||||
iv['run_tests'](os.path.join(self.contents_dir, 'MacOS', 'kitty'))
|
||||
iv['run_tests'](join(self.contents_dir, 'MacOS', 'kitty'))
|
||||
|
||||
@flush
|
||||
def set_id(self, path_to_lib, new_id):
|
||||
@ -222,10 +222,10 @@ class Freeze(object):
|
||||
@flush
|
||||
def get_local_dependencies(self, path_to_lib):
|
||||
for x, is_id in self.get_dependencies(path_to_lib):
|
||||
for y in (PREFIX + '/lib/', PREFIX + '/python/Python.framework/', '@rpath/'):
|
||||
for y in (f'{PREFIX}/lib/', f'{PREFIX}/python/Python.framework/', '@rpath/'):
|
||||
if x.startswith(y):
|
||||
if y == PREFIX + '/python/Python.framework/':
|
||||
y = PREFIX + '/python/'
|
||||
if y == f'{PREFIX}/python/Python.framework/':
|
||||
y = f'{PREFIX}/python/'
|
||||
yield x, x[len(y):], is_id
|
||||
break
|
||||
|
||||
@ -239,7 +239,7 @@ class Freeze(object):
|
||||
self.to_strip.append(path_to_lib)
|
||||
old_mode = flipwritable(path_to_lib)
|
||||
for dep, bname, is_id in self.get_local_dependencies(path_to_lib):
|
||||
ndep = self.FID + '/' + bname
|
||||
ndep = f'{self.FID}/{bname}'
|
||||
self.change_dep(dep, ndep, is_id, path_to_lib)
|
||||
ldeps = list(self.get_local_dependencies(path_to_lib))
|
||||
if ldeps:
|
||||
@ -252,7 +252,7 @@ class Freeze(object):
|
||||
@flush
|
||||
def add_python_framework(self):
|
||||
print('\nAdding Python framework')
|
||||
src = join(PREFIX + '/python', 'Python.framework')
|
||||
src = join(f'{PREFIX}/python', 'Python.framework')
|
||||
x = join(self.frameworks_dir, 'Python.framework')
|
||||
curr = os.path.realpath(join(src, 'Versions', 'Current'))
|
||||
currd = join(x, 'Versions', basename(curr))
|
||||
@ -262,12 +262,12 @@ class Freeze(object):
|
||||
shutil.copy2(join(curr, 'Python'), currd)
|
||||
self.set_id(
|
||||
join(currd, 'Python'),
|
||||
self.FID + '/Python.framework/Versions/%s/Python' % basename(curr))
|
||||
f'{self.FID}/Python.framework/Versions/{basename(curr)}/Python')
|
||||
# The following is needed for codesign
|
||||
with current_dir(x):
|
||||
os.symlink(basename(curr), 'Versions/Current')
|
||||
for y in ('Python', 'Resources'):
|
||||
os.symlink('Versions/Current/%s' % y, y)
|
||||
os.symlink(f'Versions/Current/{y}', y)
|
||||
|
||||
@flush
|
||||
def install_dylib(self, path, set_id=True):
|
||||
@ -275,7 +275,7 @@ class Freeze(object):
|
||||
if set_id:
|
||||
self.set_id(
|
||||
join(self.frameworks_dir, basename(path)),
|
||||
self.FID + '/' + basename(path))
|
||||
f'{self.FID}/{basename(path)}')
|
||||
self.fix_dependencies_in_lib(join(self.frameworks_dir, basename(path)))
|
||||
|
||||
@flush
|
||||
@ -291,11 +291,11 @@ class Freeze(object):
|
||||
'rsync.2',
|
||||
):
|
||||
print('\nAdding', x)
|
||||
x = 'lib%s.dylib' % x
|
||||
x = f'lib{x}.dylib'
|
||||
src = join(PREFIX, 'lib', x)
|
||||
shutil.copy2(src, self.frameworks_dir)
|
||||
dest = join(self.frameworks_dir, x)
|
||||
self.set_id(dest, self.FID + '/' + x)
|
||||
self.set_id(dest, f'{self.FID}/{x}')
|
||||
self.fix_dependencies_in_lib(dest)
|
||||
|
||||
@flush
|
||||
@ -321,7 +321,7 @@ class Freeze(object):
|
||||
@flush
|
||||
def add_stdlib(self):
|
||||
print('\nAdding python stdlib')
|
||||
src = PREFIX + '/python/Python.framework/Versions/Current/lib/python' + self.py_ver
|
||||
src = f'{PREFIX}/python/Python.framework/Versions/Current/lib/python{self.py_ver}'
|
||||
dest = self.python_stdlib
|
||||
if not os.path.exists(dest):
|
||||
os.makedirs(dest)
|
||||
@ -345,19 +345,19 @@ class Freeze(object):
|
||||
kitty_dir = join(self.resources_dir, 'kitty')
|
||||
bases = ('kitty', 'kittens', 'kitty_tests')
|
||||
for x in bases:
|
||||
dest = os.path.join(self.python_stdlib, x)
|
||||
os.rename(os.path.join(kitty_dir, x), dest)
|
||||
dest = join(self.python_stdlib, x)
|
||||
os.rename(join(kitty_dir, x), dest)
|
||||
if x == 'kitty':
|
||||
shutil.rmtree(os.path.join(dest, 'launcher'))
|
||||
os.rename(os.path.join(kitty_dir, '__main__.py'), os.path.join(self.python_stdlib, 'kitty_main.py'))
|
||||
shutil.rmtree(os.path.join(kitty_dir, '__pycache__'))
|
||||
pdir = os.path.join(dirname(self.python_stdlib), 'kitty-extensions')
|
||||
shutil.rmtree(join(dest, 'launcher'))
|
||||
os.rename(join(kitty_dir, '__main__.py'), join(self.python_stdlib, 'kitty_main.py'))
|
||||
shutil.rmtree(join(kitty_dir, '__pycache__'))
|
||||
pdir = join(dirname(self.python_stdlib), 'kitty-extensions')
|
||||
os.mkdir(pdir)
|
||||
print('Extracting extension modules from', self.python_stdlib, 'to', pdir)
|
||||
ext_map = extract_extension_modules(self.python_stdlib, pdir)
|
||||
shutil.copy(os.path.join(os.path.dirname(self_dir), 'site.py'), os.path.join(self.python_stdlib, 'site.py'))
|
||||
shutil.copy(join(os.path.dirname(self_dir), 'site.py'), join(self.python_stdlib, 'site.py'))
|
||||
for x in bases:
|
||||
iv['sanitize_source_folder'](os.path.join(self.python_stdlib, x))
|
||||
iv['sanitize_source_folder'](join(self.python_stdlib, x))
|
||||
self.compile_py_modules()
|
||||
freeze_python(self.python_stdlib, pdir, self.obj_dir, ext_map, develop_mode_env_var='KITTY_DEVELOP_FROM', remove_pyc_files=True)
|
||||
iv['build_frozen_launcher']([path_to_freeze_dir(), self.obj_dir])
|
||||
@ -434,23 +434,23 @@ class Freeze(object):
|
||||
''' Copy a directory d into a dmg named volname '''
|
||||
print('\nMaking dmg...')
|
||||
sys.stdout.flush()
|
||||
destdir = os.path.join(SW, 'dist')
|
||||
destdir = join(SW, 'dist')
|
||||
try:
|
||||
shutil.rmtree(destdir)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
os.mkdir(destdir)
|
||||
dmg = os.path.join(destdir, volname + '.dmg')
|
||||
dmg = join(destdir, f'{volname}.dmg')
|
||||
if os.path.exists(dmg):
|
||||
os.unlink(dmg)
|
||||
tdir = tempfile.mkdtemp()
|
||||
appdir = os.path.join(tdir, os.path.basename(d))
|
||||
appdir = join(tdir, os.path.basename(d))
|
||||
shutil.copytree(d, appdir, symlinks=True)
|
||||
if self.sign_installers:
|
||||
with timeit() as times:
|
||||
sign_app(appdir, self.notarize)
|
||||
print('Signing completed in %d minutes %d seconds' % tuple(times))
|
||||
os.symlink('/Applications', os.path.join(tdir, 'Applications'))
|
||||
print('Signing completed in {} minutes {} seconds'.format(*times))
|
||||
os.symlink('/Applications', join(tdir, 'Applications'))
|
||||
size_in_mb = int(
|
||||
subprocess.check_output(['du', '-s', '-k', tdir]).decode('utf-8')
|
||||
.split()[0]) / 1024.
|
||||
@ -466,10 +466,10 @@ class Freeze(object):
|
||||
print('\nCreating dmg...')
|
||||
with timeit() as times:
|
||||
subprocess.check_call(cmd + [dmg])
|
||||
print('dmg created in %d minutes and %d seconds' % tuple(times))
|
||||
print('dmg created in {} minutes and {} seconds'.format(*times))
|
||||
shutil.rmtree(tdir)
|
||||
size = os.stat(dmg).st_size / (1024 * 1024.)
|
||||
print('\nInstaller size: %.2fMB\n' % size)
|
||||
print(f'\nInstaller size: {size:.2f}MB\n')
|
||||
return dmg
|
||||
|
||||
|
||||
@ -477,7 +477,7 @@ def main():
|
||||
args = globals()['args']
|
||||
ext_dir = globals()['ext_dir']
|
||||
Freeze(
|
||||
os.path.join(ext_dir, kitty_constants['appname'] + '.app'),
|
||||
join(ext_dir, f'{kitty_constants["appname"]}.app'),
|
||||
dont_strip=args.dont_strip,
|
||||
sign_installers=args.sign_installers,
|
||||
notarize=args.notarize,
|
||||
|
||||
33
docs/conf.py
33
docs/conf.py
@ -13,7 +13,7 @@ import subprocess
|
||||
import sys
|
||||
import time
|
||||
from functools import partial
|
||||
from typing import Any, Callable, Dict, Iterable, List, Match, Optional, Tuple
|
||||
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple
|
||||
|
||||
from docutils import nodes
|
||||
from docutils.parsers.rst.roles import set_classes
|
||||
@ -28,7 +28,7 @@ kitty_src = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
if kitty_src not in sys.path:
|
||||
sys.path.insert(0, kitty_src)
|
||||
|
||||
from kitty.conf.types import Definition # noqa
|
||||
from kitty.conf.types import Definition, expand_opt_references # noqa
|
||||
from kitty.constants import str_version, website_url # noqa
|
||||
|
||||
# config {{{
|
||||
@ -217,7 +217,8 @@ if you specify a program-to-run you can use the special placeholder
|
||||
from kitty.remote_control import cli_msg, global_options_spec
|
||||
with open('generated/cli-kitty-at.rst', 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('kitty @\n' + '-' * 80)
|
||||
p('kitty @')
|
||||
p('-' * 80)
|
||||
p('.. program::', 'kitty @')
|
||||
p('\n\n' + as_rst(
|
||||
global_options_spec, message=cli_msg, usage='command ...', appname='kitty @'))
|
||||
@ -225,7 +226,8 @@ if you specify a program-to-run you can use the special placeholder
|
||||
for cmd_name in sorted(all_command_names()):
|
||||
func = command_for_name(cmd_name)
|
||||
p(f'.. _at_{func.name}:\n')
|
||||
p('kitty @', func.name + '\n' + '-' * 120)
|
||||
p('kitty @', func.name)
|
||||
p('-' * 120)
|
||||
p('.. program::', 'kitty @', func.name)
|
||||
p('\n\n' + as_rst(*cli_params_for(func)))
|
||||
from kittens.runner import get_kitten_cli_docs
|
||||
@ -234,12 +236,12 @@ if you specify a program-to-run you can use the special placeholder
|
||||
if data:
|
||||
with open(f'generated/cli-kitten-{kitten}.rst', 'w') as f:
|
||||
p = partial(print, file=f)
|
||||
p('.. program::', f'kitty +kitten {kitten}')
|
||||
p(f'\nSource code for {kitten}')
|
||||
p('.. program::', 'kitty +kitten', kitten)
|
||||
p('\nSource code for', kitten)
|
||||
p('-' * 72)
|
||||
p(f'\nThe source code for this kitten is `available on GitHub <https://github.com/kovidgoyal/kitty/tree/master/kittens/{kitten}>`_.')
|
||||
p('\nCommand Line Interface')
|
||||
p('-' * 72, file=f)
|
||||
p('-' * 72)
|
||||
p('\n\n' + option_spec_as_rst(
|
||||
data['options'], message=data['help_text'], usage=data['usage'], appname=f'kitty +kitten {kitten}',
|
||||
heading_char='^'))
|
||||
@ -364,19 +366,6 @@ def link_role(
|
||||
return [node], []
|
||||
|
||||
|
||||
def expand_opt_references(conf_name: str, text: str) -> str:
|
||||
conf_name += '.'
|
||||
|
||||
def expand(m: Match[str]) -> str:
|
||||
ref = m.group(1)
|
||||
if '<' not in ref and '.' not in ref:
|
||||
full_ref = conf_name + ref
|
||||
return f':opt:`{ref} <{full_ref}>`'
|
||||
return str(m.group())
|
||||
|
||||
return re.sub(r':opt:`(.+?)`', expand, text)
|
||||
|
||||
|
||||
opt_aliases: Dict[str, str] = {}
|
||||
shortcut_slugs: Dict[str, Tuple[str, str]] = {}
|
||||
|
||||
@ -414,7 +403,7 @@ def process_opt_link(env: Any, refnode: Any, has_explicit_title: bool, title: st
|
||||
conf_name, opt = target.partition('.')[::2]
|
||||
if not opt:
|
||||
conf_name, opt = 'kitty', conf_name
|
||||
full_name = conf_name + '.' + opt
|
||||
full_name = f'{conf_name}.{opt}'
|
||||
return title, opt_aliases.get(full_name, full_name)
|
||||
|
||||
|
||||
@ -422,7 +411,7 @@ def process_shortcut_link(env: Any, refnode: Any, has_explicit_title: bool, titl
|
||||
conf_name, slug = target.partition('.')[::2]
|
||||
if not slug:
|
||||
conf_name, slug = 'kitty', conf_name
|
||||
full_name = conf_name + '.' + slug
|
||||
full_name = f'{conf_name}.{slug}'
|
||||
try:
|
||||
target, stitle = shortcut_slugs[full_name]
|
||||
except KeyError:
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
# License: GPLv3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
from collections import defaultdict
|
||||
from typing import Any, DefaultDict, Dict, FrozenSet, List, Tuple, Union
|
||||
@ -42,7 +43,7 @@ def parse_flag(keymap: KeymapType, type_map: Dict[str, Any], command_class: str)
|
||||
lines = []
|
||||
for ch in type_map['flag']:
|
||||
attr, allowed_values = keymap[ch]
|
||||
q = ' && '.join(f"g.{attr} != '{x}'" for x in allowed_values)
|
||||
q = ' && '.join(f"g.{attr} != '{x}'" for x in sorted(allowed_values))
|
||||
lines.append(f'''
|
||||
case {attr}: {{
|
||||
g.{attr} = screen->parser_buf[pos++] & 0xff;
|
||||
@ -67,7 +68,7 @@ def cmd_for_report(report_name: str, keymap: KeymapType, type_map: Dict[str, Any
|
||||
flag_fmt, flag_attrs = [], []
|
||||
cv = {'flag': 'c', 'int': 'i', 'uint': 'I'}[atype]
|
||||
for ch in type_map[atype]:
|
||||
flag_fmt.append('s' + cv)
|
||||
flag_fmt.append(f's{cv}')
|
||||
attr = keymap[ch][0]
|
||||
flag_attrs.append(f'"{attr}", {conv}g.{attr}')
|
||||
return ' '.join(flag_fmt), ', '.join(flag_attrs)
|
||||
@ -240,7 +241,7 @@ static inline void
|
||||
|
||||
def write_header(text: str, path: str) -> None:
|
||||
with open(path, 'w') as f:
|
||||
print(f'// This file is generated by {__file__} do not edit!', file=f, end='\n\n')
|
||||
print(f'// This file is generated by {os.path.basename(__file__)} do not edit!', file=f, end='\n\n')
|
||||
print('#pragma once', file=f)
|
||||
print(text, file=f)
|
||||
subprocess.check_call(['clang-format', '-i', path])
|
||||
|
||||
@ -238,7 +238,7 @@ def patch_file(path: str, what: str, text: str, start_marker: str = '/* ', end_m
|
||||
end = raw.index(end_q)
|
||||
except ValueError:
|
||||
raise SystemExit(f'Failed to find "{end_q}" in {path}')
|
||||
raw = raw[:start] + start_q + '\n' + text + '\n' + raw[end:]
|
||||
raw = f'{raw[:start]}{start_q}\n{text}\n{raw[end:]}'
|
||||
f.seek(0)
|
||||
f.truncate(0)
|
||||
f.write(raw)
|
||||
@ -368,7 +368,7 @@ def generate_ctrl_mapping() -> None:
|
||||
val = str(ctrl_mapping[k])
|
||||
items.append(val)
|
||||
if k in "\\'":
|
||||
k = '\\' + k
|
||||
k = f'\\{k}'
|
||||
mi.append(f" case '{k}': return {val};")
|
||||
|
||||
for line_items in chunks(items, 6):
|
||||
|
||||
@ -80,7 +80,7 @@ def init_env(
|
||||
) -> Env:
|
||||
ans = env.copy()
|
||||
ans.cflags.append('-fPIC')
|
||||
ans.cppflags.append('-D_GLFW_' + module.upper())
|
||||
ans.cppflags.append(f'-D_GLFW_{module.upper()}')
|
||||
ans.cppflags.append('-D_GLFW_BUILD_DLL')
|
||||
|
||||
with open(os.path.join(base, 'source-info.json')) as f:
|
||||
|
||||
@ -101,7 +101,7 @@ def remote_hostname(path: str) -> Tuple[Optional[str], Optional[str]]:
|
||||
def resolve_remote_name(path: str, default: str) -> str:
|
||||
remote_dir, rh = remote_hostname(path)
|
||||
if remote_dir and rh:
|
||||
return rh + ':' + os.path.relpath(path, remote_dir)
|
||||
return f'{rh}:{os.path.relpath(path, remote_dir)}'
|
||||
return default
|
||||
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ def highlight_data(code: str, filename: str, aliases: Optional[Dict[str, str]] =
|
||||
base, ext = os.path.splitext(filename)
|
||||
alias = aliases.get(ext[1:])
|
||||
if alias is not None:
|
||||
filename = base + '.' + alias
|
||||
filename = f'{base}.{alias}'
|
||||
try:
|
||||
lexer = get_lexer_for_filename(filename, stripnl=False)
|
||||
except ClassNotFound:
|
||||
|
||||
@ -347,7 +347,7 @@ class DiffHandler(Handler):
|
||||
text = line.text
|
||||
if line.image_data is not None:
|
||||
image_involved = True
|
||||
self.write('\r\x1b[K' + text + '\x1b[0m')
|
||||
self.write(f'\r\x1b[K{text}\x1b[0m')
|
||||
if self.current_search is not None:
|
||||
self.current_search.highlight_line(self.write, lpos)
|
||||
if i < num - 1:
|
||||
@ -465,7 +465,7 @@ class DiffHandler(Handler):
|
||||
)
|
||||
else:
|
||||
counts = styled(f'{len(self.current_search)} matches', fg=self.opts.margin_fg)
|
||||
suffix = counts + ' ' + scroll_frac
|
||||
suffix = f'{counts} {scroll_frac}'
|
||||
prefix = styled(':', fg=self.opts.margin_fg)
|
||||
filler = self.screen_size.cols - wcswidth(prefix) - wcswidth(suffix)
|
||||
text = '{}{}{}'.format(prefix, ' ' * filler, suffix)
|
||||
|
||||
@ -244,14 +244,14 @@ class Differ:
|
||||
except Exception as e:
|
||||
return f'Running git diff for {left_path} vs. {right_path} generated an exception: {e}'
|
||||
if not ok:
|
||||
return output + f'\nRunning git diff for {left_path} vs. {right_path} failed'
|
||||
return f'{output}\nRunning git diff for {left_path} vs. {right_path} failed'
|
||||
left_lines = lines_for_path(left_path)
|
||||
right_lines = lines_for_path(right_path)
|
||||
try:
|
||||
patch = parse_patch(output)
|
||||
except Exception:
|
||||
import traceback
|
||||
return traceback.format_exc() + f'\nParsing diff for {left_path} vs. {right_path} failed'
|
||||
return f'{traceback.format_exc()}\nParsing diff for {left_path} vs. {right_path} failed'
|
||||
else:
|
||||
ans[key] = patch
|
||||
return ans
|
||||
|
||||
@ -101,7 +101,7 @@ def human_readable(size: int, sep: str = ' ') -> str:
|
||||
s = s[:s.find(".")+2]
|
||||
if s.endswith('.0'):
|
||||
s = s[:-2]
|
||||
return s + sep + suffix
|
||||
return f'{s}{sep}{suffix}'
|
||||
|
||||
|
||||
def fit_in(text: str, count: int) -> str:
|
||||
@ -110,7 +110,7 @@ def fit_in(text: str, count: int) -> str:
|
||||
return text
|
||||
if count > 1:
|
||||
p = truncate_point_for_length(text, count - 1)
|
||||
return text[:p] + '…'
|
||||
return f'{text[:p]}…'
|
||||
|
||||
|
||||
def fill_in(text: str, sz: int) -> str:
|
||||
@ -127,8 +127,8 @@ def place_in(text: str, sz: int) -> str:
|
||||
def format_func(which: str) -> Callable[[str], str]:
|
||||
def formatted(text: str) -> str:
|
||||
fmt = formats[which]
|
||||
return '\x1b[' + fmt + 'm' + text + '\x1b[0m'
|
||||
formatted.__name__ = which + '_format'
|
||||
return f'\x1b[{fmt}m{text}\x1b[0m'
|
||||
formatted.__name__ = f'{which}_format'
|
||||
return formatted
|
||||
|
||||
|
||||
@ -148,8 +148,8 @@ highlight_map = {'remove': ('removed_highlight', 'removed'), 'add': ('added_high
|
||||
|
||||
def highlight_boundaries(ltype: str) -> Tuple[str, str]:
|
||||
s, e = highlight_map[ltype]
|
||||
start = '\x1b[' + formats[s] + 'm'
|
||||
stop = '\x1b[' + formats[e] + 'm'
|
||||
start = f'\x1b[{formats[s]}m'
|
||||
stop = f'\x1b[{formats[e]}m'
|
||||
return start, stop
|
||||
|
||||
|
||||
|
||||
@ -729,7 +729,7 @@ def linenum_handle_result(args: List[str], data: Dict[str, Any], target_window_i
|
||||
else:
|
||||
import shlex
|
||||
text = ' '.join(shlex.quote(arg) for arg in cmd)
|
||||
w.paste_bytes(text + '\r')
|
||||
w.paste_bytes(f'{text}\r')
|
||||
elif action == 'background':
|
||||
import subprocess
|
||||
subprocess.Popen(cmd, cwd=data['cwd'])
|
||||
|
||||
@ -245,7 +245,7 @@ def main(args: List[str] = sys.argv) -> None:
|
||||
raise SystemExit(f'Unknown queries: {", ".join(extra)}')
|
||||
|
||||
for key, val in do_queries(queries, cli_opts).items():
|
||||
print(key + ':', val)
|
||||
print(f'{key}:', val)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@ -52,7 +52,7 @@ class KeysHandler(Handler):
|
||||
self.cmd.colored(etype + ' ', 'yellow')
|
||||
self.cmd.styled(key_event.text, italic=True)
|
||||
self.print()
|
||||
rep = 'CSI ' + encode_key_event(key_event)[2:]
|
||||
rep = f'CSI {encode_key_event(key_event)[2:]}'
|
||||
rep = rep.replace(';', ' ; ').replace(':', ' : ')[:-1] + ' ' + rep[-1]
|
||||
self.cmd.styled(rep, fg='magenta')
|
||||
if (key_event.shifted_key or key_event.alternate_key):
|
||||
|
||||
@ -17,7 +17,7 @@ def print_key(raw: bytearray) -> None:
|
||||
unix = ''
|
||||
for ch in raw:
|
||||
if ch < len(ctrl_keys):
|
||||
unix += '^' + ctrl_keys[ch]
|
||||
unix += f'^{ctrl_keys[ch]}'
|
||||
elif ch == 127:
|
||||
unix += '^?'
|
||||
else:
|
||||
|
||||
@ -281,7 +281,7 @@ def complete_choices(ans: Completions, prefix: str, title: str, choices: Iterabl
|
||||
if q.startswith(effective_prefix):
|
||||
if comma_separated:
|
||||
tq = q
|
||||
q = hidden_prefix + q + ','
|
||||
q = f'{hidden_prefix}{q},'
|
||||
word_transforms[q] = tq
|
||||
matches[q] = ''
|
||||
ans.add_match_group(title, matches, trailing_space=not comma_separated, word_transforms=word_transforms)
|
||||
|
||||
@ -131,7 +131,7 @@ def get_ssh_cli() -> Tuple[Set[str], Set[str]]:
|
||||
other_ssh_args: Set[str] = set()
|
||||
boolean_ssh_args: Set[str] = set()
|
||||
for k, v in ssh_options().items():
|
||||
k = '-' + k
|
||||
k = f'-{k}'
|
||||
if v:
|
||||
other_ssh_args.add(k)
|
||||
else:
|
||||
@ -213,7 +213,7 @@ class InvalidSSHArgs(ValueError):
|
||||
|
||||
def parse_ssh_args(args: List[str]) -> Tuple[List[str], List[str], bool]:
|
||||
boolean_ssh_args, other_ssh_args = get_ssh_cli()
|
||||
passthrough_args = {'-' + x for x in 'Nnf'}
|
||||
passthrough_args = {f'-{x}' for x in 'Nnf'}
|
||||
ssh_args = []
|
||||
server_args: List[str] = []
|
||||
expecting_option_val = False
|
||||
@ -230,7 +230,7 @@ def parse_ssh_args(args: List[str]) -> Tuple[List[str], List[str], bool]:
|
||||
# could be a multi-character option
|
||||
all_args = argument[1:]
|
||||
for i, arg in enumerate(all_args):
|
||||
arg = '-' + arg
|
||||
arg = f'-{arg}'
|
||||
if arg in passthrough_args:
|
||||
passthrough = True
|
||||
if arg in boolean_ssh_args:
|
||||
|
||||
@ -376,7 +376,7 @@ def fetch_themes(
|
||||
|
||||
needs_delete = False
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(suffix='-' + os.path.basename(dest_path), dir=os.path.dirname(dest_path), delete=False) as f:
|
||||
with tempfile.NamedTemporaryFile(suffix=f'-{os.path.basename(dest_path)}', dir=os.path.dirname(dest_path), delete=False) as f:
|
||||
needs_delete = True
|
||||
shutil.copyfileobj(res, f)
|
||||
f.flush()
|
||||
@ -405,7 +405,7 @@ def theme_name_from_file_name(fname: str) -> str:
|
||||
ans = ans.replace('_', ' ')
|
||||
|
||||
def camel_case(m: 'Match[str]') -> str:
|
||||
return str(m.group(1) + ' ' + m.group(2))
|
||||
return f'{m.group(1)} {m.group(2)}'
|
||||
|
||||
ans = re.sub(r'([a-z])([A-Z])', camel_case, ans)
|
||||
return ' '.join(x.capitalize() for x in filter(None, ans.split()))
|
||||
@ -533,7 +533,7 @@ class Theme:
|
||||
raw = ''
|
||||
nraw = patch_conf(raw, self.name)
|
||||
if raw:
|
||||
with open(confpath + '.bak', 'w') as f:
|
||||
with open(f'{confpath}.bak', 'w') as f:
|
||||
f.write(raw)
|
||||
atomic_save(nraw.encode('utf-8'), confpath)
|
||||
if reload_in == 'parent':
|
||||
|
||||
@ -37,7 +37,7 @@ def limit_length(text: str, limit: int = 32) -> str:
|
||||
x = truncate_point_for_length(text, limit - 1)
|
||||
if x >= len(text):
|
||||
return text
|
||||
return text[:x] + '…'
|
||||
return f'{text[:x]}…'
|
||||
|
||||
|
||||
class State(Enum):
|
||||
@ -332,7 +332,7 @@ class ThemesHandler(Handler):
|
||||
for line, width, is_current in self.themes_list.lines(num_rows):
|
||||
num_rows -= 1
|
||||
if is_current:
|
||||
line = line.replace(MARK_AFTER, '\033[' + color_code('green') + 'm')
|
||||
line = line.replace(MARK_AFTER, f'\033[{color_code("green")}m')
|
||||
self.cmd.styled('>' if is_current else ' ', fg='green')
|
||||
self.cmd.styled(line, bold=is_current, fg='green' if is_current else None)
|
||||
self.cmd.move_cursor_by(mw - width, 'right')
|
||||
|
||||
@ -155,12 +155,12 @@ def develop() -> None:
|
||||
import sys
|
||||
src = sys.argv[-1]
|
||||
sig_loader = LoadSignature()
|
||||
with open(src + '.sig', 'wb') as f:
|
||||
with open(f'{src}.sig', 'wb') as f:
|
||||
for chunk in signature_of_file(src):
|
||||
sig_loader.add_chunk(chunk)
|
||||
f.write(chunk)
|
||||
sig_loader.commit()
|
||||
with open(src + '.delta', 'wb') as f, PatchFile(src, src + '.output') as patcher:
|
||||
with open(f'{src}.delta', 'wb') as f, PatchFile(src, f'{src}.output') as patcher:
|
||||
for chunk in delta_for_file(src, sig_loader.signature):
|
||||
f.write(chunk)
|
||||
patcher.write(chunk)
|
||||
|
||||
@ -45,7 +45,7 @@ def render_path_in_width(path: str, width: int) -> str:
|
||||
if wcswidth(path) <= width:
|
||||
return path
|
||||
x = truncate_point_for_length(path, width - 1)
|
||||
return path[:x] + '…'
|
||||
return f'{path[:x]}…'
|
||||
|
||||
|
||||
def render_seconds(val: float) -> str:
|
||||
|
||||
@ -331,7 +331,7 @@ class Dircolors:
|
||||
# change .xyz to *.xyz
|
||||
yield '*' + pair[0], pair[1]
|
||||
|
||||
return ':'.join('%s=%s' % pair for pair in gen_pairs())
|
||||
return ':'.join('{}={}'.format(*pair) for pair in gen_pairs())
|
||||
|
||||
def _format_code(self, text: str, code: str) -> str:
|
||||
val = self.codes.get(code)
|
||||
|
||||
@ -163,7 +163,7 @@ def set_scrolling_region(screen_size: Optional['ScreenSize'] = None, top: Option
|
||||
|
||||
@cmd
|
||||
def scroll_screen(amt: int = 1) -> str:
|
||||
return '\033[' + str(abs(amt)) + ('T' if amt < 0 else 'S')
|
||||
return f'\033[{abs(amt)}{"T" if amt < 0 else "S"}'
|
||||
|
||||
|
||||
STANDARD_COLORS = {'black': 0, 'red': 1, 'green': 2, 'yellow': 3, 'blue': 4, 'magenta': 5, 'cyan': 6, 'gray': 7, 'white': 7}
|
||||
@ -465,7 +465,7 @@ def as_type_stub() -> str:
|
||||
for name, func in all_cmds.items():
|
||||
args = ', '.join(func_sig(func))
|
||||
if args:
|
||||
args = ', ' + args
|
||||
args = f', {args}'
|
||||
methods.append(f' def {name}(self{args}) -> str: pass')
|
||||
ans += ['', '', 'class CMD:'] + methods
|
||||
|
||||
|
||||
@ -192,7 +192,7 @@ class Table:
|
||||
if w < 2:
|
||||
text += ' ' * (2 - w)
|
||||
if len(desc) > space_for_desc:
|
||||
text += desc[:space_for_desc - 1] + '…'
|
||||
text += f'{desc[:space_for_desc - 1]}…'
|
||||
else:
|
||||
text += desc
|
||||
extra = space_for_desc - len(desc)
|
||||
|
||||
@ -62,7 +62,7 @@ else:
|
||||
except Exception:
|
||||
continue
|
||||
try:
|
||||
with open('/proc/' + x + '/stat', 'rb') as f:
|
||||
with open(f'/proc/{x}/stat', 'rb') as f:
|
||||
raw = f.read().decode('utf-8')
|
||||
except OSError:
|
||||
continue
|
||||
@ -268,7 +268,7 @@ class Child:
|
||||
# https://github.com/kovidgoyal/kitty/issues/1870
|
||||
# xterm, urxvt, konsole and gnome-terminal do not do it in my
|
||||
# testing.
|
||||
argv[0] = ('-' + exe.split('/')[-1])
|
||||
argv[0] = (f'-{exe.split("/")[-1]}')
|
||||
exe = which(exe) or exe
|
||||
pid = fast_data_types.spawn(exe, self.cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, ready_read_fd, ready_write_fd)
|
||||
os.close(slave)
|
||||
|
||||
@ -82,7 +82,7 @@ def generate_stub() -> None:
|
||||
for cmd_name in all_command_names():
|
||||
cmd = command_for_name(cmd_name)
|
||||
if cmd.options_spec:
|
||||
do(cmd.options_spec, cmd.__class__.__name__ + 'RCOptions')
|
||||
do(cmd.options_spec, f'{cmd.__class__.__name__}RCOptions')
|
||||
|
||||
save_type_stub(text, __file__)
|
||||
|
||||
|
||||
@ -12,8 +12,8 @@ from contextlib import suppress
|
||||
from typing import Any
|
||||
|
||||
|
||||
CSI = '\033['
|
||||
OSC = '\033]'
|
||||
CSI = '\x1b['
|
||||
OSC = '\x1b]'
|
||||
|
||||
|
||||
def write(x: str) -> None:
|
||||
@ -42,11 +42,11 @@ def screen_alternate_keypad_mode() -> None:
|
||||
|
||||
|
||||
def screen_cursor_position(y: int, x: int) -> None:
|
||||
write(CSI + f'{y};{x}H')
|
||||
write(f'{CSI}{y};{x}H')
|
||||
|
||||
|
||||
def screen_cursor_forward(amt: int) -> None:
|
||||
write(CSI + '%sC' % amt)
|
||||
write(f'{CSI}{amt}C')
|
||||
|
||||
|
||||
def screen_save_cursor() -> None:
|
||||
@ -58,105 +58,105 @@ def screen_restore_cursor() -> None:
|
||||
|
||||
|
||||
def screen_cursor_back1(amt: int) -> None:
|
||||
write(CSI + '%sD' % amt)
|
||||
write(f'{CSI}{amt}D')
|
||||
|
||||
|
||||
def screen_save_modes() -> None:
|
||||
write(CSI + '?s')
|
||||
write(f'{CSI}?s')
|
||||
|
||||
|
||||
def screen_restore_modes() -> None:
|
||||
write(CSI + '?r')
|
||||
write(f'{CSI}?r')
|
||||
|
||||
|
||||
def screen_designate_charset(which: int, to: int) -> None:
|
||||
w = '()'[int(which)]
|
||||
t = chr(int(to))
|
||||
write('\033' + w + t)
|
||||
write(f'\x1b{w}{t}')
|
||||
|
||||
|
||||
def select_graphic_rendition(*a: int) -> None:
|
||||
write(CSI + '%sm' % ';'.join(map(str, a)))
|
||||
write(f'{CSI}{";".join(map(str, a))}m')
|
||||
|
||||
|
||||
def screen_cursor_to_column(c: int) -> None:
|
||||
write(CSI + '%dG' % c)
|
||||
write(f'{CSI}{c}G')
|
||||
|
||||
|
||||
def screen_cursor_to_line(ln: int) -> None:
|
||||
write(CSI + '%dd' % ln)
|
||||
write(f'{CSI}{ln}d')
|
||||
|
||||
|
||||
def screen_set_mode(x: int, private: bool) -> None:
|
||||
write(CSI + ('?' if private else '') + str(x) + 'h')
|
||||
write(f'{CSI}{"?" if private else ""}{x}h')
|
||||
|
||||
|
||||
def screen_save_mode(x: int, private: bool) -> None:
|
||||
write(CSI + ('?' if private else '') + str(x) + 's')
|
||||
write(f'{CSI}{"?" if private else ""}{x}s')
|
||||
|
||||
|
||||
def screen_reset_mode(x: int, private: bool) -> None:
|
||||
write(CSI + ('?' if private else '') + str(x) + 'l')
|
||||
write(f'{CSI}{"?" if private else ""}{x}l')
|
||||
|
||||
|
||||
def screen_restore_mode(x: int, private: bool) -> None:
|
||||
write(CSI + ('?' if private else '') + str(x) + 'r')
|
||||
write(f'{CSI}{"?" if private else ""}{x}r')
|
||||
|
||||
|
||||
def screen_set_margins(t: int, b: int) -> None:
|
||||
write(CSI + '%d;%dr' % (t, b))
|
||||
write(f'{CSI}{t};{b}r')
|
||||
|
||||
|
||||
def screen_indexn(n: int) -> None:
|
||||
write(CSI + '%dS' % n)
|
||||
write(f'{CSI}{n}S')
|
||||
|
||||
|
||||
def screen_delete_characters(count: int) -> None:
|
||||
write(CSI + '%dP' % count)
|
||||
write(f'{CSI}{count}P')
|
||||
|
||||
|
||||
def screen_push_colors(which: int) -> None:
|
||||
write(CSI + '%d#P' % which)
|
||||
write(f'{CSI}{which}#P')
|
||||
|
||||
|
||||
def screen_pop_colors(which: int) -> None:
|
||||
write(CSI + '%d#Q' % which)
|
||||
write(f'{CSI}{which}#Q')
|
||||
|
||||
|
||||
def screen_report_colors() -> None:
|
||||
write(CSI + '#R')
|
||||
write(f'{CSI}#R')
|
||||
|
||||
|
||||
def screen_repeat_character(num: int) -> None:
|
||||
write(CSI + '%db' % num)
|
||||
write(f'{CSI}{num}b')
|
||||
|
||||
|
||||
def screen_insert_characters(count: int) -> None:
|
||||
write(CSI + '%d@' % count)
|
||||
write(f'{CSI}{count}@')
|
||||
|
||||
|
||||
def screen_scroll(count: int) -> None:
|
||||
write(CSI + '%dS' % count)
|
||||
write(f'{CSI}{count}S')
|
||||
|
||||
|
||||
def screen_erase_in_display(how: int, private: bool) -> None:
|
||||
write(CSI + ('?' if private else '') + str(how) + 'J')
|
||||
write(f'{CSI}{"?" if private else ""}{how}J')
|
||||
|
||||
|
||||
def screen_erase_in_line(how: int, private: bool) -> None:
|
||||
write(CSI + ('?' if private else '') + str(how) + 'K')
|
||||
write(f'{CSI}{"?" if private else ""}{how}K')
|
||||
|
||||
|
||||
def screen_delete_lines(num: int) -> None:
|
||||
write(CSI + str(num) + 'M')
|
||||
write(f'{CSI}{num}M')
|
||||
|
||||
|
||||
def screen_cursor_up2(count: int) -> None:
|
||||
write(CSI + '%dA' % count)
|
||||
write(f'{CSI}{count}A')
|
||||
|
||||
|
||||
def screen_cursor_down(count: int) -> None:
|
||||
write(CSI + '%dB' % count)
|
||||
write(f'{CSI}{count}B')
|
||||
|
||||
|
||||
def screen_carriage_return() -> None:
|
||||
@ -176,11 +176,11 @@ def screen_backspace() -> None:
|
||||
|
||||
|
||||
def screen_set_cursor(mode: int, secondary: int) -> None:
|
||||
write(CSI + '%d q' % secondary)
|
||||
write(f'{CSI}{secondary} q')
|
||||
|
||||
|
||||
def screen_insert_lines(num: int) -> None:
|
||||
write(CSI + '%dL' % num)
|
||||
write(f'{CSI}{num}L')
|
||||
|
||||
|
||||
def draw(*a: str) -> None:
|
||||
@ -188,7 +188,7 @@ def draw(*a: str) -> None:
|
||||
|
||||
|
||||
def screen_manipulate_title_stack(op: int, which: int) -> None:
|
||||
write(CSI + '%d;%dt' % (op, which))
|
||||
write(f'{CSI}{op};{which}t')
|
||||
|
||||
|
||||
def report_device_attributes(mode: int, char: int) -> None:
|
||||
@ -197,21 +197,22 @@ def report_device_attributes(mode: int, char: int) -> None:
|
||||
x += chr(char)
|
||||
if mode:
|
||||
x += str(mode)
|
||||
write(CSI + x + 'c')
|
||||
write(f'{CSI}{x}c')
|
||||
|
||||
|
||||
def screen_decsace(mode: int) -> None:
|
||||
write(CSI + str(mode) + '*x')
|
||||
write(f'{CSI}{mode}*x')
|
||||
|
||||
|
||||
def screen_set_8bit_controls(mode: int) -> None:
|
||||
write('\x1b ' + ('G' if mode else 'F'))
|
||||
write(f'\x1b {"G" if mode else "F"}')
|
||||
|
||||
|
||||
def write_osc(code: int, string: str = '') -> None:
|
||||
if string:
|
||||
string = ';' + string
|
||||
write(OSC + str(code) + string + '\x07')
|
||||
write(f'{OSC}{code};{string}\x07')
|
||||
else:
|
||||
write(f'{OSC}{code}\x07')
|
||||
|
||||
|
||||
set_dynamic_color = set_color_table_color = process_cwd_notification = write_osc
|
||||
@ -235,7 +236,7 @@ def clipboard_control(payload: str) -> None:
|
||||
clipboard_control_pending += data.lstrip(';')
|
||||
payload = clipboard_control_pending
|
||||
clipboard_control_pending = ''
|
||||
write(OSC + payload + '\x07')
|
||||
write(f'{OSC}{payload}\x07')
|
||||
|
||||
|
||||
def replay(raw: str) -> None:
|
||||
|
||||
@ -270,7 +270,7 @@ def zsh_output_serializer(ans: Completions) -> str:
|
||||
yield ans
|
||||
|
||||
for description, matches in ans.match_groups.items():
|
||||
cmd = ['compadd', '-U', '-J', shlex.quote(description), '-X', shlex.quote('%B' + description + '%b')]
|
||||
cmd = ['compadd', '-U', '-J', shlex.quote(description), '-X', shlex.quote(f'%B{description}%b')]
|
||||
if not matches.trailing_space:
|
||||
cmd += ['-S', '""']
|
||||
if matches.is_files:
|
||||
@ -350,10 +350,10 @@ def fish2_output_serializer(ans: Completions) -> str:
|
||||
|
||||
|
||||
def completions_for_first_word(ans: Completions, prefix: str, entry_points: Iterable[str], namespaced_entry_points: Iterable[str]) -> None:
|
||||
cmds = ['@' + c for c in remote_control_command_names()]
|
||||
cmds = [f'@{c}' for c in remote_control_command_names()]
|
||||
ans.add_match_group('Entry points', {
|
||||
k: '' for k in
|
||||
list(entry_points) + cmds + ['+' + k for k in namespaced_entry_points]
|
||||
list(entry_points) + cmds + [f'+{k}' for k in namespaced_entry_points]
|
||||
if not prefix or k.startswith(prefix)
|
||||
})
|
||||
if prefix:
|
||||
@ -443,7 +443,7 @@ def complete_alias_map(
|
||||
long_opt = option_map.get(parts[0])
|
||||
if long_opt is not None and complete_args is not None:
|
||||
complete_args(ans, long_opt, parts[1], Delegate())
|
||||
ans.add_prefix(parts[0] + '=')
|
||||
ans.add_prefix(f'{parts[0]}=')
|
||||
return
|
||||
opt = option_map.get(w)
|
||||
if w is last_word and not new_word:
|
||||
@ -682,7 +682,7 @@ def find_completions(words: Sequence[str], new_word: bool, entry_points: Iterabl
|
||||
if words[0].startswith('@'):
|
||||
if len(words) == 1 and not new_word:
|
||||
prefix = words[0]
|
||||
ans.add_match_group('Remote control commands', {'@' + c: '' for c in remote_control_command_names() if c.startswith(prefix)})
|
||||
ans.add_match_group('Remote control commands', {f'@{c}': '' for c in remote_control_command_names() if c.startswith(prefix)})
|
||||
else:
|
||||
complete_remote_command(ans, words[0][1:], words[1:], new_word)
|
||||
if words[0] == '+':
|
||||
|
||||
@ -418,9 +418,9 @@ def generate_c_conversion(loc: str, ctypes: List[Option]) -> str:
|
||||
def write_output(loc: str, defn: Definition) -> None:
|
||||
cls, tc = generate_class(defn, loc)
|
||||
with open(os.path.join(*loc.split('.'), 'options', 'types.py'), 'w') as f:
|
||||
f.write(cls + '\n')
|
||||
f.write(f'{cls}\n')
|
||||
with open(os.path.join(*loc.split('.'), 'options', 'parse.py'), 'w') as f:
|
||||
f.write(tc + '\n')
|
||||
f.write(f'{tc}\n')
|
||||
ctypes = []
|
||||
for opt in defn.root_group.iter_all_non_groups():
|
||||
if isinstance(opt, Option) and opt.ctype:
|
||||
@ -428,7 +428,7 @@ def write_output(loc: str, defn: Definition) -> None:
|
||||
if ctypes:
|
||||
c = generate_c_conversion(loc, ctypes)
|
||||
with open(os.path.join(*loc.split('.'), 'options', 'to-c-generated.h'), 'w') as f:
|
||||
f.write(c + '\n')
|
||||
f.write(f'{c}\n')
|
||||
|
||||
|
||||
def main() -> None:
|
||||
@ -454,6 +454,6 @@ def main() -> None:
|
||||
loc = package_name
|
||||
cls, tc = generate_class(defn, loc)
|
||||
with open(os.path.join(os.path.dirname(path), 'kitten_options_types.py'), 'w') as f:
|
||||
f.write(cls + '\n')
|
||||
f.write(f'{cls}\n')
|
||||
with open(os.path.join(os.path.dirname(path), 'kitten_options_parse.py'), 'w') as f:
|
||||
f.write(tc + '\n')
|
||||
f.write(f'{tc}\n')
|
||||
|
||||
@ -37,8 +37,8 @@ def expand_opt_references(conf_name: str, text: str) -> str:
|
||||
def expand(m: 'Match[str]') -> str:
|
||||
ref = m.group(1)
|
||||
if '<' not in ref and '.' not in ref:
|
||||
full_ref = conf_name + ref
|
||||
return f':opt:`{ref} <{full_ref}>`'
|
||||
# full ref
|
||||
return f':opt:`{ref} <{conf_name}{ref}>`'
|
||||
return str(m.group())
|
||||
|
||||
return re.sub(r':opt:`(.+?)`', expand, text)
|
||||
@ -214,7 +214,7 @@ class Option:
|
||||
if not self.documented:
|
||||
return ans
|
||||
mopts = [self] + option_group
|
||||
a('.. opt:: ' + ', '.join(conf_name + '.' + mo.name for mo in mopts))
|
||||
a('.. opt:: ' + ', '.join(f'{conf_name}.{mo.name}' for mo in mopts))
|
||||
a('.. code-block:: conf')
|
||||
a('')
|
||||
sz = max(len(x.name) for x in mopts)
|
||||
@ -330,7 +330,7 @@ class Mapping:
|
||||
raise ValueError(f'The shortcut for {self.name} has no short_text')
|
||||
sc_text = f'{conf_name}.{self.short_text}'
|
||||
shortcut_slugs[f'{conf_name}.{self.name}'] = (sc_text, self.key_text.replace('kitty_mod', kitty_mod))
|
||||
a('.. shortcut:: ' + sc_text)
|
||||
a(f'.. shortcut:: {sc_text}')
|
||||
block_started = False
|
||||
for sc in [self] + action_group:
|
||||
if sc.add_to_default and sc.documented:
|
||||
@ -534,7 +534,7 @@ class Group:
|
||||
ans[i] = ' '.join(parts)
|
||||
|
||||
if commented:
|
||||
ans = [x if x.startswith('#') or not x.strip() else ('# ' + x) for x in ans]
|
||||
ans = [x if x.startswith('#') or not x.strip() else (f'# {x}') for x in ans]
|
||||
|
||||
return ans
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ def atomic_save(data: bytes, path: str) -> None:
|
||||
|
||||
@contextmanager
|
||||
def cached_values_for(name: str) -> Generator[Dict[str, Any], None, None]:
|
||||
cached_path = os.path.join(cache_dir(), name + '.json')
|
||||
cached_path = os.path.join(cache_dir(), f'{name}.json')
|
||||
cached_values: Dict[str, Any] = {}
|
||||
try:
|
||||
with open(cached_path, 'rb') as f:
|
||||
|
||||
@ -29,7 +29,7 @@ def create_font_map(all_fonts: Iterable[CoreTextFont]) -> FontMap:
|
||||
ps = (x['postscript_name'] or '').lower()
|
||||
ans['family_map'].setdefault(f, []).append(x)
|
||||
ans['ps_map'].setdefault(ps, []).append(x)
|
||||
ans['full_map'].setdefault(f + ' ' + s, []).append(x)
|
||||
ans['full_map'].setdefault(f'{f} {s}', []).append(x)
|
||||
return ans
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ def list_fonts() -> Generator[ListedFont, None, None]:
|
||||
for fd in coretext_all_fonts():
|
||||
f = fd['family']
|
||||
if f:
|
||||
fn = (f + ' ' + (fd['style'] or '')).strip()
|
||||
fn = f'{f} {fd.get("style", "")}'.strip()
|
||||
is_mono = bool(fd['monospace'])
|
||||
yield {'family': f, 'full_name': fn, 'postscript_name': fd['postscript_name'] or '', 'is_monospace': is_mono}
|
||||
|
||||
|
||||
@ -58,7 +58,7 @@ def list_fonts() -> Generator[ListedFont, None, None]:
|
||||
if fn_:
|
||||
fn = str(fn_)
|
||||
else:
|
||||
fn = (f + ' ' + str(fd.get('style', ''))).strip()
|
||||
fn = f'{f} {fd.get("style", "")}'.strip()
|
||||
is_mono = fd.get('spacing') in ('MONO', 'DUAL')
|
||||
yield {'family': f, 'full_name': fn, 'postscript_name': str(fd.get('postscript_name', '')), 'is_monospace': is_mono}
|
||||
|
||||
|
||||
@ -28,13 +28,13 @@ def main(argv: Sequence[str]) -> None:
|
||||
groups = create_family_groups()
|
||||
for k in sorted(groups, key=lambda x: x.lower()):
|
||||
if isatty:
|
||||
print('\033[1;32m' + k + '\033[m')
|
||||
print(f'\033[1;32m{k}\033[m')
|
||||
else:
|
||||
print(k)
|
||||
for f in sorted(groups[k], key=lambda x: x['full_name'].lower()):
|
||||
p = f['full_name']
|
||||
if isatty:
|
||||
p = '\033[3m' + p + '\033[m'
|
||||
p = f'\033[3m{p}\033[m'
|
||||
if psnames:
|
||||
p += ' ({})'.format(f['postscript_name'])
|
||||
print(' ', p)
|
||||
|
||||
@ -515,7 +515,7 @@ def test_fallback_font(qtext: Optional[str] = None, bold: bool = False, italic:
|
||||
try:
|
||||
print(text, f)
|
||||
except UnicodeEncodeError:
|
||||
sys.stdout.buffer.write((text + ' %s\n' % f).encode('utf-8'))
|
||||
sys.stdout.buffer.write(f'{text} {f}\n'.encode('utf-8'))
|
||||
|
||||
|
||||
def showcase() -> None:
|
||||
|
||||
@ -58,7 +58,7 @@ def guess_type(path: str, allow_filesystem_access: bool = False) -> Optional[str
|
||||
ext = path.rpartition('.')[-1].lower()
|
||||
mt = known_extensions.get(ext)
|
||||
if mt in text_mimes:
|
||||
mt = 'text/' + mt.split('/', 1)[-1]
|
||||
mt = f'text/{mt.split("/", 1)[-1]}'
|
||||
if not mt and is_rc_file(path):
|
||||
mt = 'text/plain'
|
||||
if not mt and is_folder(path):
|
||||
|
||||
@ -219,7 +219,6 @@ encode_function_key(const KeyEvent *ev, char *output) {
|
||||
case GLFW_FKEY_PAGE_UP: S(5, '~');
|
||||
case GLFW_FKEY_PAGE_DOWN: S(6, '~');
|
||||
case GLFW_FKEY_HOME: S(1, 'H');
|
||||
case GLFW_FKEY_KP_BEGIN: S(1, 'E');
|
||||
case GLFW_FKEY_END: S(1, 'F');
|
||||
case GLFW_FKEY_F1: S(1, 'P');
|
||||
case GLFW_FKEY_F2: S(1, 'Q');
|
||||
@ -233,6 +232,7 @@ encode_function_key(const KeyEvent *ev, char *output) {
|
||||
case GLFW_FKEY_F10: S(21, '~');
|
||||
case GLFW_FKEY_F11: S(23, '~');
|
||||
case GLFW_FKEY_F12: S(24, '~');
|
||||
case GLFW_FKEY_KP_BEGIN: S(1, 'E');
|
||||
/* end special numbers */
|
||||
case GLFW_FKEY_MENU:
|
||||
// use the same encoding as xterm for this key in legacy mode (F16)
|
||||
|
||||
2
kitty/key_encoding.py
generated
2
kitty/key_encoding.py
generated
@ -181,7 +181,7 @@ class EventType(IntEnum):
|
||||
@lru_cache(maxsize=128)
|
||||
def parse_shortcut(spec: str) -> ParsedShortcut:
|
||||
if spec.endswith('+'):
|
||||
spec = spec[:-1] + 'plus'
|
||||
spec = f'{spec[:-1]}plus'
|
||||
parts = spec.split('+')
|
||||
key_name = parts[-1]
|
||||
key_name = functional_key_name_aliases.get(key_name.upper(), key_name)
|
||||
|
||||
@ -63,7 +63,7 @@ else:
|
||||
import ctypes
|
||||
for suffix in ('.0', ''):
|
||||
with suppress(Exception):
|
||||
lib = ctypes.CDLL('libxkbcommon.so' + suffix)
|
||||
lib = ctypes.CDLL(f'libxkbcommon.so{suffix}')
|
||||
break
|
||||
else:
|
||||
from ctypes.util import find_library
|
||||
|
||||
@ -369,7 +369,7 @@ def launch(
|
||||
if opts.stdin_add_formatting:
|
||||
if q in ('@screen', '@screen_scrollback', '@alternate', '@alternate_scrollback',
|
||||
'@first_cmd_output_on_screen', '@last_cmd_output', '@last_visited_cmd_output'):
|
||||
q = '@ansi_' + q[1:]
|
||||
q = f'@ansi_{q[1:]}'
|
||||
if opts.stdin_add_line_wrap_markers:
|
||||
q += '_wrap'
|
||||
penv, stdin = boss.process_stdin_source(window=active, stdin=q, copy_pipe_data=pipe_data)
|
||||
|
||||
@ -217,7 +217,7 @@ class Layout:
|
||||
self.blank_rects: List[Rect] = []
|
||||
self.layout_opts = self.parse_layout_opts(layout_opts)
|
||||
assert self.name is not None
|
||||
self.full_name = self.name + ((':' + layout_opts) if layout_opts else '')
|
||||
self.full_name = f'{self.name}:{layout_opts}' if layout_opts else self.name
|
||||
self.remove_all_biases()
|
||||
|
||||
def bias_increment_for_cell(self, is_horizontal: bool) -> float:
|
||||
|
||||
@ -44,7 +44,7 @@ def set_custom_ibeam_cursor() -> None:
|
||||
data = f.read()
|
||||
rgba_data, width, height = load_png_data(data)
|
||||
c2x = os.path.splitext(beam_cursor_data_file)
|
||||
with open(c2x[0] + '@2x' + c2x[1], 'rb') as f:
|
||||
with open(f'{c2x[0]}@2x{c2x[1]}', 'rb') as f:
|
||||
data = f.read()
|
||||
rgba_data2, width2, height2 = load_png_data(data)
|
||||
images = (rgba_data, width, height), (rgba_data2, width2, height2)
|
||||
@ -138,7 +138,7 @@ def get_macos_shortcut_for(
|
||||
def set_x11_window_icon() -> None:
|
||||
# max icon size on X11 64bits is 128x128
|
||||
path, ext = os.path.splitext(logo_png_file)
|
||||
set_default_window_icon(path + '-128' + ext)
|
||||
set_default_window_icon(f'{path}-128{ext}')
|
||||
|
||||
|
||||
def _run_app(opts: Options, args: CLIOptions, bad_lines: Sequence[BadLine] = ()) -> None:
|
||||
@ -220,7 +220,7 @@ def ensure_macos_locale() -> None:
|
||||
lang = 'en_US'
|
||||
else:
|
||||
log_error(f'Could not set LANG Cocoa returns language as: {lang}')
|
||||
os.environ['LANG'] = lang + '.UTF-8'
|
||||
os.environ['LANG'] = f'{lang}.UTF-8'
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
||||
@ -113,7 +113,7 @@ def parse_osc_99(raw: str) -> NotificationCommand:
|
||||
elif k == 'd':
|
||||
cmd.done = v != '0'
|
||||
elif k == 'a':
|
||||
cmd.actions += ',' + v
|
||||
cmd.actions += f',{v}'
|
||||
if payload_type not in ('body', 'title'):
|
||||
log_error(f'Malformed OSC 99: unknown payload type: {payload_type}')
|
||||
return NotificationCommand()
|
||||
@ -139,7 +139,7 @@ def limit_size(x: str) -> str:
|
||||
def merge_osc_99(prev: NotificationCommand, cmd: NotificationCommand) -> NotificationCommand:
|
||||
if prev.done or prev.identifier != cmd.identifier:
|
||||
return cmd
|
||||
cmd.actions = limit_size(prev.actions + ',' + cmd.actions)
|
||||
cmd.actions = limit_size(f'{prev.actions},{cmd.actions}')
|
||||
cmd.title = limit_size(prev.title + cmd.title)
|
||||
cmd.body = limit_size(prev.body + cmd.body)
|
||||
return cmd
|
||||
@ -198,7 +198,7 @@ def notify_with_command(cmd: NotificationCommand, window_id: int, notify_impleme
|
||||
title = cmd.title or cmd.body
|
||||
body = cmd.body if cmd.title else ''
|
||||
if title:
|
||||
identifier = 'i' + str(next(id_counter))
|
||||
identifier = f'i{next(id_counter)}'
|
||||
notify_implementation(title, body, identifier)
|
||||
register_identifier(identifier, cmd, window_id)
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ def url_matches_criterion(purl: 'ParseResult', url: str, unquoted_path: str, mc:
|
||||
path = unquoted_path.lower()
|
||||
for ext in mc.value.split(','):
|
||||
ext = ext.strip()
|
||||
if path.endswith('.' + ext):
|
||||
if path.endswith(f'.{ext}'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
@ -379,7 +379,7 @@ def parse_mods(parts: Iterable[str], sc: str) -> Optional[int]:
|
||||
mods = 0
|
||||
for m in parts:
|
||||
try:
|
||||
mods |= getattr(defines, 'GLFW_MOD_' + map_mod(m.upper()))
|
||||
mods |= getattr(defines, f'GLFW_MOD_{map_mod(m.upper())}')
|
||||
except AttributeError:
|
||||
if m.upper() != 'NONE':
|
||||
log_error(f'Shortcut: {sc} has unknown modifier, ignoring')
|
||||
@ -394,7 +394,7 @@ def to_modifiers(val: str) -> int:
|
||||
|
||||
def parse_shortcut(sc: str) -> SingleKey:
|
||||
if sc.endswith('+') and len(sc) > 1:
|
||||
sc = sc[:-1] + 'plus'
|
||||
sc = f'{sc[:-1]}plus'
|
||||
parts = sc.split('+')
|
||||
mods = 0
|
||||
if len(parts) > 1:
|
||||
@ -895,13 +895,13 @@ def resolve_aliases_and_parse_actions(
|
||||
parts = rest.split(maxsplit=1)
|
||||
if parts[0] != alias.name:
|
||||
continue
|
||||
new_defn = possible_alias + ' ' + alias.value + ((' ' + parts[1]) if len(parts) > 1 else '')
|
||||
new_defn = f'{possible_alias} {alias.value} {f" {parts[1]}" if len(parts) > 1 else ""}'
|
||||
new_aliases = aliases.copy()
|
||||
new_aliases[possible_alias] = [a for a in aliases[possible_alias] if a is not alias]
|
||||
yield from resolve_aliases_and_parse_actions(new_defn, new_aliases, map_type)
|
||||
return
|
||||
else: # action_alias
|
||||
new_defn = alias.value + ((' ' + rest) if rest else '')
|
||||
new_defn = f'{alias.value} {rest}' if rest else alias.value
|
||||
new_aliases = aliases.copy()
|
||||
new_aliases.pop(possible_alias)
|
||||
yield from resolve_aliases_and_parse_actions(new_defn, new_aliases, map_type)
|
||||
@ -909,7 +909,7 @@ def resolve_aliases_and_parse_actions(
|
||||
|
||||
if possible_alias == 'combine':
|
||||
sep, rest = rest.split(maxsplit=1)
|
||||
parts = re.split(r'\s*' + re.escape(sep) + r'\s*', rest)
|
||||
parts = re.split(fr'\s*{re.escape(sep)}\s*', rest)
|
||||
for x in parts:
|
||||
if x:
|
||||
yield from resolve_aliases_and_parse_actions(x, aliases, map_type)
|
||||
|
||||
33
kitty/parse-graphics-command.h
generated
33
kitty/parse-graphics-command.h
generated
@ -1,5 +1,4 @@
|
||||
// This file is generated by /home/kovid/work/kitty/./gen-apc-parsers.py do not
|
||||
// edit!
|
||||
// This file is generated by gen-apc-parsers.py do not edit!
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -148,9 +147,9 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
|
||||
case action: {
|
||||
g.action = screen->parser_buf[pos++] & 0xff;
|
||||
if (g.action != 'q' && g.action != 'p' && g.action != 't' &&
|
||||
g.action != 'd' && g.action != 'c' && g.action != 'a' &&
|
||||
g.action != 'T' && g.action != 'f') {
|
||||
if (g.action != 'T' && g.action != 'a' && g.action != 'c' &&
|
||||
g.action != 'd' && g.action != 'f' && g.action != 'p' &&
|
||||
g.action != 'q' && g.action != 't') {
|
||||
REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag "
|
||||
"value for action: 0x%x",
|
||||
g.action);
|
||||
@ -160,16 +159,16 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
|
||||
case delete_action: {
|
||||
g.delete_action = screen->parser_buf[pos++] & 0xff;
|
||||
if (g.delete_action != 'q' && g.delete_action != 'Q' &&
|
||||
g.delete_action != 'c' && g.delete_action != 'C' &&
|
||||
g.delete_action != 'N' && g.delete_action != 'i' &&
|
||||
g.delete_action != 'A' && g.delete_action != 'y' &&
|
||||
g.delete_action != 'a' && g.delete_action != 'I' &&
|
||||
g.delete_action != 'F' && g.delete_action != 'p' &&
|
||||
g.delete_action != 'z' && g.delete_action != 'x' &&
|
||||
g.delete_action != 'n' && g.delete_action != 'X' &&
|
||||
g.delete_action != 'Y' && g.delete_action != 'P' &&
|
||||
g.delete_action != 'Z' && g.delete_action != 'f') {
|
||||
if (g.delete_action != 'A' && g.delete_action != 'C' &&
|
||||
g.delete_action != 'F' && g.delete_action != 'I' &&
|
||||
g.delete_action != 'N' && g.delete_action != 'P' &&
|
||||
g.delete_action != 'Q' && g.delete_action != 'X' &&
|
||||
g.delete_action != 'Y' && g.delete_action != 'Z' &&
|
||||
g.delete_action != 'a' && g.delete_action != 'c' &&
|
||||
g.delete_action != 'f' && g.delete_action != 'i' &&
|
||||
g.delete_action != 'n' && g.delete_action != 'p' &&
|
||||
g.delete_action != 'q' && g.delete_action != 'x' &&
|
||||
g.delete_action != 'y' && g.delete_action != 'z') {
|
||||
REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag "
|
||||
"value for delete_action: 0x%x",
|
||||
g.delete_action);
|
||||
@ -179,8 +178,8 @@ static inline void parse_graphics_code(Screen *screen,
|
||||
|
||||
case transmission_type: {
|
||||
g.transmission_type = screen->parser_buf[pos++] & 0xff;
|
||||
if (g.transmission_type != 's' && g.transmission_type != 't' &&
|
||||
g.transmission_type != 'd' && g.transmission_type != 'f') {
|
||||
if (g.transmission_type != 'd' && g.transmission_type != 'f' &&
|
||||
g.transmission_type != 's' && g.transmission_type != 't') {
|
||||
REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag "
|
||||
"value for transmission_type: 0x%x",
|
||||
g.transmission_type);
|
||||
|
||||
@ -107,20 +107,20 @@ Do not send text to the active window, even if it is one of the matched windows.
|
||||
if '\x04' in decoded_data:
|
||||
decoded_data = decoded_data[:decoded_data.index('\x04')]
|
||||
keep_going = False
|
||||
ret['data'] = 'text:' + decoded_data
|
||||
ret['data'] = f'text:{decoded_data}'
|
||||
yield ret
|
||||
else:
|
||||
while True:
|
||||
data = sys.stdin.buffer.read(limit)
|
||||
if not data:
|
||||
break
|
||||
ret['data'] = 'base64:' + base64.standard_b64encode(data).decode('ascii')
|
||||
ret['data'] = f'base64:{base64.standard_b64encode(data).decode("ascii")}'
|
||||
yield ret
|
||||
|
||||
def chunks(text: str) -> CmdGenerator:
|
||||
data = parse_send_text_bytes(text).decode('utf-8')
|
||||
while data:
|
||||
ret['data'] = 'text:' + data[:limit]
|
||||
ret['data'] = f'text:{data[:limit]}'
|
||||
yield ret
|
||||
data = data[limit:]
|
||||
|
||||
@ -130,7 +130,7 @@ Do not send text to the active window, even if it is one of the matched windows.
|
||||
data = f.read(limit)
|
||||
if not data:
|
||||
break
|
||||
ret['data'] = 'base64:' + base64.standard_b64encode(data).decode('ascii')
|
||||
ret['data'] = f'base64:{base64.standard_b64encode(data).decode("ascii")}'
|
||||
yield ret
|
||||
|
||||
sources = []
|
||||
|
||||
2
kitty/rgb.py
generated
2
kitty/rgb.py
generated
@ -28,7 +28,7 @@ def parse_single_color(c: str) -> int:
|
||||
def parse_sharp(spec: str) -> Optional[Color]:
|
||||
if len(spec) in (3, 6, 9, 12):
|
||||
part_len = len(spec) // 3
|
||||
colors = re.findall(r'[a-fA-F0-9]{%d}' % part_len, spec)
|
||||
colors = re.findall(fr'[a-fA-F0-9]{{{part_len}}}', spec)
|
||||
return Color(*map(parse_single_color, colors))
|
||||
return None
|
||||
|
||||
|
||||
@ -221,7 +221,7 @@ def real_main(global_opts: RCOptions) -> None:
|
||||
if e.code != 0:
|
||||
print(end=output_prefix, flush=True)
|
||||
print_err(e)
|
||||
print_err('Use "{}" to see how to use this command.'.format(emph('help ' + cmd)))
|
||||
print_err('Use "{}" to see how to use this command.'.format(emph(f'help {cmd}')))
|
||||
continue
|
||||
except Exception:
|
||||
print(end=output_prefix, flush=True)
|
||||
|
||||
@ -102,14 +102,14 @@ class ColorFormatter:
|
||||
ans = '9'
|
||||
elif q == 'tab':
|
||||
col = color_from_int((self.draw_data.tab_bg if self.which == '4' else self.draw_data.tab_fg)(self.tab_data))
|
||||
ans = '8' + color_as_sgr(col)
|
||||
ans = f'8{color_as_sgr(col)}'
|
||||
else:
|
||||
if name.startswith('_'):
|
||||
q = '#' + name[1:]
|
||||
q = f'#{name[1:]}'
|
||||
c = to_color(q)
|
||||
if c is None:
|
||||
raise AttributeError(f'{name} is not a valid color')
|
||||
ans = '8' + color_as_sgr(c)
|
||||
ans = f'8{color_as_sgr(c)}'
|
||||
return f'\x1b[{self.which}{ans}m'
|
||||
|
||||
|
||||
|
||||
@ -471,8 +471,8 @@ def get_capabilities(query_string: str, opts: 'Options') -> Generator[str, None,
|
||||
|
||||
def result(encoded_query_name: str, x: Optional[str] = None) -> str:
|
||||
if x is None:
|
||||
return '0+r' + encoded_query_name
|
||||
return '1+r' + encoded_query_name + '=' + hexlify(str(x).encode('utf-8')).decode('ascii')
|
||||
return f'0+r{encoded_query_name}'
|
||||
return f'1+r{encoded_query_name}={hexlify(str(x).encode("utf-8")).decode("ascii")}'
|
||||
|
||||
for encoded_query_name in query_string.split(';'):
|
||||
name = qname = unhexlify(encoded_query_name).decode('utf-8')
|
||||
|
||||
35
publish.py
35
publish.py
@ -40,7 +40,7 @@ def echo_cmd(cmd: Iterable[str]) -> None:
|
||||
isatty = sys.stdout.isatty()
|
||||
end = '\n'
|
||||
if isatty:
|
||||
end = '\x1b[m' + end
|
||||
end = f'\x1b[m{end}'
|
||||
print('\x1b[92m', end='')
|
||||
print(shlex.join(cmd), end=end, flush=True)
|
||||
|
||||
@ -146,11 +146,11 @@ def run_website(args: Any) -> None:
|
||||
|
||||
|
||||
def sign_file(path: str) -> None:
|
||||
dest = path + '.sig'
|
||||
dest = f'{path}.sig'
|
||||
with suppress(FileNotFoundError):
|
||||
os.remove(dest)
|
||||
subprocess.check_call([
|
||||
os.environ['PENV'] + '/gpg-as-kovid', '--output', path + '.sig',
|
||||
os.environ['PENV'] + '/gpg-as-kovid', '--output', f'{path}.sig',
|
||||
'--detach-sig', path
|
||||
])
|
||||
|
||||
@ -159,7 +159,7 @@ def run_sdist(args: Any) -> None:
|
||||
with tempfile.TemporaryDirectory() as tdir:
|
||||
base = os.path.join(tdir, f'kitty-{version}')
|
||||
os.mkdir(base)
|
||||
subprocess.check_call('git archive HEAD | tar -x -C ' + base, shell=True)
|
||||
subprocess.check_call(f'git archive HEAD | tar -x -C {base}', shell=True)
|
||||
dest = os.path.join(base, 'docs', '_build')
|
||||
os.mkdir(dest)
|
||||
for x in 'html man'.split():
|
||||
@ -167,9 +167,9 @@ def run_sdist(args: Any) -> None:
|
||||
dest = os.path.abspath(os.path.join('build', f'kitty-{version}.tar'))
|
||||
subprocess.check_call(['tar', '-cf', dest, os.path.basename(base)], cwd=tdir)
|
||||
with suppress(FileNotFoundError):
|
||||
os.remove(dest + '.xz')
|
||||
os.remove(f'{dest}.xz')
|
||||
subprocess.check_call(['xz', '-9', dest])
|
||||
sign_file(dest + '.xz')
|
||||
sign_file(f'{dest}.xz')
|
||||
|
||||
|
||||
class ReadFileWithProgressReporting(io.FileIO): # {{{
|
||||
@ -231,7 +231,7 @@ class Base: # {{{
|
||||
|
||||
class GitHub(Base): # {{{
|
||||
|
||||
API = 'https://api.github.com/'
|
||||
API = 'https://api.github.com'
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@ -244,12 +244,12 @@ class GitHub(Base): # {{{
|
||||
):
|
||||
self.files, self.reponame, self.version, self.username, self.password, self.replace = (
|
||||
files, reponame, version, username, password, replace)
|
||||
self.current_tag_name = self.version if self.version == 'nightly' else ('v' + self.version)
|
||||
self.current_tag_name = self.version if self.version == 'nightly' else f'v{self.version}'
|
||||
self.is_nightly = self.current_tag_name == 'nightly'
|
||||
self.requests = s = requests.Session()
|
||||
s.auth = (self.username, self.password)
|
||||
s.headers.update({'Accept': 'application/vnd.github.v3+json'})
|
||||
self.url_base = f'{self.API}repos/{self.username}/{self.reponame}/releases/'
|
||||
self.url_base = f'{self.API}/repos/{self.username}/{self.reponame}/releases'
|
||||
|
||||
def patch(self, url: str, fail_msg: str, **data: Any) -> None:
|
||||
rdata = json.dumps(data)
|
||||
@ -262,7 +262,7 @@ class GitHub(Base): # {{{
|
||||
self.fail(r, fail_msg)
|
||||
|
||||
def update_nightly_description(self, release_id: int) -> None:
|
||||
url = self.url_base + str(release_id)
|
||||
url = f'{self.url_base}/{release_id}'
|
||||
now = str(datetime.datetime.utcnow()).split('.')[0] + ' UTC'
|
||||
with open('.git/refs/heads/master') as f:
|
||||
commit = f.read().strip()
|
||||
@ -276,7 +276,7 @@ class GitHub(Base): # {{{
|
||||
# self.clean_older_releases(releases)
|
||||
release = self.create_release()
|
||||
upload_url = release['upload_url'].partition('{')[0]
|
||||
asset_url = self.url_base + 'assets/{}'
|
||||
asset_url = f'{self.url_base}/assets/{{}}'
|
||||
existing_assets = self.existing_assets(release['id'])
|
||||
if self.is_nightly:
|
||||
for fname in existing_assets:
|
||||
@ -308,7 +308,7 @@ class GitHub(Base): # {{{
|
||||
self.info(f'\nDeleting old released installers from: {release["tag_name"]}')
|
||||
for asset in release['assets']:
|
||||
r = self.requests.delete(
|
||||
f'{self.API}repos/{self.username}/{self.reponame}/releases/assets/{asset["id"]}')
|
||||
f'{self.url_base}/assets/{asset["id"]}')
|
||||
if r.status_code != 204:
|
||||
self.fail(r, f'Failed to delete obsolete asset: {asset["name"]} for release: {release["tag_name"]}')
|
||||
|
||||
@ -336,7 +336,7 @@ class GitHub(Base): # {{{
|
||||
return bool(error_code == 'already_exists')
|
||||
|
||||
def existing_assets(self, release_id: str) -> Dict[str, str]:
|
||||
url = f'{self.API}repos/{self.username}/{self.reponame}/releases/{release_id}/assets'
|
||||
url = f'{self.url_base}/{release_id}/assets'
|
||||
r = self.requests.get(url)
|
||||
if r.status_code != 200:
|
||||
self.fail(r, 'Failed to get assets for release')
|
||||
@ -345,15 +345,14 @@ class GitHub(Base): # {{{
|
||||
def create_release(self) -> Dict[str, Any]:
|
||||
' Create a release on GitHub or if it already exists, return the existing release '
|
||||
# Check for existing release
|
||||
url = f'{self.API}repos/{self.username}/{self.reponame}/releases/tags/{self.current_tag_name}'
|
||||
url = f'{self.url_base}/tags/{self.current_tag_name}'
|
||||
r = self.requests.get(url)
|
||||
if r.status_code == 200:
|
||||
return dict(r.json())
|
||||
if self.is_nightly:
|
||||
raise SystemExit('No existing nightly release found on GitHub')
|
||||
url = f'{self.API}repos/{self.username}/{self.reponame}/releases'
|
||||
r = self.requests.post(
|
||||
url,
|
||||
self.url_base,
|
||||
data=json.dumps({
|
||||
'tag_name': self.current_tag_name,
|
||||
'target_commitish': 'master',
|
||||
@ -394,7 +393,7 @@ def files_for_upload() -> Dict[str, str]:
|
||||
files[f'build/kitty-{version}.tar.xz.sig'] = 'Source code GPG signature'
|
||||
for path, desc in signatures.items():
|
||||
sign_file(path)
|
||||
files[path + '.sig'] = desc
|
||||
files[f'{path}.sig'] = desc
|
||||
for f in files:
|
||||
if not os.path.exists(f):
|
||||
raise SystemExit(f'The release artifact {f} does not exist')
|
||||
@ -460,7 +459,7 @@ def exec_actions(actions: Iterable[str], args: Any) -> None:
|
||||
for action in actions:
|
||||
print('Running', action)
|
||||
cwd = os.getcwd()
|
||||
globals()['run_' + action](args)
|
||||
globals()[f'run_{action}'](args)
|
||||
os.chdir(cwd)
|
||||
|
||||
|
||||
|
||||
4
setup.py
4
setup.py
@ -710,7 +710,7 @@ def compile_c_extension(
|
||||
def on_success() -> None:
|
||||
os.rename(dest, real_dest)
|
||||
|
||||
compilation_database.add_command(desc, cmd, partial(newer, real_dest, *objects), on_success=on_success, key=CompileKey('', module + '.so'))
|
||||
compilation_database.add_command(desc, cmd, partial(newer, real_dest, *objects), on_success=on_success, key=CompileKey('', f'{module}.so'))
|
||||
|
||||
|
||||
def find_c_files() -> Tuple[List[str], List[str]]:
|
||||
@ -1112,7 +1112,7 @@ def create_macos_app_icon(where: str = 'Resources') -> None:
|
||||
'iconutil', '-c', 'icns', iconset_dir, '-o', icns_dir
|
||||
])
|
||||
except FileNotFoundError:
|
||||
print(error('iconutil not found') + ', using png2icns (without retina support) to convert the logo', file=sys.stderr)
|
||||
print(f'{error("iconutil not found")}, using png2icns (without retina support) to convert the logo', file=sys.stderr)
|
||||
subprocess.check_call([
|
||||
'png2icns', icns_dir
|
||||
] + [os.path.join(iconset_dir, logo) for logo in [
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user