diff --git a/bold_is_bright.patch b/bold_is_bright.patch new file mode 100644 index 0000000..4a95081 --- /dev/null +++ b/bold_is_bright.patch @@ -0,0 +1,849 @@ +diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml +index c64877153..ed2930008 100644 +--- a/.github/FUNDING.yml ++++ b/.github/FUNDING.yml +@@ -1,4 +1,2 @@ +-github: kovidgoyal +-patreon: kovidgoyal +-liberapay: kovidgoyal ++custom: https://my.fsf.org/donate + custom: https://sw.kovidgoyal.net/kitty/support.html +diff --git a/README.asciidoc b/README.asciidoc +deleted file mode 100644 +index 5a24555ee..000000000 +--- a/README.asciidoc ++++ /dev/null +@@ -1,14 +0,0 @@ +-= kitty - the fast, feature-rich, cross-platform, GPU based terminal +- +-See https://sw.kovidgoyal.net/kitty/[the kitty website]. +- +-image:https://github.com/kovidgoyal/kitty/workflows/CI/badge.svg["Build status", link="https://github.com/kovidgoyal/kitty/actions?query=workflow%3ACI"] +- +-https://sw.kovidgoyal.net/kitty/faq/[Frequently Asked Questions] +- +-To ask other questions about kitty usage, use either the https://github.com/kovidgoyal/kitty/discussions/[discussions on GitHub] or the +-https://www.reddit.com/r/KittyTerminal[Reddit community] +- +-Packaging status in various repositories: +- +-image:https://repology.org/badge/vertical-allrepos/kitty.svg["Packaging status", link="https://repology.org/project/kitty/versions"] +diff --git a/README.md b/README.md +new file mode 100644 +index 000000000..d02f48469 +--- /dev/null ++++ b/README.md +@@ -0,0 +1,49 @@ ++

++kittypatch-logo ++ ++KittyPatch ++ ++ ++forked from kitty ++ ++

++ ++

++
++A blazingly fast GPU based terminal emulator. ++

++ ++

++(With added extras) ++

++ ++ ++--- ++ ++ ++ ++ ++ ++ ++ ++ ++

++Sneak Peek ↓ ++

++ ++

++
++KittyPatch adds the bold_is_bright config option, which kitty does not and will likely never support! ++

++ ++--- ++ ++

++Instructions ↓ ++

++
++ ++

++For now, you'll need to build the latest master branch from source.
++
++

