To: vim-dev@vim.org Subject: Patch 6.3a.023 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.3a.023 Problem: Completion on the command line doesn't handle backslashes properly. Only the tail of matches is shown, even when not completing filenames. Solution: When turning the string into a pattern double backslashes. Don't omit the path when not expanding files or directories. Files: src/ex_getln.c *** ../vim-6.3a.022/src/ex_getln.c Fri May 7 10:59:37 2004 --- src/ex_getln.c Fri May 14 14:47:41 2004 *************** *** 93,99 **** static int showmatches __ARGS((expand_T *xp, int wildmenu)); static void set_expand_context __ARGS((expand_T *xp)); static int ExpandFromContext __ARGS((expand_T *xp, char_u *, int *, char_u ***, int)); ! static int glob_in_path_prefix __ARGS((expand_T *xp)); #ifdef FEAT_CMDL_COMPL static int ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file, char *dirname)); # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) --- 93,99 ---- static int showmatches __ARGS((expand_T *xp, int wildmenu)); static void set_expand_context __ARGS((expand_T *xp)); static int ExpandFromContext __ARGS((expand_T *xp, char_u *, int *, char_u ***, int)); ! static int expand_showtail __ARGS((expand_T *xp)); #ifdef FEAT_CMDL_COMPL static int ExpandRTDir __ARGS((char_u *pat, int *num_file, char_u ***file, char *dirname)); # if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL) *************** *** 2713,2719 **** if (xp->xp_numfiles == -1) { set_expand_context(xp); ! cmd_showtail = !glob_in_path_prefix(xp); } if (xp->xp_context == EXPAND_UNSUCCESSFUL) --- 2713,2719 ---- if (xp->xp_numfiles == -1) { set_expand_context(xp); ! cmd_showtail = expand_showtail(xp); } if (xp->xp_context == EXPAND_UNSUCCESSFUL) *************** *** 3226,3232 **** set_expand_context(xp); i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos, &num_files, &files_found); ! showtail = !glob_in_path_prefix(xp); if (i != EXPAND_OK) return i; --- 3226,3232 ---- set_expand_context(xp); i = expand_cmdline(xp, ccline.cmdbuff, ccline.cmdpos, &num_files, &files_found); ! showtail = expand_showtail(xp); if (i != EXPAND_OK) return i; *************** *** 3399,3432 **** return t; } ! static int ! glob_in_path_prefix(xp) expand_T *xp; { char_u *s; char_u *end; if (xp->xp_context != EXPAND_FILES && xp->xp_context != EXPAND_DIRECTORIES) return FALSE; end = gettail(xp->xp_pattern); ! if (end == xp->xp_pattern) return FALSE; for (s = xp->xp_pattern; s < end; s++) { ! if (*s == '\\') /* skip backslash */ ! if (*++s == 0) ! break; ! ! switch (*s) ! { ! case '*': case '?': case '[': ! return TRUE; ! } } ! return FALSE; } /* --- 3399,3434 ---- return t; } ! /* ! * Return TRUE if we only need to show the tail of completion matches. ! * When not completing file names or there is a wildcard in the path FALSE is ! * returned. ! */ static int ! expand_showtail(xp) expand_T *xp; { char_u *s; char_u *end; + /* When not completing file names a "/" may mean something different. */ if (xp->xp_context != EXPAND_FILES && xp->xp_context != EXPAND_DIRECTORIES) return FALSE; end = gettail(xp->xp_pattern); ! if (end == xp->xp_pattern) /* there is no path separator */ return FALSE; for (s = xp->xp_pattern; s < end; s++) { ! /* Skip escaped wildcards. Only when the backslash is not a path ! * separator, on DOS the '*' "path\*\file" must not be skipped. */ ! if (rem_backslash(s)) ! ++s; ! else if (vim_strchr((char_u *)"*?[", *s) != NULL) ! return FALSE; } ! return TRUE; } /* *************** *** 3434,3440 **** * When expanding file names: The string will be used with expand_wildcards(). * Copy the file name into allocated memory and add a '*' at the end. * When expanding other names: The string will be used with regcomp(). Copy ! * the name into allocated memory and add ".*" at the end. */ char_u * addstar(fname, len, context) --- 3436,3442 ---- * When expanding file names: The string will be used with expand_wildcards(). * Copy the file name into allocated memory and add a '*' at the end. * When expanding other names: The string will be used with regcomp(). Copy ! * the name into allocated memory and prepend "^". */ char_u * addstar(fname, len, context) *************** *** 3474,3479 **** --- 3476,3486 ---- /* Buffer names are like file names. "." should be literal */ if (context == EXPAND_BUFFERS && fname[i] == '.') new_len++; /* "." becomes "\." */ + + /* Custom expansion takes care of special things, match + * backslashes literally (perhaps also for other types?) */ + if (context == EXPAND_USER_DEFINED && fname[i] == '\\') + new_len++; /* '\' becomes "\\" */ } retval = alloc(new_len); if (retval != NULL) *************** *** 3482,3488 **** j = 1; for (i = 0; i < len; i++, j++) { ! if (fname[i] == '\\' && ++i == len) /* skip backslash */ break; switch (fname[i]) --- 3489,3498 ---- j = 1; for (i = 0; i < len; i++, j++) { ! /* Skip backslash. But why? At least keep it for custom ! * expansion. */ ! if (context != EXPAND_USER_DEFINED ! && fname[i] == '\\' && ++i == len) break; switch (fname[i]) *************** *** 3496,3501 **** --- 3506,3514 ---- case '.': if (context == EXPAND_BUFFERS) retval[j++] = '\\'; break; + case '\\': if (context == EXPAND_USER_DEFINED) + retval[j++] = '\\'; + break; } retval[j] = fname[i]; } *** ../vim-6.3a.022/src/version.c Fri May 14 12:52:00 2004 --- src/version.c Fri May 14 13:32:02 2004 *************** *** 643,644 **** --- 643,646 ---- { /* Add new patch number below this line */ + /**/ + 23, /**/ -- What the word 'politics' means: 'Poli' in Latin meaning 'many' and 'tics' meaning 'bloodsucking creatures'. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///