Search code examples
zshgnome-terminal

How to bind CTRL + Enter in zsh?


I want to bind Ctrl+Enter ↵ in zsh:

bindkey '^M' autosuggest-execute

But it seems that the terminal sends the same escape sequence for any modifier key except for Alt.

$ showkey -a

Press any keys - Ctrl-D will terminate this program

^M       13 0015 0x0d # Enter
^M       13 0015 0x0d # CTRL  + Enter
^M       13 0015 0x0d # SHIFT + Enter
^[^M     27 0033 0x1b # ALT   + Enter
         13 0015 0x0d

I am not sure if the problem is specific to gnome-terminal. I have also tested this in mate-terminal and xterm and the results were the same. Is there any way to detect CTRL + Enter?


Solution

  • Here is the solution for xterm, gnome-terminal and any other terminal emulator for the XWindow system.

    Note that mapping Ctrl + Enter to a specific shell command can be specifically done with xterm, in a specific way that has no impact on other terminal emulators running on the same X Server. With gnome-terminal, there is a more generic solution, but it will apply simultaneously to every terminal emulators on your XWindow server, not only gnome-terminal. So, depending on your needs, you have to choose one of these two solutions.

    First, here is the solution that fits specifically with xterm:

    Let's bind Ctrl + Enter to a sequence that is not already bound by other combinations: with xterm, this can be done by specifying some X resources to populate the translations table. For instance, bind to Esc + M. Then, use bindkey in zsh to bind this specific sequence to your ZLE function (autosuggest-execute according to you question).

    To try, just follow those steps:

    1- launch xterm this way:

    % xterm -xrm '*.VT100.translations: #override Ctrl <Key>Return: string(0x1b) string("M")'
    

    Note: we have used Return, but this is Enter that we will map this way.

    2- in the new xterm window, use bindkey:

    % bindkey '^[M' autosuggest-execute
    

    3- now type CTRL-Enter to run autosuggest-execute

    Here is the more generic solution, for almost every terminal emulators:

    Like above, let's bind Ctrl + Enter to a sequence that is not already bound by other combinations (we choose Esc + M here). Use the Compose (5) X11 mechanism: add a file $HOME/.XCompose containing a specific mapping for the multi-key input sequence Ctrl + M. Then, use bindkey in zsh to bind this specific sequence to your ZLE function (autosuggest-execute according to your question).

    To try, just follow those steps:

    1- create a new file named $HOME/.XCompose

    Add the following content in this file:

    include "%L"
    ! Ctrl <Return> : "\033M"
    

    Note 1: we have used Return, but this is Enter that we will map this way.

    Note 2: the ! is not a comment mark, it is important to keep it at the beginning of this line.

    Note 3: the first line (include...) is here to keep other shortcuts working (for instance ^ + e mapped into ê).

    2- now, you can launch gnome-terminal

    3- in the new gnome-terminal window, use bindkey:

    % bindkey '^[M' autosuggest-execute
    

    4- now type CTRL-Enter to run autosuggest-execute