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

<C-6> mappings dont work #170

Closed
MaikoID opened this issue Aug 12, 2016 · 13 comments
Closed

<C-6> mappings dont work #170

MaikoID opened this issue Aug 12, 2016 · 13 comments
Labels
input Keyboard or other input events

Comments

@MaikoID
Copy link

MaikoID commented Aug 12, 2016

Hey guys very nice work so far.

I'm having a strange behaviour where I can't switch between current and previous windows buffer from nvim-qt, nvim in terminal works just fine.
There is no CTRL printed when I do the cmd bellow:
:map <C-V><C-6>
it gets replaced by just :map 6

Any map using CTRL+NUMBER simple doesn't work; This is a huge problem for me because I'm used to change my buffer by numbers =|

@equalsraf
Copy link
Owner

Ok we need to narrow this down a bit, Ctrl-number mappings should work, for example the following works for me in normal mode

nmap <C-1> iC-1 is ok<CR><ESC>

But other numbers e.g. 6 dont work

nmap <C-6> iC-6 is ok<CR><ESC>

I could use some more info about your setup

  • what system are you running on Linux/Windows
  • What keyboard layout do you use?

Here is a code snippet if anyone wants to debug it

diff --git a/src/gui/shell.cpp b/src/gui/shell.cpp
index 05ca325..3f6996a 100644
--- a/src/gui/shell.cpp
+++ b/src/gui/shell.cpp
@@ -563,12 +563,14 @@ void Shell::keyPressEvent(QKeyEvent *ev)

        // FIXME mousehide - conceal mouse pointer when typing

+       qDebug() << "Received keypress" << ev->text() << ev->key();
        QString inp = Input.convertKey(ev->text(), ev->key(), ev->modifiers());
        if (inp.isEmpty()) {
                QWidget::keyPressEvent(ev);
                return;
        }

+       qDebug() << "Sending input" << inp;
        m_nvim->neovimObject()->vim_input(m_nvim->encode(inp));
        // FIXME: bytes might not be written, and need to be buffered
 }

For C-6 it gets me (Qt::key reference)

Received keypress "" 16777249
Received keypress "\u001E" 54
Sending input "\u001E"
Received keypress "" 16777250

@MaikoID
Copy link
Author

MaikoID commented Aug 12, 2016

Hi, thanks for your answer, see the solicited info bellow:

  • Ubuntu 14.04
  • pt-br

BR

@MaikoID
Copy link
Author

MaikoID commented Aug 23, 2016

Update:
I had to install Ubuntu 16.04 because a fault intel video driver;
I'm glad I can't reproduce this issue for now, because it's working as expected in on 16.04.

BR

@lambdalisue
Copy link
Contributor

lambdalisue commented Oct 5, 2016

In case you didn't aware. It seems Ctrl-6 is equal to Ctrl-^ in Vim.

Mostly the ^ character is positioned on the 6 key,
pressing CTRL and 6 then gets you what we call CTRL-^.

http://vimdoc.sourceforge.net/htmldoc/editing.html#CTRL-^

@equalsraf equalsraf added the input Keyboard or other input events label Jul 25, 2018
@equalsraf equalsraf changed the title Missing CTRL+NUMBER mappings ?? <C-6> mappings dont work Jul 25, 2018
@skyegecko
Copy link

skyegecko commented Apr 15, 2020

I'm currently experiencing this issue. I use <C-6> according to its standard Vim mapping as an alias of <C-^>

Environment: Windows 10

NVIM v0.5.0-427-g1f56f9a4b
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compilation: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe /DWIN32 /D_WINDOWS /W3 /MD /Zi /O2 /Ob1 /DNDEBUG /W3 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -DWIN32 -D_WIN32_WINNT=0x0600 -DINCLUDE_GENERATED_DECLARATIONS -DUTF8PROC_STATIC -DNVIM_MSGPACK_HAS_FLOAT32 -DNVIM_UNIBI_HAS_VAR_FROM -DMIN_LOG_LEVEL=3 -IC:/projects/neovim/build/config -IC:/projects/neovim/src -IC:/projects/nvim-deps/usr/include -IC:/projects/neovim/build/src/nvim/auto -IC:/projects/neovim/build/include
Compiled by appveyor@APPVYR-WIN

