From 3c4af515fa54a5057f439afa6f46e37c135add0d Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Wed, 30 Sep 2026 11:14:14 -0400 Subject: [PATCH] feat(config): add television cable integration and related keybindings across shells --- .chezmoiignore.tmpl | 4 ++ dot_bashrc | 11 ++++ dot_config/bash/functions/gho.bash | 5 +- dot_config/bash/keybinds.bash | 61 +++++++++++++++++++ dot_config/fish/functions/_pj_bind_down.fish | 8 +-- .../functions/fish_user_key_bindings.fish | 10 +-- dot_config/fish/functions/gho.fish | 5 +- dot_config/kitty/pass_keys.py | 9 +-- dot_config/symlink_television.tmpl | 1 + dot_config/zsh/functions/gho.zsh | 5 +- dot_config/zsh/keybinds.zsh | 30 ++++++++- dot_zshrc | 9 +++ 12 files changed, 137 insertions(+), 21 deletions(-) create mode 100644 dot_config/bash/keybinds.bash create mode 100644 dot_config/symlink_television.tmpl diff --git a/.chezmoiignore.tmpl b/.chezmoiignore.tmpl index 54b7871..79ed109 100644 --- a/.chezmoiignore.tmpl +++ b/.chezmoiignore.tmpl @@ -12,6 +12,10 @@ bun.lock public dist +# Linked, not copied: ~/.config/television is a symlink to this directory +# (dot_config/symlink_television.tmpl), so edits apply without chezmoi apply. +television + # Runtime/plugin state living inside managed trees — not managed .config/lazygit/.omc/** .config/yazi/plugins/** diff --git a/dot_bashrc b/dot_bashrc index b691a20..73c7bab 100644 --- a/dot_bashrc +++ b/dot_bashrc @@ -16,6 +16,11 @@ export GOPATH="$HOME/.local/share/go" export GOBIN="$GOPATH/bin" case ":$PATH:" in *":$GOBIN:"*) ;; *) PATH="$GOBIN:$PATH" ;; esac +# Repo roots (ghq) — same as fish's conf.d/10-env.fish; the ghq-repos tv +# cable (ctrl-o) lists this root. +export GHQ_ROOT="$HOME/Code" +export CODE_ROOT="$HOME/Code" + # Android SDK — relocated under ~/.local/share/android. export ANDROID_HOME="$HOME/.local/share/android" export ANDROID_SDK_ROOT="$ANDROID_HOME" @@ -46,5 +51,11 @@ fi # Prompt — starship, consistent with fish command -v starship >/dev/null 2>&1 && eval "$(starship init bash)" +# television: _tv completion (its ctrl-r is taken over by atuin below) +command -v tv >/dev/null 2>&1 && eval "$(tv init bash)" + +# Readline keybinds — bash ports of fish_user_key_bindings.fish (tv cables) +[ -f "$HOME/.config/bash/keybinds.bash" ] && . "$HOME/.config/bash/keybinds.bash" + . "$HOME/.atuin/bin/env" eval "$(atuin init bash)" diff --git a/dot_config/bash/functions/gho.bash b/dot_config/bash/functions/gho.bash index de28fd9..9008f3f 100644 --- a/dot_config/bash/functions/gho.bash +++ b/dot_config/bash/functions/gho.bash @@ -1,7 +1,8 @@ -# Pick a ghq repo / Obsidian vault + cd; picker lives in ~/.local/bin/gho. +# Pick a ghq repo / Obsidian vault with tv (ghq-repos cable) + cd. gho() { local dir - dir=$(command gho) || return + dir=$(tv ghq-repos) || return + [ -n "$dir" ] || return cd "$dir" || return clear if [ -d .git ]; then diff --git a/dot_config/bash/keybinds.bash b/dot_config/bash/keybinds.bash new file mode 100644 index 0000000..259531b --- /dev/null +++ b/dot_config/bash/keybinds.bash @@ -0,0 +1,61 @@ +# ~/.config/bash/keybinds.bash — readline ports of the television keys in +# fish_user_key_bindings.fish / zsh keybinds.zsh: +# ctrl-o → gho (ghq-repos cable, cd) ctrl-e → tv git-files (nvim) +# ctrl-p → pj (pj cable) down → pj on an empty prompt +# ctrl-t → tv smart autocomplete (tv init bash ships no ctrl-t) +# Keys owned by kitty.conf never reach the shell: ctrl-h/j/k/l (pass_keys.py). + +# bind -x runs in the shell process, so gho's cd persists — but readline keeps +# drawing the prompt it started with. Each key is therefore a macro: \C-xN +# stashes the typed line and runs the command, \C-m accepts the now-empty +# line (bash prints a fresh prompt for the new cwd; nothing reaches history), +# and \C-x0 restores the stash into the new line. +_kb_run() { + _kb_line=$READLINE_LINE _kb_point=$READLINE_POINT + READLINE_LINE='' READLINE_POINT=0 + "$@" itself: (n)vim and fzf move -# their own splits/selection, and tmux/herdr run the same vim-aware handoff one -# layer down (tmux.conf `is_vim`, vim-herdr-navigation). Anything else means -# kitty owns the panes, so kitty moves its own window. -PASSTHROUGH = r'\b(vim|nvim|fzf|tmux|herdr)\b' +# their own splits/selection, tv binds ctrl-h to goto_parent_dir, and tmux/herdr +# run the same vim-aware handoff one layer down (tmux.conf `is_vim`, +# vim-herdr-navigation). Anything else means kitty owns the panes, so kitty +# moves its own window. +PASSTHROUGH = r'\b(vim|nvim|fzf|tv|tmux|herdr)\b' # Return True if any foreground process in the window matches PASSTHROUGH diff --git a/dot_config/symlink_television.tmpl b/dot_config/symlink_television.tmpl new file mode 100644 index 0000000..f1675a5 --- /dev/null +++ b/dot_config/symlink_television.tmpl @@ -0,0 +1 @@ +{{ .chezmoi.sourceDir }}/television diff --git a/dot_config/zsh/functions/gho.zsh b/dot_config/zsh/functions/gho.zsh index de28fd9..9008f3f 100644 --- a/dot_config/zsh/functions/gho.zsh +++ b/dot_config/zsh/functions/gho.zsh @@ -1,7 +1,8 @@ -# Pick a ghq repo / Obsidian vault + cd; picker lives in ~/.local/bin/gho. +# Pick a ghq repo / Obsidian vault with tv (ghq-repos cable) + cd. gho() { local dir - dir=$(command gho) || return + dir=$(tv ghq-repos) || return + [ -n "$dir" ] || return cd "$dir" || return clear if [ -d .git ]; then diff --git a/dot_config/zsh/keybinds.zsh b/dot_config/zsh/keybinds.zsh index 1083a90..e3a1f43 100644 --- a/dot_config/zsh/keybinds.zsh +++ b/dot_config/zsh/keybinds.zsh @@ -8,6 +8,8 @@ unsetopt flow_control # free ^Q/^S in zle so the ctrl-q exit bind fires # Generic runner: widget `run-` executes (function or binary) with # the tty as stdin, then repaints — fish's `commandline -f repaint`. # cwd changes from gho/yy persist: widgets run in the shell process. +# gho, pj and `tv git-files` open television cables (~/.config/television/ +# cable) — the same keys do the same in fish and bash. _zle-run() { local cmd=${WIDGET#run-} zle -I @@ -19,17 +21,39 @@ for _cmd in purple clip-last gho pj omp yy lazygit; do done unset _cmd -# ctrl-e: yazi, same as ctrl-f (cd's to yazi's exit dir on quit). -bindkey '^E' run-yy +# ctrl-e: tv git-files (bat preview, enter opens nvim). +_zle-tv-git-files() { + zle -I + tv git-files /dev/null 2>&1 && eval "$(suv init zsh)" # Prompt — starship, consistent with fish command -v starship >/dev/null 2>&1 && eval "$(starship init zsh)" +# television: ctrl-t smart autocomplete (its ctrl-r is taken over by atuin +# below, as in fish) +command -v tv >/dev/null 2>&1 && eval "$(tv init zsh)" + # Fish-style syntax highlighting (zsh-users/zsh-syntax-highlighting). # MUST stay last in .zshrc: it wraps every zle widget defined above # (keybinds, compinit, suv/starship hooks).