diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3585f0f8..12d01bd4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -81,7 +81,7 @@ jobs: if: ${{ !(inputs.enable_debug_tmate || inputs.enable_debug_vnc) || (inputs.debug_kitty_version == matrix.kitty_version && inputs.debug_nvim_version == matrix.nvim_version) }} run: | sudo apt update - sudo apt install -y xfce4 libxcb-xkb1 xsel tmux + sudo apt install -y xfce4 libxcb-xkb1 xsel tmux fish # homebrew is not used but is required to reproduce an issue for a test case /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" diff --git a/lua/kitty-scrollback/kitty_commands.lua b/lua/kitty-scrollback/kitty_commands.lua index 40e25a64..4873ba69 100644 --- a/lua/kitty-scrollback/kitty_commands.lua +++ b/lua/kitty-scrollback/kitty_commands.lua @@ -146,22 +146,25 @@ M.send_lines_to_kitty_and_quit = function(lines, execute_command) end, lines), '\r' ) - local nul_character = [[\x00]] -- see https://en.wikipedia.org/wiki/Null_character local start_bracketed_paste = [[\x1b[200~]] -- see https://cirw.in/blog/bracketed-paste local stop_bracketed_paste = [[\x1b[201~]] -- see https://cirw.in/blog/bracketed-paste - -- the beginning nul is used to separate any existing commands in kitty that may end with escape - -- if escape is present, then bash autocompletion will be triggered because bracketed paste mode starts with an escape - -- the ending nul is used to remove deselect the text after pasting to the terminal - cmd_str = nul_character - .. start_bracketed_paste - .. cmd_str - .. stop_bracketed_paste - .. nul_character + cmd_str = start_bracketed_paste .. cmd_str .. stop_bracketed_paste + + ksb_util.system_handle_error({ + p.kitty_data.kitty_path, + '@', + 'send-text', + '--match=id:' .. p.kitty_data.window_id, + cmd_str, + }, error_header) if execute_command then -- add a carriage return to execute command - cmd_str = cmd_str .. '\r' + cmd_str = '\r' + else + -- an empty bracketed paste is used to deselect the text after pasting to the terminal + cmd_str = start_bracketed_paste .. stop_bracketed_paste end ksb_util.system_handle_error({ @@ -171,6 +174,7 @@ M.send_lines_to_kitty_and_quit = function(lines, execute_command) '--match=id:' .. p.kitty_data.window_id, cmd_str, }, error_header) + ksb_util.quitall() end diff --git a/tests/kitty-scrollback/kitty_scrollback_fish_spec.lua b/tests/kitty-scrollback/kitty_scrollback_fish_spec.lua new file mode 100644 index 00000000..470a4ca4 --- /dev/null +++ b/tests/kitty-scrollback/kitty_scrollback_fish_spec.lua @@ -0,0 +1,95 @@ +local h = require('tests.kitty-scrollback.helpers') + +h.setup_backport() + +local ksb_dir = h.ksb_dir() +h.debug({ + ksb_dir = ksb_dir, + kitty_conf = ksb_dir .. 'tests/kitty.conf', +}) + +local tmpsock +local kitty_instance + +local shell = h.debug(h.is_github_action and '/bin/fish' or 'fish') + +describe('kitty-scrollback.nvim', function() + h.init_nvim() + + before_each(function() + vim.fn.mkdir(ksb_dir .. 'tests/workdir', 'p') + tmpsock = h.tempsocket(ksb_dir .. 'tmp/') + local kitty_cmd = h.debug({ + h.kitty, + '--listen-on=unix:' .. tmpsock, + '--config', + ksb_dir .. 'tests/kitty.conf', + '--override', + 'shell=' .. shell, + '--session', + '-', -- read session from stdin + }) + kitty_instance = h.wait_for_kitty_remote_connection(kitty_cmd, tmpsock, { + stdin = 'cd ' .. ksb_dir .. 'tests/workdir', + }) + h.feed_kitty({ + h.send_as_string([[ +function fish_prompt + echo "fish \$ " +end +]]), + h.with_pause_seconds_before(h.send_without_newline(h.clear())), + }) + h.pause_seconds() + end) + + after_each(function() + kitty_instance:kill(2) + kitty_instance = nil + vim.fn.delete(vim.fn.fnamemodify(tmpsock, ':p:h'), 'rf') + end) + + it('should not have autocomplete in executed command', function() + h.assert_screen_equals( + h.feed_kitty({ + h.with_pause_seconds_before([[echo autocomplete test]]), + h.open_kitty_scrollback_nvim(), + h.send_without_newline([[a]]), + h.send_without_newline([[echo]]), + h.send_without_newline(h.control_enter()), + }), + { + stdout = [[ +fish $ echo autocomplete test +autocomplete test +fish $ echo + +fish $ +]], + cursor_y = 5, + cursor_x = 8, + } + ) + end) + + it('should have autocomplete available after cursor in current command', function() + h.assert_screen_equals( + h.feed_kitty({ + h.with_pause_seconds_before([[echo autocomplete test]]), + h.open_kitty_scrollback_nvim(), + h.send_without_newline([[a]]), + h.send_without_newline([[echo]]), + h.send_without_newline(h.shift_enter()), + }), + { + stdout = [[ +fish $ echo autocomplete test +autocomplete test +fish $ echo autocomplete test +]], + cursor_y = 3, + cursor_x = 12, + } + ) + end) +end)