This seems to be an artifact of unfinished code in terminal.c. There doesn't seem to be a "more context" box in the issue form so I'm going to dump everything in the "steps to reproduce" box.
xterm-codes (see vim :help about it). I've found that XTerm and Termux (the Android app) allow this issue to reproduce. I haven't extensively tested with other terminals or screens.vim --clean:terminalNotice that these keys produce, respectively: 7, 1, 9, 3. Notice that these correspond exactly to the keys on the numpad whose (non-numlock) functions are Home, End, PgUp, PgDn. The numpad keys themselves are not the subject of this issue, they are important context for the issue with the editing pad keys.
When Vim senses that the terminal may be compatible with xterm-codes, and xtermcodes is enabled, it requests a bunch of termcap strings from the terminal directly, overriding whatever it read from terminfo, in particular: kh, @7, kP, kN (respectively, Home, End, PgUp, PgDn on the editing pad), K1, K4, K3, K5 (respectively, Home, End, PgUp, PgDn on the numpad). Related code.
The final requirement is this: the terminal needs to respond, for the corresponding editing pad keys and numpad keys, with the same escape sequence. This can be entirely true, for example XTerm sends the same escape sequence for editing pad Home and numpad Home (when numlock is off). Vim requests these codes after setting the terminal to application mode, so the result is that <xHome> and <kHome> match the same string (ESC O H, using SS3 instead of CSI), likewise for the other keys.
(I expect that, if there exists a terminfo file that satisfies this final reproducing requirement directly, then this issue would reproduce by simply setting $TERM to that string. I haven't explored for such a terminfo, and importantly XTerm's terminfo doesn't do this (unlike what XTerm itself responds, surprisingly!), so terminals which borrow XTerm's terminfo don't automatically cause this issue to reproduce.)
This causes nothing out of the ordinary throughout most of Vim (that i've seen so far...), except :terminal. When inserting into an active :terminal, it seems to prefer interpreting the "xHome or kHome" ambiguity as kHome. This by itself is still not a problem because this can still be reasonably expected to produce the escape sequence for the Home function. But the code that translates the key into terminal input decides that kHome should produce numpad 7 instead, likewise for the other keys.
Thus, the observed behaviour: pressing Home on the editing pad produces 7, and it's impossible to use Home (and End, PgUp, PgDn) inside the :terminal.
There is an extremely easy workaround, courtesy of this Arch Wiki thread: tmap <kHome> <xHome>, likewise for the other keys. This causes :terminal to see xHome instead of kHome, and correctly translate it to a Home keypress. I don't see any reason for kHome to work any differently in :terminal (if numlock is on, the terminal will just send 7, indistinguishable between numpad and number row), so I consider this a bug.
Setting noxtermcodes is also an easy workaround, though it also makes Vim think XTerm can only render 8 colors. (t_Co is set to 8 instead of 256)
Pressing Home, End, PgUp, PgDn in :terminal should produce escape sequences that correspond to the function (this appears to be, respectively, ESC [ H, ESC [ F, ESC [ 5 ~, ESC [ 6 ~), and ultimately should allow the program running inside the :terminal to understand the function being used (e.g. readline moves to the left/right edge of the cmdline, or goes up/down in history, of course depending on its configuration)
9.1.1336
Operating system:
"x86_64-linux"Linux 6.12.28, NixOS, 25.05 (Warbler), 25.05pre799423.adaa24fbf467yesyesnix-env (Nix) 2.28.3"nixos""home-manager"/nix/store/3g6wk26mlpsxqmin7fng91nnlkq6nsy1-nixos/nixosTerminal: XTerm(397)
Value of $TERM: xterm
Shell: GNU bash, version 5.2.37(1)-release (x86_64-pc-linux-gnu)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Thanks, that is quite a detailed bug report. Unfortunately I don't currently know the terminal code well enough to attempt to fix it right now.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I've made a new discovery: if I tell XTerm to use "VT220 Keyboard Mode" (either through the entry in the "Main Options" menu, or the -kt vt220 option, or the XTerm.keyboardType: vt220 resource), it changes the behaviour of the keys involved in this issue. This time, the editing pad keys and numpad keys always produce distinct escape sequences, e.g. editing pad Home produces ESC [ 1 ~, while numpad Home produces ESC O w (after activating application mode, terminfo smkx). This is reflected in the data that Vim receives in response to xterm-codes:
(vim --clean with default keyboard mode)
20250525_12h43m57s_grim.png (view on web)
(vim --clean with vt220 keyboard mode)
20250525_12h44m15s_grim.png (view on web)
So, this could be another workaround! Indeed, using this VT220 Keyboard Mode causes the End, PgUp and PgDn keys to work perfectly in :terminal. But, somehow, not Home, which still produces 7! I cannot yet explain this behaviour. The only clue I have is that it seems Vim by default understands ESC [ 1 ~ as kHome, but the same is true of the End key...
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I also have this nuisance recently popping up in my awareness on NixOS, and it's feels new to me as of either late 25.05 or recent 25.11 changes.
VIM - Vi IMproved 9.1 (2024 Jan 02, compiled Jan 01 1980 00:00:00)\n - Included patches: 1-765).If I run vim -u NONE, the good functionality is restored. If I then run :source ${VIM_INSTALL}/share/vim/vimrc where the ${VIM_INSTALL} here is really just any installed edition of vim. I'm abstracting that here to point out that this is the same on multiple editions of vim (NixOS 24.05, 24.11, 25.05, 25.11 are what I tried). In brief, just source .../share/vim/vimrc to get it to break again.
After such a source, these are then loaded:
:scriptnames
1: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vimrc
2: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/syntax/syntax.vim
3: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/syntax/synload.vim
4: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/syntax/syncolor.vim
5: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/colors/lists/default.vim
6: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/filetype.vim
7: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/scripts.vim
8: /nix/store/2qyb624x1fhd22gwdg94gcnihzysxxzh-vim-full-9.1.0765/share/vim/vim91/autoload/dist/script.vim
This leads to me to believe that the issue is somehow in what's supporting vim. In guake and gnome-console, supported by Gnome3, on Wayland the issue occurs, so maybe something changed for the worse in those and not here.
To get back to work, I'm doing this.
tmap <kHome> <Home>
tmap <kEnd> <End>
tmap <kPageUp> <PageUp>
tmap <kPageDown> <PageDown>
Does this have any negative implications? Can we simply install that into a late-load .vim and call it a day?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@Bujiraso Nice find! I looked into it, and it seems that the important difference is the esckeys setting. When running Vim with -u NONE, it starts in compatible mode by default, which sets noesckeys. This turns off several features of Vim; the most noticeable to a beginner is the ability to use the arrow keys to move the cursor while in insert mode, but it also suppresses some terminal identification features, meaning that it has a similar effect to setting noxtermcodes. In my main post I mentioned that setting noxtermcodes is a possible workaround for this issue. You also correctly identified the workaround using tmap that I also mentioned.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
❗
thank you @AstroSnail
set noesckeys
Is a fix!
Should something be pushed to this codebase?
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
@chrisbra I'm trying to follow along with Vim's key translation code, in the hope to puzzle together why pressing Home preferentially turns into kHome in the :terminal. I followed the code back to vgetorpeek, which produces K_SPECIAL followed by a termcap string over three separate invocations, but I'm having trouble finding how vgetorpeek reads the Home key and looks up its termcap string. Do you know vgetorpeek well enough to help out?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I think I understand what vgetorpeek does now. It reads input with inchar, and applies mappings with handle_mapping. handle_mapping further calls check_termcode, which converts terminal key sequences to termcap strings. Speaking of which, check_termcode seems to have some odd behaviour.
Part of the task of check_termcode is looking at each position in the typeahead buffer typebuf, and for each position looping through all of the known termcap strings to see if one matches. If it matches, then it replaces the terminal key sequence with a special sequence that other parts of Vim can understand, independent of the terminal being used.
vim -u NONE understands the following (relevant) termcaps when running in an XTerm-like terminal:
t_@7 <End> ^[[@;*F
t_K1 <kHome> ^[[1;*~
t_K3 <kPageUp> ^[Oy
t_K4 <kEnd> ^[[4;*~
t_K5 <kPageDown> ^[Os
t_kN <PageDown> ^[[6;*~
t_kP <PageUp> ^[[5;*~
t_kh <Home> ^[[@;*H
<xEnd> ^[O*F
<xHome> ^[O*H
Inside Vim, with the default keyboard mode, XTerm sends ESC O H when I press the Home key. check_termcode will compare it against each of the known termcaps in order, and it eventually matches <xHome>. Before returning <xHome>, it goes through handle_x_keys (defined here) which turns <xHome> into <Home> (termcap kh). A similar process turns an End keypress into <xEnd> and then into <End>, while PgUp and PgDn simply turn into <PageUp> and <PageDown> respectively.
vim --clean (with working xtermcodes) understands the following (relevant) termcaps when running in XTerm (with the default keyboard mode):
t_@7 <End> ^[[@;*F
t_K1 <kHome> ^[OH
t_K1 <kHome> ^[[1;*~
t_K3 <kPageUp> ^[[5~
t_K4 <kEnd> ^[OF
t_K4 <kEnd> ^[[4;*~
t_K5 <kPageDown> ^[[6~
t_kN <PageDown> ^[[6;*~
t_kP <PageUp> ^[[5;*~
t_kh <Home> ^[[@;*H
<xEnd> ^[O*F
<xHome> ^[O*H
Notice that there are new definitions for <kHome>, <kEnd>, <kPageUp> and <kPageDown>. This is expected due to xtermcodes, as I explained in the first post. Now when XTerm sends ESC O H, check_termcode will find <kHome> first, because the loop looks at the termcap strings in order. This time, a quirk of check_termcodes manifests: there is code that is supposed to prefer a key definition that is not in the numpad, but it can only match termcap definitions without modifiers. In this case the alternative <xHome> has a modifier parameter, so it won't be used. The end result is that Home on the editing pad gets parsed as <kHome>. The exact same thing happens for End, PgUp and PgDn.
For fun, I also looked at what happened in my other discovery #17331 (comment). vim --clean, running in XTerm with VT220 keyboard mode, understands the following termcaps:
t_@7 <End> ^[[4~
t_@7 <End> ^[[@;*F
t_K1 <kHome> ^[Ow
t_K1 <kHome> ^[[1;*~
t_K3 <kPageUp> ^[Oy
t_K4 <kEnd> ^[Oq
t_K4 <kEnd> ^[[4;*~
t_K5 <kPageDown> ^[Os
t_kN <PageDown> ^[[6;*~
t_kP <PageUp> ^[[5;*~
t_kh <Home> ^[[1~
t_kh <Home> ^[[@;*H
<xEnd> ^[O*F
<xHome> ^[O*H
In this mode, XTerm sends ESC [ 1 ~ when I press Home. The first match is <kHome>, and this time it matches with a modifier parameter; the code in check_termcode that handles this case completely lacks the consideration to prefer a non-numpad definition. However, the first matches for End, PgUp and PgDn are <End>, <PageUp> and <PageDown> respectively, so those keys all work fine in this situation.
My opinion is that check_termcode should be changed so that it prefers non-numpad key definitions in all cases, instead of the quirked behaviour it has currently which depends on the termcap array order and on whether the definitions have modifiers.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I decided to look at the history of the parts involved in this bug, and it turns out it might be quite old! I had to download the CVS version history from SourceForge to look at versions older than vim 7.0, and on a http mirror of the defunct ftp distribution for versions older than vim 5.5 (I only found 5.0, 4.6 and 3.0).
Vim had check_termcode with a working loop to avoid keypad keys since, at the latest, vim 4.6 (Mar 1997). Presumably this was implemented for terminals whose termcap/terminfo descriptions use the same code for kh/khome and K1/ka1, etc. Current ncurses seems to avoid this as far as possible, only historical terminal descriptions have this property; perhaps the most interesting of these is ansi.sys and its variants. All modern terminal definitions in ncurses and all builtin terminal definitions in Vim always have distinct codes for all keys.
Vim added the xterm-codes feature in vim 6.0 (Sep 2001) with parallel development of the corresponding feature in XTerm (iterated a few times before finalizing in patch 149, Dec 2000). One of the tasks of got_code_from_term is to delete codes that are duplicated over more than one termcap, so when multiple xterm-codes replies contain the same code, only the last one is kept and the others are removed. It finds duplicates using find_term_bykeys. It doesn't consider keypad keys specially, and those are always the last keys to be requested (only ahead of the backtab), so Vim will delete the <Home> termcap in favour of <kHome>.
Vim added modifier support in vim 7.0 (May 2006) (this version is present in the current git history). To do this, a new branch was added to check_termcode to handle codes with modifiers. This branch lacks the loop to avoid keypad keys, and the existing loop has not been updated to recognize keys with modifiers. find_term_bykeys was also not updated for keys with modifiers. All the keys relevant to this issue had their builtin definitions changed to include modifiers, which causes two effects:
check_termcode.got_code_from_term.The first of these effects is undesirable, and is patched in #19145. The second is accidentally desirable; I don't want xterm-codes to wipe the <Home> termcap like in Vim 6! Ideally got_code_from_term would also try to prefer keeping editing-pad keys and wiping away keypad keys, instead of the current behaviour where only the last received termcap is kept.
It's funny that this bug is a lot older than the feature that best exposes it: :terminal was developed throughout patches to vim 8.0 and was released in vim 8.1 (May 2018).
I would also like to leave a mention to a note in intro.txt that has been practically unchanged since vim 4.6 (Mar 1997) (then in vim_ref.txt) describing the intended behaviour of <Home> and <kHome>. As far as I can tell, its statement has not been true for Vim inside XTerm since vim 6.0! (and XTerm patch 149)
@Bujiraso As far as I can tell, this problem is not caused by a recent change at all. But I don't make custom mappings for <Home> so this problem is not very noticeable. The fact that it only occurs in terminals compatible with xterm-codes, which are rather few, compounds the hiding of the issue.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I decided to look at the history of the parts involved in this bug, and it turns out it might be quite old! I had to download the CVS version history from SourceForge to look at versions older than vim 7.0, and on a http mirror of the defunct ftp distribution for versions older than vim 5.5 (I only found 5.0, 4.6 and 3.0).
See: https://github.com/vim/vim-history
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@dkearns Thank you! I've updated my comment with links to that repo and corrected the version numbers.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@Bujiraso As far as I can tell, this problem is not caused by a recent change at all. But I don't make custom mappings for
<Home>so this problem is not very noticeable. The fact that it only occurs in terminals compatible withxterm-codes, which are rather few, compounds the hiding of the issue.
Interesting! No complaint that this may not result from any proximal vim-side code change, but I can say with significant confidence since I have years of the exact same hardware, OS+DE, app choices including terminal emulator, and workflow that it leaves one of these options for me:
No horse in the race here, just thought to observe. We at least have a great work-around for me, my terminal works again with the tmap's -- I didn't like the set (no)esckeys solutions, and hopefully the PR lines all the ducks up nicely for a fix without those work-arounds 😃
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()