From e502cff8cbfd9ed11cfb1053939e01f80789aaf6 Mon Sep 17 00:00:00 2001 From: rootiest Date: Mon, 18 May 2026 20:34:00 -0400 Subject: [PATCH 1/5] fix(keybinds): guard bindings on required binaries and fix fzf bg-transform - conf.d/fzf.fish: skip fzf_configure_bindings if fzf is not in PATH - key_bindings.fish: only bind Ctrl+Alt+= when qalc is installed - _qalc_eval: return 1 early if qalc is absent so callers can react - _smart_execute: fall back to normal execute when _qalc_eval returns 1 - integrations/fzf.fish: replace bg-transform with transform (available since fzf 0.53; bg-transform requires a newer version and caused "unknown action" errors on fzf 0.60 devel) --- conf.d/fzf.fish | 3 ++- conf.d/key_bindings.fish | 4 ++-- functions/_qalc_eval.fish | 2 ++ functions/_smart_execute.fish | 4 ++-- integrations/fzf.fish | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/conf.d/fzf.fish b/conf.d/fzf.fish index 446dd3c..7143bea 100644 --- a/conf.d/fzf.fish +++ b/conf.d/fzf.fish @@ -9,7 +9,8 @@ end # This variable is global so that it can be referenced by fzf_configure_bindings and in tests set --global _fzf_search_vars_command '_fzf_search_variables (set --show | psub) (set --names | psub)' -# Install the default bindings, which are mnemonic and minimally conflict with fish's preset bindings +# Install the default bindings only if fzf is available +type -q fzf || exit fzf_configure_bindings # Doesn't erase autoloaded _fzf_* functions because they are not easily accessible once key bindings are erased diff --git a/conf.d/key_bindings.fish b/conf.d/key_bindings.fish index b725bc3..8b8dd06 100644 --- a/conf.d/key_bindings.fish +++ b/conf.d/key_bindings.fish @@ -52,7 +52,7 @@ function fish_user_key_bindings bind ctrl-g __insert_previous_path_head bind ctrl-f __interactive_history_sub bind ctrl-alt-u _replace_command_token - bind ctrl-alt-= _qalc_eval + type -q qalc && bind ctrl-alt-= _qalc_eval bind ctrl-enter _smart_execute # Set bindings for all Vi modes: @@ -61,7 +61,7 @@ function fish_user_key_bindings bind --mode $mode ctrl-g __insert_previous_path_head bind --mode $mode ctrl-f __interactive_history_sub bind --mode $mode ctrl-alt-u _replace_command_token - bind --mode $mode ctrl-alt-= _qalc_eval + type -q qalc && bind --mode $mode ctrl-alt-= _qalc_eval bind --mode $mode ctrl-enter _smart_execute end end diff --git a/functions/_qalc_eval.fish b/functions/_qalc_eval.fish index 212810f..69aa255 100644 --- a/functions/_qalc_eval.fish +++ b/functions/_qalc_eval.fish @@ -3,6 +3,8 @@ # Returns the result of a qalc calculation function _qalc_eval + type -q qalc || return 1 + # Get the current command line buffer set -l cmd (commandline) diff --git a/functions/_smart_execute.fish b/functions/_smart_execute.fish index f2fe8d9..cb1bd33 100644 --- a/functions/_smart_execute.fish +++ b/functions/_smart_execute.fish @@ -15,8 +15,8 @@ function _smart_execute --description 'Execute different functions based on the # 2. Dispatch based on buffer content switch "$cmd" case '*=' - # If it ends in =, run qalc - _qalc_eval + # If it ends in =, run qalc; fall back to normal execute if qalc is absent + _qalc_eval; or commandline -f execute # case 'g *' # # EXAMPLE FUTURE EXTENSION diff --git a/integrations/fzf.fish b/integrations/fzf.fish index b76ce16..527f452 100644 --- a/integrations/fzf.fish +++ b/integrations/fzf.fish @@ -206,7 +206,7 @@ function fzf_key_bindings # Prepend the options to allow user customizations set -p -- FZF_DEFAULT_OPTS \ - '--bind="focus,resize:bg-transform:if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \ + '--bind="focus,resize:transform:if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \ '--preview="string collect -- (test \\"$FZF_SELECT_COUNT\\" -gt 0; and string collect -- {+2..}) \\"\\n# \\"'$date_cmd' {2..} | fish_indent --ansi"' \ '--preview-window="right,50%,wrap-word,follow,info,hidden"' end -- 2.52.0 From 7acd099b3ec7570adb2d7e8b2db6371cef17f638 Mon Sep 17 00:00:00 2001 From: rootiest Date: Mon, 18 May 2026 20:37:18 -0400 Subject: [PATCH 2/5] fix(fzf): prefer bg-transform, fall back to transform on older fzf Detect fzf version once at shell startup inside fzf_key_bindings. Use bg-transform (non-blocking) on fzf >= 0.62 and the synchronous transform on older builds (e.g. 0.60 devel which lacks bg-transform). The chosen action is captured into fzf-history-widget via fish's --inherit-variable so the check runs once, not on every Ctrl+R press. --- integrations/fzf.fish | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/integrations/fzf.fish b/integrations/fzf.fish index 527f452..b1a2c1a 100644 --- a/integrations/fzf.fish +++ b/integrations/fzf.fish @@ -31,6 +31,14 @@ function fzf_key_bindings return 1 end + # bg-transform runs the preview toggle in a background thread (non-blocking). + # It was added after fzf 0.60; fall back to the synchronous transform on older builds. + set -l _fzf_ver (fzf --version | string match -r '^(\d+)\.(\d+)') + set -l _fzf_transform_action transform + if test -n "$_fzf_ver[3]"; and test "$_fzf_ver[3]" -ge 62 + set _fzf_transform_action bg-transform + end + #----BEGIN INCLUDE common.fish # NOTE: Do not directly edit this section, which is copied from "common.fish". # To modify it, one can edit "common.fish" and run "./update.sh" to apply @@ -177,7 +185,7 @@ function fzf_key_bindings commandline -f repaint end - function fzf-history-widget -d "Show command history" + function fzf-history-widget --inherit-variable _fzf_transform_action -d "Show command history" set -l -- command_line (commandline) set -l -- current_line (commandline -L) set -l -- total_lines (count $command_line) @@ -206,7 +214,7 @@ function fzf_key_bindings # Prepend the options to allow user customizations set -p -- FZF_DEFAULT_OPTS \ - '--bind="focus,resize:transform:if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \ + '--bind="focus,resize:'$_fzf_transform_action':if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \ '--preview="string collect -- (test \\"$FZF_SELECT_COUNT\\" -gt 0; and string collect -- {+2..}) \\"\\n# \\"'$date_cmd' {2..} | fish_indent --ansi"' \ '--preview-window="right,50%,wrap-word,follow,info,hidden"' end -- 2.52.0 From d7471e2eca026715094ac4538cfd496f4b8bfb8a Mon Sep 17 00:00:00 2001 From: rootiest Date: Mon, 18 May 2026 20:50:48 -0400 Subject: [PATCH 3/5] fix(fzf): fall back to plain wrap on older fzf lacking wrap-word MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit wrap-word in --preview-window was added alongside bg-transform. Reuse the existing _fzf_transform_action variable (already inherited by fzf-history-widget) to select wrap-word on newer fzf and plain wrap on older builds — no additional version check needed. --- integrations/fzf.fish | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/integrations/fzf.fish b/integrations/fzf.fish index b1a2c1a..f376650 100644 --- a/integrations/fzf.fish +++ b/integrations/fzf.fish @@ -213,10 +213,13 @@ function fzf_key_bindings end # Prepend the options to allow user customizations + # wrap-word requires the same newer fzf as bg-transform; fall back to plain wrap + set -l _fzf_wrap_opt wrap + test "$_fzf_transform_action" = bg-transform; and set _fzf_wrap_opt wrap-word set -p -- FZF_DEFAULT_OPTS \ '--bind="focus,resize:'$_fzf_transform_action':if test \\"$FZF_COLUMNS\\" -gt 100 -a \\\\( \\"$FZF_SELECT_COUNT\\" -gt 0 -o \\\\( -z \\"$FZF_WRAP\\" -a (string length -- {}) -gt (math $FZF_COLUMNS - 4) \\\\) -o (string collect -- {2..} | fish_indent | count) -gt 1 \\\\); echo show-preview; else echo hide-preview; end"' \ '--preview="string collect -- (test \\"$FZF_SELECT_COUNT\\" -gt 0; and string collect -- {+2..}) \\"\\n# \\"'$date_cmd' {2..} | fish_indent --ansi"' \ - '--preview-window="right,50%,wrap-word,follow,info,hidden"' + '--preview-window="right,50%,'$_fzf_wrap_opt',follow,info,hidden"' end set -lx FZF_DEFAULT_OPTS_FILE -- 2.52.0 From bdbdf2e8e0d376a60df40c6c9d3d2632e1680376 Mon Sep 17 00:00:00 2001 From: rootiest Date: Mon, 18 May 2026 20:52:44 -0400 Subject: [PATCH 4/5] fix(fzf): omit --preview-wrap-sign on older fzf builds preview-wrap-sign is unavailable in fzf 0.60 devel. Reuse the existing _fzf_transform_action gate to conditionally append it to the history widget base options, keeping parity with the wrap-word and bg-transform fallbacks. --- integrations/fzf.fish | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/integrations/fzf.fish b/integrations/fzf.fish index f376650..65767c0 100644 --- a/integrations/fzf.fish +++ b/integrations/fzf.fish @@ -191,8 +191,12 @@ function fzf_key_bindings set -l -- total_lines (count $command_line) set -l -- fzf_query (string escape -- $command_line[$current_line]) + # preview-wrap-sign requires newer fzf; omit it on older builds + set -l _fzf_preview_wrap_sign '' + test "$_fzf_transform_action" = bg-transform; and set _fzf_preview_wrap_sign ' --preview-wrap-sign="↳ "' + set -lx -- FZF_DEFAULT_OPTS (__fzf_defaults '' \ - '--nth=2..,.. --scheme=history --multi --no-multi-line --no-wrap --wrap-sign="\t\t\t↳ " --preview-wrap-sign="↳ "' \ + '--nth=2..,.. --scheme=history --multi --no-multi-line --no-wrap --wrap-sign="\t\t\t↳ "'$_fzf_preview_wrap_sign \ '--bind=\'shift-delete:execute-silent(for i in (string split0 -- <{+f}); eval builtin history delete --exact --case-sensitive -- (string escape -n -- $i | string replace -r "^\d*\\\\\\t" ""); end)+reload(eval $FZF_DEFAULT_COMMAND)\'' \ '--bind="alt-enter:become(string join0 -- (string collect -- {+2..} | fish_indent -i))"' \ "--bind=ctrl-r:toggle-sort,alt-r:toggle-raw --highlight-line $FZF_CTRL_R_OPTS" \ -- 2.52.0 From 653093565255a571f1bc533ac560413eed69b8d9 Mon Sep 17 00:00:00 2001 From: rootiest Date: Mon, 18 May 2026 20:54:10 -0400 Subject: [PATCH 5/5] fix(fzf): omit toggle-raw bind on older fzf builds toggle-raw is unavailable in fzf 0.60 devel. Gate it alongside preview-wrap-sign using the existing _fzf_transform_action check, consolidating both version-conditional variables into one block. --- integrations/fzf.fish | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/integrations/fzf.fish b/integrations/fzf.fish index 65767c0..b3ee476 100644 --- a/integrations/fzf.fish +++ b/integrations/fzf.fish @@ -191,15 +191,19 @@ function fzf_key_bindings set -l -- total_lines (count $command_line) set -l -- fzf_query (string escape -- $command_line[$current_line]) - # preview-wrap-sign requires newer fzf; omit it on older builds + # These options require newer fzf; omit them on older builds set -l _fzf_preview_wrap_sign '' - test "$_fzf_transform_action" = bg-transform; and set _fzf_preview_wrap_sign ' --preview-wrap-sign="↳ "' + set -l _fzf_toggle_raw '' + if test "$_fzf_transform_action" = bg-transform + set _fzf_preview_wrap_sign ' --preview-wrap-sign="↳ "' + set _fzf_toggle_raw ,alt-r:toggle-raw + end set -lx -- FZF_DEFAULT_OPTS (__fzf_defaults '' \ '--nth=2..,.. --scheme=history --multi --no-multi-line --no-wrap --wrap-sign="\t\t\t↳ "'$_fzf_preview_wrap_sign \ '--bind=\'shift-delete:execute-silent(for i in (string split0 -- <{+f}); eval builtin history delete --exact --case-sensitive -- (string escape -n -- $i | string replace -r "^\d*\\\\\\t" ""); end)+reload(eval $FZF_DEFAULT_COMMAND)\'' \ '--bind="alt-enter:become(string join0 -- (string collect -- {+2..} | fish_indent -i))"' \ - "--bind=ctrl-r:toggle-sort,alt-r:toggle-raw --highlight-line $FZF_CTRL_R_OPTS" \ + "--bind=ctrl-r:toggle-sort$_fzf_toggle_raw --highlight-line $FZF_CTRL_R_OPTS" \ '--accept-nth=2.. --delimiter="\t" --tabstop=4 --read0 --print0 --with-shell='(status fish-path)\\ -c) # Add dynamic preview options if preview command isn't already set by user -- 2.52.0