I'm not sure how to get the neovim-qt version but it is the one that is bundled with the Appveyor build.

Below I build from current master, which reproduces the issue.


nvim running under the windows terminal supports using <C-6> to switch buffers. Typing <C-V><C-6> in insert mode under nvim on the terminal results in the control character being literally inserted, and displayed as ^^, as expected.

When in neovim-qt, typing <C-V><C-6> in insert mode initially doesn't perform any input. If I press <C-6> another two times, the resulting inserted text is <C-ÿ>. Indeed, by entering various numbers while holding the control key down, a variety of key combinations are output. All require three numbers to be entered.

The problem with this is that it becomes impossible to make a mapping for a single Ctrl + number keypress, as it seems the program is waiting for further input before deciding what to do.


I uncommented the keypress debug lines in the source and built with Qt 5.12.8 in Debug mode. Running under QTCreator I get the following output:

QKeyEvent ev: QKeyEvent(KeyPress, Key_Control, ControlModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"

or, when trying to enter the control character via Ctrl-V:

QKeyEvent ev: QKeyEvent(KeyPress, Key_Control, ControlModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_V, ControlModifier, text="\u0016")
   "\u0016"
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"

@jgehrig
Copy link
Collaborator

jgehrig commented Apr 15, 2020

@dutchgecko

Thanks for the detailed description! We should be able to fix this if there isn't platform-specific logic getting in the way...

I'm not sure how to get the neovim-qt version but it is the one that is bundled with the Appveyor build.

nvim-qt --version now works. It provides version and some additional information.

This was added recently, so if it doesn't work you're on an old version. The version you built from master is what we should use for testing/validation of this issue.

This looks like this is a Windows input bug. I cannot reproduce on Linux.

I'm struggling to follow the desired scenario here... Sorry, I am not familiar with or <C-^>. Is the issue that you cannot map <C-X>, where X is a number?

It would help me if you write could you write a quick set of repro steps in the following format:

Repro Steps:

  1. Open neovim-qt nvim-qt -- -u NONE or neovim nvim -u NONE
  2. ??? Manually configure your maps here ??? Ex) :map ...
  3. ??? Describe the keys you press in order ??? Ex) Press Ctrl + V

Observe: X happened but I expected Y.

For example, here is what I did to verify on Linux:

  1. Open neovim-qt nvim-qt -- -u NONE
  2. Enter 'Insert Mode', press i key.
  3. Press Ctrl + V keys
  4. Notice ^ character appears in the buffer.
  5. Press Ctrl + 6 keys
  6. Notice ^^ appears in the buffer.

Observe: The ^^ is inserted as you described for Windows nvim terminal.

Don't leave any room for interpretation or configuration differences. Be very explicit.

I think getting this working is a matter of massaging the QKeyEvents properly in input.cpp. I am hoping this is just a matter of handling the correct corner cases. :)

@skyegecko
Copy link

skyegecko commented Apr 15, 2020

Each of the following numbered steps were carried out with a fresh instance of nvim-qt -- -u NONE. Spoilers: skip to step 4 for a let-down.

  1. Key sequence: i<C-v><C-6>
  • Expected: Control sequence in buffer, displayed as ^^
  • Result: Only the leading caret ^ is displayed, nvim is still waiting for input
  • Key sequence output:
QKeyEvent ev: QKeyEvent(KeyPress, Key_I, text="i")
   "i"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Control, ControlModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_V, ControlModifier, text="\u0016")
   "\u0016"
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"
  1. Key sequence: :e 1.txt<CR>:e 2.txt<CR><C-S-6><C-S-6>
  • Expected: open two buffers named 1.txt and 2.txt, switch between them
  • Result: opened two buffers named 1.txt and 2.txt, switched between them
    • Since <C-6> and <C-S-6> are aliases of eachother, I expect step 3 to have the same results
  • Key sequence output:
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Colon, ShiftModifier, text=":")
   ":"
QKeyEvent ev: QKeyEvent(KeyPress, Key_E, text="e")
   "e"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_1, text="1")
   "1"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Period, text=".")
   "."
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_X, text="x")
   "x"
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Return, text="\r")
   "<Enter>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Colon, ShiftModifier, text=":")
   ":"
