From ef32488890e04e8a6b12a13f471a37481761724f Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 27 Feb 2022 00:07:46 +0800 Subject: [PATCH 1/3] Shell integration: Fix fish pipestatus being overwritten --- .../kitty-shell-integration.fish | 58 +++++-------------- 1 file changed, 16 insertions(+), 42 deletions(-) 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 47204ada9..c4ec80fd2 100644 --- a/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish +++ b/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish @@ -74,53 +74,27 @@ function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after # Enable prompt marking with OSC 133 if not contains "no-prompt-mark" $_ksi and not set -q __ksi_prompt_state - set --global __ksi_prompt_state first-run - - 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 - echo -en "\e]133;D\a" - end + function __ksi_mark_prompt_start --on-event fish_prompt + contains "$__ksi_prompt_state" post-exec pre-exec "" + and echo -en "\e]133;D\a" set --global __ksi_prompt_state prompt-start echo -en "\e]133;A\a" - return $cmd_status - end - - 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 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 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 - echo -en "\e]133;B\a" - return $cmd_status end + __ksi_mark_prompt_start functions -c fish_prompt __ksi_original_fish_prompt - - # Check whether the mode prompt function exists and is not empty - if functions --no-details fish_mode_prompt | string match -qnvr '^ *(#|function |end$|$)' - # When vi mode changes, fish redraws fish_prompt when fish_mode_prompt is empty. - # Some prompt rely on this side effect to draw vi mode indicator. - # See https://github.com/starship/starship/issues/1283 - functions -c fish_mode_prompt __ksi_original_fish_mode_prompt - function fish_mode_prompt - __ksi_prompt_start - __ksi_original_fish_mode_prompt - end - function fish_prompt - __ksi_prompt_end - end - else - function fish_prompt - __ksi_prompt_start - __ksi_prompt_end - end + function fish_prompt + # 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 + # op is a list because fish splits on newlines in command substitution + set --local op (__ksi_original_fish_prompt) + # print all but last element of the list, each followed by a new line + set -q op[2] + and printf '%s\n' $op[1..-2] + # print the last component without a newline + printf '%s' $op[-1] + set --global __ksi_prompt_state prompt-end + echo -en "\e]133;B\a" end function __ksi_mark_output_start --on-event fish_preexec From 121778e5c6795afcc3908d2bdf2fbcf8592a1f09 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 27 Feb 2022 00:08:36 +0800 Subject: [PATCH 2/3] Remove unnecessary function checks --- .../vendor_conf.d/kitty-shell-integration.fish | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) 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 c4ec80fd2..c3017756a 100644 --- a/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish +++ b/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish @@ -32,18 +32,14 @@ function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after # Enable cursor shape changes for default mode and vi mode if not contains "no-cursor" $_ksi - and not functions -q __ksi_set_cursor - - function __ksi_block_cursor --on-event fish_preexec -d "Set cursor shape to blinking default shape before executing command" - echo -en "\e[0 q" - end - function __ksi_set_cursor --on-variable fish_key_bindings -d "Set the cursor shape for different modes when switching key bindings" if test "$fish_key_bindings" = fish_default_key_bindings - not functions -q __ksi_bar_cursor || return function __ksi_bar_cursor --on-event fish_prompt -d "Set cursor shape to blinking bar on prompt" echo -en "\e[5 q" end + # Change the cursor shape on first run + set -q argv[1] + and __ksi_bar_cursor else functions --erase __ksi_bar_cursor contains "$fish_key_bindings" fish_vi_key_bindings fish_hybrid_key_bindings @@ -66,9 +62,11 @@ function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after test "$fish_bind_mode" = "insert" && echo -en "\e[5 q" || echo -en "\e[1 q" end - __ksi_set_cursor - functions -q __ksi_bar_cursor - and __ksi_bar_cursor + function __ksi_default_cursor --on-event fish_preexec -d "Set cursor shape to blinking default shape before executing command" + echo -en "\e[0 q" + end + + __ksi_set_cursor init end # Enable prompt marking with OSC 133 From e2f16ff62451eccb4fc901d30042ceca23940188 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 27 Feb 2022 00:27:31 +0800 Subject: [PATCH 3/3] Add fish pipestatus integration tests and changelog entries --- docs/changelog.rst | 4 ++++ kitty_tests/shell_integration.py | 26 +++++++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 3cd1b9e4d..e8b69a058 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -137,6 +137,10 @@ Detailed list of changes - Shell integration: bash: Fix rendering of multiline prompts with more than two lines (:iss:`4681`) +- Shell integration: fish: Check fish version 3.3.0+ and exit on outdated versions (:pull:`4745`) + +- Shell integration: fish: Fix pipestatus being overwritten (:pull:`4756`) + - Linux: Fix fontconfig alias not being used if the aliased font is dual spaced instead of monospaced (:iss:`4649`) - macOS: Add an option :opt:`macos_menubar_title_max_length` to control the max length of the window title displayed in the global menubar (:iss:`2132`) diff --git a/kitty_tests/shell_integration.py b/kitty_tests/shell_integration.py index 540c686f3..ab0675953 100644 --- a/kitty_tests/shell_integration.py +++ b/kitty_tests/shell_integration.py @@ -151,7 +151,9 @@ RPS1="{rps1}" set -g fish_greeting function fish_prompt; echo -n "{fish_prompt}"; end function fish_right_prompt; echo -n "{right_prompt}"; end -function _ksi_test_comp; contains "{completions_dir}" $fish_complete_path; and echo ok; end +function _test_comp_path; contains "{completions_dir}" $fish_complete_path; and echo ok; end +function _set_key; set -g fish_key_bindings fish_$argv[1]_key_bindings; end +function _set_status_prompt; function fish_prompt; echo -n "$pipestatus $status {fish_prompt}"; end; end ''') as pty: q = fish_prompt + ' ' * (pty.screen.columns - len(fish_prompt) - len(right_prompt)) + right_prompt pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 1) @@ -164,7 +166,7 @@ function _ksi_test_comp; contains "{completions_dir}" $fish_complete_path; and e # completion and prompt marking pty.send_cmd_to_child('clear') - pty.send_cmd_to_child('_ksi_test_comp') + pty.send_cmd_to_child('_test_comp_path') pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 2) q = '\n'.join(str(pty.screen.line(i)) for i in range(1, pty.screen.cursor.y)) self.ae(q, 'ok') @@ -196,16 +198,30 @@ function _ksi_test_comp; contains "{completions_dir}" $fish_complete_path; and e pty.wait_till(lambda: pty.screen.cursor.shape == 0 and pty.screen.cursor.y > 1) pty.write_to_child('\x04') pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BEAM) - pty.send_cmd_to_child('fish_vi_key_bindings') + pty.send_cmd_to_child('_set_key vi') pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BLOCK) - pty.write_to_child('i') pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BEAM) pty.write_to_child('\x1b') pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BLOCK) pty.write_to_child('r') pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_UNDERLINE) + pty.write_to_child('\x1b') + pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BLOCK) + pty.write_to_child('i') + pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BEAM) + pty.send_cmd_to_child('_set_key default') - pty.write_to_child('\x1biexit\r') + # pipestatus + pty.send_cmd_to_child('clear;false|true|false') + pty.send_cmd_to_child('echo $pipestatus $status') + pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 2) + self.ae(pty.last_cmd_output(), '1 0 1 1') + pty.send_cmd_to_child('_set_status_prompt') + pty.send_cmd_to_child('false|true|false') + pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 4) + self.assertTrue(str(pty.screen.line(pty.screen.cursor.y)).startswith(f'1 0 1 1 {fish_prompt}')) + + pty.send_cmd_to_child('exit') @unittest.skipUnless(bash_ok(), 'bash not installed or too old') def test_bash_integration(self):