Make kitty --version fast

It's now approx 3ms on my system and 1.23 times faster than alacritty
--version
This commit is contained in:
Kovid Goyal 2024-06-22 12:27:29 +05:30
parent ad328bfeaa
commit 581db0ab7a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 79 additions and 1 deletions

View File

@ -249,7 +249,7 @@ get_docs_ref_map(PyObject *self UNUSED, PyObject *args UNUSED) {
static PyObject*
wrapped_kittens(PyObject *self UNUSED, PyObject *args UNUSED) {
const char *wrapped_kitten_names = WRAPPED_KITTENS;
static const char *wrapped_kitten_names = WRAPPED_KITTENS;
PyObject *ans = PyUnicode_FromString(wrapped_kitten_names);
if (ans == NULL) return NULL;
PyObject *s = PyUnicode_Split(ans, NULL, -1);

View File

@ -356,6 +356,57 @@ delegate_to_kitten_if_possible(int argc, char *argv[], char* exe_dir) {
if (argc > 3 && strcmp(argv[1], "+") == 0 && strcmp(argv[2], "kitten") == 0 && is_wrapped_kitten(argv[3])) exec_kitten(argc - 2, argv + 2, exe_dir);
}
static bool
is_boolean_flag(const char *x) {
static const char *all_boolean_options = KITTY_CLI_BOOL_OPTIONS;
char buf[128];
snprintf(buf, sizeof(buf), " %s ", x);
return strstr(all_boolean_options, buf) != NULL;
}
static void
handle_fast_commandline(int argc, char *argv[]) {
char current_option_expecting_argument[128] = {0};
bool version_requested = false;
for (int i = 1; i < argc; i++) {
const char *arg = argv[i];
if (current_option_expecting_argument[0]) {
current_option_expecting_argument[0] = 0;
} else {
if (!arg || !arg[0] || !arg[1] || arg[0] != '-' || strcmp(arg, "--") == 0) break;
if (arg[1] == '-') { // long opt
const char *equal = strchr(arg, '=');
if (equal == NULL) {
if (strcmp(arg+2, "version") == 0) {
version_requested = true;
} else if (!is_boolean_flag(arg+2)) {
strncpy(current_option_expecting_argument, arg+2, sizeof(current_option_expecting_argument)-1);
}
}
} else {
char buf[2] = {0};
for (int i = 1; arg[i] != 0; i++) {
switch(arg[i]) {
case 'v': version_requested = true; break;
default:
buf[0] = arg[i]; buf[1] = 0;
if (!is_boolean_flag(buf)) { current_option_expecting_argument[0] = arg[i]; current_option_expecting_argument[1] = 0; }
}
}
}
}
}
if (version_requested) {
if (isatty(STDOUT_FILENO)) {
printf("\x1b[3mkitty\x1b[23m \x1b[32m%s\x1b[39m created by \x1b[1;34mKovid Goyal\x1b[22;39m\n", KITTY_VERSION);
} else {
printf("kitty %s created by Kovid Goyal\n", KITTY_VERSION);
}
exit(0);
}
}
int main(int argc, char *argv[], char* envp[]) {
if (argc < 1 || !argv) { fprintf(stderr, "Invalid argc/argv\n"); return 1; }
if (!ensure_working_stdio()) return 1;
@ -370,6 +421,7 @@ int main(int argc, char *argv[], char* envp[]) {
strncpy(exe_dir_buf, exe, sizeof(exe_dir_buf));
char *exe_dir = dirname(exe_dir_buf);
delegate_to_kitten_if_possible(argc, argv, exe_dir);
handle_fast_commandline(argc, argv);
int num, ret=0;
char lib[PATH_MAX+1] = {0};
if (KITTY_LIB_PATH[0] == '/') {

View File

@ -1203,6 +1203,30 @@ def build_static_binaries(args: Options, launcher_dir: str) -> None:
build_static_kittens(args, launcher_dir, args.dir_for_static_binaries, for_platform=(os_, arch))
@lru_cache(2)
def kitty_cli_boolean_options() -> Tuple[str, ...]:
with open(os.path.join(src_base, 'kitty/cli.py')) as f:
raw = f.read()
m = re.search(r"^\s*OPTIONS = '''(.+?)'''", raw, flags=re.MULTILINE | re.DOTALL)
assert m is not None
ans: List[str] = []
in_option: List[str] = []
prev_line_was_blank = False
for line in m.group(1).splitlines():
if in_option:
is_blank = not line.strip()
if is_blank:
if prev_line_was_blank:
in_option = []
prev_line_was_blank = is_blank
if line.startswith('type=bool-'):
ans.extend(x.lstrip('-') for x in in_option)
else:
if line.startswith('-'):
in_option = line.strip().split()
return tuple(ans)
def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 'source') -> None:
werror = '' if args.ignore_compiler_warnings else '-pedantic-errors -Werror'
cflags = f'-Wall {werror} -fpie'.split()
@ -1260,6 +1284,8 @@ def build_launcher(args: Options, launcher_dir: str = '.', bundle_type: str = 's
os.makedirs(launcher_dir, exist_ok=True)
os.makedirs(build_dir, exist_ok=True)
objects = []
cppflags.append('-DKITTY_CLI_BOOL_OPTIONS=" ' + ' '.join(kitty_cli_boolean_options()) + ' "')
cppflags.append('-DKITTY_VERSION="' + '.'.join(map(str, version)) + '"')
for src in ('kitty/launcher/main.c',):
obj = os.path.join(build_dir, src.replace('/', '-').replace('.c', '.o'))
objects.append(obj)