mrjones2014 / smart-splits.nvim

🧠 Smart, seamless, directional navigation and resizing of Neovim + terminal multiplexer splits. Supports tmux, Wezterm, and Kitty. Think about splits in terms of "up/down/left/right".
MIT License
990 stars 43 forks source link

[Bug]: Limitations with Kitty navigation over SSH #103

Closed mrjones2014 closed 6 months ago

mrjones2014 commented 1 year ago

Similar Issues

Neovim Version

n/a doesn't matter what version

Multiplexer Integration

Wezterm and Kitty both affected

Steps to Reproduce

  1. Create split
  2. SSH into a remote server and run nvim from the remote server in the split

Expected Behavior

You can use the keymaps to navigate between Neovim split panes.

Actual Behavior

You can't because the pane does not report the remote foreground process name, so the keymaps can't check if nvim is running in the pane.

Minimal Configuration to Reproduce

local root = vim.fn.fnamemodify('./.repro', ':p')

-- set stdpaths to use .repro
for _, name in ipairs({ 'config', 'data', 'state', 'cache' }) do
  vim.env[('XDG_%s_HOME'):format(name:upper())] = root .. '/' .. name
end

-- bootstrap lazy
local lazypath = root .. '/plugins/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
  vim.fn.system({
    'git',
    'clone',
    '--filter=blob:none',
    '--single-branch',
    'https://github.com/folke/lazy.nvim.git',
    lazypath,
  })
end
vim.opt.runtimepath:prepend(lazypath)

-- install plugins
local plugins = {
  -- do not remove the colorscheme! it makes testing nicer
  'folke/tokyonight.nvim',
  'mrjones2014/smart-splits.nvim',
  -- add any other pugins here
}

require('lazy').setup(plugins, {
  root = root .. '/plugins',
})

require('smart-splits').setup({
  -- add any options here
})

-- recommended mappings
-- resizing splits
-- these keymaps will also accept a range,
-- for example `10<A-h>` will `resize_left` by `(10 * config.default_amount)`
vim.keymap.set('n', '<A-h>', require('smart-splits').resize_left)
vim.keymap.set('n', '<A-j>', require('smart-splits').resize_down)
vim.keymap.set('n', '<A-k>', require('smart-splits').resize_up)
vim.keymap.set('n', '<A-l>', require('smart-splits').resize_right)
-- moving between splits
vim.keymap.set('n', '<C-h>', require('smart-splits').move_cursor_left)
vim.keymap.set('n', '<C-j>', require('smart-splits').move_cursor_down)
vim.keymap.set('n', '<C-k>', require('smart-splits').move_cursor_up)
vim.keymap.set('n', '<C-l>', require('smart-splits').move_cursor_right)
-- swapping buffers between windows
vim.keymap.set('n', '<leader><leader>h', require('smart-splits').swap_buf_left)
vim.keymap.set('n', '<leader><leader>j', require('smart-splits').swap_buf_down)
vim.keymap.set('n', '<leader><leader>k', require('smart-splits').swap_buf_up)
vim.keymap.set('n', '<leader><leader>l', require('smart-splits').swap_buf_right)

-- add anything else here
vim.opt.termguicolors = true
-- do not remove the colorscheme! it makes testing nicer
vim.cmd([[colorscheme tokyonight]])

Additional Details and/or Screenshots

This appears to be a limitation in the multiplexer of Wezterm and Kitty.

Wezterm

Note Issue has been resolved for Wezterm by #105

pane:get_foreground_process_name():

This information is only available for local panes. Multiplexer panes do not report this information. Similarly, if you are using eg: ssh to connect to a remote host, you won't be able to access the name of the remote process that is running.

Opened discussion: https://github.com/wez/wezterm/discussions/3648

Kitty

Opened discussion: https://github.com/kovidgoyal/kitty/discussions/6229

mrjones2014 commented 1 year ago

cc @phgz

mrjones2014 commented 1 year ago

Edited issue to indicate that it is solved for Wezterm

mrjones2014 commented 1 year ago

Kitty added user var support.

mrjones2014 commented 6 months ago

I believe this is fixed by #175

AniAggarwal commented 5 months ago

