diff --git a/docs/shell-integration.rst b/docs/shell-integration.rst index 27e30818f..0ea752147 100644 --- a/docs/shell-integration.rst +++ b/docs/shell-integration.rst @@ -68,6 +68,8 @@ no-prompt-mark no-complete Turn off completion for the kitty command. + Note that for the ``fish`` shell this does not take effect, since fish + already comes with a kitty completion script. More ways to browse command output diff --git a/shell-integration/fish/vendor_completions.d/kitty.fish b/shell-integration/fish/vendor_completions.d/kitty.fish index 804160a9c..7734d975f 100644 --- a/shell-integration/fish/vendor_completions.d/kitty.fish +++ b/shell-integration/fish/vendor_completions.d/kitty.fish @@ -1,5 +1,7 @@ -if functions -q _ksi_completions - complete -f -c kitty -a "(_ksi_completions)" -else - complete -f -c kitty -a "(commandline -cop | kitty +complete fish)" +function __ksi_completions + set --local ct (commandline --current-token) + set --local tokens (commandline --tokenize --cut-at-cursor --current-process) + printf "%s\n" $tokens $ct | command kitty +complete fish2 end + +complete -f -c kitty -a "(__ksi_completions)" diff --git a/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish b/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish index 50b18d675..88863eb3d 100644 --- a/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish +++ b/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish @@ -1,10 +1,10 @@ #!/bin/fish -status --is-interactive || exit 0 -not functions -q _ksi_schedule || exit 0 +status is-interactive || exit 0 +not functions -q __ksi_schedule || exit 0 -function _ksi_main - functions --erase _ksi_main _ksi_schedule +function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after other scripts have run, we hope" + functions --erase __ksi_schedule test -n "$KITTY_SHELL_INTEGRATION" || return 0 if set -q XDG_DATA_DIRS KITTY_FISH_XDG_DATA_DIR @@ -20,135 +20,116 @@ function _ksi_main set --local _ksi (string split " " -- "$KITTY_SHELL_INTEGRATION") set --erase KITTY_SHELL_INTEGRATION KITTY_FISH_XDG_DATA_DIR - function _ksi_osc + function __ksi_osc printf "\e]%s\a" "$argv[1]" end - if not contains "no-complete" $_ksi - and not functions -q _ksi_completions - function _ksi_completions - set --local ct (commandline --current-token) - set --local tokens (commandline --tokenize --cut-at-cursor --current-process) - printf "%s\n" $tokens $ct | command kitty +complete fish2 - end - end - if not contains "no-cursor" $_ksi - and not functions -q _ksi_set_cursor + and not functions -q __ksi_set_cursor - function _ksi_set_cursor --on-variable fish_key_bindings + function __ksi_set_cursor --on-variable fish_key_bindings -d "Set cursor shape for fish default mode" if test "$fish_key_bindings" = fish_default_key_bindings - and not functions -q _ksi_bar_cursor _ksi_block_cursor + not functions -q __ksi_bar_cursor __ksi_block_cursor || return - function _ksi_bar_cursor --on-event fish_prompt + function __ksi_bar_cursor --on-event fish_prompt printf "\e[5 q" end - function _ksi_block_cursor --on-event fish_preexec + function __ksi_block_cursor --on-event fish_preexec printf "\e[2 q" end else - functions --erase _ksi_bar_cursor _ksi_block_cursor + functions --erase __ksi_bar_cursor __ksi_block_cursor end end + __ksi_set_cursor + functions -q __ksi_bar_cursor + and __ksi_bar_cursor - function _ksi_set_vi_cursor - set -q $argv[1] || set --global $argv[1] $argv[2] blink - end - - _ksi_set_cursor - _ksi_set_vi_cursor fish_cursor_default block - _ksi_set_vi_cursor fish_cursor_insert line - _ksi_set_vi_cursor fish_cursor_replace_one underscore - _ksi_set_vi_cursor fish_cursor_visual block - - # Change the cursor shape on the first run - if functions -q _ksi_bar_cursor - _ksi_bar_cursor - else if contains "$fish_key_bindings" fish_vi_key_bindings fish_hybrid_key_bindings - if functions -q fish_vi_cursor_handle - fish_vi_cursor_handle - else if test "$fish_bind_mode" = "insert" - printf "\e[5 q" + # Set the vi mode cursor shapes only when none of them are configured + set --local vi_modes fish_cursor_{default,insert,replace_one,visual} + set --local vi_cursor_shapes block line underscore block + set -q $vi_modes + if test "$status" -eq 4 + for i in 1 2 3 4 + set --global $vi_modes[$i] $vi_cursor_shapes[$i] blink end + # Change the vi mode cursor shape on the first run + contains "$fish_key_bindings" fish_vi_key_bindings fish_hybrid_key_bindings + and test "$fish_bind_mode" = "insert" && printf "\e[5 q" || printf "\e[1 q" end - - functions --erase _ksi_set_vi_cursor end if not contains "no-prompt-mark" $_ksi - and not functions -q _ksi_mark - set --global _ksi_prompt_state "first-run" + and not set -q __ksi_prompt_state + set --global __ksi_prompt_state first-run - function _ksi_function_is_not_empty -d "Check if the specified function exists and is not empty" + function __ksi_function_is_not_empty -d "Check if the specified function exists and is not empty" functions --no-details $argv[1] | string match -qnvr '^ *(#|function |end$|$)' end - function _ksi_mark -d "Tell kitty to mark the current cursor position using OSC 133" - _ksi_osc "133;$argv[1]" + function __ksi_mark -d "Tell kitty to mark the current cursor position using OSC 133" + __ksi_osc "133;$argv[1]" end - function _ksi_start_prompt - set --local cmd_status "$status" - if test "$_ksi_prompt_state" != "postexec" -a "$_ksi_prompt_state" != "first-run" - _ksi_mark "D" + function __ksi_prompt_start + # preserve the command exit code from $status + set --local cmd_status $status + if contains "$__ksi_prompt_state" post-exec first-run + __ksi_mark D end - set --global _ksi_prompt_state "prompt_start" - _ksi_mark "A" - return "$cmd_status" # preserve the value of $status + set --global __ksi_prompt_state prompt-start + __ksi_mark A + return $cmd_status end - function _ksi_end_prompt - set --local cmd_status "$status" + function __ksi_prompt_end + set --local cmd_status $status # fish trims one trailing newline from the output of fish_prompt, so # we need to do the same. See https://github.com/kovidgoyal/kitty/issues/4032 - set --local op (_ksi_original_fish_prompt) # op is an array because fish splits on newlines in command substitution + set --local op (__ksi_original_fish_prompt) # op is a list because fish splits on newlines in command substitution if set -q op[2] - printf '%s\n' $op[1..-2] # print all but last element of array, each followed by a new line + printf '%s\n' $op[1..-2] # print all but last element of the list, each followed by a new line end printf '%s' $op[-1] # print the last component without a newline - set --global _ksi_prompt_state "prompt_end" - _ksi_mark "B" - return "$cmd_status" # preserve the value of $status + set --global __ksi_prompt_state prompt-end + __ksi_mark B + return $cmd_status end - functions -c fish_prompt _ksi_original_fish_prompt + functions -c fish_prompt __ksi_original_fish_prompt - if _ksi_function_is_not_empty fish_mode_prompt + if __ksi_function_is_not_empty fish_mode_prompt # see https://github.com/starship/starship/issues/1283 # for why we have to test for a non-empty fish_mode_prompt - functions -c fish_mode_prompt _ksi_original_fish_mode_prompt + functions -c fish_mode_prompt __ksi_original_fish_mode_prompt function fish_mode_prompt - _ksi_start_prompt - _ksi_original_fish_mode_prompt + __ksi_prompt_start + __ksi_original_fish_mode_prompt end function fish_prompt - _ksi_end_prompt + __ksi_prompt_end end else function fish_prompt - _ksi_start_prompt - _ksi_end_prompt + __ksi_prompt_start + __ksi_prompt_end end end - function _ksi_mark_output_start --on-event fish_preexec - set --global _ksi_prompt_state "preexec" - _ksi_mark "C" + function __ksi_mark_output_start --on-event fish_preexec + set --global __ksi_prompt_state pre-exec + __ksi_mark C end - function _ksi_mark_output_end --on-event fish_postexec - set --global _ksi_prompt_state "postexec" - _ksi_mark "D;$status" + function __ksi_mark_output_end --on-event fish_postexec + set --global __ksi_prompt_state post-exec + __ksi_mark "D;$status" end # with prompt marking kitty clears the current prompt on resize so we need # fish to redraw it set --global fish_handle_reflow 1 - functions --erase _ksi_function_is_not_empty + functions --erase __ksi_function_is_not_empty end end - -function _ksi_schedule --on-event fish_prompt -d "Setup kitty integration after other scripts have run, we hope" - _ksi_main -end