zellij-org / zellij

A terminal workspace with batteries included
https://zellij.dev
MIT License
20.45k stars 635 forks source link

Can't bind Ctrl-j #2679

Closed willothy closed 4 months ago

willothy commented 1 year ago

zellij --version: 0.37.2 stty size: 50 254 uname -av or ver(Windows): Linux ... 6.4.8-arch1-1 #1 SMP PREEMPT_DYNAMIC ... x86_64 GNU/Linux

wezterm --version: wezterm 20230717-111633-94ab0496

I'm attempting to setup smooth pane changes between Neovim, Wezterm and Zellij. My intended bindings use Ctrl h/j/k/l to move focus, and Alt h/j/k/l to resize. All of those work, except for Ctrl j, and I can't figure out why. I've disabled default keybinds in Zellij, ensured that the key isn't bound to anything in Wezterm, and still can't get it to work as expected.

To reproduce:

willothy commented 1 year ago

Seems like a termwiz issue, see https://github.com/wez/wezterm/issues/2511

Edit: Maybe not, I've just tested it and termwiz is able to properly register Ctrl-j.

p00f commented 1 year ago

I can't bind Ctrl-m either, can you @willothy ?

willothy commented 1 year ago

I can't bind Ctrl-m either, can you @willothy ?

I haven't tried, no <C-j> was a dealbreaker for me, but I'll test that out today and update here.

ssipos90 commented 1 year ago

I can't bind it either. Ctrl-j sends an enter. In tmux navigation is fine.

    normal clear-defaults=true {
        bind "Ctrl a" { SwitchToMode "Tmux"; }

        bind "Ctrl h" { MoveFocus "Left"; }
        bind "Ctrl j" { MoveFocus "Down"; }
        bind "Ctrl k" { MoveFocus "Up"; }
        bind "Ctrl l" { MoveFocus "Right"; }
    }

zsh 5.9 zellij 0.37.2 alacritty 0.12.2 (9d9982df) Manjaro Linux 23.0.0

flinesse commented 10 months ago

It seems that zellij mimics the behavior of many line editor's response to control sequences. As a quick test in addition to https://github.com/zellij-org/zellij/issues/2846#issuecomment-1760310459, I tried unbinding Ctrl j by giving bindkey -r '^J' in zsh and using the following keybinds with clear-defaults=true at the top level:

    shared_except "locked" {
        bind "Ctrl g"          { SwitchToMode "Locked"; }
        bind "Ctrl q"          { Detach; }
        bind "Ctrl Q"          { Quit; }
        bind "Ctrl ;"          { NewPane "Down"; }
        bind "Ctrl '"          { NewPane "Right"; }
        bind "Ctrl j"          { MoveFocus "Down"; }
        bind "Ctrl k"          { MoveFocus "Up"; }
        bind "Ctrl h"          { MoveFocusOrTab "Left"; }
        bind "Ctrl l"          { MoveFocusOrTab "Right"; }
        ...
    }

Doing Ctrl j now in zellij gives me a sound indicator by macOS that no program responded to this input.

There should probably be a caveat in the allowable keybinds documentation that mentions this behavior for anyone looking to wholly customize zellij to their liking.

swaits commented 10 months ago

+1 on this on MacOS, wezterm, fish.

fishel-feng commented 10 months ago

+1

Vinh-CHUC commented 6 months ago

+1 on macos/tmux/zsh if that's relevant

alankritjoshi commented 5 months ago

I was losing my head over this today, thanks for reporting this!

Until this is fixed, I will be using alt-centered-config.

cavanaug commented 5 months ago

fwiw, as a vi user this defect is preventing me from really evaluating and switching to zellij

hiasr commented 4 months ago

At the moment, the issue lies with the way Zellij currently processes the key events. This is done through the termwiz crate provided by wezterm. They follow the ASCII specification where Ctrl+J is bound to line feed (\n) and Ctrl+m is bound to carriage return (\r), they do this by hardcoding these inputs to enter.

Binding Ctrl+j in tmux works because they first process the raw keybindings and send these to the terminal instead of converting them to enters. Most terminals nowadays use Ctrl+m as the enter command, you can try binding this in tmux and will see that your enter key now does the same as Ctrl+m.

A possible solution would be to either handle these cases before parsing or request changes in upstream to be able to not parse control sequences (which would then need to be done in the client). Both solutions would be pretty hacky. I am mostly in favor of solution 1, with the note that it only happens if a keybinding is bound to e.g Ctrl+j, in order to prevent compatibility issues with other terminals which might use Ctrl+j as enter. I would be willing to implement this, but would first like feedback if the maintainers support this. @imsnif

imsnif commented 4 months ago

Hi @hiasr - we preprocess such events in this function: https://github.com/zellij-org/zellij/blob/fca7a209d2c90ed8e2447f1c60ab630bc9455c13/zellij-utils/src/input/mod.rs#L61

If you can get it to work from there (possibly passing the client's keybindings to be able to see of Ctrl j was bound), I'd be willing to consider it. But I'll ask any such solution to be rigorously (manually) tested in all popular modern terminals to make sure we're not breaking anything when bound/unbound.

hiasr commented 4 months ago

This can be closed now that #3307 has been merged!