christoomey / vim-tmux-navigator

Seamless navigation between tmux panes and vim splits
MIT License
5.36k stars 332 forks source link

CTRL-L mapping refreshing screen instead of moving right to vsplit #189

Closed supernoveau closed 6 years ago

supernoveau commented 6 years ago

I use the brewed version of Vim (version 8.0.1300) on macOS Sierra. I am using vim-tmux-navigator, with the "default" config from the README.md.

Just this week the CTRL-L key mapping started refreshed the screen instead of moving right in a vsplit in vim from Netrw only file system view. It works from inside a file (i.e. after pressing enter from Netrw).

Any ideas on what this might be? Not sure what other information you need on my configurations or system, let me know.

Thank you.

christoomey commented 6 years ago

Hmm, sounds like Ctrl-l is being passed through to the underlying app. In the shell this will clear the screen, while vim will handle it as a navigation command.

My guess is the vim detection is failing somehow. Can you try:

  1. Exit all tmux sessions (run tmux list-sessions to confirm all closed), then start a new one to confirm that things are broken with your current config
  2. Assuming no change after restarting tmux, paste your tmux conf here
supernoveau commented 6 years ago

There's definitely no additional detached open sessions (error connecting to /private/tmp/tmux-501/default (No such file or directory) after `tmux list-sessions). CTRL-L refresh is definitely happening.

This is my config. Please note, I've tried both binding options - the one from your README.md (L27-35) and the one uncommented below (L37-52).

# remap prefix to Control + a
set -g prefix C-a

# bind 'C-a C-a' to type 'C-a'
bind C-a send-prefix
unbind C-b

# Start window numbering at 1
set -g base-index 1

# Allow for faster key repetition
set -s escape-time 0

# Use vim keybindings in copy mode
setw -g mode-keys vi

# Setup 'v' to begin selection as in Vim
#bind-key -t vi-copy v begin-selection
#bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

# Update default binding of `Enter` to also use copy-pipe
#unbind -t vi-copy Enter
#bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"

bind-key -T copy-mode-vi Enter send-keys -X copy-pipe "reattach-to-user-namespace pbcopy"

# Smart pane switching with awareness of Vim splits.
# See: https://github.com/christoomey/vim-tmux-navigator
#is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
#    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
#bind-key -n C-h if-shell "$is_vim" "send-keys C-h"  "select-pane -L"
#bind-key -n C-j if-shell "$is_vim" "send-keys C-j"  "select-pane -D"
#bind-key -n C-k if-shell "$is_vim" "send-keys C-k"  "select-pane -U"
#bind-key -n C-l if-shell "$is_vim" "send-keys C-l"  "select-pane -R"
#bind-key -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"

# Smart pane switching with fzf (instead of above)
is_vim="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?(view|n?vim?x?)(diff)?$'"
is_fzf="ps -o state= -o comm= -t '#{pane_tty}' \
    | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?fzf$'"
bind -n C-h run "($is_vim && tmux send-keys C-h) || \
    tmux select-pane -L"
bind -n C-j run "($is_vim && tmux send-keys C-j)  || \
    ($is_fzf && tmux send-keys C-j) || \
    tmux select-pane -D"
bind -n C-k run "($is_vim && tmux send-keys C-k) || \
    ($is_fzf && tmux send-keys C-k)  || \
    tmux select-pane -U"
bind -n C-l run "($is_vim && tmux send-keys C-l) || \
    tmux select-pane -R"
bind-key -n C-\ if-shell "$is_vim" "send-keys C-\\" "select-pane -l"

# Fix macOS Sierra copy paste problem https://github.com/tmux/tmux/issues/543#issuecomment-248980734
set -g default-shell $SHELL 
set -g default-command "reattach-to-user-namespace -l ${SHELL}"

######################
### DESIGN CHANGES ###
######################

# panes
set -g pane-border-fg black
set -g pane-active-border-fg brightred

## Status bar design
# status line
set -g status-justify left
set -g status-bg default
set -g status-fg colour12
set -g status-interval 2

# messaging
set -g message-fg black
set -g message-bg yellow
set -g message-command-fg blue
set -g message-command-bg black

#window mode
setw -g mode-bg colour6
setw -g mode-fg colour0

# window status
setw -g window-status-format " #F#I:#W#F "
setw -g window-status-current-format " #F#I:#W#F "
setw -g window-status-format "#[fg=magenta]#[bg=black] #I #[bg=cyan]#[fg=colour8] #W "
setw -g window-status-current-format "#[bg=brightmagenta]#[fg=colour8] #I #[fg=colour8]#[bg=colour14] #W "
setw -g window-status-current-bg colour0
setw -g window-status-current-fg colour11
setw -g window-status-current-attr dim
setw -g window-status-bg green
setw -g window-status-fg black
setw -g window-status-attr reverse

# Info on left (I don't have a session display for now)
set -g status-left ''

# loud or quiet?
set-option -g visual-activity off
set-option -g visual-bell off
set-option -g visual-silence off
set-window-option -g monitor-activity off
set-option -g bell-action none

set -g default-terminal "screen-256color"

# The modes {
setw -g clock-mode-colour colour135
setw -g mode-attr bold
setw -g mode-fg colour196
setw -g mode-bg colour238

# }
# The panes {

set -g pane-border-bg colour235
set -g pane-border-fg colour238
set -g pane-active-border-bg colour236
set -g pane-active-border-fg colour51

# }
# The statusbar {

set -g status-position bottom
set -g status-bg colour234
set -g status-fg colour137
set -g status-attr dim
set -g status-left ''
set -g status-right '#[fg=colour233,bg=colour241,bold] %d/%m #[fg=colour233,bg=colour245,bold] %H:%M:%S '
set -g status-right-length 50
set -g status-left-length 20