QKeyEvent ev: QKeyEvent(KeyPress, Key_E, text="e")
   "e"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_2, text="2")
   "2"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Period, text=".")
   "."
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_X, text="x")
   "x"
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Return, text="\r")
   "<Enter>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Control, ShiftModifier|ControlModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_AsciiCircum, ShiftModifier|ControlModifier, text="\u001E")
   "<S-\u001E>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_AsciiCircum, ShiftModifier|ControlModifier, text="\u001E")
   "<S-\u001E>"
  1. Key sequence is :e 1.txt<CR>:e 2.txt<CR><C-6><C-6>
  • Expected: open two buffers named 1.txt and 2.txt, switch between them, as for step 2
  • Result: buffer does not switch. The showcmd area at bottom right displays 66, as if the Ctrl key wasn't being pressed.
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Colon, ShiftModifier, text=":")
   ":"
QKeyEvent ev: QKeyEvent(KeyPress, Key_E, text="e")
   "e"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_1, text="1")
   "1"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Period, text=".")
   "."
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_X, text="x")
   "x"
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Return, text="\r")
   "<Enter>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Colon, ShiftModifier, text=":")
   ":"
QKeyEvent ev: QKeyEvent(KeyPress, Key_E, text="e")
   "e"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_2, text="2")
   "2"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Period, text=".")
   "."
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_X, text="x")
   "x"
QKeyEvent ev: QKeyEvent(KeyPress, Key_T, text="t")
   "t"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Return, text="\r")
   "<Enter>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Control, ControlModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"
  1. Key sequence :map <C-6> :echo 'hello'<CR> <CR><C-6>
  • Expected: message 'hello' appears
  • Result: message 'hello' appears
  • Key sequence output:
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Colon, ShiftModifier, text=":")
   ":"
QKeyEvent ev: QKeyEvent(KeyPress, Key_M, text="m")
   "m"
QKeyEvent ev: QKeyEvent(KeyPress, Key_A, text="a")
   "a"
QKeyEvent ev: QKeyEvent(KeyPress, Key_P, text="p")
   "p"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Less, ShiftModifier, text="<")
   "<lt>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_C, ShiftModifier, text="C")
   "C"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Minus, text="-")
   "-"
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, text="6")
   "6"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Greater, ShiftModifier, text=">")
   ">"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Colon, ShiftModifier, text=":")
   ":"
QKeyEvent ev: QKeyEvent(KeyPress, Key_E, text="e")
   "e"
QKeyEvent ev: QKeyEvent(KeyPress, Key_C, text="c")
   "c"
QKeyEvent ev: QKeyEvent(KeyPress, Key_H, text="h")
   "h"
QKeyEvent ev: QKeyEvent(KeyPress, Key_O, text="o")
   "o"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Space, text=" ")
   "<Space>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Apostrophe, text="'")
   "'"
QKeyEvent ev: QKeyEvent(KeyPress, Key_H, text="h")
   "h"
QKeyEvent ev: QKeyEvent(KeyPress, Key_E, text="e")
   "e"
QKeyEvent ev: QKeyEvent(KeyPress, Key_L, text="l")
   "l"
QKeyEvent ev: QKeyEvent(KeyPress, Key_L, text="l")
   "l"
QKeyEvent ev: QKeyEvent(KeyPress, Key_O, text="o")
   "o"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Apostrophe, text="'")
   "'"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Shift, ShiftModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_Less, ShiftModifier, text="<")
   "<lt>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_C, ShiftModifier, text="C")
   "C"
QKeyEvent ev: QKeyEvent(KeyPress, Key_R, ShiftModifier, text="R")
   "R"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Greater, ShiftModifier, text=">")
   ">"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Return, text="\r")
   "<Enter>"
QKeyEvent ev: QKeyEvent(KeyPress, Key_Control, ControlModifier)
   ""
QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="6")
   "<C-6>"

So, it turns out you can map to ctrl-number, but that ctrl-6 is not mapped to switch buffer by default. That caught me off guard, as the mapping is listed in :help CTRL-6, and works as expected under gVim and terminal versions of vim and neovim.

I realise that the problem I was running into is not the same as the originally posted bug. I'll leave it up to you to decide whether my report is a bug or not.

