diff options
-rw-r--r-- | runtime/doc/quickfix.txt | 4 | ||||
-rw-r--r-- | runtime/doc/todo.txt | 15 | ||||
-rw-r--r-- | runtime/doc/version7.txt | 23 | ||||
-rw-r--r-- | src/eval.c | 23 | ||||
-rw-r--r-- | src/ex_cmds.c | 6 | ||||
-rw-r--r-- | src/gui_gtk_x11.c | 11 | ||||
-rw-r--r-- | src/gui_x11.c | 40 | ||||
-rw-r--r-- | src/main.c | 47 | ||||
-rw-r--r-- | src/misc1.c | 295 | ||||
-rw-r--r-- | src/proto/gui_riscos.pro | 2 | ||||
-rw-r--r-- | src/proto/gui_x11.pro | 2 | ||||
-rw-r--r-- | src/proto/misc1.pro | 1 |
12 files changed, 380 insertions, 89 deletions
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt index 7c50427c92..37025e98da 100644 --- a/runtime/doc/quickfix.txt +++ b/runtime/doc/quickfix.txt @@ -1,4 +1,4 @@ -*quickfix.txt* For Vim version 7.0aa. Last change: 2005 May 20 +*quickfix.txt* For Vim version 7.0aa. Last change: 2005 Jul 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -334,6 +334,8 @@ advantages are: Examples: > :vimgrep /an error/ *.c :vimgrep /\<FileName\>/ *.h include/* + :vimgrep /myfunc/ **/*.c +< For the use of "**" see |starstar-wildcard|. :vim[grep][!] {pattern} {file} ... Like above, but instead of enclosing the pattern in a diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 264a06dc22..211ee93ff6 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2005 Jul 24 +*todo.txt* For Vim version 7.0aa. Last change: 2005 Jul 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -52,18 +52,12 @@ Awaiting response: - Win32: tearoff menu window should have a scrollbar when it's taller than the screen. - mblen(NULL, 0) also in Vim 6.3? - -Win32: Crash when pasting Simplified Chinese in utf-8. (rainux, 2005 June 20) +- Win32: Crash when pasting Simplified Chinese in utf-8. (rainux, 2005 June + 20) PLANNED FOR VERSION 7.0: -- REFACTORING: - Improve the interface between the generic GUI code and the system-specific - code. Generic code handles text window with scrollbars, system-specific - code menu, toolbar, etc. -- Support using "**" in filename for ":next", ":vimgrep", etc., so that a - directory tree can be searched. - Store messages to allow SCROLLING BACK for all commands. And other "less" like commands. - "INTELLISENSE". First cleanup the Insert-mode completion. @@ -313,6 +307,7 @@ Awaiting updated patches: (2003 May 13) raisewin() raise gvim window (see HierAssist patch for Tcl implementation ~/vim/HierAssist/ ) + 7 Make globpath() also work with upwards search. (Brian Medley) 7 Add patch from Benoit Cerrina to integrate Vim and Perl functions better. Now also works for Ruby (2001 Nov 10) - Patch from Herculano de Lima Einloft Neto for better formatting of the @@ -1573,7 +1568,6 @@ Built-in script language: Alternative: Support packages. {package-name}:{function-name}(). Packages are loaded automatically when first used, from $VIMRUNTIME/packages (or use a search path). -7 Make globpath() also work with "**" and upwards search. (Brian Medley) 7 Add the markclear() function to delete a mark in another buffer. Charles Campbell (2004 Jan 9) http://mysite.verizon.net/astronaut/vim/index.html#Patch @@ -3156,7 +3150,6 @@ Various improvements: 9 Support ACLs on more systems. 7 Add ModeMsgVisual, ModeMsgInsert, etc. so that each mode message can be highlighted differently. -8 Allow using "**" as a wildcard in commands like ":next" and ":args". 7 Add a message area for the user. Set some option to reserve space (above the command line?). Use an ":echouser" command to display the message (truncated to fit in the space). diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt index 0bd1e7d8cc..ce0c4a4e8f 100644 --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2005 Jul 21 +*version7.txt* For Vim version 7.0aa. Last change: 2005 Jul 25 VIM REFERENCE MANUAL by Bram Moolenaar @@ -222,6 +222,10 @@ patterns, this also allows grepping in compressed and remote files. If you want to use the search results in a script you can use the |getqflist()| function. +To search in files in various directories the "**" pattern can be used. It +expands into an arbitrary depth of directories. "**" can be used in all +places where file names are expanded, thus also with |:next| and |:args|. + POSIX compatibility *new-posix* ------------------- @@ -614,7 +618,7 @@ invalid characters after the register name. |:redir| ":redir => variable" and ":redir =>> variable" write or append to a variable. (Yegappan Lakshmanan) |:redir| -":redir @{a-z}>>" appends to register a to z. +":redir @{a-z}>>" appends to register a to z. (Yegappan Lakshmanan) The 'verbosefile' option can be used to log messages in a file. Verbose messages are not displayed then. The "-V{filename}" argument can be used to @@ -693,11 +697,15 @@ prepending "8bit-". Added the "customlist" completion argument to a user-defined command. The user-defined completion function should return the completion candidates as a -Vim List and the returned results are not filtered by Vim. +Vim List and the returned results are not filtered by Vim. (Yegappan +Lakshmanan) Win32: Balloons can have multiple lines if common controls supports it. (Sergey Khorev) +The 's' flag is added to the search() and searchpair() function to set the +' mark if the cursor is moved. (Yegappan Lakshmanan) + ============================================================================== COMPILE TIME CHANGES *compile-changes-7* @@ -720,6 +728,15 @@ to detect memory leaks. Some memory will always reported as leaked, such as allocated by X11 library functions and the memory allocated in alloc_cmdbuff() to store the ":quit" command. +Moved the code for printing to src/hardcopy.c. + +Moved some code from main() to separate functions to make it easier to see +what is being done. Use a structure to avoid a lot of arguments to the +functions. + +Moved unix_expandpath() to misc1.c, so that it can also be used by os_mac.c +without copying the code. + ============================================================================== BUG FIXES *bug-fixes-7* diff --git a/src/eval.c b/src/eval.c index 40ec9f3e31..f18a3a95bf 100644 --- a/src/eval.c +++ b/src/eval.c @@ -12724,6 +12724,7 @@ f_reverse(argvars, rettv) #define SP_NOMOVE 1 /* don't move cursor */ #define SP_REPEAT 2 /* repeat to find outer pair */ #define SP_RETCOUNT 4 /* return matchcount */ +#define SP_SETPCMARK 8 /* set previous context mark */ static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); @@ -12761,6 +12762,7 @@ get_search_arg(varp, flagsp) case 'n': mask = SP_NOMOVE; break; case 'r': mask = SP_REPEAT; break; case 'm': mask = SP_RETCOUNT; break; + case 's': mask = SP_SETPCMARK; break; } if (mask == 0) { @@ -12799,7 +12801,14 @@ f_search(argvars, rettv) dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ if (dir == 0) goto theend; - if ((flags & ~SP_NOMOVE) != 0) + /* + * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. + * Check to make sure only those flags are set. + * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both + * flags cannot be set. Check for that condition also. + */ + if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || + ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) { EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); goto theend; @@ -12810,6 +12819,8 @@ f_search(argvars, rettv) SEARCH_KEEP, RE_SEARCH) != FAIL) { rettv->vval.v_number = pos.lnum; + if (flags & SP_SETPCMARK) + setpcmark(); curwin->w_cursor = pos; /* "/$" will put the cursor after the end of the line, may need to * correct that here */ @@ -12853,6 +12864,14 @@ f_searchpair(argvars, rettv) dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ if (dir == 0) goto theend; + /* + * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. + */ + if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) + { + EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); + goto theend; + } /* Optional fifth argument: skip expresion */ if (argvars[3].v_type == VAR_UNKNOWN @@ -12980,6 +12999,8 @@ do_searchpair(spat, mpat, epat, dir, skip, flags) ++retval; else retval = pos.lnum; + if (flags & SP_SETPCMARK) + setpcmark(); curwin->w_cursor = pos; if (!(flags & SP_REPEAT)) break; diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 8d8e3129be..2118f2691f 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -5369,13 +5369,15 @@ find_help_tags(arg, num_matches, matches, keep_lang) char_u *s, *d; int i; static char *(mtable[]) = {"*", "g*", "[*", "]*", ":*", - "/*", "/\\*", "\"*", "/\\(\\)", + "/*", "/\\*", "\"*", "**", + "/\\(\\)", "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?", "/\\?", "/\\z(\\)", "\\=", ":s\\=", "[count]", "[quotex]", "[range]", "[pattern]", "\\|", "\\%$"}; static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star", - "/star", "/\\\\star", "quotestar", "/\\\\(\\\\)", + "/star", "/\\\\star", "quotestar", "starstar", + "/\\\\(\\\\)", "?", ":?", "?<CR>", "g?", "g?g?", "g??", "z?", "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=", "\\[count]", "\\[quotex]", "\\[range]", diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index d93f7bc756..65817a4fba 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -4066,8 +4066,11 @@ is_cjk_font(PangoFontDescription *font_desc) } #endif /* HAVE_GTK2 */ +/* + * Adjust gui.char_height (after 'linespace' was changed). + */ int -gui_mch_adjust_charsize(void) +gui_mch_adjust_charheight(void) { #ifdef HAVE_GTK2 PangoFontMetrics *metrics; @@ -4082,14 +4085,14 @@ gui_mch_adjust_charsize(void) pango_font_metrics_unref(metrics); gui.char_height = (ascent + descent + PANGO_SCALE - 1) / PANGO_SCALE - + p_linespace; + + p_linespace; /* LINTED: avoid warning: bitwise operation on signed value */ gui.char_ascent = PANGO_PIXELS(ascent + p_linespace * PANGO_SCALE / 2); #else /* !HAVE_GTK2 */ gui.char_height = gui.current_font->ascent + gui.current_font->descent - + p_linespace; + + p_linespace; gui.char_ascent = gui.current_font->ascent + p_linespace / 2; #endif /* !HAVE_GTK2 */ @@ -4553,7 +4556,7 @@ gui_mch_init_font(char_u *font_name, int fontset) if (gui.char_width <= 0) gui.char_width = 8; - gui_mch_adjust_charsize(); + gui_mch_adjust_charheight(); /* Set the fontname, which will be used for information purposes */ hl_set_font_name(font_name); diff --git a/src/gui_x11.c b/src/gui_x11.c index e29b74fcc0..4dc4db3206 100644 --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -632,15 +632,14 @@ gui_x11_expose_cb(w, dud, event, dum) #if (defined(FEAT_NETBEANS_INTG) || defined(FEAT_SUN_WORKSHOP)) \ || defined(PROTO) /* - * This function fills in the XRectangle object with the current - * x,y coordinates and height, width so that an XtVaSetValues to - * the same shell of those resources will restore the window to its - * formar position and dimensions. + * This function fills in the XRectangle object with the current x,y + * coordinates and height, width so that an XtVaSetValues to the same shell of + * those resources will restore the window to its formar position and + * dimensions. * - * Note: This function may fail, in which case the XRectangle will - * be unchanged. Be sure to have the XRectangle set with the - * proper values for a failed condition prior to calling this - * function. + * Note: This function may fail, in which case the XRectangle will be + * unchanged. Be sure to have the XRectangle set with the proper values for a + * failed condition prior to calling this function. */ static void shellRectangle(Widget shell, XRectangle *r) @@ -1807,7 +1806,7 @@ gui_mch_set_shellsize(width, height, min_width, min_height, } /* - * Allow 10 pixels for horizontal borders, 30 for vertical borders. + * Allow 10 pixels for horizontal borders, 'guiheadroom' for vertical borders. * Is there no way in X to find out how wide the borders really are? */ void @@ -2019,8 +2018,11 @@ gui_mch_get_fontname(font, name) } #endif +/* + * Adjust gui.char_height (after 'linespace' was changed). + */ int -gui_mch_adjust_charsize() +gui_mch_adjust_charheight() { #ifdef FEAT_XFONTSET if (gui.fontset != NOFONTSET) @@ -2076,24 +2078,6 @@ gui_mch_set_fontset(fontset) } #endif -#if 0 /* not used */ -/* - * Return TRUE if the two fonts given are equivalent. - */ - int -gui_mch_same_font(f1, f2) - GuiFont f1; - GuiFont f2; -{ -#ifdef FEAT_XFONTSET - if (gui.fontset != NULL) - return f1 == f2; - else -#endif - return ((XFontStruct *)f1)->fid == ((XFontStruct *)f2)->fid; -} -#endif - /* * If a font is not going to be used, free its structure. */ diff --git a/src/main.c b/src/main.c index 1beaca47f9..f6a31aa110 100644 --- a/src/main.c +++ b/src/main.c @@ -39,7 +39,6 @@ typedef struct char **argv; int evim_mode; /* started as "evim" */ - int bin_mode; /* -b argument used */ char_u *use_vimrc; /* vimrc from -u argument */ int n_commands; /* no. of commands from + or -c */ @@ -367,15 +366,6 @@ main # endif #endif - /* "-b" argument used. Check before expanding file names, because for - * Win32 this makes us edit a shortcut file itself, instead of the file it - * links to. */ - if (params.bin_mode) - { - set_options_bin(curbuf->b_p_bin, 1, 0); - curbuf->b_p_bin = 1; /* binary file I/O */ - } - if (GARGCOUNT > 0) { #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE) @@ -420,8 +410,13 @@ main TIME_MSG("expanding arguments"); #ifdef FEAT_DIFF - if (params.diff_mode && params.window_count == -1) - params.window_count = 0; /* open up to 3 files in a window */ + if (params.diff_mode) + { + if (params.window_count == -1) + params.window_count = 0; /* open up to 3 windows */ + if (params.vert_windows == MAYBE) + params.vert_windows = TRUE; /* use vertical split */ + } #endif /* Don't redraw until much later. */ @@ -1453,7 +1448,7 @@ command_line_scan(parmp) int had_minmin = FALSE; /* found "--" argument */ int want_argument; /* option argument with argument */ int c; - char_u *p; + char_u *p = NULL; long n; --argc; @@ -1597,7 +1592,11 @@ command_line_scan(parmp) break; case 'b': /* "-b" binary mode */ - parmp->bin_mode = TRUE; /* postpone to after reading .exrc files */ + /* Needs to be effective before expanding file names, because + * for Win32 this makes us edit a shortcut file itself, + * instead of the file it links to. */ + set_options_bin(curbuf->b_p_bin, 1, 0); + curbuf->b_p_bin = 1; /* binary file I/O */ break; case 'C': /* "-C" Compatible */ @@ -1691,7 +1690,8 @@ command_line_scan(parmp) case 'o': /* "-o[N]" open N horizontal split windows */ #ifdef FEAT_WINDOWS /* default is 0: open window for each file */ - parmp->window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0); + parmp->window_count = get_number_arg((char_u *)argv[0], + &argv_idx, 0); parmp->vert_windows = FALSE; #endif break; @@ -1699,7 +1699,8 @@ command_line_scan(parmp) case 'O': /* "-O[N]" open N vertical split windows */ #if defined(FEAT_VERTSPLIT) && defined(FEAT_WINDOWS) /* default is 0: open window for each file */ - parmp->window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0); + parmp->window_count = get_number_arg((char_u *)argv[0], + &argv_idx, 0); parmp->vert_windows = TRUE; #endif break; @@ -1817,7 +1818,8 @@ command_line_scan(parmp) { if (parmp->n_commands >= MAX_ARG_CMDS) mainerr(ME_EXTRA_CMD, NULL); - parmp->commands[parmp->n_commands++] = (char_u *)argv[0] + argv_idx; + parmp->commands[parmp->n_commands++] = (char_u *)argv[0] + + argv_idx; argv_idx = -1; break; } @@ -1890,13 +1892,15 @@ command_line_scan(parmp) parmp->commands[parmp->n_commands++] = p; } else - parmp->commands[parmp->n_commands++] = (char_u *)argv[0]; + parmp->commands[parmp->n_commands++] = + (char_u *)argv[0]; break; case '-': /* "--cmd {command}" execute command */ if (parmp->n_pre_commands >= MAX_ARG_CMDS) mainerr(ME_EXTRA_CMD, NULL); - parmp->pre_commands[parmp->n_pre_commands++] = (char_u *)argv[0]; + parmp->pre_commands[parmp->n_pre_commands++] = + (char_u *)argv[0]; break; /* case 'd': -d {device} is handled in mch_check_win() for the @@ -2052,7 +2056,7 @@ scripterror: #endif alist_add(&global_alist, p, #if (!defined(UNIX) && !defined(__EMX__)) || defined(ARCHIE) - parmp->literal ? 2 : 0 /* add buffer number after expanding */ + parmp->literal ? 2 : 0 /* add buffer nr after exp. */ #else 2 /* add buffer number now and use curbuf */ #endif @@ -2425,7 +2429,8 @@ source_startup_scripts(parmp) */ if (parmp->use_vimrc != NULL) { - if (STRCMP(parmp->use_vimrc, "NONE") == 0 || STRCMP(parmp->use_vimrc, "NORC") == 0) + if (STRCMP(parmp->use_vimrc, "NONE") == 0 + || STRCMP(parmp->use_vimrc, "NORC") == 0) { #ifdef FEAT_GUI if (use_gvimrc == NULL) /* don't load gvimrc either */ diff --git a/src/misc1.c b/src/misc1.c index f0de5935a2..7c50470f76 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -8158,24 +8158,33 @@ namelowcpy( # endif /* - * Recursively build up a list of files in "gap" matching the first wildcard - * in `path'. Called by expand_wildcards(). + * Recursively expand one path component into all matching files and/or + * directories. Adds matches to "gap". Handles "*", "?", "[a-z]", "**", etc. * Return the number of matches found. * "path" has backslashes before chars that are not to be expanded, starting * at "path[wildoff]". + * Return the number of matches found. + * NOTE: much of this is identical to unix_expandpath(), keep in sync! */ static int dos_expandpath( garray_T *gap, char_u *path, int wildoff, - int flags) /* EW_* flags */ + int flags, /* EW_* flags */ + int didstar) /* expaneded "**" once already */ { - char_u *buf; - char_u *path_end; - char_u *p, *s, *e; - int start_len = gap->ga_len; - int ok; + char_u *buf; + char_u *path_end; + char_u *p, *s, *e; + int start_len = gap->ga_len; + char_u *pat; + regmatch_T regmatch; + int starts_with_dot; + int matches; + int len; + int starstar = FALSE; + static int stardepth = 0; /* depth for "**" expansion */ #ifdef WIN3264 WIN32_FIND_DATA fb; HANDLE hFind = (HANDLE)0; @@ -8186,15 +8195,19 @@ dos_expandpath( #else struct ffblk fb; #endif - int matches; - int starts_with_dot; - int len; - char_u *pat; - regmatch_T regmatch; char_u *matchname; + int ok; + + /* Expanding "**" may take a long time, check for CTRL-C. */ + if (stardepth > 0) + { + ui_breakcheck(); + if (got_int) + return 0; + } /* make room for file name */ - buf = alloc((unsigned int)STRLEN(path) + BASENAMELEN + 5); + buf = alloc((int)STRLEN(path) + BASENAMELEN + 5); if (buf == NULL) return 0; @@ -8247,6 +8260,11 @@ dos_expandpath( --s; } + /* Check for "**" between "s" and "e". */ + for (p = s; p < e; ++p) + if (p[0] == '*' && p[1] == '*') + starstar = TRUE; + starts_with_dot = (*s == '.'); pat = file_pat_to_reg_pat(s, e, NULL, FALSE); if (pat == NULL) @@ -8269,6 +8287,17 @@ dos_expandpath( /* remember the pattern or file name being looked for */ matchname = vim_strsave(s); + /* If "**" is by itself, this is the first time we encounter it and more + * is following then find matches without any directory. */ + if (!didstar && stardepth < 100 && starstar && e - s == 2 + && *path_end == '/') + { + STRCPY(s, path_end + 1); + ++stardepth; + (void)dos_expandpath(gap, buf, (int)(s - buf), flags, TRUE); + --stardepth; + } + /* Scan all files in the directory with "dir/ *.*" */ STRCPY(s, "*.*"); #ifdef WIN3264 @@ -8325,12 +8354,24 @@ dos_expandpath( namelowcpy(s, p); #endif len = (int)STRLEN(buf); + + if (starstar && stardepth < 100) + { + /* For "**" in the pattern first go deeper in the tree to + * find matches. */ + STRCPY(buf + len, "/**"); + STRCPY(buf + len + 3, path_end); + ++stardepth; + (void)dos_expandpath(gap, buf, len + 1, flags, TRUE); + --stardepth; + } + STRCPY(buf + len, path_end); if (mch_has_exp_wildcard(path_end)) { /* need to expand another component of the path */ /* remove backslashes for the remaining components only */ - (void)dos_expandpath(gap, buf, len + 1, flags); + (void)dos_expandpath(gap, buf, len + 1, flags, FALSE); } else { @@ -8408,10 +8449,232 @@ mch_expandpath( char_u *path, int flags) /* EW_* flags */ { - return dos_expandpath(gap, path, 0, flags); + return dos_expandpath(gap, path, 0, flags, FALSE); } # endif /* MSDOS || FEAT_GUI_W16 || WIN3264 */ +#if (defined(UNIX) && !defined(VMS)) || defined(USE_UNIXFILENAME) \ + || defined(PROTO) +/* + * Unix style wildcard expansion code. + * It's here because it's used both for Unix and Mac. + */ +static int pstrcmp __ARGS((const void *, const void *)); + + static int +pstrcmp(a, b) + const void *a, *b; +{ + return (pathcmp(*(char **)a, *(char **)b, -1)); +} + +/* + * Recursively expand one path component into all matching files and/or + * directories. Adds matches to "gap". Handles "*", "?", "[a-z]", "**", etc. + * "path" has backslashes before chars that are not to be expanded, starting + * at "path + wildoff". + * Return the number of matches found. + * NOTE: much of this is identical to dos_expandpath(), keep in sync! + */ + int +unix_expandpath(gap, path, wildoff, flags, didstar) + garray_T *gap; + char_u *path; + int wildoff; + int flags; /* EW_* flags */ + int didstar; /* expanded "**" once already */ +{ + char_u *buf; + char_u *path_end; + char_u *p, *s, *e; + int start_len = gap->ga_len; + char_u *pat; + regmatch_T regmatch; + int starts_with_dot; + int matches; + int len; + int starstar = FALSE; + static int stardepth = 0; /* depth for "**" expansion */ + + DIR *dirp; + struct dirent *dp; + + /* Expanding "**" may take a long time, check for CTRL-C. */ + if (stardepth > 0) + { + ui_breakcheck(); + if (got_int) + return 0; + } + + /* make room for file name */ + buf = alloc((int)STRLEN(path) + BASENAMELEN + 5); + if (buf == NULL) + return 0; + + /* + * Find the first part in the path name that contains a wildcard. + * Copy it into "buf", including the preceding characters. + */ + p = buf; + s = buf; + e = NULL; + path_end = path; + while (*path_end != NUL) + { + /* May ignore a wildcard that has a backslash before it; it will + * be removed by rem_backslash() or file_pat_to_reg_pat() below. */ + if (path_end >= path + wildoff && rem_backslash(path_end)) + *p++ = *path_end++; + else if (*path_end == '/') + { + if (e != NULL) + break; + s = p + 1; + } + else if (path_end >= path + wildoff + && vim_strchr((char_u *)"*?[{~$", *path_end) != NULL) + e = p; +#ifdef FEAT_MBYTE + if (has_mbyte) + { + len = (*mb_ptr2len_check)(path_end); + STRNCPY(p, path_end, len); + p += len; + path_end += len; + } + else +#endif + *p++ = *path_end++; + } + e = p; + *e = NUL; + + /* now we have one wildcard component between "s" and "e" */ + /* Remove backslashes between "wildoff" and the start of the wildcard + * component. */ + for (p = buf + wildoff; p < s; ++p) + if (rem_backslash(p)) + { + STRCPY(p, p + 1); + --e; + --s; + } + + /* Check for "**" between "s" and "e". */ + for (p = s; p < e; ++p) + if (p[0] == '*' && p[1] == '*') + starstar = TRUE; + + /* convert the file pattern to a regexp pattern */ + starts_with_dot = (*s == '.'); + pat = file_pat_to_reg_pat(s, e, NULL, FALSE); + if (pat == NULL) + { + vim_free(buf); + return 0; + } + + /* compile the regexp into a program */ +#ifdef MACOS_X /* Can/Should we use CASE_INSENSITIVE_FILENAME instead ?*/ + regmatch.rm_ic = TRUE; /* Behave like Terminal.app */ +#else + regmatch.rm_ic = FALSE; /* Don't ever ignore case */ +#endif + regmatch.regprog = vim_regcomp(pat, RE_MAGIC); + vim_free(pat); + + if (regmatch.regprog == NULL) + { + vim_free(buf); + return 0; + } + + /* If "**" is by itself, this is the first time we encounter it and more + * is following then find matches without any directory. */ + if (!didstar && stardepth < 100 && starstar && e - s == 2 + && *path_end == '/') + { + STRCPY(s, path_end + 1); + ++stardepth; + (void)unix_expandpath(gap, buf, (int)(s - buf), flags, TRUE); + --stardepth; + } + + /* open the directory for scanning */ + *s = NUL; + dirp = opendir(*buf == NUL ? "." : (char *)buf); + + /* Find all matching entries */ + if (dirp != NULL) + { + for (;;) + { + dp = readdir(dirp); + if (dp == NULL) + break; + if ((dp->d_name[0] != '.' || starts_with_dot) + && vim_regexec(®match, (char_u *)dp->d_name, (colnr_T)0)) + { + STRCPY(s, dp->d_name); + len = STRLEN(buf); + + if (starstar && stardepth < 100) + { + /* For "**" in the pattern first go deeper in the tree to + * find matches. */ + STRCPY(buf + len, "/**"); + STRCPY(buf + len + 3, path_end); + ++stardepth; + (void)unix_expandpath(gap, buf, len + 1, flags, TRUE); + --stardepth; + } + + STRCPY(buf + len, path_end); + if (mch_has_exp_wildcard(path_end)) /* handle more wildcards */ + { + /* need to expand another component of the path */ + /* remove backslashes for the remaining components only */ + (void)unix_expandpath(gap, buf, len + 1, flags, FALSE); + } + else + { + /* no more wildcards, check if there is a match */ + /* remove backslashes for the remaining components only */ + if (*path_end != NUL) + backslash_halve(buf + len + 1); + if (mch_getperm(buf) >= 0) /* add existing file */ + { +#if defined(MACOS_X) && defined(FEAT_MBYTE) + size_t precomp_len = STRLEN(buf)+1; + char_u *precomp_buf = + mac_precompose_path(buf, precomp_len, &precomp_len); + if (precomp_buf) + { + mch_memmove(buf, precomp_buf, precomp_len); + vim_free(precomp_buf); + } +#endif + addfile(gap, buf, flags); + } + } + } + } + + closedir(dirp); + } + + vim_free(buf); + vim_free(regmatch.regprog); + + matches = gap->ga_len - start_len; + if (matches > 0) + qsort(((char_u **)gap->ga_data) + start_len, matches, + sizeof(char_u *), pstrcmp); + return matches; +} +#endif + /* * Generic wildcard expansion code. * diff --git a/src/proto/gui_riscos.pro b/src/proto/gui_riscos.pro index ab4e8bc9b2..9bfc02b16c 100644 --- a/src/proto/gui_riscos.pro +++ b/src/proto/gui_riscos.pro @@ -15,7 +15,7 @@ void gui_mch_set_shellsize __ARGS((int width, int height, int min_width, int min void gui_mch_get_screen_dimensions __ARGS((int *screen_w, int *screen_h)); int gui_mch_init_font __ARGS((char_u *font_name, int do_fontset)); GuiFont gui_mch_get_font __ARGS((char_u *name, int giveErrorIfMissing)); -int gui_mch_adjust_charsize __ARGS((void)); +int gui_mch_adjust_charheight __ARGS((void)); void gui_mch_set_font __ARGS((GuiFont font)); void gui_mch_set_fontset __ARGS((GuiFontset fontset)); void gui_mch_free_font __ARGS((GuiFont font)); diff --git a/src/proto/gui_x11.pro b/src/proto/gui_x11.pro index f49f590f4c..3fd4673bc5 100644 --- a/src/proto/gui_x11.pro +++ b/src/proto/gui_x11.pro @@ -16,7 +16,7 @@ void gui_mch_get_screen_dimensions __ARGS((int *screen_w, int *screen_h)); int gui_mch_init_font __ARGS((char_u *font_name, int do_fontset)); GuiFont gui_mch_get_font __ARGS((char_u *name, int giveErrorIfMissing)); char_u *gui_mch_get_fontname __ARGS((GuiFont font, char_u *name)); -int gui_mch_adjust_charsize __ARGS((void)); +int gui_mch_adjust_charheight __ARGS((void)); void gui_mch_set_font __ARGS((GuiFont font)); void gui_mch_set_fontset __ARGS((GuiFontset fontset)); void gui_mch_free_font __ARGS((GuiFont font)); diff --git a/src/proto/misc1.pro b/src/proto/misc1.pro index be4c9df437..5842072897 100644 --- a/src/proto/misc1.pro +++ b/src/proto/misc1.pro @@ -84,6 +84,7 @@ void line_breakcheck __ARGS((void)); void fast_breakcheck __ARGS((void)); int expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); int match_suffix __ARGS((char_u *fname)); +int unix_expandpath __ARGS((garray_T *gap, char_u *path, int wildoff, int flags, int didstar)); int gen_expand_wildcards __ARGS((int num_pat, char_u **pat, int *num_file, char_u ***file, int flags)); void addfile __ARGS((garray_T *gap, char_u *f, int flags)); char_u *get_cmd_output __ARGS((char_u *cmd, char_u *infile, int flags)); |