comparison src/map.c @ 28674:38f7a132bba3 v8.2.4861

patch 8.2.4861: it is not easy to restore saved mappings Commit: https://github.com/vim/vim/commit/51d04d16f21e19d6eded98f9530d84089102f925 Author: Ernie Rael <errael@raelity.com> Date: Wed May 4 15:40:22 2022 +0100 patch 8.2.4861: it is not easy to restore saved mappings Problem: It is not easy to restore saved mappings. Solution: Make mapset() accept a dict argument. (Ernie Rael, closes https://github.com/vim/vim/issues/10295)
author Bram Moolenaar <Bram@vim.org>
date Wed, 04 May 2022 16:45:03 +0200
parents 9ae2c32841fb
children 141fb1d233ba
comparison
equal deleted inserted replaced
28673:1bb2e8f5cc4b 28674:38f7a132bba3
2281 static void 2281 static void
2282 mapblock2dict( 2282 mapblock2dict(
2283 mapblock_T *mp, 2283 mapblock_T *mp,
2284 dict_T *dict, 2284 dict_T *dict,
2285 char_u *lhsrawalt, // may be NULL 2285 char_u *lhsrawalt, // may be NULL
2286 int buffer_local) // false if not buffer local mapping 2286 int buffer_local, // false if not buffer local mapping
2287 int abbr) // true if abbreviation
2287 { 2288 {
2288 char_u *lhs = str2special_save(mp->m_keys, TRUE); 2289 char_u *lhs = str2special_save(mp->m_keys, TRUE);
2289 char_u *mapmode = map_mode_to_chars(mp->m_mode); 2290 char_u *mapmode = map_mode_to_chars(mp->m_mode);
2290 2291
2291 dict_add_string(dict, "lhs", lhs); 2292 dict_add_string(dict, "lhs", lhs);
2305 (long)mp->m_script_ctx.sc_version); 2306 (long)mp->m_script_ctx.sc_version);
2306 dict_add_number(dict, "lnum", (long)mp->m_script_ctx.sc_lnum); 2307 dict_add_number(dict, "lnum", (long)mp->m_script_ctx.sc_lnum);
2307 dict_add_number(dict, "buffer", (long)buffer_local); 2308 dict_add_number(dict, "buffer", (long)buffer_local);
2308 dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L); 2309 dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L);
2309 dict_add_string(dict, "mode", mapmode); 2310 dict_add_string(dict, "mode", mapmode);
2311 dict_add_number(dict, "abbr", abbr ? 1L : 0L);
2310 2312
2311 vim_free(mapmode); 2313 vim_free(mapmode);
2312 } 2314 }
2313 2315
2314 static void 2316 static void
2379 } 2381 }
2380 2382
2381 } 2383 }
2382 else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL) 2384 else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL)
2383 mapblock2dict(mp, rettv->vval.v_dict, 2385 mapblock2dict(mp, rettv->vval.v_dict,
2384 did_simplify ? keys_simplified : NULL, buffer_local); 2386 did_simplify ? keys_simplified : NULL,
2387 buffer_local, abbr);
2385 2388
2386 vim_free(keys_buf); 2389 vim_free(keys_buf);
2387 vim_free(alt_keys_buf); 2390 vim_free(alt_keys_buf);
2388 } 2391 }
2389 2392
2446 lhs = str2special_save(mp->m_keys, TRUE); 2449 lhs = str2special_save(mp->m_keys, TRUE);
2447 (void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify); 2450 (void)replace_termcodes(lhs, &keys_buf, flags, &did_simplify);
2448 vim_free(lhs); 2451 vim_free(lhs);
2449 2452
2450 mapblock2dict(mp, d, 2453 mapblock2dict(mp, d,
2451 did_simplify ? keys_buf : NULL, buffer_local); 2454 did_simplify ? keys_buf : NULL,
2455 buffer_local, abbr);
2452 vim_free(keys_buf); 2456 vim_free(keys_buf);
2453 } 2457 }
2454 } 2458 }
2455 } 2459 }
2456 } 2460 }
2485 || (argvars[1].v_type != VAR_UNKNOWN 2489 || (argvars[1].v_type != VAR_UNKNOWN
2486 && check_for_opt_bool_arg(argvars, 2) == FAIL))) 2490 && check_for_opt_bool_arg(argvars, 2) == FAIL)))
2487 return; 2491 return;
2488 2492
2489 get_maparg(argvars, rettv, FALSE); 2493 get_maparg(argvars, rettv, FALSE);
2494 }
2495
2496 /*
2497 * Get the mapping mode from the mode string.
2498 * It may contain multiple characters, eg "nox", or "!", or ' '
2499 * Return 0 if there is an error.
2500 */
2501 static int
2502 get_map_mode_string(char_u *mode_string, int abbr)
2503 {
2504 char_u *p = mode_string;
2505 int mode = 0;
2506 int tmode;
2507 int modec;
2508 const int MASK_V = VISUAL + SELECTMODE;
2509 const int MASK_MAP = VISUAL + SELECTMODE + NORMAL + OP_PENDING;
2510 const int MASK_BANG = INSERT + CMDLINE;
2511
2512 if (*p == NUL)
2513 p = (char_u *)" "; // compatibility
2514 while ((modec = *p++))
2515 {
2516 switch (modec)
2517 {
2518 case 'i': tmode = INSERT; break;
2519 case 'l': tmode = LANGMAP; break;
2520 case 'c': tmode = CMDLINE; break;
2521 case 'n': tmode = NORMAL; break;
2522 case 'x': tmode = VISUAL; break;
2523 case 's': tmode = SELECTMODE; break;
2524 case 'o': tmode = OP_PENDING; break;
2525 case 't': tmode = TERMINAL; break;
2526 case 'v': tmode = MASK_V; break;
2527 case '!': tmode = MASK_BANG; break;
2528 case ' ': tmode = MASK_MAP; break;
2529 default:
2530 return 0; // error, unknown mode character
2531 }
2532 mode |= tmode;
2533 }
2534 if ((abbr && (mode & ~MASK_BANG) != 0)
2535 || (!abbr && (mode & (mode-1)) != 0 // more than one bit set
2536 && (
2537 // false if multiple bits set in mode and mode is fully
2538 // contained in one mask
2539 !(((mode & MASK_BANG) != 0 && (mode & ~MASK_BANG) == 0)
2540 || ((mode & MASK_MAP) != 0 && (mode & ~MASK_MAP) == 0)))))
2541 return 0;
2542
2543 return mode;
2490 } 2544 }
2491 2545
2492 /* 2546 /*
2493 * "mapset()" function 2547 * "mapset()" function
2494 */ 2548 */
2516 linenr_T lnum; 2570 linenr_T lnum;
2517 mapblock_T **map_table = maphash; 2571 mapblock_T **map_table = maphash;
2518 mapblock_T **abbr_table = &first_abbr; 2572 mapblock_T **abbr_table = &first_abbr;
2519 int nowait; 2573 int nowait;
2520 char_u *arg; 2574 char_u *arg;
2521 2575 int dict_only;
2576
2577 // If first arg is a dict, then that's the only arg permitted.
2578 dict_only = argvars[0].v_type == VAR_DICT;
2522 if (in_vim9script() 2579 if (in_vim9script()
2523 && (check_for_string_arg(argvars, 0) == FAIL 2580 && (check_for_string_or_dict_arg(argvars, 0) == FAIL
2524 || check_for_bool_arg(argvars, 1) == FAIL 2581 || (dict_only && check_for_unknown_arg(argvars, 1) == FAIL)
2525 || check_for_dict_arg(argvars, 2) == FAIL)) 2582 || (!dict_only
2583 && (check_for_string_arg(argvars, 0) == FAIL
2584 || check_for_bool_arg(argvars, 1) == FAIL
2585 || check_for_dict_arg(argvars, 2) == FAIL))))
2526 return; 2586 return;
2527 2587
2528 which = tv_get_string_buf_chk(&argvars[0], buf); 2588 if (dict_only)
2529 if (which == NULL) 2589 {
2590 d = argvars[0].vval.v_dict;
2591 which = dict_get_string(d, (char_u *)"mode", FALSE);
2592 is_abbr = dict_get_bool(d, (char_u *)"abbr", -1);
2593 if (which == NULL || is_abbr < 0)
2594 {
2595 emsg(_(e_entries_missing_in_mapset_dict_argument));
2596 return;
2597 }
2598 }
2599 else
2600 {
2601 which = tv_get_string_buf_chk(&argvars[0], buf);
2602 if (which == NULL)
2603 return;
2604 is_abbr = (int)tv_get_bool(&argvars[1]);
2605
2606 if (argvars[2].v_type != VAR_DICT)
2607 {
2608 emsg(_(e_dictionary_required));
2609 return;
2610 }
2611 d = argvars[2].vval.v_dict;
2612 }
2613 mode = get_map_mode_string(which, is_abbr);
2614 if (mode == 0)
2615 {
2616 semsg(_(e_illegal_map_mode_string_str), which);
2530 return; 2617 return;
2531 mode = get_map_mode(&which, 0); 2618 }
2532 is_abbr = (int)tv_get_bool(&argvars[1]); 2619
2533
2534 if (argvars[2].v_type != VAR_DICT)
2535 {
2536 emsg(_(e_key_not_present_in_dictionary));
2537 return;
2538 }
2539 d = argvars[2].vval.v_dict;
2540 2620
2541 // Get the values in the same order as above in get_maparg(). 2621 // Get the values in the same order as above in get_maparg().
2542 lhs = dict_get_string(d, (char_u *)"lhs", FALSE); 2622 lhs = dict_get_string(d, (char_u *)"lhs", FALSE);
2543 lhsraw = dict_get_string(d, (char_u *)"lhsraw", FALSE); 2623 lhsraw = dict_get_string(d, (char_u *)"lhsraw", FALSE);
2544 lhsrawalt = dict_get_string(d, (char_u *)"lhsrawalt", FALSE); 2624 lhsrawalt = dict_get_string(d, (char_u *)"lhsrawalt", FALSE);