Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switching in Vim doesn't work (Solution also posted here) #418

Open
BriHan-Tech opened this issue Dec 2, 2024 · 1 comment
Open

Switching in Vim doesn't work (Solution also posted here) #418

BriHan-Tech opened this issue Dec 2, 2024 · 1 comment

Comments

@BriHan-Tech
Copy link

BriHan-Tech commented Dec 2, 2024

Problem

When I have windows in vim, I am unable to switch between them; however, I am able to switch between Vim windows and Tmux Panes

System Specs

  1. Apple M3 Pro Sequoia 15.1.1
  2. NVIM v0.10.2
  3. tmux 3.5a

Solution

From some debugging work, I realized the is_vim check currently doesn't always accurately return if the process is a vim process or not. This is because vim processes could be nested.

To properly check if the process is a vim process or not, I have wrote the script that goes through the descendent processes to check if there is a vim process or not.

Here is the repository with my solution: https://github.com/BriHan-Tech/is-vim

Note:

  1. I definitely know there is a better solution; however, for now, I just needed it to work.
  2. pstree might require users to install something extra; however, you can probably do pstree with regex to get an one-line solution.

Here is the code for my solution:

is_vim.sh

#!/usr/bin/env bash

pane_pid=$(tmux display -p "#{pane_pid}")

[ -z "$pane_pid" ] && exit 1 

# Retrieve all descendant processes of the tmux pane's shell by iterating through the process tree.
# This includes child processes and their descendants recursively.
descendants=$(ps -eo pid=,ppid=,stat= | awk -v pid="$pane_pid" '{
    if ($3 !~ /^T/) {
        pid_array[$1]=$2
    }
} END {
    for (p in pid_array) {
        current_pid = p
        while (current_pid != "" && current_pid != "0") {
            if (current_pid == pid) {
                print p
                break
            }
            current_pid = pid_array[current_pid]
        }
    }
}')

if [ -n "$descendants" ]; then

    descendant_pids=$(echo "$descendants" | tr '\n' ',' | sed 's/,$//')

    ps -o args= -p "$descendant_pids" | grep -iqE "(^|/)([gn]?vim?x?)(diff)?"

    if [ $? -eq 0 ]; then
        exit 0
    fi
fi

exit 1

tmux.conf

bind-key -n 'C-h' if-shell '~/.config/tmux/plugins/is-vim/is_vim.sh' 'send-keys C-h' 'select-pane -L'
bind-key -n 'C-j' if-shell '~/.config/tmux/plugins/is-vim/is_vim.sh' 'send-keys C-j' 'select-pane -D'
bind-key -n 'C-k' if-shell '~/.config/tmux/plugins/is-vim/is_vim.sh' 'send-keys C-k' 'select-pane -U'
bind-key -n 'C-l' if-shell '~/.config/tmux/plugins/is-vim/is_vim.sh' 'send-keys C-l' 'select-pane -R'

bind-key -T copy-mode-vi 'C-h' select-pane -L
bind-key -T copy-mode-vi 'C-j' select-pane -D
bind-key -T copy-mode-vi 'C-k' select-pane -U
bind-key -T copy-mode-vi 'C-l' select-pane -R
@S1M1S
Copy link

S1M1S commented Dec 9, 2024

Your solution works for me on:

Apple M4 Sequoia 15.1.1
NVIM v0.10.2
tmux 3.5a

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants