[edit: for all ref's to 'vim', read 'neovim' - see comments for clarification]
On a UK keyboard, the shifted characters for the number keys (1...9, and 0) are;-
! " £ $ % ^ & * ( )
When I use vim within xterm, xterm generates most of the above characters as-is (ie, if I press 'shift-1', vim sees a '!' character). However, for reasons that I cannot fathom, xterm treats the '6' key differently from the rest; if I press 'shift-6', vim sees 'shift-^' rather than just '^'.
There are a few other keys scattered around the keyboard that have the same issue. It doesn't seem to bother vim when entering text but it is a problem because it breaks quite a few key mappings in various scripts for vim (I have previously added additional mappings; '<S-^>' instead of just '^' but it's an unsatisfactory solution)
To try and fix this, I added the following key translation to ~/.Xresources
;-
XTerm*vt100.translations: #override \
~Ctrl ~Meta ~Alt Shift<Key>^: string("^") \n\
~Ctrl ~Meta ~Alt Shift<Key>_: string("_") \n\
~Ctrl ~Meta ~Alt Shift<Key>{: string("{") \n\
~Ctrl ~Meta ~Alt Shift<Key>}: string("}") \n\
~Ctrl ~Meta ~Alt Shift<Key>@: string("@") \n\
~Ctrl ~Meta ~Alt Shift<Key>~: string("~") \n\
~Ctrl ~Meta ~Alt Shift<Key>|: string("|")
(just for reference, the 6 characters _ { } @ ~ and | are generated from the shifted keys - [ ] ' # and \ respectively)
This (mostly) "works" (pressing shift-6 now presents vim with the character sequence '^' instead of 'shift-^')
However, I have now created a new problem; shift-7 now generates the character '{' instead of '&', and shift-0 now generates '}' instead of ')'. All the other keys seem to be correct
So, I tried adding an extra two translations (and yes, I realise they aren't really translating anything but I thought it worth a go);-
~Ctrl ~Meta ~Alt ~Shift <Key>&: string("&") \n\
~Ctrl ~Meta ~Alt ~Shift <Key>): string(")")
...but this makes no difference at all. I also tried the following but same result;-
~Ctrl ~Meta ~Alt Shift<Key>7: string("&") \n\
~Ctrl ~Meta ~Alt Shift<Key>0: string(")")
Can anyone cast any light on what I'm missing please? Why does xterm behave like this in the first place for only some keys (I've never seen this problem using any other terminal)? Am I going about fixing this the wrong way? Have I just missed out a part of the fix?
Any help would be much appreciated
I have spent quite some time looking further at this. I have posted on the nvim issues thread (I tried what was suggested), and done quite a lot of experimenting. I did find that setting the Xterm key translations as shown in my original post actually caused a LOT of issues; some particular keys (with and without modifiers) behaved very badly to the point where my "fix" was actually worse than the original problem.
But there WAS light at the end of the tunnel! I removed all the Xterm key translations and I added the following to the start of my `.vimrc`;-
" The following were added because neovim was seeing/interpreting
" some characters as 'shift-X' rather than just 'X'; this becomes
" apparent in mappings and insert mode with <C-v>X. The characters
" with issues are ^ _ { } @ ~ and |.
" Some of the other alphabetical characters don't seem to be
" recognised at all in insert mode and <C-v>X; u, U, o, O, x, X.
" They seem to work ok in mappings though, so shouldn't be a problem
if has('nvim')
nmap <S-^> ^
nmap <S-_> _
nmap <S-{> {
nmap <S-}> }
nmap <S-@> @
nmap <S-~> ~
nmap <S-bar> <bar>
" Added to fix later mappings for <leader>X
nmap <leader><S-^> <leader>^
nmap <leader><S-@> <leader>@
nmap <leader><S-~> <leader>~
nmap <leader><S-bar> <leader><bar>
endif
With the above in place, I can now create a mapping such as the following and it works as intended
nnoremap ^ :echo "Hello"<cr>
As you can see, I also added 4 mappings to handle <leader>...
key sequences (these are the only four I need currently). To me, it makes absolutely no sense that I needed to do this (it's not like I press \
and (say) @
at the same time; they are pressed sequentially) but if I didn't add these then mappings such as \@
do not work. Following on from this, it's clear that any mapping such as <C-^>
or <C-|>
would also need their own special maps
adding...
nmap <C-S-^> <C-^>
nmap <C-S-\> <C-Bar>
Just to add to the fun, note that <C-|>
actually comes into nvim as <C-S-\>
!!!!
Anyway, this seems to be a reliable fix for the problem I had without causing side effects. I still think there is something dodgy going on with nvim's interpretation of xterm key codes but as I know very little about how the keyboard driver works and the whole complex chain of events that happen before a key press actually hits the application, I'm going to leave it at this.
Thanks to all those who made suggestions to try and help with this.
R.