This unfortunately still does not work for me using the steps outlined in the readme, nor with a large assortment of options I tried. What should I be doing to connect over ssh? Should I be using the ssh kitten? Also, should I be using the -R flag to set up some sort of forwarding? And should I set the forward_remote_control option? I see the readme says to use /tmp/mykitty but the documentation for truly convenient ssh says that abstract sockets don't work.

Sorry about all the questions; no combinations of those above options seemed to work for my use case.

I have kitty + nvim installed on local and remote machine. I also have identical nvim and kitty configs on both ends. I am able to create a split and then kitten ssh to my remote machine and enter nvim. But, I cannot switch from nvim across a kitty split. I can go the other way. SmartSplitLog shows that it detects kitty backend.

If I ssh without the kitten then no backend is detected and I can switch across kitty splits but cannot switch within nvim splits (i.e. instead of moving between the two splits in the nvim window, it will move to a different kitty window).

Let me know what I can do help debug, happy to provide log files and try some stuff :)

mrjones2014 commented 5 months ago

I'm not too sure unfortunately. I don't use Kitty, a lot of the kitty support stuff has come from community contributions. First thing I would check is if you're on the latest version of Kitty (or at least one that supports user variables).

Perhaps some other Kitty users could chime in here. @phgz @oddnugget does it work for you in Kitty? Are you using the SSH Kitten or regular ssh command?

And should I set the forward_remote_control option?

That could possibly be the issue, try setting that and see if it works.

abstract sockets don't work

Not too sure what you mean by "abstract" sockets. Could you drop a link to the documentation in question?

AniAggarwal commented 5 months ago

Thanks for making and maintaining this plugin! I unfortunately haven't been able to meaningfully debug since I don't have a great understanding of sockets. I'll try to take some time over the next few days and learn how this works and maybe I'll find the issue myself or at least be able to provide more meaningful debugging outputs.

I believe the abstract sockets refers to using @mykitty as a socket rather than /tmp/mykitty, from this documentation. Here's some more details on it.

Here's a discussion on the Kitty side trying to debug the kitty side. https://github.com/kovidgoyal/kitty/discussions/5891#discussioncomment-9852795

I can confirm that the plugin works as expected following the steps in the above discussion post when ssh'd to localhost, but not while ssh'd to a remote host.

oddnugget commented 5 months ago

Perhaps some other Kitty users could chime in here. @phgz @oddnugget does it work for you in Kitty? Are you using the SSH Kitten or regular ssh command?

I'm using the kitten ssh command with the allow_remote_control yes and listen_on unix:/tmp/mykitty set in the kitty config. I also have a /kitty/ssh.conf with the host alias and forward_remote_control yes set for that host.

There was a lot of trial and error that eventually led to me getting it working, so im not certain which configs are necessary.

mrjones2014 commented 5 months ago

I'm guessing that forward_remote_control yes is needed. @oddnugget are you on Linux or macOS?

I'm wondering if both Linux and macOS need to use unix:/tmp/mykitty style socket path since abstract sockets (@mykitty) won't work.

oddnugget commented 5 months ago

I'm guessing that forward_remote_control yes is needed. @oddnugget are you on Linux or macOS?

I'm wondering if both Linux and macOS need to use unix:/tmp/mykitty style socket path since abstract sockets (@mykitty) won't work.

Im on macOS

AniAggarwal commented 5 months ago

I am unfortunately also on Mac OS and have a similar config. I am able to recreate the issue with these steps every time. When using the exact setup you have just mentioned I still run into the same issue of being able to nagivate within neovim but not across kitty windows.

Smart Splits does indeed detect the kitty backend. Using kitten ssh with the -v command shows the ports are being allocated/forwarded correctly. I tried setting the log level to trace but wasn't able to get any output. What else can I do to debug this? It seems like the kitty side is working.

mrjones2014 commented 4 months ago

Sorry for the delay. It's been crazy at my day job.

I tried setting the log level to trace but wasn't able to get any output.

In smart-splits.nvim or in Kitty? If you set the log level like so

require('smart-splits').setup({ log_level = 'trace' })

you should definitely be getting logs in :SmartSplitsLog so that's strange 🤔