mikesmithgh / kitty-scrollback.nvim

😽 Open your Kitty scrollback buffer with Neovim. Ameowzing!
Apache License 2.0
487 stars 11 forks source link

feat: add tmux support #115

Open tummetott opened 11 months ago

tummetott commented 11 months ago

tmux support

[!IMPORTANT]\ 🧪 tmux support is currently experimental This issue is used to track all tmux related issues or questions. Please comment on this issue instead of created a new issue while tmux support is considered experimental.

The following checklist is planned to be completed before moving these feature to stable.

This issue has been modified. See details on the original issue below.

Original issue below

Hello, First of all, I wanted to express my admiration for your plugin, which I had the pleasure of discovering after attending your talk at the nvim conference.

While experimenting with your plugin, I encountered a specific issue related to its compatibility with tmux. It appears that the kitty_get_text.extent setting do not seem to function as expected when used in conjunction with tmux. It has come to my attention that this setting, regardless of the value chosen—be it (all, first_cmd_output_on_screen, last_cmd_output, last_non_empty_output, last_visited_cmd_output, selection), —seems to consistently yield the same result. In essence, it consistently displays only the content visible on the screen, akin to the behavior one would expect when setting the setting to screen.

The root cause of this behavior lies in the fact that the kitty @ get-text command consistently retrieves only the content visible on the current screen. Unfortunately, tmux retains all text within its internal buffer, which remains inaccessible to the kitty scrollback history.

I understand that some of these modes, such as last_visited_cmd_output, are inherently dependent on kitty-specific features that tmux lacks. However, I wonder if there might be a way to at least make the full mode compatible with tmux.

I'd like to offer a couple of suggestions that might help in achieving this compatibility:

tmux capture-pane -p -S - -E -

The -p flag directs the output to stdout.

The -S and -E options specify the starting and ending line numbers for the capture. For instance, '0' represents the first line of the visible pane, and negative numbers refer to lines in the history. The use of '-' with -S denotes the start of the history, and '-' with -E indicates the end of the visible pane.

While I lack the confidence to submit a pull request myself, I sincerely hope that these suggestions prove useful in enhancing the compatibility of your plugin with tmux. I believe that such compatibility would greatly benefit users like me who rely on both tools in their development workflow.

tummetott commented 11 months ago

However, I'm not sure about how altering the input source from kitty @ get-text to tmux capture-pane -p -S - -E - might impact the handling of ANSI escape sequences. Upon examining your code, I've noticed that you employ sed for filtering out a number of these escape sequences. However, I lack clarity regarding the specific ANSI sequences that tmux generates, as they might differ from those produced by kitty?

mikesmithgh commented 11 months ago

@tummetott thanks! It looks like there is an -e flag that will keep the ANSI escape sequences.

tmux capture-pane -e -p -S - -E -

     capture-pane [-aepPqCJN] [-b buffer-name] [-E end-line] [-S start-line] [-t target-pane]
                   (alias: capturep)
             Capture the contents of a pane.  If -p is given, the output goes to stdout, otherwise to the buffer specified with -b or a new buffer if
             omitted.  If -a is given, the alternate screen is used, and the history is not accessible.  If no alternate screen exists, an error will be
             returned unless -q is given.  If -e is given, the output includes escape sequences for text and background attributes.  -C also escapes non-
             printable characters as octal \xxx.  -N preserves trailing spaces at each line's end and -J preserves trailing spaces and joins any wrapped
             lines.  -P captures only any output that the pane has received that is the beginning of an as-yet incomplete escape sequence.

             -S and -E specify the starting and ending line numbers, zero is the first line of the visible pane and negative numbers are lines in the
             history.  ‘-’ to -S is the start of the history and to -E the end of the visible pane.  The default is to capture only the visible contents of
             the pane.

I'd have to look into this a bit, but this seems like a good idea to me 😸.

Since kitty-scrollback.nvim runs in a kitten (separate process) it does not have access to the TMUX environment variable. I played around a bit and may be able to determine if tmux is running in kitty_scrollback_nvim.py with the code:

        print(w.child.foreground_processes)
        fg_process_entrypoints = list(
            map(
                lambda pd: next(
                    iter(pd.get(
                        'cmdline',
                        [],
                    )),
                    None,
                ),
                w.child.foreground_processes,
            ))
        print(fg_process_entrypoints)
        if 'tmux' in fg_process_entrypoints:
            print('perform alternative logic')
        else:
            print('perform normal logic')

output

[{'pid': 83576, 'cmdline': ['tmux'], 'cwd': '/Users/mike'}]
['tmux']
perform alternative logic

if this logic holds, I should be able to use tmux capture-pane instead of kitty @ get-text.

mikesmithgh commented 11 months ago

Reference: https://github.com/roosta/tmux-fuzzback

milch commented 10 months ago

I don't remember if GH sends out notifications when an issue is mentioned, but I added a PoC over at #151

mikesmithgh commented 9 months ago
        print(w.child.foreground_processes)
        fg_process_entrypoints = list(
            map(
                lambda pd: next(
                    iter(pd.get(
                        'cmdline',
                        [],
                    )),
                    None,
                ),
                w.child.foreground_processes,
            ))
        print(fg_process_entrypoints)
        if 'tmux' in fg_process_entrypoints:
            print('perform alternative logic')
        else:
            print('perform normal logic')

this approach does not work since the TMUX_PANE env variable is needed

mikesmithgh commented 9 months ago

Current plan:

Setup .tmux.conf with a command similar to

bind h run-shell 'kitty @ kitten /Users/mike/gitrepos/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py --env "TMUX=$TMUX" --env "TMUX_PANE=%#{pane_id}"'

kitty-scrollback.nvim logic:

mikesmithgh commented 9 months ago

🎉 I have added experimental tmux support to the latest release 4.1.0 🎉

See the README section tmux (🧪 experimental ) for setup instructions.

I have also added a checklist to this issue to include what I consider needs to be completed to make this feature stable.

If you have any questions or issues please comment on this PR. Thanks!

tummetott commented 9 months ago

AMAZING. I'll look into this soon. thanks you in advance

mikesmithgh commented 9 months ago

🎉 I have added cursor position fixes to take into account the tmux status line and added some basic test coverage in the latest release 4.2.1 🎉

jphalip commented 1 week ago

Hi there. I've followed the instructions in the README for tmux, but when I execute PREFIX+[, all I get is the following error:

'kitty @ kitten ~/.local/share/nvim/lazy/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py --env "TMUX=$TMUX" --env "TMUX_PANE=%8"' returned 1

Do you know how I could troubleshoot to figure out why that command is failing? Thanks!

jphalip commented 5 days ago

Just a quick note that I was able to open the tmux pane scrollback in Neovim in search mode like so:

tmux capture-pane -t$TMUX_PANE -e -p -S - -E - | nvim -R + -c 'lua require("lazy").load({ plugins = { "vim-plugin-AnsiEsc" } })' -c 'call AnsiEsc#AnsiEsc(0)' -c 'set nomodifiable' -c 'call feedkeys("?")' -

This uses the powerman/vim-plugin-AnsiEsc plugin to display the original terminal colors in Neovim.

If you don't care about the colors, then this simpler command works:

tmux capture-pane -p -S- | nvim -R + -c 'set nomodifiable' -c 'call feedkeys("?")' -

Anyways, I'm not sure if this is directly relevant to the work done in this issue, but I just thought I'd share in case it helps.