+diff --git a/current-version.txt b/current-version.txt +new file mode 100644 +index 000000000..918820be2 +--- /dev/null ++++ b/current-version.txt +@@ -0,0 +1 @@ ++0.19.3 +\ No newline at end of file +diff --git a/docs/binary.rst b/docs/binary.rst +index 4b60736fe..1d8c4a667 100644 +--- a/docs/binary.rst ++++ b/docs/binary.rst +@@ -31,7 +31,7 @@ Manually installing + + If something goes wrong or you simply do not want to run the installer, you can + manually download and install |kitty| from the `GitHub releases page +-`__. If you are on macOS, download ++`__. If you are on macOS, download + the :file:`.dmg` and install as normal. If you are on Linux, download the + tarball and extract it into a directory. The |kitty| executable will be in the + :file:`bin` sub-directory. +diff --git a/docs/build.rst b/docs/build.rst +index 6f515ea81..fcf25a94e 100644 +--- a/docs/build.rst ++++ b/docs/build.rst +@@ -1,9 +1,9 @@ + Build from source + ================== + +-.. image:: https://github.com/kovidgoyal/kitty/workflows/CI/badge.svg ++.. image:: https://github.com/KittyPatch/kitty/workflows/CI/badge.svg + :alt: Build status +- :target: https://github.com/kovidgoyal/kitty/actions?query=workflow%3ACI ++ :target: https://github.com/KittyPatch/kitty/actions?query=workflow%3ACI + + .. highlight:: sh + +@@ -154,7 +154,7 @@ Notes for Linux/macOS packagers + ---------------------------------- + + The released |kitty| source code is available as a `tarball`_ from +-`the GitHub releases page `__. ++`the GitHub releases page `__. + + While |kitty| does use Python, it is not a traditional Python package, so please + do not install it in site-packages. +diff --git a/docs/conf.py b/docs/conf.py +index 721ce7d60..ac1a6c78e 100644 +--- a/docs/conf.py ++++ b/docs/conf.py +@@ -33,8 +33,8 @@ + # -- Project information ----------------------------------------------------- + + project = 'kitty' +-copyright = time.strftime('%Y, Kovid Goyal') +-author = 'Kovid Goyal' ++copyright = time.strftime('%Y, Kovid Goyal, KittyPatch') ++author = 'Kovid Goyal, KittyPatch' + building_man_pages = 'man' in sys.argv + + # The short X.Y version +@@ -100,7 +100,7 @@ + rst_prolog = ''' + .. |kitty| replace:: *kitty* + .. |version| replace:: VERSION +-.. _tarball: https://github.com/kovidgoyal/kitty/releases/download/vVERSION/kitty-VERSION.tar.xz ++.. _tarball: https://github.com/KittyPatch/kitty/releases/download/vVERSION/kitty-VERSION.tar.xz + .. role:: italic + + '''.replace('VERSION', str_version) +@@ -215,7 +215,7 @@ def commit_role( + f'GitHub commit id "{text}" not recognized.', line=lineno) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] +- url = f'https://github.com/kovidgoyal/kitty/commit/{commit_id}' ++ url = f'https://github.com/KittyPatch/kitty/commit/{commit_id}' + set_classes(options) + short_id = subprocess.check_output( + f'git rev-list --max-count=1 --abbrev-commit --skip=# {commit_id}'.split()).decode('utf-8').strip() +diff --git a/docs/support.rst b/docs/support.rst +index 373714812..c0ff06981 100644 +--- a/docs/support.rst ++++ b/docs/support.rst +@@ -1,5 +1,21 @@ ++A message from us at KittyPatch ++=============================== ++ ++KittyPatch was created as a home for useful features that are unavailable ++in the kitty main branch. To this end, we do not accept donations directly. ++ ++If you wish to support KittyPatch: share your ideas and spread the word. ++ ++If you still wish to donate, please `support the Free Software Foundation ++`. ++ ++ ++ ++A message from the maintainer of Kitty ++====================================== + Support kitty development ❤️ + ============================== ++>>>>>>> upstream/master + + My goal with |kitty| is to move the stagnant terminal ecosystem forward. To that + end kitty has many foundational features, such as: :doc:`image support +diff --git a/kitty/cell_vertex.glsl b/kitty/cell_vertex.glsl +index 0eda08295..aa84d4d7a 100644 +--- a/kitty/cell_vertex.glsl ++++ b/kitty/cell_vertex.glsl +@@ -3,6 +3,7 @@ + + #define {WHICH_PROGRAM} + #define NOT_TRANSPARENT ++#define BOLD_SHIFT {BOLD_SHIFT} + #define DECORATION_SHIFT {DECORATION_SHIFT} + #define REVERSE_SHIFT {REVERSE_SHIFT} + #define STRIKE_SHIFT {STRIKE_SHIFT} +@@ -17,6 +18,7 @@ layout(std140) uniform CellRenderData { + float xstart, ystart, dx, dy, sprite_dx, sprite_dy, background_opacity, use_cell_bg_for_selection_fg, use_cell_fg_for_selection_fg, use_cell_for_selection_bg; + + uint default_fg, default_bg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted; ++ uint bold_is_bright; + + uint xnum, ynum, cursor_fg_sprite_idx; + float cursor_x, cursor_y, cursor_w; +@@ -93,6 +95,22 @@ vec3 color_to_vec(uint c) { + return vec3(gamma_lut[r], gamma_lut[g], gamma_lut[b]); + } + ++uint byte_to_bool(uint n) { ++ uint n1 = (n >> 1) | n; ++ uint n2 = (n1 >> 2) | n1; ++ uint n3 = (n2 >> 4) | n2; ++ return n3 & 1u; ++} ++ ++uint brighten_color(uint c, uint is_bold) { ++ uint table_idx = (c >> 8) & 0xFFu; ++ uint is_table_color = c & 1u; ++ uint is_rgb_color = byte_to_bool(c & 0xFEu); ++ uint is_8bit_color = byte_to_bool(table_idx & 0xF8u); ++ uint should_brighten = bold_is_bright * is_bold * (1u >> (is_rgb_color + is_8bit_color)) * is_table_color; ++ return c | (0x800u * should_brighten); ++} ++ + uint resolve_color(uint c, uint defval) { + // Convert a cell color to an actual color based on the color table + int t = int(c & BYTE_MASK); +@@ -161,6 +179,7 @@ void main() { + // set cell color indices {{{ + uvec2 default_colors = uvec2(default_fg, default_bg); + uint text_attrs = sprite_coords[3]; ++ uint is_bold = ((text_attrs >> BOLD_SHIFT) & ONE); + uint is_reversed = ((text_attrs >> REVERSE_SHIFT) & ONE); + uint is_inverted = is_reversed + inverted; + int fg_index = fg_index_map[is_inverted]; +@@ -170,10 +189,10 @@ void main() { + float cell_has_block_cursor = cell_has_cursor * is_block_cursor; + int mark = int(text_attrs >> MARK_SHIFT) & MARK_MASK; + uint has_mark = uint(step(1, float(mark))); +- uint bg_as_uint = resolve_color(colors[bg_index], default_colors[bg_index]); ++ uint bg_as_uint = resolve_color(brighten_color(colors[bg_index], is_bold), default_colors[bg_index]); + bg_as_uint = has_mark * color_table[NUM_COLORS + mark] + (ONE - has_mark) * bg_as_uint; + vec3 bg = color_to_vec(bg_as_uint); +- uint fg_as_uint = resolve_color(colors[fg_index], default_colors[fg_index]); ++ uint fg_as_uint = resolve_color(brighten_color(colors[fg_index], is_bold), default_colors[fg_index]); + // }}} + + // Foreground {{{ +diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi +index 5d0b39bea..c4253a4b6 100644 +--- a/kitty/fast_data_types.pyi ++++ b/kitty/fast_data_types.pyi +@@ -265,6 +265,7 @@ CELL_FG_PROGRAM: int + CELL_PROGRAM: int + CELL_SPECIAL_PROGRAM: int + CSI: int ++BOLD: int + DCS: int + DECORATION: int + DIM: int +diff --git a/kitty/options/definition.py b/kitty/options/definition.py +index 4a80eadb4..17e003dc2 100644 +--- a/kitty/options/definition.py ++++ b/kitty/options/definition.py +@@ -1328,6 +1328,10 @@ + ) + egr() # }}} + ++opt('bold_is_bright', 'no', ++ option_type='to_bool', ctype='bool', ++ long_text='Display bold text with bright colors' ++ ) + + # colors {{{ + agr('colors', 'Color scheme') +diff --git a/kitty/options/parse.py b/kitty/options/parse.py +index d4a607f15..1ce4bfe5a 100644 +--- a/kitty/options/parse.py ++++ b/kitty/options/parse.py +@@ -100,6 +100,9 @@ def bell_path(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + def bold_font(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['bold_font'] = str(val) + ++ def bold_is_bright(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ++ ans['bold_is_bright'] = to_bool(val) ++ + def bold_italic_font(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + ans['bold_italic_font'] = str(val) + +diff --git a/kitty/options/to-c-generated.h b/kitty/options/to-c-generated.h +index c1ea350a2..249ea38e9 100644 +--- a/kitty/options/to-c-generated.h ++++ b/kitty/options/to-c-generated.h +@@ -837,6 +837,19 @@ convert_from_opts_dim_opacity(PyObject *py_opts, Options *opts) { + Py_DECREF(ret); + } + ++static void ++convert_from_python_bold_is_bright(PyObject *val, Options *opts) { ++ opts->bold_is_bright = PyObject_IsTrue(val); ++} ++ ++static void ++convert_from_opts_bold_is_bright(PyObject *py_opts, Options *opts) { ++ PyObject *ret = PyObject_GetAttrString(py_opts, "bold_is_bright"); ++ if (ret == NULL) return; ++ convert_from_python_bold_is_bright(ret, opts); ++ Py_DECREF(ret); ++} ++ + static void + convert_from_python_mark1_foreground(PyObject *val, Options *opts) { + opts->mark1_foreground = color_as_int(val); +@@ -1188,6 +1201,8 @@ convert_opts_from_python_opts(PyObject *py_opts, Options *opts) { + if (PyErr_Occurred()) return false; + convert_from_opts_dim_opacity(py_opts, opts); + if (PyErr_Occurred()) return false; ++ convert_from_opts_bold_is_bright(py_opts, opts); ++ if (PyErr_Occurred()) return false; + convert_from_opts_mark1_foreground(py_opts, opts); + if (PyErr_Occurred()) return false; + convert_from_opts_mark1_background(py_opts, opts); +diff --git a/kitty/options/types.py b/kitty/options/types.py +index dde02d82f..3ab3b0c65 100644 +--- a/kitty/options/types.py ++++ b/kitty/options/types.py +@@ -71,6 +71,7 @@ + 'bell_on_tab', + 'bell_path', + 'bold_font', ++ 'bold_is_bright', + 'bold_italic_font', + 'box_drawing_scale', + 'clear_all_mouse_actions', +@@ -490,6 +491,7 @@ class Options: + bell_on_tab: str = '🔔 ' + bell_path: typing.Optional[str] = None + bold_font: str = 'auto' ++ bold_is_bright: bool = False + bold_italic_font: str = 'auto' + box_drawing_scale: typing.Tuple[float, float, float, float] = (0.001, 1.0, 1.5, 2.0) + clear_all_mouse_actions: bool = False +diff --git a/kitty/shaders.c b/kitty/shaders.c +index b5e86f479..cd0062975 100644 +--- a/kitty/shaders.c ++++ b/kitty/shaders.c +@@ -303,6 +303,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c + GLfloat xstart, ystart, dx, dy, sprite_dx, sprite_dy, background_opacity, use_cell_bg_for_selection_fg, use_cell_fg_for_selection_color, use_cell_for_selection_bg; + + GLuint default_fg, default_bg, highlight_fg, highlight_bg, cursor_fg, cursor_bg, url_color, url_style, inverted; ++ GLuint bold_is_bright; + + GLuint xnum, ynum, cursor_fg_sprite_idx; + GLfloat cursor_x, cursor_y, cursor_w; +@@ -374,6 +375,7 @@ cell_update_uniform_block(ssize_t vao_idx, Screen *screen, int uniform_buffer, c + rd->sprite_dx = 1.0f / (float)x; rd->sprite_dy = 1.0f / (float)y; + rd->inverted = inverted ? 1 : 0; + rd->background_opacity = os_window->is_semi_transparent ? os_window->background_opacity : 1.0f; ++ rd->bold_is_bright = OPT(bold_is_bright) ? 1 : 0; + + #undef COLOR + rd->url_color = OPT(url_color); rd->url_style = OPT(url_style); +diff --git a/kitty/state.c b/kitty/state.c +index d06767266..f08b8bd3e 100644 +--- a/kitty/state.c ++++ b/kitty/state.c +@@ -1130,6 +1130,7 @@ PYWRAP1(patch_global_colors) { + P(background); P(url_color); + P(mark1_background); P(mark1_foreground); P(mark2_background); P(mark2_foreground); + P(mark3_background); P(mark3_foreground); ++ P(bold_is_bright); + } + if (PyErr_Occurred()) return NULL; + Py_RETURN_NONE; +diff --git a/kitty/state.h b/kitty/state.h +index 454aa90d0..7353f5197 100644 +--- a/kitty/state.h ++++ b/kitty/state.h +@@ -39,6 +39,7 @@ typedef struct { + char_type *select_by_word_characters_forward; + color_type url_color, background, foreground, active_border_color, inactive_border_color, bell_border_color, tab_bar_background, tab_bar_margin_color; + color_type mark1_foreground, mark1_background, mark2_foreground, mark2_background, mark3_foreground, mark3_background; ++ bool bold_is_bright; + monotonic_t repaint_delay, input_delay; + bool focus_follows_mouse; + unsigned int hide_window_decorations; +diff --git a/kitty/window.py b/kitty/window.py +index 959931877..b2017423a 100644 +--- a/kitty/window.py ++++ b/kitty/window.py +@@ -44,6 +44,7 @@ + from .fast_data_types import ( + BGIMAGE_PROGRAM, + BLIT_PROGRAM, ++ BOLD, + CELL_BG_PROGRAM, + CELL_FG_PROGRAM, + CELL_PROGRAM, +@@ -392,6 +393,7 @@ def __call__(self, semi_transparent: bool = False) -> None: + STRIKE_SHIFT=STRIKETHROUGH, + DIM_SHIFT=DIM, + DECORATION_SHIFT=DECORATION, ++ BOLD_SHIFT=BOLD, + MARK_SHIFT=MARK, + MARK_MASK=MARK_MASK, + DECORATION_MASK=DECORATION_MASK, +diff --git a/logo/kitty-framed.svg b/logo/kitty-framed.svg +index 310ea8a29..461f08320 100644 +--- a/logo/kitty-framed.svg ++++ b/logo/kitty-framed.svg +@@ -1 +1,195 @@ +- +\ No newline at end of file ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/logo/kitty.svg b/logo/kitty.svg +index dc4b6e42c..32d06f031 100644 +--- a/logo/kitty.svg ++++ b/logo/kitty.svg +@@ -1 +1,206 @@ +- +\ No newline at end of file ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ image/svg+xml ++ ++ ++ ++ ++ Kovid Goyal ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/publish.py b/publish.py +index 20e082760..f555246be 100755 +--- a/publish.py ++++ b/publish.py +@@ -25,7 +25,7 @@ + + os.chdir(os.path.dirname(os.path.abspath(__file__))) + docs_dir = os.path.abspath('docs') +-publish_dir = os.path.abspath(os.path.join('..', 'kovidgoyal.github.io', 'kitty')) ++publish_dir = os.path.abspath(os.path.join('..', 'kittypatch.github.io', 'kitty')) + building_nightly = False + with open('kitty/constants.py') as f: + raw = f.read() +@@ -101,7 +101,7 @@ def run_man(args: Any) -> None: + + + def run_html(args: Any) -> None: +- call('make FAIL_WARN=1 "OPTS=-D analytics_id=G-XTJK3R7GF2" dirhtml', cwd=docs_dir) ++ call('make FAIL_WARN=1 "OPTS=-D analytics_id=UA-XXXXXXXX-X" dirhtml', cwd=docs_dir) + add_old_redirects('docs/_build/dirhtml') + + diff --git a/disable-test_ssh_bootstrap_with_different_launchers.patch b/disable-test_ssh_bootstrap_with_different_launchers.patch new file mode 100644 index 0000000..584815b --- /dev/null +++ b/disable-test_ssh_bootstrap_with_different_launchers.patch @@ -0,0 +1,13 @@ +diff --git a/kitty_tests/ssh.py b/kitty_tests/ssh.py +index 1f424146..d3cc191b 100644 +--- a/kitty_tests/ssh.py ++++ b/kitty_tests/ssh.py +@@ -166,7 +166,7 @@ def test_ssh_bootstrap_with_different_launchers(self): + for sh in self.all_possible_sh: + if sh == 'sh' or 'python' in sh: + q = shutil.which(launcher) +- if q: ++ if q and not 'zsh' in q: + with self.subTest(sh=sh, launcher=q), tempfile.TemporaryDirectory() as tdir: + self.check_bootstrap(sh, tdir, test_script='env; exit 0', SHELL_INTEGRATION_VALUE='', launcher=q) + diff --git a/fix-test_ssh_env_vars.patch b/fix-test_ssh_env_vars.patch new file mode 100644 index 0000000..719b38b --- /dev/null +++ b/fix-test_ssh_env_vars.patch @@ -0,0 +1,13 @@ +diff --git a/kitty_tests/ssh.py b/kitty_tests/ssh.py +index 7b3bdbeb..710aeceb 100644 +--- a/kitty_tests/ssh.py ++++ b/kitty_tests/ssh.py +@@ -272,8 +272,6 @@ def check_bootstrap(self, sh, home_dir, login_shell='', SHELL_INTEGRATION_VALUE= + + def check_untar_or_fail(): + q = pty.screen_contents() +- if 'bzip2' in q: +- raise ValueError('Untarring failed with screen contents:\n' + q) + return 'UNTAR_DONE' in q + pty.wait_till(check_untar_or_fail) + self.assertTrue(os.path.exists(os.path.join(home_dir, '.terminfo/kitty.terminfo'))) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..290ba63 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1688438960, + "narHash": "sha256-aIFcxU2qtI/LupfwcwTbVbadrF1KZLw2tsxyyl7WYtU=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "62fed675bc20ceac4471d844164ec146888f0c27", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-23.05-small", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..fce024a --- /dev/null +++ b/flake.nix @@ -0,0 +1,54 @@ +# vim: set noet sw=2 ts=2 sts=2: +{ + description = "kitty"; + inputs = { + nixpkgs.url = github:NixOS/nixpkgs/nixos-23.05-small; + }; + outputs = { self, nixpkgs }: + let + allSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + forAllSystems = f: (nixpkgs.lib.genAttrs allSystems (system: f { + pkgs = import nixpkgs { inherit system; }; + })); + in rec { + defaultPackage = forAllSystems ({pkgs}: + with pkgs; + callPackage ./kitty.nix { } + ); + packages = forAllSystems ({pkgs}: + with pkgs; + { default = callPackage ./kitty.nix { }; } + ); + devShell = forAllSystems ({pkgs}: + with pkgs; + let + sw = callPackage ./kitty.nix { }; + environment = + (lib.attrsets.filterAttrs (n: v: null != (builtins.match "^[A-Z_]+$" n)) sw) + // { RAILS_ENV = "development"; }; + q = lib.strings.escapeShellArg; + in + mkShell { + name = "kitty-dev"; + inputsFrom = [sw]; + shellHook = '' + ${lib.strings.concatStringsSep " " (builtins.attrValues (builtins.mapAttrs (n: v: "${n}=${q v}") environment))} + export ${lib.strings.concatStringsSep " " (builtins.attrValues (builtins.mapAttrs (n: v: q n) environment))} + ''; + } + // environment + ); + + apps = forAllSystems ({pkgs}: + with pkgs; + let + kitty = callPackage ./kitty.nix { }; + in { + server = { + type = "app"; + program = "dev.sh"; + }; + } + ); + }; +} diff --git a/kitty.nix b/kitty.nix new file mode 100644 index 0000000..36a6a6a --- /dev/null +++ b/kitty.nix @@ -0,0 +1,244 @@ +{ lib, stdenv, fetchFromGitHub, python3Packages, libunistring +, harfbuzz, fontconfig, pkg-config, ncurses, imagemagick +, libstartup_notification, libGL, libX11, libXrandr, libXinerama, libXcursor +, libxkbcommon, libXi, libXext, wayland-protocols, wayland +, lcms2 +, librsync +, openssl +, installShellFiles +, dbus +, Libsystem ? null +, Cocoa ? null +, Kernel ? null +, UniformTypeIdentifiers ? null +, UserNotifications ? null +, libcanberra +, libicns +, libpng +, python3 +, zlib +, bashInteractive +, zsh +, fish +, nixosTests +, go +, buildGoModule +, nix-update-script +}: + +with python3Packages; +buildPythonApplication rec { + pname = "kitty-patch"; + version = "0.28.1"; + format = "other"; + + src = fetchFromGitHub { + owner = "kovidgoyal"; + repo = "kitty"; + rev = "refs/tags/v${version}"; + hash = "sha256-pAo+bT10rdQOf9j3imKWCCMFGm8KntUeTQUrEE1wYZc="; + }; + vendorHash = "sha256-vq19exqsEtXhN20mgC5GCpYGm8s9AC6nlfCfG1lUiI8="; + + buildInputs = [ + harfbuzz + ncurses + lcms2 + librsync + openssl.dev + ] ++ lib.optionals stdenv.isDarwin [ + Cocoa + Kernel + UniformTypeIdentifiers + UserNotifications + libpng + python3 + zlib + ] ++ lib.optionals (stdenv.isDarwin && stdenv.isx86_64) [ + Libsystem + ] ++ lib.optionals stdenv.isLinux [ + fontconfig libunistring libcanberra libX11 + libXrandr libXinerama libXcursor libxkbcommon libXi libXext + wayland-protocols wayland dbus libGL + ]; + + nativeBuildInputs = [ + installShellFiles + ncurses + pkg-config + sphinx + furo + sphinx-copybutton + sphinxext-opengraph + sphinx-inline-tabs + go + ] ++ lib.optionals stdenv.isDarwin [ + imagemagick + libicns # For the png2icns tool. + ]; + + outputs = [ "out" "terminfo" "shell_integration" "kitten" ]; + + patches = [ + # Gets `test_ssh_env_vars` to pass when `bzip2` is in the output of `env`. + ./fix-test_ssh_env_vars.patch + + # Needed on darwin + + # Gets `test_ssh_shell_integration` to pass for `zsh` when `compinit` complains about + # permissions. + ./zsh-compinit.patch + + # Skip `test_ssh_bootstrap_with_different_launchers` when launcher is `zsh` since it causes: + # OSError: master_fd is in error condition + ./disable-test_ssh_bootstrap_with_different_launchers.patch + + ./bold_is_bright.patch + ]; + + # Causes build failure due to warning + hardeningDisable = lib.optional stdenv.cc.isClang "strictoverflow"; + + CGO_ENABLED = 0; + GOFLAGS = "-trimpath"; + + go-modules = (buildGoModule { + pname = "kitty-go-modules"; + inherit src vendorHash version; + }).go-modules; + + configurePhase = '' + export GOCACHE=$TMPDIR/go-cache + export GOPATH="$TMPDIR/go" + export GOPROXY=off + cp -r --reflink=auto ${go-modules} vendor + ''; + + buildPhase = let + commonOptions = '' + --update-check-interval=0 \ + --shell-integration=enabled\ no-rc + ''; + darwinOptions = '' + --disable-link-time-optimization \ + ${commonOptions} + ''; + in '' + runHook preBuild + ${ lib.optionalString (stdenv.isDarwin && stdenv.isx86_64) "export MACOSX_DEPLOYMENT_TARGET=11" } + ${if stdenv.isDarwin then '' + ${python.pythonForBuild.interpreter} setup.py build ${darwinOptions} + make docs + ${python.pythonForBuild.interpreter} setup.py kitty.app ${darwinOptions} + '' else '' + ${python.pythonForBuild.interpreter} setup.py linux-package \ + --egl-library='${lib.getLib libGL}/lib/libEGL.so.1' \ + --startup-notification-library='${libstartup_notification}/lib/libstartup-notification-1.so' \ + --canberra-library='${libcanberra}/lib/libcanberra.so' \ + --fontconfig-library='${fontconfig.lib}/lib/libfontconfig.so' \ + ${commonOptions} + ${python.pythonForBuild.interpreter} setup.py build-launcher + ''} + runHook postBuild + ''; + + nativeCheckInputs = [ + pillow + + # Shells needed for shell integration tests + bashInteractive + zsh + fish + ]; + + # skip failing tests due to darwin sandbox + preCheck = lib.optionalString stdenv.isDarwin '' + substituteInPlace kitty_tests/file_transmission.py \ + --replace test_file_get dont_test_file_get \ + --replace test_path_mapping_receive dont_test_path_mapping_receive + substituteInPlace kitty_tests/shell_integration.py \ + --replace test_fish_integration dont_test_fish_integration + substituteInPlace kitty_tests/open_actions.py \ + --replace test_parsing_of_open_actions dont_test_parsing_of_open_actions + substituteInPlace kitty_tests/ssh.py \ + --replace test_ssh_connection_data dont_test_ssh_connection_data + substituteInPlace kitty_tests/fonts.py \ + --replace 'class Rendering(BaseTest)' 'class Rendering' + # theme collection test starts an http server + rm tools/themes/collection_test.go + ''; + + checkPhase = '' + runHook preCheck + + # Fontconfig error: Cannot load default config file: No such file: (null) + export FONTCONFIG_FILE=${fontconfig.out}/etc/fonts/fonts.conf + + # Required for `test_ssh_shell_integration` to pass. + export TERM=kitty + + make test + runHook postCheck + ''; + + installPhase = '' + runHook preInstall + mkdir -p $out + mkdir -p $kitten/bin + ${if stdenv.isDarwin then '' + mkdir "$out/bin" + ln -s ../Applications/kitty.app/Contents/MacOS/kitty "$out/bin/kitty" + ln -s ../Applications/kitty.app/Contents/MacOS/kitten "$out/bin/kitten" + cp ./kitty.app/Contents/MacOS/kitten "$kitten/bin/kitten" + mkdir "$out/Applications" + cp -r kitty.app "$out/Applications/kitty.app" + + installManPage 'docs/_build/man/kitty.1' + '' else '' + cp -r linux-package/{bin,share,lib} $out + cp linux-package/bin/kitten $kitten/bin/kitten + ''} + wrapProgram "$out/bin/kitty" --prefix PATH : "$out/bin:${lib.makeBinPath [ imagemagick ncurses.dev ]}" + + installShellCompletion --cmd kitty \ + --bash <("$out/bin/kitty" +complete setup bash) \ + --fish <("$out/bin/kitty" +complete setup fish2) \ + --zsh <("$out/bin/kitty" +complete setup zsh) + + terminfo_src=${if stdenv.isDarwin then + ''"$out/Applications/kitty.app/Contents/Resources/terminfo"'' + else + "$out/share/terminfo"} + + mkdir -p $terminfo/share + mv "$terminfo_src" $terminfo/share/terminfo + + mkdir -p $out/nix-support + echo "$terminfo" >> $out/nix-support/propagated-user-env-packages + + cp -r 'shell-integration' "$shell_integration" + + runHook postInstall + ''; + + passthru = { + updateScript = nix-update-script {}; + tests.test = nixosTests.terminal-emulators.kitty; + }; + + meta = with lib; { + homepage = "https://github.com/kovidgoyal/kitty"; + description = "A modern, hackable, featureful, OpenGL based terminal emulator"; + license = licenses.gpl3Only; + changelog = "https://sw.kovidgoyal.net/kitty/changelog/"; + platforms = platforms.darwin ++ platforms.linux; + maintainers = with maintainers; [ tex rvolosatovs Luflosi adamcstephens ]; + }; +} // + (if stdenv.isDarwin then + { KITTY_NO_LTO = ""; } + else { + KITTY_EGL_LIBRARY = "${lib.getLib libGL}/lib/libEGL.so.1"; + KITTY_STARTUP_NOTIFICATION_LIBRARY = "${libstartup_notification}/lib/libstartup-notification-1.so"; + KITTY_CANBERRA_LIBRARY = "${libcanberra}/lib/libcanberra.so"; + }) diff --git a/zsh-compinit.patch b/zsh-compinit.patch new file mode 100644 index 0000000..168f80c --- /dev/null +++ b/zsh-compinit.patch @@ -0,0 +1,13 @@ +diff --git a/kitty_tests/ssh.py b/kitty_tests/ssh.py +index 1f424146..d9a65d25 100644 +--- a/kitty_tests/ssh.py ++++ b/kitty_tests/ssh.py +@@ -268,6 +268,8 @@ def check_untar_or_fail(): + return 'UNTAR_DONE' in q + pty.wait_till(check_untar_or_fail) + self.assertTrue(os.path.exists(os.path.join(home_dir, '.terminfo/kitty.terminfo'))) ++ if login_shell == 'zsh': ++ pty.send_cmd_to_child('y') + if SHELL_INTEGRATION_VALUE != 'enabled': + pty.wait_till(lambda: len(pty.screen_contents().splitlines()) > 1) + self.assertEqual(pty.screen.cursor.shape, 0)