To: vim-dev@vim.org Subject: Patch 6.2.063 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.063 Problem: When using custom completion end up with no matches. Solution: Make cmd_numfiles and cmd_files local to completion to avoid that they are overwritten when ExpandOne() is called recursively by f_glob(). Files: src/eval.c, src/ex_docmd.c, src/ex_getln.c, src/proto/ex_getln.pro, src/misc1.c, src/structs.h, src/tag.c *** ../vim-6.2.062/src/eval.c Sun Jul 27 15:01:56 2003 --- src/eval.c Thu Jul 31 19:47:34 2003 *************** *** 3933,3941 **** * for 'suffixes' and 'wildignore' */ if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1])) flags |= WILD_KEEP_ALL; xpc.xp_context = EXPAND_FILES; - xpc.xp_backslash = XP_BS_NONE; retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); } } --- 3935,3944 ---- * for 'suffixes' and 'wildignore' */ if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1])) flags |= WILD_KEEP_ALL; + ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); + ExpandCleanup(&xpc); } } *************** *** 4543,4553 **** { expand_T xpc; xpc.xp_context = EXPAND_FILES; - xpc.xp_backslash = XP_BS_NONE; retvar->var_type = VAR_STRING; retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]), NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); } /* --- 4546,4557 ---- { expand_T xpc; + ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; retvar->var_type = VAR_STRING; retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]), NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); + ExpandCleanup(&xpc); } /* *** ../vim-6.2.062/src/ex_docmd.c Sun Jul 27 14:35:27 2003 --- src/ex_docmd.c Sat Jul 26 18:36:31 2003 *************** *** 3694,3704 **** { expand_T xpc; xpc.xp_context = EXPAND_FILES; ! xpc.xp_backslash = XP_BS_NONE; ! if ((p = ExpandOne(&xpc, eap->arg, NULL, WILD_LIST_NOTFOUND|WILD_ADD_SLASH, ! WILD_EXPAND_FREE)) == NULL) return FAIL; } if (p != NULL) --- 3694,3706 ---- { expand_T xpc; + ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; ! p = ExpandOne(&xpc, eap->arg, NULL, WILD_LIST_NOTFOUND|WILD_ADD_SLASH, ! WILD_EXPAND_FREE); ! ExpandCleanup(&xpc); ! if (p == NULL) return FAIL; } if (p != NULL) *** ../vim-6.2.062/src/ex_getln.c Thu May 29 22:45:46 2003 --- src/ex_getln.c Sat Jul 26 18:57:18 2003 *************** *** 35,43 **** static struct cmdline_info ccline; /* current cmdline_info */ - static int cmd_numfiles = -1; /* number of files found by - file name completion */ - static char_u **cmd_files = NULL; /* list of files */ static int cmd_showtail; /* Only show path tail in lists ? */ --- 35,40 ---- *************** *** 207,212 **** --- 204,211 ---- ccline.cmdlen = ccline.cmdpos = 0; ccline.cmdbuff[0] = NUL; + ExpandInit(&xpc); + #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl && *curwin->w_p_rlc == 's' && (firstc == '/' || firstc == '?')) *************** *** 339,345 **** && c != K_PAGEDOWN && c != K_PAGEUP && c != K_KPAGEDOWN && c != K_KPAGEUP && c != K_LEFT && c != K_RIGHT ! && (cmd_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N))) { vim_free(lookfor); lookfor = NULL; --- 338,344 ---- && c != K_PAGEDOWN && c != K_PAGEUP && c != K_KPAGEDOWN && c != K_KPAGEUP && c != K_LEFT && c != K_RIGHT ! && (xpc.xp_numfiles > 0 || (c != Ctrl_P && c != Ctrl_N))) { vim_free(lookfor); lookfor = NULL; *************** *** 349,355 **** /* * works like CTRL-P (unless 'wc' is ). */ ! if (c != p_wc && c == K_S_TAB && cmd_numfiles != -1) c = Ctrl_P; #ifdef FEAT_WILDMENU --- 348,354 ---- /* * works like CTRL-P (unless 'wc' is ). */ ! if (c != p_wc && c == K_S_TAB && xpc.xp_numfiles != -1) c = Ctrl_P; #ifdef FEAT_WILDMENU *************** *** 371,377 **** #endif /* free expanded names when finished walking through matches */ ! if (cmd_numfiles != -1 && !(c == p_wc && KeyTyped) && c != p_wcm && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A && c != Ctrl_L) --- 370,376 ---- #endif /* free expanded names when finished walking through matches */ ! if (xpc.xp_numfiles != -1 && !(c == p_wc && KeyTyped) && c != p_wcm && c != Ctrl_N && c != Ctrl_P && c != Ctrl_A && c != Ctrl_L) *************** *** 629,638 **** */ if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm) { ! if (cmd_numfiles > 0) /* typed p_wc at least twice */ { /* if 'wildmode' contains "list" may still need to list */ ! if (cmd_numfiles > 1 && !did_wild_list && (wim_flags[wim_index] & WIM_LIST)) { --- 628,637 ---- */ if ((c == p_wc && !gotesc && KeyTyped) || c == p_wcm) { ! if (xpc.xp_numfiles > 0) /* typed p_wc at least twice */ { /* if 'wildmode' contains "list" may still need to list */ ! if (xpc.xp_numfiles > 1 && !did_wild_list && (wim_flags[wim_index] & WIM_LIST)) { *************** *** 673,679 **** /* when more than one match, and 'wildmode' first contains * "list", or no change and 'wildmode' contains "longest,list", * list all matches */ ! if (res == OK && cmd_numfiles > 1) { /* a "longest" that didn't do anything is skipped (but not * "list:longest") */ --- 672,678 ---- /* when more than one match, and 'wildmode' first contains * "list", or no change and 'wildmode' contains "longest,list", * list all matches */ ! if (res == OK && xpc.xp_numfiles > 1) { /* a "longest" that didn't do anything is skipped (but not * "list:longest") */ *************** *** 713,719 **** vim_beep(); } #ifdef FEAT_WILDMENU ! else if (cmd_numfiles == -1) xpc.xp_context = EXPAND_NOTHING; #endif } --- 712,718 ---- vim_beep(); } #ifdef FEAT_WILDMENU ! else if (xpc.xp_numfiles == -1) xpc.xp_context = EXPAND_NOTHING; #endif } *************** *** 1207,1213 **** case Ctrl_N: /* next match */ case Ctrl_P: /* previous match */ ! if (cmd_numfiles > 0) { if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, 0) == FAIL) --- 1206,1212 ---- case Ctrl_N: /* next match */ case Ctrl_P: /* previous match */ ! if (xpc.xp_numfiles > 0) { if (nextwild(&xpc, (c == Ctrl_P) ? WILD_PREV : WILD_NEXT, 0) == FAIL) *************** *** 1529,1534 **** --- 1528,1535 ---- cmd_fkmap = 0; #endif + ExpandCleanup(&xpc); + #ifdef FEAT_SEARCH_EXTRA if (did_incsearch) { *************** *** 2590,2596 **** int difflen; int v; ! if (cmd_numfiles == -1) { set_expand_context(xp); cmd_showtail = !glob_in_path_prefix(xp); --- 2591,2597 ---- int difflen; int v; ! if (xp->xp_numfiles == -1) { set_expand_context(xp); cmd_showtail = !glob_in_path_prefix(xp); *************** *** 2678,2686 **** if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL) return FAIL; ! if (cmd_numfiles <= 0 && p2 == NULL) beep_flush(); ! else if (cmd_numfiles == 1) /* free expanded pattern */ (void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE); --- 2679,2687 ---- if (xp->xp_context == EXPAND_MAPPINGS && p2 == NULL) return FAIL; ! if (xp->xp_numfiles <= 0 && p2 == NULL) beep_flush(); ! else if (xp->xp_numfiles == 1) /* free expanded pattern */ (void)ExpandOne(xp, NULL, NULL, 0, WILD_FREE); *************** *** 2693,2699 **** * Return a pointer to alloced memory containing the new string. * Return NULL for failure. * ! * Results are cached in cmd_files and cmd_numfiles. * * mode = WILD_FREE: just free previously expanded matches * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches --- 2694,2700 ---- * Return a pointer to alloced memory containing the new string. * Return NULL for failure. * ! * Results are cached in xp->xp_files and xp->xp_numfiles. * * mode = WILD_FREE: just free previously expanded matches * mode = WILD_EXPAND_FREE: normal expansion, do not keep matches *************** *** 2734,2745 **** */ if (mode == WILD_NEXT || mode == WILD_PREV) { ! if (cmd_numfiles > 0) { if (mode == WILD_PREV) { if (findex == -1) ! findex = cmd_numfiles; --findex; } else /* mode == WILD_NEXT */ --- 2735,2746 ---- */ if (mode == WILD_NEXT || mode == WILD_PREV) { ! if (xp->xp_numfiles > 0) { if (mode == WILD_PREV) { if (findex == -1) ! findex = xp->xp_numfiles; --findex; } else /* mode == WILD_NEXT */ *************** *** 2752,2762 **** if (findex < 0) { if (orig_save == NULL) ! findex = cmd_numfiles - 1; else findex = -1; } ! if (findex >= cmd_numfiles) { if (orig_save == NULL) findex = 0; --- 2753,2763 ---- if (findex < 0) { if (orig_save == NULL) ! findex = xp->xp_numfiles - 1; else findex = -1; } ! if (findex >= xp->xp_numfiles) { if (orig_save == NULL) findex = 0; *************** *** 2765,2786 **** } #ifdef FEAT_WILDMENU if (p_wmnu) ! win_redr_status_matches(xp, cmd_numfiles, cmd_files, findex, ! cmd_showtail); #endif if (findex == -1) return vim_strsave(orig_save); ! return vim_strsave(cmd_files[findex]); } else return NULL; } /* free old names */ ! if (cmd_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) { ! FreeWild(cmd_numfiles, cmd_files); ! cmd_numfiles = -1; vim_free(orig_save); orig_save = NULL; } --- 2766,2787 ---- } #ifdef FEAT_WILDMENU if (p_wmnu) ! win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, ! findex, cmd_showtail); #endif if (findex == -1) return vim_strsave(orig_save); ! return vim_strsave(xp->xp_files[findex]); } else return NULL; } /* free old names */ ! if (xp->xp_numfiles != -1 && mode != WILD_ALL && mode != WILD_LONGEST) { ! FreeWild(xp->xp_numfiles, xp->xp_files); ! xp->xp_numfiles = -1; vim_free(orig_save); orig_save = NULL; } *************** *** 2789,2795 **** if (mode == WILD_FREE) /* only release file name */ return NULL; ! if (cmd_numfiles == -1) { vim_free(orig_save); orig_save = orig; --- 2790,2796 ---- if (mode == WILD_FREE) /* only release file name */ return NULL; ! if (xp->xp_numfiles == -1) { vim_free(orig_save); orig_save = orig; *************** *** 2797,2803 **** /* * Do the expansion. */ ! if (ExpandFromContext(xp, str, &cmd_numfiles, &cmd_files, options) == FAIL) { #ifdef FNAME_ILLEGAL --- 2798,2804 ---- /* * Do the expansion. */ ! if (ExpandFromContext(xp, str, &xp->xp_numfiles, &xp->xp_files, options) == FAIL) { #ifdef FNAME_ILLEGAL *************** *** 2809,2815 **** EMSG2(_(e_nomatch2), str); #endif } ! else if (cmd_numfiles == 0) { if (!(options & WILD_SILENT)) EMSG2(_(e_nomatch2), str); --- 2810,2816 ---- EMSG2(_(e_nomatch2), str); #endif } ! else if (xp->xp_numfiles == 0) { if (!(options & WILD_SILENT)) EMSG2(_(e_nomatch2), str); *************** *** 2817,2836 **** else { /* Escape the matches for use on the command line. */ ! ExpandEscape(xp, str, cmd_numfiles, cmd_files, options); /* * Check for matching suffixes in file names. */ if (mode != WILD_ALL && mode != WILD_LONGEST) { ! if (cmd_numfiles) ! non_suf_match = cmd_numfiles; else non_suf_match = 1; if ((xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES) ! && cmd_numfiles > 1) { /* * More than one match; check suffix. --- 2818,2837 ---- else { /* Escape the matches for use on the command line. */ ! ExpandEscape(xp, str, xp->xp_numfiles, xp->xp_files, options); /* * Check for matching suffixes in file names. */ if (mode != WILD_ALL && mode != WILD_LONGEST) { ! if (xp->xp_numfiles) ! non_suf_match = xp->xp_numfiles; else non_suf_match = 1; if ((xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES) ! && xp->xp_numfiles > 1) { /* * More than one match; check suffix. *************** *** 2839,2845 **** */ non_suf_match = 0; for (i = 0; i < 2; ++i) ! if (match_suffix(cmd_files[i])) ++non_suf_match; } if (non_suf_match != 1) --- 2840,2846 ---- */ non_suf_match = 0; for (i = 0; i < 2; ++i) ! if (match_suffix(xp->xp_files[i])) ++non_suf_match; } if (non_suf_match != 1) *************** *** 2855,2887 **** beep_flush(); } if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE)) ! ss = vim_strsave(cmd_files[0]); } } } /* Find longest common part */ ! if (mode == WILD_LONGEST && cmd_numfiles > 0) { ! for (len = 0; cmd_files[0][len]; ++len) { ! for (i = 0; i < cmd_numfiles; ++i) { #ifdef CASE_INSENSITIVE_FILENAME if (xp->xp_context == EXPAND_DIRECTORIES || xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_BUFFERS) { ! if (TOLOWER_LOC(cmd_files[i][len]) != ! TOLOWER_LOC(cmd_files[0][len])) break; } else #endif ! if (cmd_files[i][len] != cmd_files[0][len]) break; } ! if (i < cmd_numfiles) { if (!(options & WILD_NO_BEEP)) vim_beep(); --- 2856,2888 ---- beep_flush(); } if (!(non_suf_match != 1 && mode == WILD_EXPAND_FREE)) ! ss = vim_strsave(xp->xp_files[0]); } } } /* Find longest common part */ ! if (mode == WILD_LONGEST && xp->xp_numfiles > 0) { ! for (len = 0; xp->xp_files[0][len]; ++len) { ! for (i = 0; i < xp->xp_numfiles; ++i) { #ifdef CASE_INSENSITIVE_FILENAME if (xp->xp_context == EXPAND_DIRECTORIES || xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_BUFFERS) { ! if (TOLOWER_LOC(xp->xp_files[i][len]) != ! TOLOWER_LOC(xp->xp_files[0][len])) break; } else #endif ! if (xp->xp_files[i][len] != xp->xp_files[0][len]) break; } ! if (i < xp->xp_numfiles) { if (!(options & WILD_NO_BEEP)) vim_beep(); *************** *** 2891,2930 **** ss = alloc((unsigned)len + 1); if (ss) { ! STRNCPY(ss, cmd_files[0], len); ss[len] = NUL; } findex = -1; /* next p_wc gets first one */ } /* Concatenate all matching names */ ! if (mode == WILD_ALL && cmd_numfiles > 0) { len = 0; ! for (i = 0; i < cmd_numfiles; ++i) ! len += (long_u)STRLEN(cmd_files[i]) + 1; ss = lalloc(len, TRUE); if (ss != NULL) { *ss = NUL; ! for (i = 0; i < cmd_numfiles; ++i) { ! STRCAT(ss, cmd_files[i]); ! if (i != cmd_numfiles - 1) STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " "); } } } if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) ! { ! FreeWild(cmd_numfiles, cmd_files); ! cmd_numfiles = -1; ! } return ss; } void ExpandEscape(xp, str, numfiles, files, options) expand_T *xp; --- 2892,2954 ---- ss = alloc((unsigned)len + 1); if (ss) { ! STRNCPY(ss, xp->xp_files[0], len); ss[len] = NUL; } findex = -1; /* next p_wc gets first one */ } /* Concatenate all matching names */ ! if (mode == WILD_ALL && xp->xp_numfiles > 0) { len = 0; ! for (i = 0; i < xp->xp_numfiles; ++i) ! len += (long_u)STRLEN(xp->xp_files[i]) + 1; ss = lalloc(len, TRUE); if (ss != NULL) { *ss = NUL; ! for (i = 0; i < xp->xp_numfiles; ++i) { ! STRCAT(ss, xp->xp_files[i]); ! if (i != xp->xp_numfiles - 1) STRCAT(ss, (options & WILD_USE_NL) ? "\n" : " "); } } } if (mode == WILD_EXPAND_FREE || mode == WILD_ALL) ! ExpandCleanup(xp); return ss; } + /* + * Prepare an expand structure for use. + */ + void + ExpandInit(xp) + expand_T *xp; + { + xp->xp_backslash = XP_BS_NONE; + xp->xp_numfiles = -1; + xp->xp_files = NULL; + } + + /* + * Cleanup an expand structure after use. + */ + void + ExpandCleanup(xp) + expand_T *xp; + { + if (xp->xp_numfiles >= 0) + { + FreeWild(xp->xp_numfiles, xp->xp_files); + xp->xp_numfiles = -1; + } + } + void ExpandEscape(xp, str, numfiles, files, options) expand_T *xp; *************** *** 3078,3084 **** int attr; int showtail; ! if (cmd_numfiles == -1) { set_expand_context(xp); i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos, --- 3102,3108 ---- int attr; int showtail; ! if (xp->xp_numfiles == -1) { set_expand_context(xp); i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos, *************** *** 3090,3097 **** } else { ! num_files = cmd_numfiles; ! files_found = cmd_files; showtail = cmd_showtail; } --- 3114,3121 ---- } else { ! num_files = xp->xp_numfiles; ! files_found = xp->xp_files; showtail = cmd_showtail; } *************** *** 3215,3221 **** cmdline_row = msg_row; /* will put it back later */ } ! if (cmd_numfiles == -1) FreeWild(num_files, files_found); return EXPAND_OK; --- 3239,3245 ---- cmdline_row = msg_row; /* will put it back later */ } ! if (xp->xp_numfiles == -1) FreeWild(num_files, files_found); return EXPAND_OK; *** ../vim-6.2.062/src/proto/ex_getln.pro Sun Jun 1 12:26:09 2003 --- src/proto/ex_getln.pro Sat Jul 26 18:38:51 2003 *************** *** 14,19 **** --- 14,21 ---- void compute_cmdrow __ARGS((void)); void gotocmdline __ARGS((int clr)); char_u *ExpandOne __ARGS((expand_T *xp, char_u *str, char_u *orig, int options, int mode)); + void ExpandInit __ARGS((expand_T *xp)); + void ExpandCleanup __ARGS((expand_T *xp)); void ExpandEscape __ARGS((expand_T *xp, char_u *str, int numfiles, char_u **files, int options)); void tilde_replace __ARGS((char_u *orig_pat, int num_files, char_u **files)); char_u *sm_gettail __ARGS((char_u *s)); *** ../vim-6.2.062/src/misc1.c Thu May 29 20:32:05 2003 --- src/misc1.c Sat Jul 26 18:37:24 2003 *************** *** 3212,3221 **** { expand_T xpc; xpc.xp_context = EXPAND_FILES; - xpc.xp_backslash = XP_BS_NONE; var = ExpandOne(&xpc, dst, NULL, WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE); mustfree = TRUE; } --- 3212,3222 ---- { expand_T xpc; + ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; var = ExpandOne(&xpc, dst, NULL, WILD_ADD_SLASH|WILD_SILENT, WILD_EXPAND_FREE); + ExpandCleanup(&xpc); mustfree = TRUE; } *** ../vim-6.2.062/src/structs.h Mon May 26 21:08:40 2003 --- src/structs.h Sat Jul 26 18:30:51 2003 *************** *** 376,381 **** --- 376,384 ---- char_u *xp_pattern; /* start of item to expand */ char_u *xp_arg; /* generic expansion argument */ int xp_backslash; /* one of the XP_BS_ values */ + int xp_numfiles; /* number of files found by + file name completion */ + char_u **xp_files; /* list of files */ } expand_T; /* values for xp_backslash */ *** ../vim-6.2.062/src/tag.c Sun Jun 1 14:41:25 2003 --- src/tag.c Thu Jul 31 18:27:34 2003 *************** *** 2811,2820 **** */ if (expand && mch_has_wildcard(fname)) { xpc.xp_context = EXPAND_FILES; - xpc.xp_backslash = XP_BS_NONE; expanded_fname = ExpandOne(&xpc, (char_u *)fname, NULL, WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); if (expanded_fname != NULL) fname = expanded_fname; } --- 2811,2821 ---- */ if (expand && mch_has_wildcard(fname)) { + ExpandInit(&xpc); xpc.xp_context = EXPAND_FILES; expanded_fname = ExpandOne(&xpc, (char_u *)fname, NULL, WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); + ExpandCleanup(&xpc); if (expanded_fname != NULL) fname = expanded_fname; } *** ../vim-6.2.062/src/version.c Sun Aug 10 14:52:30 2003 --- src/version.c Sun Aug 10 22:14:52 2003 *************** *** 632,633 **** --- 632,635 ---- { /* Add new patch number below this line */ + /**/ + 63, /**/ -- From "know your smileys": ...---... SOS /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Creator of Vim - Vi IMproved -- http://www.Vim.org \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///