To: vim_dev@googlegroups.com Subject: Patch 8.1.1785 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.1785 Problem: Map functionality mixed with character input. Solution: Move the map functionality to a separate file. (Yegappan Lakshmanan, closes #4740) Graduate the +localmap feature. Files: Filelist, src/Make_cyg_ming.mak, src/Make_morph.mak, src/Make_mvc.mak, src/Make_vms.mms, src/Makefile, src/README.md, src/buffer.c, src/feature.h, src/evalfunc.c, src/ex_docmd.c, src/getchar.c, src/map.c, src/proto.h, src/proto/getchar.pro, src/proto/map.pro, src/version.c, src/structs.h *** ../vim-8.1.1784/Filelist 2019-07-28 14:15:21.326943663 +0200 --- Filelist 2019-08-01 13:59:19.199279912 +0200 *************** *** 60,65 **** --- 60,66 ---- src/keymap.h \ src/macros.h \ src/main.c \ + src/map.c \ src/mark.c \ src/mbyte.c \ src/memfile.c \ *************** *** 199,204 **** --- 200,206 ---- src/proto/json.pro \ src/proto/list.pro \ src/proto/main.pro \ + src/proto/map.pro \ src/proto/mark.pro \ src/proto/mbyte.pro \ src/proto/memfile.pro \ *** ../vim-8.1.1784/src/Make_cyg_ming.mak 2019-07-28 14:15:21.326943663 +0200 --- src/Make_cyg_ming.mak 2019-08-01 13:59:19.199279912 +0200 *************** *** 736,741 **** --- 736,742 ---- $(OUTDIR)/json.o \ $(OUTDIR)/list.o \ $(OUTDIR)/main.o \ + $(OUTDIR)/map.o \ $(OUTDIR)/mark.o \ $(OUTDIR)/memfile.o \ $(OUTDIR)/memline.o \ *** ../vim-8.1.1784/src/Make_morph.mak 2019-07-28 14:15:21.326943663 +0200 --- src/Make_morph.mak 2019-08-01 13:59:19.199279912 +0200 *************** *** 56,61 **** --- 56,62 ---- json.c \ list.c \ main.c \ + map.c \ mark.c \ mbyte.c \ memfile.c \ *** ../vim-8.1.1784/src/Make_mvc.mak 2019-07-28 14:15:21.326943663 +0200 --- src/Make_mvc.mak 2019-08-01 13:59:19.203279888 +0200 *************** *** 745,750 **** --- 745,751 ---- $(OUTDIR)\json.obj \ $(OUTDIR)\list.obj \ $(OUTDIR)\main.obj \ + $(OUTDIR)\map.obj \ $(OUTDIR)\mark.obj \ $(OUTDIR)\mbyte.obj \ $(OUTDIR)\memfile.obj \ *************** *** 1556,1561 **** --- 1557,1564 ---- $(OUTDIR)/main.obj: $(OUTDIR) main.c $(INCL) $(CUI_INCL) + $(OUTDIR)/map.obj: $(OUTDIR) map.c $(INCL) + $(OUTDIR)/mark.obj: $(OUTDIR) mark.c $(INCL) $(OUTDIR)/memfile.obj: $(OUTDIR) memfile.c $(INCL) *************** *** 1769,1774 **** --- 1772,1778 ---- proto/json.pro \ proto/list.pro \ proto/main.pro \ + proto/map.pro \ proto/mark.pro \ proto/memfile.pro \ proto/memline.pro \ *** ../vim-8.1.1784/src/Make_vms.mms 2019-07-28 14:15:21.326943663 +0200 --- src/Make_vms.mms 2019-08-01 13:59:19.203279888 +0200 *************** *** 312,319 **** evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c \ if_cscope.c if_xcmdsrv.c fileio.c findfile.c fold.c getchar.c \ hardcopy.c hashtab.c highlight.c indent.c insexpand.c json.c list.c \ ! main.c mark.c menu.c mbyte.c memfile.c memline.c message.c misc1.c \ ! misc2.c move.c normal.c ops.c option.c popupmnu.c popupwin.c \ profiler.c quickfix.c regexp.c search.c session.c sha256.c sign.c \ spell.c spellfile.c syntax.c tag.c term.c termlib.c testing.c \ textprop.c ui.c undo.c usercmd.c userfunc.c version.c viminfo.c \ --- 312,319 ---- evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c \ if_cscope.c if_xcmdsrv.c fileio.c findfile.c fold.c getchar.c \ hardcopy.c hashtab.c highlight.c indent.c insexpand.c json.c list.c \ ! main.c map.c mark.c menu.c mbyte.c memfile.c memline.c message.c \ ! misc1.c misc2.c move.c normal.c ops.c option.c popupmnu.c popupwin.c \ profiler.c quickfix.c regexp.c search.c session.c sha256.c sign.c \ spell.c spellfile.c syntax.c tag.c term.c termlib.c testing.c \ textprop.c ui.c undo.c usercmd.c userfunc.c version.c viminfo.c \ *************** *** 327,334 **** ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj \ fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \ highlight.obj indent.obj insexpand.obj json.obj list.obj main.obj \ ! mark.obj menu.obj memfile.obj memline.obj message.obj misc1.obj \ ! misc2.obj move.obj mbyte.obj normal.obj ops.obj option.obj \ popupmnu.obj popupwin.obj profiler.obj quickfix.obj regexp.obj \ search.obj session.obj sha256.obj sign.obj spell.obj spellfile.obj \ syntax.obj tag.obj term.obj termlib.obj testing.obj textprop.obj \ --- 327,334 ---- ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj \ fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \ highlight.obj indent.obj insexpand.obj json.obj list.obj main.obj \ ! map.obj mark.obj menu.obj memfile.obj memline.obj message.obj \ ! misc1.obj misc2.obj move.obj mbyte.obj normal.obj ops.obj option.obj \ popupmnu.obj popupwin.obj profiler.obj quickfix.obj regexp.obj \ search.obj session.obj sha256.obj sign.obj spell.obj spellfile.obj \ syntax.obj tag.obj term.obj termlib.obj testing.obj textprop.obj \ *************** *** 630,635 **** --- 630,638 ---- ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ arabic.c + map.obj : map.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ + [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ mark.obj : mark.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h \ *** ../vim-8.1.1784/src/Makefile 2019-07-28 14:20:21.897426097 +0200 --- src/Makefile 2019-08-01 13:59:19.203279888 +0200 *************** *** 1612,1617 **** --- 1612,1618 ---- json.c \ list.c \ main.c \ + map.c \ mark.c \ memfile.c \ memline.c \ *************** *** 1735,1740 **** --- 1736,1742 ---- objects/indent.o \ objects/insexpand.o \ objects/list.o \ + objects/map.o \ objects/mark.o \ objects/memline.o \ objects/menu.o \ *************** *** 1879,1884 **** --- 1881,1887 ---- json.pro \ list.pro \ main.pro \ + map.pro \ mark.pro \ mbyte.pro \ memfile.pro \ *************** *** 3169,3174 **** --- 3172,3180 ---- objects/main.o: main.c $(CCC) -o $@ main.c + objects/map.o: map.c + $(CCC) -o $@ map.c + objects/mark.o: mark.c $(CCC) -o $@ mark.c *************** *** 3604,3609 **** --- 3610,3619 ---- auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h + objects/map.o: map.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/mark.o: mark.c vim.h protodef.h auto/config.h feature.h os_unix.h \ auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ *** ../vim-8.1.1784/src/README.md 2019-07-28 14:15:21.326943663 +0200 --- src/README.md 2019-08-01 13:59:19.203279888 +0200 *************** *** 38,43 **** --- 38,44 ---- indent.c | C and Lisp indentation insexpand.c | Insert mode completion mark.c | marks + map.c | mapping and abbreviations mbyte.c | multi-byte character handling memfile.c | storing lines for buffers in a swapfile memline.c | storing lines for buffers in memory *** ../vim-8.1.1784/src/buffer.c 2019-07-27 17:31:33.024355342 +0200 --- src/buffer.c 2019-08-01 14:11:01.106574665 +0200 *************** *** 951,960 **** #ifdef FEAT_NETBEANS_INTG netbeans_file_killed(buf); #endif - #ifdef FEAT_LOCALMAP map_clear_int(buf, MAP_ALL_MODES, TRUE, FALSE); /* clear local mappings */ map_clear_int(buf, MAP_ALL_MODES, TRUE, TRUE); /* clear local abbrevs */ - #endif VIM_CLEAR(buf->b_start_fenc); } --- 951,958 ---- *** ../vim-8.1.1784/src/feature.h 2019-07-28 15:21:50.809275875 +0200 --- src/feature.h 2019-08-01 14:14:36.561172246 +0200 *************** *** 166,175 **** /* * +localmap Mappings and abbreviations local to a buffer. */ - #ifdef FEAT_NORMAL - # define FEAT_LOCALMAP - #endif /* * +insert_expand CTRL-N/CTRL-P/CTRL-X in insert mode. Takes about --- 166,173 ---- /* * +localmap Mappings and abbreviations local to a buffer. + * Now always included. */ /* * +insert_expand CTRL-N/CTRL-P/CTRL-X in insert mode. Takes about *** ../vim-8.1.1784/src/evalfunc.c 2019-07-28 17:57:04.845046867 +0200 --- src/evalfunc.c 2019-08-01 14:11:13.534493284 +0200 *************** *** 6189,6197 **** "lispindent", #endif "listcmds", - #ifdef FEAT_LOCALMAP "localmap", - #endif #ifdef FEAT_LUA # ifndef DYNAMIC_LUA "lua", --- 6189,6195 ---- *************** *** 7396,7479 **** rettv->vval.v_number = (varnumber_T)time(NULL); } - static void - get_maparg(typval_T *argvars, typval_T *rettv, int exact) - { - char_u *keys; - char_u *which; - char_u buf[NUMBUFLEN]; - char_u *keys_buf = NULL; - char_u *rhs; - int mode; - int abbr = FALSE; - int get_dict = FALSE; - mapblock_T *mp; - int buffer_local; - - /* return empty string for failure */ - rettv->v_type = VAR_STRING; - rettv->vval.v_string = NULL; - - keys = tv_get_string(&argvars[0]); - if (*keys == NUL) - return; - - if (argvars[1].v_type != VAR_UNKNOWN) - { - which = tv_get_string_buf_chk(&argvars[1], buf); - if (argvars[2].v_type != VAR_UNKNOWN) - { - abbr = (int)tv_get_number(&argvars[2]); - if (argvars[3].v_type != VAR_UNKNOWN) - get_dict = (int)tv_get_number(&argvars[3]); - } - } - else - which = (char_u *)""; - if (which == NULL) - return; - - mode = get_map_mode(&which, 0); - - keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE, FALSE); - rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); - vim_free(keys_buf); - - if (!get_dict) - { - /* Return a string. */ - if (rhs != NULL) - { - if (*rhs == NUL) - rettv->vval.v_string = vim_strsave((char_u *)""); - else - rettv->vval.v_string = str2special_save(rhs, FALSE); - } - - } - else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL) - { - /* Return a dictionary. */ - char_u *lhs = str2special_save(mp->m_keys, TRUE); - char_u *mapmode = map_mode_to_chars(mp->m_mode); - dict_T *dict = rettv->vval.v_dict; - - dict_add_string(dict, "lhs", lhs); - dict_add_string(dict, "rhs", mp->m_orig_str); - dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L); - dict_add_number(dict, "expr", mp->m_expr ? 1L : 0L); - dict_add_number(dict, "silent", mp->m_silent ? 1L : 0L); - dict_add_number(dict, "sid", (long)mp->m_script_ctx.sc_sid); - dict_add_number(dict, "lnum", (long)mp->m_script_ctx.sc_lnum); - dict_add_number(dict, "buffer", (long)buffer_local); - dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L); - dict_add_string(dict, "mode", mapmode); - - vim_free(lhs); - vim_free(mapmode); - } - } - #ifdef FEAT_FLOAT /* * "log()" function --- 7394,7399 ---- *** ../vim-8.1.1784/src/ex_docmd.c 2019-07-28 15:21:50.813275855 +0200 --- src/ex_docmd.c 2019-08-01 13:59:19.203279888 +0200 *************** *** 29,39 **** static void append_command(char_u *cmd); static char_u *find_command(exarg_T *eap, int *full); - static void ex_abbreviate(exarg_T *eap); - static void ex_map(exarg_T *eap); - static void ex_unmap(exarg_T *eap); - static void ex_mapclear(exarg_T *eap); - static void ex_abclear(exarg_T *eap); #ifndef FEAT_MENU # define ex_emenu ex_ni # define ex_menu ex_ni --- 29,34 ---- *************** *** 231,237 **** static void ex_pwd(exarg_T *eap); static void ex_equal(exarg_T *eap); static void ex_sleep(exarg_T *eap); - static void do_exmap(exarg_T *eap, int isabbrev); static void ex_winsize(exarg_T *eap); static void ex_wincmd(exarg_T *eap); #if defined(FEAT_GUI) || defined(UNIX) || defined(VMS) || defined(MSWIN) --- 226,231 ---- *************** *** 5347,5407 **** return OK; } - /* - * ":abbreviate" and friends. - */ - static void - ex_abbreviate(exarg_T *eap) - { - do_exmap(eap, TRUE); /* almost the same as mapping */ - } - - /* - * ":map" and friends. - */ - static void - ex_map(exarg_T *eap) - { - /* - * If we are sourcing .exrc or .vimrc in current directory we - * print the mappings for security reasons. - */ - if (secure) - { - secure = 2; - msg_outtrans(eap->cmd); - msg_putchar('\n'); - } - do_exmap(eap, FALSE); - } - - /* - * ":unmap" and friends. - */ - static void - ex_unmap(exarg_T *eap) - { - do_exmap(eap, FALSE); - } - - /* - * ":mapclear" and friends. - */ - static void - ex_mapclear(exarg_T *eap) - { - map_clear(eap->cmd, eap->arg, eap->forceit, FALSE); - } - - /* - * ":abclear" and friends. - */ - static void - ex_abclear(exarg_T *eap) - { - map_clear(eap->cmd, eap->arg, TRUE, TRUE); - } - static void ex_autocmd(exarg_T *eap) { --- 5341,5346 ---- *************** *** 7782,7806 **** (void)vpeekc(); } - static void - do_exmap(exarg_T *eap, int isabbrev) - { - int mode; - char_u *cmdp; - - cmdp = eap->cmd; - mode = get_map_mode(&cmdp, eap->forceit || isabbrev); - - switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'), - eap->arg, mode, isabbrev)) - { - case 1: emsg(_(e_invarg)); - break; - case 2: emsg((isabbrev ? _(e_noabbr) : _(e_nomap))); - break; - } - } - /* * ":winsize" command (obsolete). */ --- 7721,7726 ---- *** ../vim-8.1.1784/src/getchar.c 2019-07-27 21:05:16.679942758 +0200 --- src/getchar.c 2019-08-01 14:11:40.714315554 +0200 *************** *** 52,77 **** */ static int block_redo = FALSE; - /* - * Make a hash value for a mapping. - * "mode" is the lower 4 bits of the State for the mapping. - * "c1" is the first character of the "lhs". - * Returns a value between 0 and 255, index in maphash. - * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode. - */ - #define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + SELECTMODE + OP_PENDING + TERMINAL)) ? (c1) : ((c1) ^ 0x80)) - - /* - * Each mapping is put in one of the 256 hash lists, to speed up finding it. - */ - static mapblock_T *(maphash[256]); - static int maphash_valid = FALSE; - - /* - * List used for abbreviations. - */ - static mapblock_T *first_abbr = NULL; /* first entry in abbrlist */ - static int KeyNoremap = 0; /* remapping flags */ /* --- 52,57 ---- *************** *** 113,125 **** static void may_sync_undo(void); static void closescript(void); static int vgetorpeek(int); - static void map_free(mapblock_T **); - static void validate_maphash(void); - static void showmap(mapblock_T *mp, int local); static int inchar(char_u *buf, int maxlen, long wait_time); - #ifdef FEAT_EVAL - static char_u *eval_map_expr(char_u *str, int c); - #endif /* * Free and clear a buffer. --- 93,99 ---- *************** *** 911,916 **** --- 885,899 ---- } /* + * Returns TRUE when keys cannot be remapped. + */ + int + noremap_keys(void) + { + return KeyNoremap & (RM_NONE|RM_SCRIPT); + } + + /* * Insert a string in position 'offset' in the typeahead buffer (for "@r" * and ":normal" command, vgetorpeek() and check_termcode()). * *************** *** 1962,1970 **** int keylen; char_u *s; mapblock_T *mp; - #ifdef FEAT_LOCALMAP mapblock_T *mp2; - #endif mapblock_T *mp_match; int mp_match_len = 0; int timedout = FALSE; /* waited for more than 1 second --- 1945,1951 ---- *************** *** 2112,2118 **** mp = NULL; max_mlen = 0; c1 = typebuf.tb_buf[typebuf.tb_off]; ! if (no_mapping == 0 && maphash_valid && (no_zero_mapping == 0 || c1 != '0') && (typebuf.tb_maplen == 0 || (p_remap --- 2093,2099 ---- mp = NULL; max_mlen = 0; c1 = typebuf.tb_buf[typebuf.tb_off]; ! if (no_mapping == 0 && is_maphash_valid() && (no_zero_mapping == 0 || c1 != '0') && (typebuf.tb_maplen == 0 || (p_remap *************** *** 2141,2159 **** nolmaplen = 0; } #endif ! #ifdef FEAT_LOCALMAP ! /* First try buffer-local mappings. */ ! mp = curbuf->b_maphash[MAP_HASH(local_State, c1)]; ! mp2 = maphash[MAP_HASH(local_State, c1)]; if (mp == NULL) { ! /* There are no buffer-local mappings. */ mp = mp2; mp2 = NULL; } - #else - mp = maphash[MAP_HASH(local_State, c1)]; - #endif /* * Loop until a partly matching mapping is found or * all (local) mappings have been checked. --- 2122,2136 ---- nolmaplen = 0; } #endif ! // First try buffer-local mappings. ! mp = get_buf_maphash_list(local_State, c1); ! mp2 = get_maphash_list(local_State, c1); if (mp == NULL) { ! // There are no buffer-local mappings. mp = mp2; mp2 = NULL; } /* * Loop until a partly matching mapping is found or * all (local) mappings have been checked. *************** *** 2164,2173 **** mp_match = NULL; mp_match_len = 0; for ( ; mp != NULL; ! #ifdef FEAT_LOCALMAP ! mp->m_next == NULL ? (mp = mp2, mp2 = NULL) : ! #endif ! (mp = mp->m_next)) { /* * Only consider an entry if the first character --- 2141,2148 ---- mp_match = NULL; mp_match_len = 0; for ( ; mp != NULL; ! mp->m_next == NULL ? (mp = mp2, mp2 = NULL) ! : (mp = mp->m_next)) { /* * Only consider an entry if the first character *************** *** 3194,5389 **** ); } #endif - - /* - * map[!] : show all key mappings - * map[!] {lhs} : show key mapping for {lhs} - * map[!] {lhs} {rhs} : set key mapping for {lhs} to {rhs} - * noremap[!] {lhs} {rhs} : same, but no remapping for {rhs} - * unmap[!] {lhs} : remove key mapping for {lhs} - * abbr : show all abbreviations - * abbr {lhs} : show abbreviations for {lhs} - * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs} - * noreabbr {lhs} {rhs} : same, but no remapping for {rhs} - * unabbr {lhs} : remove abbreviation for {lhs} - * - * maptype: 0 for :map, 1 for :unmap, 2 for noremap. - * - * arg is pointer to any arguments. Note: arg cannot be a read-only string, - * it will be modified. - * - * for :map mode is NORMAL + VISUAL + SELECTMODE + OP_PENDING - * for :map! mode is INSERT + CMDLINE - * for :cmap mode is CMDLINE - * for :imap mode is INSERT - * for :lmap mode is LANGMAP - * for :nmap mode is NORMAL - * for :vmap mode is VISUAL + SELECTMODE - * for :xmap mode is VISUAL - * for :smap mode is SELECTMODE - * for :omap mode is OP_PENDING - * for :tmap mode is TERMINAL - * - * for :abbr mode is INSERT + CMDLINE - * for :iabbr mode is INSERT - * for :cabbr mode is CMDLINE - * - * Return 0 for success - * 1 for invalid arguments - * 2 for no match - * 4 for out of mem - * 5 for entry not unique - */ - int - do_map( - int maptype, - char_u *arg, - int mode, - int abbrev) /* not a mapping but an abbreviation */ - { - char_u *keys; - mapblock_T *mp, **mpp; - char_u *rhs; - char_u *p; - int n; - int len = 0; /* init for GCC */ - char_u *newstr; - int hasarg; - int haskey; - int did_it = FALSE; - #ifdef FEAT_LOCALMAP - int did_local = FALSE; - #endif - int round; - char_u *keys_buf = NULL; - char_u *arg_buf = NULL; - int retval = 0; - int do_backslash; - int hash; - int new_hash; - mapblock_T **abbr_table; - mapblock_T **map_table; - int unique = FALSE; - int nowait = FALSE; - int silent = FALSE; - int special = FALSE; - #ifdef FEAT_EVAL - int expr = FALSE; - #endif - int noremap; - char_u *orig_rhs; - - keys = arg; - map_table = maphash; - abbr_table = &first_abbr; - - /* For ":noremap" don't remap, otherwise do remap. */ - if (maptype == 2) - noremap = REMAP_NONE; - else - noremap = REMAP_YES; - - /* Accept , , ,