Skip to content

Commit

Permalink
fix(fish): use empty bracketed paste instead of NUL char (#251)
Browse files Browse the repository at this point in the history
When executing a command, the ending NUL character
triggers fish shell autocompletion. This doesn't
impact functionality but looks odd. Replace NUL
character with an empty bracketed paste to fix
this issue and keep the desired behavior of
removing selection after paste in bash shell.

closes #250
  • Loading branch information
mikesmithgh committed May 23, 2024
1 parent 8bf3320 commit af16e06
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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)"
Expand Down
24 changes: 14 additions & 10 deletions lua/kitty-scrollback/kitty_commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand All @@ -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

Expand Down
95 changes: 95 additions & 0 deletions tests/kitty-scrollback/kitty_scrollback_fish_spec.lua
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit af16e06

Please sign in to comment.