3 Commits
3 changed files with 60 additions and 11 deletions
+11
View File
@@ -1,5 +1,16 @@
# Changelog # Changelog
## 2026-08-26
- Fixed macOS shortcuts (`Cmd+T`, `Ctrl+Tab`, `Cmd+Shift+]`, `Cmd+Shift+[`, `Cmd+K`, `Cmd+Shift+E`) in Zellij + Ghostty after disabling the Kitty keyboard protocol:
- Mapped Ghostty keybindings (`super+t`, `super+shift+]`, `super+shift+[`, `ctrl+tab`, `ctrl+shift+tab`, `super+k`, `super+shift+e`) to send standard `Alt` (`ESC`-prefix) text sequences (`\x1bt`, `\x1b}`, `\x1b{`, `\x1bK`, `\x1bE`).
- Added matching `Alt` keybindings (`Alt t`, `Alt ]`, `Alt }`, `Alt [`, `Alt {`, `Alt Shift k`, `Alt Shift e`) in `zellij.nix` for tab creation, tab navigation, scroll mode, and scrollback editing. Symbols like `]` and `}` are parsed by Zellij's termwiz input engine as distinct character codes (`'}'` vs `']'`), so binding both `Alt }` and `Alt Shift ]` ensures `\x1b}` triggers tab navigation correctly.
- Keeps Kitty keyboard protocol disabled in Zellij (`support_kitty_keyboard_protocol = false`) so no CSI-u flags leak into Fish shell, guaranteeing zero post-TUI typing lag while restoring all shortcuts.
- Fixed persistent Fish typing lag after long TUI sessions (Neovim, jjui, Yazi) inside Zellij + Ghostty, which the `no-query-term` / Ghostty-integration fixes from 2026-08-25 did not resolve:
- Verified on Fish 4.8.1 that the `query-term` feature already defaults to `off`, so exporting `fish_features = no-query-term` is a no-op on this Fish version — it isn't the cause of (or fix for) this class of lag.
- Set `support_kitty_keyboard_protocol = false` in `zellij.nix`. Zellij and Ghostty have several open upstream bugs (zellij-org/zellij#3887, #3723, #4178) where the Kitty keyboard protocol's enhancement-flag stack is left in an elevated state after a full-screen TUI exits without properly popping it. Every subsequent keystroke then arrives as a CSI-u sequence that Fish must wait out an escape-disambiguation timeout to parse, which reads as typing lag that worsens the longer the TUI session ran, and persists until the pane's protocol state resets (e.g. a fresh shell/pane). Disabling the protocol support in Zellij avoids the whole bug class; trades off precise modifier reporting (e.g. distinguishing Ctrl+Shift+key) for TUIs running inside Zellij panes, which this setup doesn't otherwise depend on (Shift+Enter is handled via a literal Ghostty `text:` keybind, not the Kitty protocol).
## 2026-08-25 ## 2026-08-25
- Fixed Nix evaluation warnings for `stdenv` deprecation and `gemini-cli`: - Fixed Nix evaluation warnings for `stdenv` deprecation and `gemini-cli`:
@@ -36,15 +36,15 @@ in
quit-after-last-window-closed = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin true; quit-after-last-window-closed = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin true;
fullscreen = if pkgs.stdenv.hostPlatform.isDarwin then true else false; fullscreen = if pkgs.stdenv.hostPlatform.isDarwin then true else false;
keybind = [ keybind = [
"super+t=unbind" # Pass super-t to underlying tool (e.g. zellij tabs) # Translate Mac Super & Ctrl combinations into Alt (ESC prefix) sequences
"super+shift+]=unbind" # so Zellij receives them without needing Kitty keyboard protocol
"super+shift+[=unbind" "super+t=text:\\x1bt"
"ctrl+tab=unbind" "super+shift+]=text:\\x1b}"
"ctrl+shift+tab=unbind" "super+shift+[=text:\\x1b{"
"ctrl+tab=text:\\x1b[9;5u" "ctrl+tab=text:\\x1b}"
"ctrl+shift+tab=text:\\x1b[9;6u" "ctrl+shift+tab=text:\\x1b{"
"super+k=unbind" "super+k=text:\\x1bK"
"super+shift+e=unbind" "super+shift+e=text:\\x1bE"
]; ];
}; };
themes."gruvbox" = { themes."gruvbox" = {
@@ -134,6 +134,15 @@ in
# default_layout = "compact-top"; # default_layout = "compact-top";
# Remove border # Remove border
pane_frames = false; pane_frames = false;
# Ghostty + Zellij have several open upstream bugs where the Kitty
# keyboard protocol's "enhancement" flags get left in a stuck/elevated
# state after a full-screen TUI exits (e.g. zellij-org/zellij#3887,
# #3723, #4178), causing every subsequent keystroke to be sent as a
# CSI-u sequence that fish has to wait out an escape-timeout to
# disambiguate. This shows up as typing lag that builds up the longer
# you were inside the TUI, until the pane's protocol state resets.
# Disabling it entirely avoids the whole bug class.
support_kitty_keyboard_protocol = false;
# Scrollback # Scrollback
scrollback_editor = config.home.sessionVariables.EDITOR; scrollback_editor = config.home.sessionVariables.EDITOR;
@@ -286,9 +295,33 @@ in
"bind \"Super Shift ]\"" = { "bind \"Super Shift ]\"" = {
GoToNextTab = { }; GoToNextTab = { };
}; };
"bind \"Alt ]\"" = {
GoToNextTab = { };
};
"bind \"Alt }\"" = {
GoToNextTab = { };
};
"bind \"Alt Shift ]\"" = {
GoToNextTab = { };
};
"bind \"Alt Shift }\"" = {
GoToNextTab = { };
};
"bind \"Super Shift [\"" = { "bind \"Super Shift [\"" = {
GoToPreviousTab = { }; GoToPreviousTab = { };
}; };
"bind \"Alt [\"" = {
GoToPreviousTab = { };
};
"bind \"Alt {\"" = {
GoToPreviousTab = { };
};
"bind \"Alt Shift [\"" = {
GoToPreviousTab = { };
};
"bind \"Alt Shift {\"" = {
GoToPreviousTab = { };
};
"bind \"Ctrl Tab\"" = { "bind \"Ctrl Tab\"" = {
GoToNextTab = { }; GoToNextTab = { };
}; };
@@ -298,7 +331,7 @@ in
"bind \"Super t\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { "bind \"Super t\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
NewTab = { }; NewTab = { };
}; };
"bind \"Alt t\"" = lib.mkIf pkgs.stdenv.hostPlatform.isLinux { "bind \"Alt t\"" = {
NewTab = { }; NewTab = { };
}; };
"bind \"Super k\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { "bind \"Super k\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
@@ -306,13 +339,18 @@ in
_args = [ "scroll" ]; _args = [ "scroll" ];
}; };
}; };
"bind \"Alt Shift k\"" = {
SwitchToMode = {
_args = [ "scroll" ];
};
};
"bind \"Super Shift e\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin { "bind \"Super Shift e\"" = lib.mkIf pkgs.stdenv.hostPlatform.isDarwin {
EditScrollback = { }; EditScrollback = { };
SwitchToMode = { SwitchToMode = {
_args = [ "locked" ]; _args = [ "locked" ];
}; };
}; };
"bind \"Alt Shift e\"" = lib.mkIf pkgs.stdenv.hostPlatform.isLinux { "bind \"Alt Shift e\"" = {
EditScrollback = { }; EditScrollback = { };
SwitchToMode = { SwitchToMode = {
_args = [ "locked" ]; _args = [ "locked" ];