setw -g window-status-current-fg colour81
setw -g window-status-current-bg colour238
setw -g window-status-current-attr bold
setw -g window-status-current-format ' #I#[fg=colour250]:#[fg=colour255]#W#[fg=colour50]#F '

setw -g window-status-fg colour138
setw -g window-status-bg colour235
setw -g window-status-attr none
setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F '

setw -g window-status-bell-attr bold
setw -g window-status-bell-fg colour255
setw -g window-status-bell-bg colour1

# }
# The messages {

set -g message-attr bold
set -g message-fg colour232
set -g message-bg colour166

# }
christoomey commented 6 years ago

Hmmm, I'm not seeing anything that looks off in the tmux conf.

To confirm, is it only C-l that behaves unexpectedly, or do others of the key bindings also behave oddly?

Also, can you confirm what the ps process list looks like for both a vim pane, and a non-vim pane? Steps to get that:

  1. Use prefix-q to get the pane's ID
  2. Get the pane's tty by running the following with the ID from above replaced tmux display-message -t <ID-HERE> -p '#{pane_tty}' | xargs ps -o state= -o comm= -t
blueyed commented 6 years ago

Have you checked :verb map <c-l> ? Maybe there is a buffer specific mapping?

supernoveau commented 6 years ago

@christoomey Yes, it is only CTRL-L that is behaving unexpectedly.

Response from your command in a tmux pane is:

Ss   -bash
S+   xargs
R+   ps

Response in a vim pane is:

Ss   -bash
S+   vim

@blueyed Response from :verb map <c-l> is:

n  <C-L>        @<Plug>NetrwRefresh
        Last set from /usr/local/Cellar/vim/8.0.1300/share/vim/vim80/autoload/netrw.vim
n  <C-L>       * :TmuxNavigateRight<CR>
        Last set from ~/dotfiles/vim/plugged/vim-tmux-navigator/plugin/tmux_navigator.vim
blueyed commented 6 years ago

Might be netrw overwriting the mapping for that buffer then: it probably refreshes your dir listing.

supernoveau commented 6 years ago

Thanks for your help on this @blueyed @christoomey.

So I got to a solution that is probably a hack, but a working one!

I added the following to my ~/.vimrc:

augroup netrw_mapping
  autocmd!
  autocmd filetype netrw call NetrwMapping()
augroup END

function! NetrwMapping()
  nnoremap <buffer> <c-l> :wincmd l<cr>
endfunction

I couldn't directly call the TmuxNavigateRight plugin function because it is scoped to the plugin.

See here and here for more.

chmanie commented 4 years ago

Thanks @almccann, that's what I needed. I modified it a bit to not show the command in the status bar:

augroup netrw_mapping
  autocmd!
  autocmd filetype netrw call NetrwMapping()
augroup END

function! NetrwMapping()
  nnoremap <silent> <buffer> <c-l> :TmuxNavigateRight<CR>
endfunction
nfischer commented 4 years ago

Any chance this could get merged into the plugin?

mgarort commented 4 years ago

In my experience this is what happens with <Plug> mappings: even if you try to remap them manually, the <Plug> mapping will prevail.

The solution is to map the <Plug>NetrwRefresh command to something else, thus releasing <C-l> so that it can be used in manual keybindings. For instance, I've added to my .vimrc:

" Freed <C-l> in Netrw
nmap <leader><leader><leader><leader><leader><leader>l <Plug>NetrwRefresh

This binds <Plug>NetrwRefresh to a ridiculous key combination (I will never ever press <leader> so many times in a row), which is what I want because I have no use for this command so I don't intend to use it.

Now I can bind <C-l> to whatever I need :)

mirosval commented 3 years ago

I've solved this in .vim/after/ftplugin/netrw.vim with the following contents:

nnoremap <buffer> <C-l> :TmuxNavigateRight<cr>
saifazmi commented 9 months ago

Solution for NeoVim in lua

place the following remap in: ~/.config/nvim/after/ftplugin/netrw.lua

vim.keymap.set('n', '<c-l>', ':TmuxNavigateRight<CR>', {
    silent = true, buffer = true
})
zeb139 commented 5 months ago

Edit: I'm an idiot and had gotten it to work by simply commenting out the offending netrw binding in nvim itself. I've removed the original comment.

The less hacky solution that is working for me with NeoVim is to put the following in init.lua before most everything else:

vim.api.nvim_set_keymap('n', '<c-l>', "<Plug>NetrwRefresh", { noremap = true, silent = true , nowait = true});                                       

require('lazy').setup("plugins")   -- ^ Must go before Lazy setup, else it doesn't work
MohammadLashkari commented 5 months ago

Hi, I like to navigate between Netrw and my code using <C-l> and <C-h>. However, when I switch to the Netrw right split, I can't return to the editor with <C-l> when using the default explore style. Additionally, when the explore style is set to tree (let g:netrw_liststyle=3), pressing <C-l> opens a new explorer window. I'm not sure why it behaves this way, but unbinding <C-l> seems to fix the issue. Wouldn't it be better if the plugin unbound the keymap by default?

Here's the solution I've been using:

Vim

autocmd FileType netrw silent! unmap <buffer> <C-L>

Neovim

vim.api.nvim_create_autocmd("FileType", {
  pattern = "netrw",
  callback = function()
    vim.api.nvim_buf_del_keymap(0, 'n', '<C-L>')
  end,
})
nfischer commented 5 months ago

I wrote PR #393 to pull a workaround directly into the plugin. You should be able to remove the autocommand workarounds from your vimrc/init.lua if you want.