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