-*todo.txt* For Vim version 9.2. Last change: 2026 Jul 30
+*todo.txt* For Vim version 9.2. Last change: 2026 Jul 31
VIM REFERENCE MANUAL by Bram Moolenaar
*known-bugs*
-------------------- Known bugs and current work -----------------------
-Mapping with modifier is not recognized after a partial mapping. Probably
-because the typeahead was simplified when looking for a matching mapping.
-Need to somehow undo the simplification. #12002
-
With 'smoothscroll' the scroll position is lost when a window is temporarily
squeezed to a couple of lines, for example ":help" followed by ":close". In
restore_snapshot_rec() restore more values from the snapshot, instead of
#define RM_NONE 1 // tb_noremap: don't remap
#define RM_SCRIPT 2 // tb_noremap: remap local script mappings
#define RM_ABBR 4 // tb_noremap: don't remap, do abbrev.
+#define RM_SIMPLIFIED 8 // tb_noremap: modifiers merged into the key
// typebuf.tb_buf has three parts: room in front (for result of mappings), the
// middle for typeahead and room for new characters (which needs to be 3 *
{
char_u new_string[MB_MAXBYTES];
int len;
+ int key_offset = offset;
if (offset == 0)
{
else
{
tp[2] = modifier;
- if (put_string_in_typebuf(offset + 3, 1, new_string, len,
+ key_offset = offset + 3;
+ if (put_string_in_typebuf(key_offset, 1, new_string, len,
NULL, 0, NULL) == FAIL)
return -1;
}
+
+ // A mapping for the simplified key can be used for it even
+ // when the key protocol is enabled.
+ for (int i = 0; i < len; ++i)
+ typebuf.tb_noremap[typebuf.tb_off + key_offset + i]
+ |= RM_SIMPLIFIED;
return len;
}
}
if (mp->m_keys[0] == tb_c1
&& (mp->m_mode & local_State)
&& !(mp->m_simplified && key_protocol_enabled()
- && typebuf.tb_maplen == 0)
+ && typebuf.tb_maplen == 0
+ && (typebuf.tb_noremap[typebuf.tb_off]
+ & RM_SIMPLIFIED) == 0)
&& ((mp->m_mode & MODE_LANGMAP) == 0
|| typebuf.tb_maplen == 0))
{
// If only script-local mappings are allowed, check if the
// mapping starts with K_SNR.
s = typebuf.tb_noremap + typebuf.tb_off;
- if (*s == RM_SCRIPT
+ if ((*s & ~RM_SIMPLIFIED) == RM_SCRIPT
&& (mp->m_keys[0] != K_SPECIAL
|| mp->m_keys[1] != KS_EXTRA
|| mp->m_keys[2] != KE_SNR))
if (in_osc || no_mapping == 0 || allow_keys != 0)
{
if (in_osc || ((typebuf.tb_maplen == 0
- || (p_remap && typebuf.tb_noremap[
- typebuf.tb_off] == RM_YES))
+ || (p_remap && (typebuf.tb_noremap[typebuf.tb_off]
+ & ~RM_SIMPLIFIED) == RM_YES))
&& !*timedout))
keylen = check_termcode(max_mlen + 1, NULL, 0, NULL);
else
gotchars(typebuf.tb_buf
+ typebuf.tb_off, 1);
}
- KeyNoremap = typebuf.tb_noremap[typebuf.tb_off];
+ KeyNoremap = typebuf.tb_noremap[typebuf.tb_off]
+ & ~RM_SIMPLIFIED;
del_typebuf(1, 0);
}
break; // got character, break the for loop
set timeoutlen&
endfunc
+func Test_modifyOtherKeys_after_partial_mapping()
+ new
+ set timeoutlen=10
+ imap <C-J> x
+ imap ab y
+ call setline(1, '')
+
+ " "a" is a partial match for the "ab" mapping, CTRL-J is simplified while
+ " looking for that mapping and must still match the <C-J> mapping.
+ call feedkeys("aa" .. GetEscCodeCSI27('J', 5) .. "\<Esc>", 'Lx!')
+ call assert_equal('ax', getline(1))
+
+ " A NL that was not simplified from the key protocol does not use the
+ " mapping for CTRL-J.
+ %d _
+ call feedkeys("aa\<C-J>\<Esc>", 'Lx!')
+ call assert_equal(['a', ''], getline(1, '$'))
+
+ iunmap <C-J>
+ iunmap ab
+ set timeoutlen&
+ bwipe!
+endfunc
+
func Test_modifyOtherKeys_ambiguous_mapping()
new
set timeoutlen=10