forked from aniani/vim
patch 9.1.0814: mapset() may remove unrelated mapping
Problem: mapset() may remove unrelated mapping whose {rhs} matches the restored mapping's {lhs}. Solution: only match by {lhs} when unmapping for mapset() (zeertzjq). closes: #15935 Signed-off-by: zeertzjq <zeertzjq@outlook.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
parent
118072862b
commit
fdf135a052
22
src/map.c
22
src/map.c
@ -408,9 +408,11 @@ list_mappings(
|
|||||||
* noreabbr {lhs} {rhs} : same, but no remapping for {rhs}
|
* noreabbr {lhs} {rhs} : same, but no remapping for {rhs}
|
||||||
* unabbr {lhs} : remove abbreviation for {lhs}
|
* unabbr {lhs} : remove abbreviation for {lhs}
|
||||||
*
|
*
|
||||||
* maptype: MAPTYPE_MAP for :map
|
* maptype: MAPTYPE_MAP for :map or :abbr
|
||||||
* MAPTYPE_UNMAP for :unmap
|
* MAPTYPE_UNMAP for :unmap or :unabbr
|
||||||
* MAPTYPE_NOREMAP for noremap
|
* MAPTYPE_NOREMAP for :noremap or :noreabbr
|
||||||
|
* MAPTYPE_UNMAP_LHS is like MAPTYPE_UNMAP, but doesn't try to match
|
||||||
|
* with {rhs} if there is no match with {lhs}.
|
||||||
*
|
*
|
||||||
* arg is pointer to any arguments. Note: arg cannot be a read-only string,
|
* arg is pointer to any arguments. Note: arg cannot be a read-only string,
|
||||||
* it will be modified.
|
* it will be modified.
|
||||||
@ -470,6 +472,7 @@ do_map(
|
|||||||
int expr = FALSE;
|
int expr = FALSE;
|
||||||
#endif
|
#endif
|
||||||
int did_simplify = FALSE;
|
int did_simplify = FALSE;
|
||||||
|
int unmap_lhs_only = FALSE;
|
||||||
int noremap;
|
int noremap;
|
||||||
char_u *orig_rhs;
|
char_u *orig_rhs;
|
||||||
|
|
||||||
@ -477,6 +480,12 @@ do_map(
|
|||||||
map_table = maphash;
|
map_table = maphash;
|
||||||
abbr_table = &first_abbr;
|
abbr_table = &first_abbr;
|
||||||
|
|
||||||
|
if (maptype == MAPTYPE_UNMAP_LHS)
|
||||||
|
{
|
||||||
|
unmap_lhs_only = TRUE;
|
||||||
|
maptype = MAPTYPE_UNMAP;
|
||||||
|
}
|
||||||
|
|
||||||
// For ":noremap" don't remap, otherwise do remap.
|
// For ":noremap" don't remap, otherwise do remap.
|
||||||
if (maptype == MAPTYPE_NOREMAP)
|
if (maptype == MAPTYPE_NOREMAP)
|
||||||
noremap = REMAP_NONE;
|
noremap = REMAP_NONE;
|
||||||
@ -619,6 +628,7 @@ do_map(
|
|||||||
int did_local = FALSE;
|
int did_local = FALSE;
|
||||||
int keyround1_simplified = keyround == 1 && did_simplify;
|
int keyround1_simplified = keyround == 1 && did_simplify;
|
||||||
int round;
|
int round;
|
||||||
|
int num_rounds;
|
||||||
|
|
||||||
if (keyround == 2)
|
if (keyround == 2)
|
||||||
{
|
{
|
||||||
@ -742,8 +752,8 @@ do_map(
|
|||||||
// an entry with a matching 'to' part. This was done to allow
|
// an entry with a matching 'to' part. This was done to allow
|
||||||
// ":ab foo bar" to be unmapped by typing ":unab foo", where "foo" will
|
// ":ab foo bar" to be unmapped by typing ":unab foo", where "foo" will
|
||||||
// be replaced by "bar" because of the abbreviation.
|
// be replaced by "bar" because of the abbreviation.
|
||||||
for (round = 0; (round == 0 || maptype == MAPTYPE_UNMAP) && round <= 1
|
num_rounds = maptype == MAPTYPE_UNMAP && !unmap_lhs_only ? 2 : 1;
|
||||||
&& !did_it && !got_int; ++round)
|
for (round = 0; round < num_rounds && !did_it && !got_int; ++round)
|
||||||
{
|
{
|
||||||
// need to loop over all hash lists
|
// need to loop over all hash lists
|
||||||
for (int hash = 0; hash < 256 && !got_int; ++hash)
|
for (int hash = 0; hash < 256 && !got_int; ++hash)
|
||||||
@ -2817,7 +2827,7 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
|
|||||||
if (arg == NULL)
|
if (arg == NULL)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
do_map(MAPTYPE_UNMAP, arg, mode, is_abbr);
|
do_map(MAPTYPE_UNMAP_LHS, arg, mode, is_abbr);
|
||||||
vim_free(arg);
|
vim_free(arg);
|
||||||
|
|
||||||
mp_result[0] = map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs,
|
mp_result[0] = map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs,
|
||||||
|
@ -540,6 +540,25 @@ func Test_map_restore_negative_sid()
|
|||||||
call delete('Xresult')
|
call delete('Xresult')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
" Check that restoring a mapping doesn't remove a mapping whose {rhs} matches
|
||||||
|
" the restored mapping's {lhs}.
|
||||||
|
func Test_map_restore_with_rhs_match_lhs()
|
||||||
|
nnoremap <F2> <F3>
|
||||||
|
nnoremap <F3> <F4>
|
||||||
|
call assert_equal('<F3>', maparg('<F2>', 'n'))
|
||||||
|
call assert_equal('<F4>', maparg('<F3>', 'n'))
|
||||||
|
let d = maparg('<F3>', 'n', v:false, v:true)
|
||||||
|
nunmap <F3>
|
||||||
|
call assert_equal('<F3>', maparg('<F2>', 'n'))
|
||||||
|
call assert_equal('', maparg('<F3>', 'n'))
|
||||||
|
call mapset(d)
|
||||||
|
call assert_equal('<F3>', maparg('<F2>', 'n'))
|
||||||
|
call assert_equal('<F4>', maparg('<F3>', 'n'))
|
||||||
|
|
||||||
|
nunmap <F2>
|
||||||
|
nunmap <F3>
|
||||||
|
endfunc
|
||||||
|
|
||||||
def Test_maplist()
|
def Test_maplist()
|
||||||
new
|
new
|
||||||
def ClearMappingsAbbreviations()
|
def ClearMappingsAbbreviations()
|
||||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
814,
|
||||||
/**/
|
/**/
|
||||||
813,
|
813,
|
||||||
/**/
|
/**/
|
||||||
|
@ -1016,6 +1016,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
|||||||
#define MAPTYPE_MAP 0
|
#define MAPTYPE_MAP 0
|
||||||
#define MAPTYPE_UNMAP 1
|
#define MAPTYPE_UNMAP 1
|
||||||
#define MAPTYPE_NOREMAP 2
|
#define MAPTYPE_NOREMAP 2
|
||||||
|
#define MAPTYPE_UNMAP_LHS 3
|
||||||
|
|
||||||
// Values for "noremap" argument of ins_typebuf(). Also used for
|
// Values for "noremap" argument of ins_typebuf(). Also used for
|
||||||
// map->m_noremap and menu->noremap[].
|
// map->m_noremap and menu->noremap[].
|
||||||
|
Loading…
x
Reference in New Issue
Block a user