changeset 445:c773cb978acf v7.0116

updated for version 7.0116
author vimboss
date Mon, 25 Jul 2005 20:46:57 +0000
parents d0d15b184c56
children 7472c565592a
files runtime/doc/quickfix.txt runtime/doc/todo.txt runtime/doc/version7.txt src/eval.c src/ex_cmds.c src/gui_gtk_x11.c src/gui_x11.c src/main.c src/misc1.c src/proto/gui_riscos.pro src/proto/gui_x11.pro src/proto/misc1.pro
diffstat 12 files changed, 381 insertions(+), 90 deletions(-) [+]
line wrap: on
line diff
--- 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 @@ 5.1 using Vim's internal grep
 			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
--- 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 @@ 8   Add ":fungroup" command, to group fu
     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 @@ 8   Add command like ":normal" that acce
 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).
--- 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 c
 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 na
 ":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 wil
 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*
 
--- 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, ski
 		++retval;
 	    else
 		retval = pos.lnum;
+	    if (flags & SP_SETPCMARK)
+		setpcmark();
 	    curwin->w_cursor = pos;
 	    if (!(flags & SP_REPEAT))
 		break;
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -5369,13 +5369,15 @@ find_help_tags(arg, num_matches, matches
     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]",
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -4066,8 +4066,11 @@ is_cjk_font(PangoFontDescription *font_d
 }
 #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
     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);
--- 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
 }
 
 /*
- * 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.
  */
--- 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 */
--- 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 */
-{
-    char_u		*buf;
-    char_u		*path_end;
-    char_u		*p, *s, *e;
-    int			start_len = gap->ga_len;
-    int			ok;
+    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;
+    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(&regmatch, (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.
  *
--- a/src/proto/gui_riscos.pro
+++ b/src/proto/gui_riscos.pro
@@ -15,7 +15,7 @@ void gui_mch_set_shellsize __ARGS((int w
 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));
--- a/src/proto/gui_x11.pro
+++ b/src/proto/gui_x11.pro
@@ -16,7 +16,7 @@ void gui_mch_get_screen_dimensions __ARG
 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));
--- 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));