feat(config): integrate iris and streamline keybindings

This commit is contained in:
Prad Nukala committed 2026-10-05 09:15:20 -04:00
1 parent 43dfe48848
commit 0692ae332b
15 files changed
+268 -137

No files matched your search

-2
View File
@@ -1,2 +0,0 @@
source "$HOME/.atuin/bin/env.fish"
+16 -54
View File
@@ -33,11 +33,6 @@ fish_add_path $HOME/.grok/bin
# Generated for envman. Do not edit.
test -s ~/.config/envman/load.fish; and source ~/.config/envman/load.fish
if status is-interactive
atuin init fish | source
atuin ai init fish | source
end
# cmux
fish_add_path "/home/prad/.cmux/bin"
fish_add_path "/home/prad/.cache/.bun/bin"
@@ -46,53 +41,20 @@ for _f in $HOME/.config/herdr/plugins/github/herdr-automatic-rename-*/shell/hook
test -r "$_f"; and source "$_f"; and break
end
# Question mark at start of line - natural language mode
function _atuin_ai_question_mark
set -l buf (commandline -b)
# If buffer is empty or just contains '?', trigger natural language mode
if test -z "$buf" -o "$buf" = "?"
commandline -r ""
# Close the semantic prompt zone (OSC 133 C) so terminals with
# shell integration don't erase the TUI's output during their
# resize-time prompt reflow.
printf '\033]133;C\007' > /dev/tty
# Run atuin ai inline, swapping stdout and stderr
set -l output (atuin ai inline --hook 3>&1 1>&2 2>&3 | string collect)
if string match --quiet '__atuin_ai_print__:*' "$output"
echo (string replace "__atuin_ai_print__:" "" -- "$output" | string collect)
commandline -f repaint
else if test "$output" = "__atuin_ai_cancel__"
commandline -f repaint
else if string match --quiet '__atuin_ai_execute__:*' "$output"
# Execute the command immediately
set -l cmd (string replace "__atuin_ai_execute__:" "" -- "$output" | string collect)
commandline -r "$cmd"
commandline -f repaint
commandline -f execute
else if string match --quiet '__atuin_ai_insert__:*' "$output"
# Insert the command for editing
set -l cmd (string replace "__atuin_ai_insert__:" "" -- "$output" | string collect)
commandline -r "$cmd"
commandline -f repaint
else if test -n "$output"
# Default: insert for editing
commandline -r "$output"
commandline -f repaint
else
commandline -f repaint
end
else if not contains -- "$fish_key_bindings" fish_vi_key_bindings fish_hybrid_key_bindings
# Not at empty prompt, just insert the question mark
commandline -i "?"
end
end
# Set up keybindings
bind "?" _atuin_ai_question_mark
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv fish)"
# iris (~/.config/iris/config.toml). The init's first half `exec`s iris from an
# interactive fish, which then starts this config again inside its pty; the
# second half installs the cwd/command hooks there. Skipped where iris is not
# installed. `IRIS_RESCUE=1 fish` opens a plain fish (e.g. if iris breaks).
if command -q iris
# fish's `query-term` feature asks the terminal for its capabilities and,
# in kitty, turns on the kitty keyboard protocol (keys as CSI-u escapes).
# iris reads raw key bytes and cannot parse those, so its menu never
# opened in kitty. Feature flags are read at startup, so export the opt-out
# before `exec iris`: the fish iris starts inherits it.
if status is-interactive; and not set -q IRIS_PID; and not set -q IRIS_RESCUE
set -gx fish_features no-query-term
end
iris init fish | source
end
+6
View File
@@ -0,0 +1,6 @@
function _bind_run --description 'run a command from a key binding (iris-aware), then repaint'
_iris_busy start
$argv
_iris_busy stop
commandline -f repaint
end
+2
View File
@@ -1,6 +1,8 @@
function _gho_bind --description 'ctrl-o: gho (tv --inline), then redraw the prompt in the right place'
set -l before $PWD
_iris_busy start
gho
_iris_busy stop
if test "$PWD" = "$before"
# Cancelled (or the nvim action ran): tv --inline left the cursor on
# the line below the prompt; step back so repaint redraws in place.
+15
View File
@@ -0,0 +1,15 @@
function _iris_busy --description 'tell iris a key binding is running a program (start|stop)'
# iris (~/.config/iris) learns a command is running from fish_preexec /
# fish_postexec, which never fire for programs a key binding starts. Without
# this, iris keeps treating the screen as an idle prompt while tv, yazi or
# lazygit run: it swallows up/down/tab and can draw its menu over them.
# Same messages as iris's own hooks; a no-op outside iris.
set -q IRIS_FD; or return 0
switch "$argv[1]"
case start
printf 'IRIS_CMD_START\x00' >&$IRIS_FD 2>/dev/null
case stop
printf 'IRIS_CMD_STOP:0\x00' >&$IRIS_FD 2>/dev/null
end
return 0
end
+3 -4
View File
@@ -1,14 +1,13 @@
function _pj_bind --description 'ctrl-p / down: pj (tv --inline), then redraw the prompt in the right place'
function _pj_bind --description 'ctrl-p: pj (tv --inline), then redraw the prompt in the right place'
# pj reports through $PJ_STATE: `open` = the picker was cancelled and
# left the cursor on the line below the prompt; empty = no task sources,
# nothing drawn — but fish's repaint after an external command still
# lands one line low, so both step back up. `ran` = a task printed
# output: new line, prompt below it.
set -lx PJ_STATE (mktemp)
if contains -- --quiet $argv
set -lx PJ_QUIET 1
end
_iris_busy start
pj
_iris_busy stop
set -l state (cat $PJ_STATE)
switch "$state"
case open ''
@@ -1,21 +0,0 @@
function _pj_bind_down --description "down arrow: pj tv cable on an idle empty prompt, else fish's down-or-search"
# Mirror of atuin's up binding (atuin owns up, this owns down). Everything
# that legitimately needs the arrow keys keeps them:
# - non-empty buffer → multiline cursor movement / forward history search
# - paging mode → tab-completion pager navigation (tab on an empty
# line opens the pager with an empty buffer)
# - search mode → history-search navigation
# down-or-search is fish's own input function, called as a command exactly
# the way atuin's _atuin_bind_up calls up-or-search.
set -l buf (commandline | string collect)
if test -n "$buf"; or commandline --paging-mode; or commandline --search-mode
down-or-search
return
end
# _pj_bind runs ~/.local/bin/pj (also ctrl-p), which opens the `pj` tv
# cable. --quiet (PJ_QUIET) keeps it silent when the tree has no task
# source at all, so down is a no-op outside projects instead of printing
# an error per press.
_pj_bind --quiet
end
@@ -3,8 +3,10 @@ function _tv_inline --description 'tv --inline below the prompt, cursor back on
# its own first row when it exits; step back up so the following
# `commandline -f repaint` redraws the prompt in place instead of one line
# lower. /dev/tty keeps the move out of callers that capture stdout (gho).
_iris_busy start
tv $argv --inline
set -l st $status
_iris_busy stop
printf '\033[A' >/dev/tty
return $st
end
@@ -10,33 +10,29 @@ function fish_user_key_bindings
# Keys owned by kitty.conf never reach fish and are NOT bound here:
# ctrl-g → lazygit overlay, ctrl-y → yazi vsplit,
# ctrl-h/j/k/l → vim-aware split nav (pass_keys.py).
# ctrl-e: tv git-files (bat preview, enter opens nvim). ctrl-o, ctrl-p
# and down also open tv cables — same keys in zsh and bash. tv runs
# ctrl-e: tv git-files (bat preview, enter opens nvim). ctrl-o and
# ctrl-p also open tv cables — same keys in zsh and bash. tv runs
# --inline below the prompt; _tv_inline/_gho_bind/_pj_bind put the
# prompt back in place (or below any output) afterwards. ctrl-a:
# omp-session resumes or starts omp for the repo (same in zsh); when it
# opens the omp-sessions cable and it is cancelled, it steps back up.
# Every binding that runs a program tells iris via _iris_busy
# (_bind_run, _tv_inline, _gho_bind, _pj_bind), or iris would keep
# its prompt key handling while tv/yazi/lazygit own the screen.
bind -M $mode ctrl-e '_tv_inline git-files; commandline -f repaint'
bind -M $mode ctrl-b purple repaint
bind -M $mode ctrl-y clip-last
bind -M $mode ctrl-b '_bind_run purple'
bind -M $mode ctrl-y '_bind_run clip-last'
bind -M $mode ctrl-o _gho_bind
bind -M $mode ctrl-p _pj_bind
bind -M $mode ctrl-a 'omp-session; commandline -f repaint'
bind -M $mode ctrl-w 'atuin ai inline; commandline -f repaint'
bind -M $mode ctrl-a '_bind_run omp-session'
# ctrl-z at the prompt: fg the only background job, or pick one from
# the jobs tv cable when there are several (_jobs_bind).
bind -M $mode ctrl-z _jobs_bind
# Arrow keys: atuin owns up (bound from config.fish, survives the
# fish_vi_key_bindings reset above because that only erases presets),
# down opens the pj tv cable — but only on an idle, empty prompt; see
# _pj_bind_down.
bind -M $mode down _pj_bind_down
# ctrl-f: yazi (cd's to yazi's exit dir on quit).
bind -M $mode ctrl-f 'yy; commandline -f repaint'
bind -M $mode ctrl-g 'lazygit; commandline -f repaint'
bind -M $mode ctrl-f '_bind_run yy'
bind -M $mode ctrl-g '_bind_run lazygit'
# ctrl-c routes through the clear wrapper (kitty scrollback + prompt
# pinned to the bottom) AND wipes any text typed on the command line.