edit: on second thought, I think the interaction with Ctrl-v is unintuitive and might be a bug.

@jgehrig
Copy link
Collaborator

jgehrig commented Apr 15, 2020

On Linux: Scenarios 1-3 work, Scenario 4 does not work.

On Windows: Scenarios 1-4 do not work.

Does Scenario 4 work in nvim? I can't seem to get that working with nvim -u NONE either...

Here are the QKeyEvents in question on Linux:

QKeyEvent ev: QKeyEvent(KeyPress, Key_6, ControlModifier, text="\u001E")
   "\u001E"

QKeyEvent ev: QKeyEvent(KeyPress, Key_AsciiCircum, ShiftModifier|ControlModifier, text="\u001E")
   "<S-\u001E>"

Linux's key events don't look right to me either... However I don't know what the input SHOULD be in this case.

Since :map <C-6> doesn't trigger in nvim, and Windows doesn't handle these scenario's I suspect <C-6> isn't the correct sequence to send.

I realise that the problem I was running into is not the same as the originally posted bug. I'll leave it up to you to decide whether my report is a bug or not.

This smells like a bug to me. So far, I don't see anything preventing us from modifying Input::convertKey to make this work on all platforms. I am happy to fix this once we understand the problem.

However, we need to understand the correct way to send these events. What key string does neovim require for this case?

@skyegecko
Copy link

I'm not sure what you mean "scenario x works/does not work". To be clear, scenarios 2 and 4 on windows produce the expected result.

:map <C-6> :echo 'hello'<CR> in terminal nvim does not result in a mapping that triggers off pressing Ctrl-6. nvim prints E23 which implies that the default <C-^> mapping is being triggered.

@jgehrig
Copy link
Collaborator

jgehrig commented Apr 16, 2020

Good point... Not very clear.

Here is a good set of steps that clearly captures the behavior differences:

  1. Open nvim nvim -u NONE or neovim-qt nvim-qt -- -u NONE
  2. Add the following map: :map <C-^> :echo 'C^ Triggered!'<CR>
  3. Add the following map: :map <C-6> :echo 'C6 Triggered!'<CR>
  4. Add the following map: :map <C-S-6> :echo 'CS6 Triggered!'<CR>
  5. Add the following map: :map <C-S-^> :echo 'CS^ Triggered!'<CR>
  6. Press Control + 6.
  7. Press Control + Shift + 6

On Windows/nvim:

  • Step 6 C^ Triggered!
  • Step 7 C^ Triggered!

On Linux/nvim:

  • Step 6 C^ Triggered!
  • Step 7 C^ Triggered!

On Windows/nvim-qt:

  • Step 6 6
  • Step 7 CS^ Triggered!

On Linux/nvim-qt:

  • Step 6 C^ Triggered!
  • Step 7 CS^ Triggered

Based on these observations, Control/Shift + Key_6 should be sent to neovim as <C-^>.

This is definitely a bug, and should be an easy fix. Thanks for helping me reason though this! 👍

@jgehrig
Copy link
Collaborator

jgehrig commented Aug 6, 2020

The fix is available in v0.2.16.

Marking as closed.

@jgehrig jgehrig closed this as completed Aug 6, 2020
@zeertzjq
Copy link

zeertzjq commented Oct 2, 2021

This may be worth noting:

Translating CTRL-6 into CTRL-^ is done by terminal emulator, not Neovim, and there may be terminal emulators that do not translate CTRL-6 to CTRL-^ (although I don't know any). Is it necessary to adhere to a terminal-dependent behavior?

The only reference related to this I can find is https://sw.kovidgoyal.net/kitty/keyboard-protocol/#legacy-ctrl-mapping-of-ascii-keys.

@skyegecko
Copy link

there may be terminal emulators that do not translate CTRL-6 to CTRL-^ (although I don't know any)

Alacritty does not under Windows by default. Not sure about Alacritty on other platforms.

You're right that this translation is a feature of the terminal, but since nvim is a terminal program I think it makes sense that a GUI should provide terminal-like behaviour that nvim depends on.

In the instance of this bug, typing C-6 sometimes just produced the character '6', which made mapping C-6 to C-^ impossible.

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

No branches or pull requests

6 participants