updated for version 7.0226
diff --git a/src/auto/configure b/src/auto/configure
index 13cb226..3dfa1b6 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -2838,10 +2838,6 @@
   echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6
 
-    if test x$prefix = xNONE; then
-    prefix=/Applications
-  fi
-
   echo "$as_me:$LINENO: checking --disable-darwin argument" >&5
 echo $ECHO_N "checking --disable-darwin argument... $ECHO_C" >&6
   # Check whether --enable-darwin or --disable-darwin was given.
@@ -3395,6 +3391,10 @@
     if test "x$CARBON" = "xyes"; then
       if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk -a "X$enable_gui" != Xgtk2; then
 	with_x=no
+
+		if test x$prefix = xNONE; then
+	  prefix=/Applications
+	fi
       fi
     fi
   fi
diff --git a/src/configure.in b/src/configure.in
index 1797f69..3412b95 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -85,11 +85,6 @@
 if test "`(uname) 2>/dev/null`" = Darwin; then
   AC_MSG_RESULT(yes)
 
-  dnl Default install directory is not /usr/local
-  if test x$prefix = xNONE; then
-    prefix=/Applications
-  fi
-
   AC_MSG_CHECKING(--disable-darwin argument)
   AC_ARG_ENABLE(darwin,
 	  [  --disable-darwin        Disable Darwin (Mac OS X) support.],
@@ -165,6 +160,11 @@
     if test "x$CARBON" = "xyes"; then
       if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk -a "X$enable_gui" != Xgtk2; then
 	with_x=no
+
+	dnl Default install directory is not /usr/local
+	if test x$prefix = xNONE; then
+	  prefix=/Applications
+	fi
       fi
     fi
   fi
diff --git a/src/ex_getln.c b/src/ex_getln.c
index e7fc0be..2af0e7c 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1377,7 +1377,23 @@
 		    break;
 		goto cmdline_changed;
 
-	case Ctrl_L:	    /* longest common part */
+	case Ctrl_L:
+#ifdef FEAT_SEARCH_EXTRA
+		if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
+		{
+		    /* Add a character from under the cursor for 'incsearch' */
+		    if (did_incsearch
+				   && !equalpos(curwin->w_cursor, old_cursor))
+		    {
+			c = gchar_cursor();
+			if (c != NUL)
+			    break;
+		    }
+		    goto cmdline_not_changed;
+		}
+#endif
+
+		/* completion: longest common part */
 		if (nextwild(&xpc, WILD_LONGEST, 0) == FAIL)
 		    break;
 		goto cmdline_changed;
@@ -1665,6 +1681,8 @@
 	 */
 	if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
 	{
+	    pos_T	end_pos;
+
 	    /* if there is a character waiting, search and redraw later */
 	    if (char_avail())
 	    {
@@ -1696,7 +1714,7 @@
 		    /* cancelled searching because a char was typed */
 		    incsearch_postponed = TRUE;
 	    }
-	    if (i)
+	    if (i != 0)
 		highlight_match = TRUE;		/* highlight position */
 	    else
 		highlight_match = FALSE;	/* remove highlight */
@@ -1717,7 +1735,7 @@
 		pos_T	    save_pos = curwin->w_cursor;
 
 		/*
-		 * First move cursor to end of match, then to start.  This
+		 * First move cursor to end of match, then to the start.  This
 		 * moves the whole match onto the screen when 'nowrap' is set.
 		 */
 		curwin->w_cursor.lnum += search_match_lines;
@@ -1728,14 +1746,20 @@
 		    coladvance((colnr_T)MAXCOL);
 		}
 		validate_cursor();
+		end_pos = curwin->w_cursor;
 		curwin->w_cursor = save_pos;
 	    }
+
 	    validate_cursor();
 
 	    save_cmdline(&save_ccline);
 	    update_screen(SOME_VALID);
 	    restore_cmdline(&save_ccline);
 
+	    /* Leave it at the end to make CTRL-R CTRL-W work. */
+	    if (i != 0)
+		curwin->w_cursor = end_pos;
+
 	    msg_starthere();
 	    redrawcmdline();
 	    did_incsearch = TRUE;
@@ -2813,6 +2837,7 @@
 {
     long		i;
     char_u		*arg;
+    char_u		*p;
     int			allocated;
     struct cmdline_info	save_ccline;
 
@@ -2845,7 +2870,40 @@
 	/* Got the value of a special register in "arg". */
 	if (arg == NULL)
 	    return FAIL;
-	cmdline_paste_str(arg, literally);
+
+	/* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
+	 * part of the word. */
+	p = arg;
+	if (p_is && regname == Ctrl_W)
+	{
+	    char_u  *w;
+	    int	    len;
+
+	    /* Locate start of last word in the cmd buffer. */
+	    for (w = ccline.cmdbuff + ccline.cmdlen; w > ccline.cmdbuff; )
+	    {
+#ifdef FEAT_MBYTE
+		if (has_mbyte)
+		{
+		    len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
+		    if (!vim_iswordc(mb_ptr2char(w - len)))
+			break;
+		    w -= len;
+		}
+		else
+#endif
+		{
+		    if (!vim_iswordc(w[-1]))
+			break;
+		    --w;
+		}
+	    }
+	    len = (ccline.cmdbuff + ccline.cmdlen) - w;
+	    if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
+		p += len;
+	}
+
+	cmdline_paste_str(p, literally);
 	if (allocated)
 	    vim_free(arg);
 	return OK;
diff --git a/src/misc2.c b/src/misc2.c
index dece0d9..9c84786 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -151,11 +151,15 @@
     int		head = 0;
 #endif
 
-    one_more = (State & INSERT) || restart_edit != NUL
+    one_more = (State & INSERT)
+		    || restart_edit != NUL
 #ifdef FEAT_VISUAL
-					  || (VIsual_active && *p_sel != 'o')
+		    || (VIsual_active && *p_sel != 'o')
 #endif
-					  ;
+#ifdef FEAT_VIRTUALEDIT
+		    || (ve_flags & VE_ONEMORE)
+#endif
+		    ;
     line = ml_get_curline();
 
     if (wcol >= MAXCOL)
@@ -5486,8 +5490,6 @@
 }
 #endif
 
-#if defined(FEAT_EX_EXTRA) || defined(FEAT_CMDL_COMPL) \
-    || (defined(FEAT_SYN_HL) && defined(FEAT_MBYTE)) || defined(PROTO)
 /*
  * Sort an array of strings.
  */
@@ -5515,7 +5517,6 @@
 {
     qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
 }
-#endif
 
 #if !defined(NO_EXPANDPATH) || defined(PROTO)
 /*
diff --git a/src/popupmenu.c b/src/popupmenu.c
index ca3547c..e8ff417 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -58,6 +58,7 @@
     int		row;
     int		height;
     int		col;
+    int		above_row = cmdline_row;
 
 redo:
     def_width = PUM_DEF_WIDTH;
@@ -80,6 +81,12 @@
     else
 	top_clear = 0;
 
+    /* When the preview window is at the bottom stop just above it.  Also
+     * avoid drawing over the status line so that it's clear there is a window
+     * boundary. */
+    if (lastwin->w_p_pvw)
+	above_row -= lastwin->w_height + lastwin->w_status_height + 1;
+
     /*
      * Figure out the size and position of the pum.
      */
@@ -92,8 +99,8 @@
 
     /* Put the pum below "row" if possible.  If there are few lines decide on
      * where there is more room. */
-    if (row >= cmdline_row - pum_height
-			      && row > (cmdline_row - top_clear - height) / 2)
+    if (row >= above_row - pum_height
+			      && row > (above_row - top_clear - height) / 2)
     {
 	/* pum above "row" */
 	if (row >= size)
@@ -116,8 +123,8 @@
     {
 	/* pum below "row" */
 	pum_row = row + height;
-	if (size > cmdline_row - pum_row)
-	    pum_height = cmdline_row - pum_row;
+	if (size > above_row - pum_row)
+	    pum_height = above_row - pum_row;
 	else
 	    pum_height = size;
 	if (p_ph > 0 && pum_height > p_ph)
diff --git a/src/regexp.c b/src/regexp.c
index 2ff8ea3..dd07ea7 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -6531,53 +6531,53 @@
  * This is impossible, so we declare a pointer to a function returning a
  * pointer to a function returning void. This should work for all compilers.
  */
-typedef void (*(*fptr) __ARGS((char_u *, int)))();
+typedef void (*(*fptr_T) __ARGS((int *, int)))();
 
-static fptr do_upper __ARGS((char_u *, int));
-static fptr do_Upper __ARGS((char_u *, int));
-static fptr do_lower __ARGS((char_u *, int));
-static fptr do_Lower __ARGS((char_u *, int));
+static fptr_T do_upper __ARGS((int *, int));
+static fptr_T do_Upper __ARGS((int *, int));
+static fptr_T do_lower __ARGS((int *, int));
+static fptr_T do_Lower __ARGS((int *, int));
 
 static int vim_regsub_both __ARGS((char_u *source, char_u *dest, int copy, int magic, int backslash));
 
-    static fptr
+    static fptr_T
 do_upper(d, c)
-    char_u *d;
-    int c;
-{
-    *d = TOUPPER_LOC(c);
-
-    return (fptr)NULL;
-}
-
-    static fptr
-do_Upper(d, c)
-    char_u *d;
-    int c;
-{
-    *d = TOUPPER_LOC(c);
-
-    return (fptr)do_Upper;
-}
-
-    static fptr
-do_lower(d, c)
-    char_u *d;
-    int c;
-{
-    *d = TOLOWER_LOC(c);
-
-    return (fptr)NULL;
-}
-
-    static fptr
-do_Lower(d, c)
-    char_u	*d;
+    int		*d;
     int		c;
 {
-    *d = TOLOWER_LOC(c);
+    *d = MB_TOUPPER(c);
 
-    return (fptr)do_Lower;
+    return (fptr_T)NULL;
+}
+
+    static fptr_T
+do_Upper(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOUPPER(c);
+
+    return (fptr_T)do_Upper;
+}
+
+    static fptr_T
+do_lower(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOLOWER(c);
+
+    return (fptr_T)NULL;
+}
+
+    static fptr_T
+do_Lower(d, c)
+    int		*d;
+    int		c;
+{
+    *d = MB_TOLOWER(c);
+
+    return (fptr_T)do_Lower;
 }
 
 /*
@@ -6587,7 +6587,8 @@
  * pattern.  If that previous pattern also contains a ~ we should go back a
  * step further...  But we insert the previous pattern into the current one
  * and remember that.
- * This still does not handle the case where "magic" changes. TODO?
+ * This still does not handle the case where "magic" changes.  So require the
+ * user to keep his hands off of "magic".
  *
  * The tildes are parsed once before the first call to vim_regsub().
  */
@@ -6729,17 +6730,14 @@
     char_u	*dst;
     char_u	*s;
     int		c;
+    int		cc;
     int		no = -1;
-    fptr	func = (fptr)NULL;
+    fptr_T	func = (fptr_T)NULL;
     linenr_T	clnum = 0;	/* init for GCC */
     int		len = 0;	/* init for GCC */
 #ifdef FEAT_EVAL
     static char_u *eval_result = NULL;
 #endif
-#ifdef FEAT_MBYTE
-    int		l;
-#endif
-
 
     /* Be paranoid... */
     if (source == NULL || dest == NULL)
@@ -6840,16 +6838,16 @@
 	    {
 		switch (*src++)
 		{
-		case 'u':   func = (fptr)do_upper;
+		case 'u':   func = (fptr_T)do_upper;
 			    continue;
-		case 'U':   func = (fptr)do_Upper;
+		case 'U':   func = (fptr_T)do_Upper;
 			    continue;
-		case 'l':   func = (fptr)do_lower;
+		case 'l':   func = (fptr_T)do_lower;
 			    continue;
-		case 'L':   func = (fptr)do_Lower;
+		case 'L':   func = (fptr_T)do_Lower;
 			    continue;
 		case 'e':
-		case 'E':   func = (fptr)NULL;
+		case 'E':   func = (fptr_T)NULL;
 			    continue;
 		}
 	    }
@@ -6882,28 +6880,28 @@
 
 	    /* Write to buffer, if copy is set. */
 #ifdef FEAT_MBYTE
-	    if (has_mbyte && (l = (*mb_ptr2len)(src - 1)) > 1)
+	    if (has_mbyte)
+		c = mb_ptr2char(src - 1);
+#endif
+
+	    if (func == (fptr_T)NULL)	/* just copy */
+		cc = c;
+	    else
+		/* Turbo C complains without the typecast */
+		func = (fptr_T)(func(&cc, c));
+
+#ifdef FEAT_MBYTE
+	    if (has_mbyte)
 	    {
-		/* TODO: should use "func" here. */
+		src += mb_ptr2len(src - 1) - 1;
 		if (copy)
-		    mch_memmove(dst, src - 1, l);
-		dst += l - 1;
-		src += l - 1;
+		    mb_char2bytes(cc, dst);
+		dst += mb_char2len(cc) - 1;
 	    }
 	    else
-	    {
 #endif
 		if (copy)
-		{
-		    if (func == (fptr)NULL)	/* just copy */
-			*dst = c;
-		    else			/* change case */
-			func = (fptr)(func(dst, c));
-		    /* Turbo C complains without the typecast */
-		}
-#ifdef FEAT_MBYTE
-	    }
-#endif
+		    *dst = cc;
 	    dst++;
 	}
 	else
@@ -6976,29 +6974,39 @@
 			    }
 			    dst += 2;
 			}
-#ifdef FEAT_MBYTE
-			else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
-			{
-			    /* TODO: should use "func" here. */
-			    if (copy)
-				mch_memmove(dst, s, l);
-			    dst	+= l;
-			    s += l - 1;
-			    len	-= l - 1;
-			}
-#endif
 			else
 			{
-			    if (copy)
-			    {
-				if (func == (fptr)NULL)	    /* just copy */
-				    *dst = *s;
-				else			    /* change case */
-				    func = (fptr)(func(dst, *s));
+#ifdef FEAT_MBYTE
+			    if (has_mbyte)
+				c = mb_ptr2char(s);
+			    else
+#endif
+				c = *s;
+
+			    if (func == (fptr_T)NULL)	/* just copy */
+				cc = c;
+			    else
 				/* Turbo C complains without the typecast */
+				func = (fptr_T)(func(&cc, c));
+
+#ifdef FEAT_MBYTE
+			    if (has_mbyte)
+			    {
+				int l = mb_ptr2len(s) - 1;
+
+				s += l;
+				len -= l;
+				if (copy)
+				    mb_char2bytes(cc, dst);
+				dst += mb_char2len(cc) - 1;
 			    }
-			    ++dst;
+			    else
+#endif
+				if (copy)
+				    *dst = cc;
+			    dst++;
 			}
+
 			++s;
 			--len;
 		    }
diff --git a/src/undo.c b/src/undo.c
index 27f04b9..330915d 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -89,6 +89,7 @@
 static void u_doit __ARGS((int count));
 static void u_undoredo __ARGS((void));
 static void u_undo_end __ARGS((void));
+static void u_add_time __ARGS((char_u *buf, size_t buflen, time_t tt));
 static void u_freeheader __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
 static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
 static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
@@ -637,11 +638,14 @@
  * When "step" is negative go back in time, otherwise goes forward in time.
  * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
  * seconds.
+ * When "absolute" is TRUE use "step" as the sequence number to jump to.
+ * "sec" must be FALSE then.
  */
     void
-undo_time(step, sec)
+undo_time(step, sec, absolute)
     long	step;
     int		sec;
+    int		absolute;
 {
     long	    target;
     long	    closest;
@@ -668,7 +672,12 @@
 
     /* "target" is the node below which we want to be.  When going forward
      * the current one also counts, thus do one less. */
-    if (step < 0)
+    if (absolute)
+    {
+	target = step;
+	closest = -2;
+    }
+    else if (step < 0)
     {
 	if (sec)
 	    target = (long)curbuf->b_u_seq_time + step;
@@ -787,6 +796,13 @@
 
 	if (uhp != NULL)    /* found it */
 	    break;
+
+	if (absolute)
+	{
+	    EMSGN(_("Undo number %ld not found"), step);
+	    return;
+	}
+
 	if (closest == closest_start)
 	{
 	    if (step < 0)
@@ -1152,8 +1168,9 @@
     static void
 u_undo_end()
 {
-    long	sec;
     char	*msg;
+    u_header_T	*uhp;
+    char_u	msgbuf[80];
 
 #ifdef FEAT_FOLDING
     if ((fdo_flags & FDO_UNDO) && KeyTyped)
@@ -1185,12 +1202,18 @@
 	    msg = N_("changes");
     }
 
-    if (curbuf->b_u_curhead == 0)
-	sec = 0;
+    if (curbuf->b_u_curhead != NULL)
+	uhp = curbuf->b_u_curhead;
     else
-	sec = time(NULL) - curbuf->b_u_curhead->uh_time;
+	uhp = curbuf->b_u_newhead;
 
-    smsg((char_u *)_("%ld %s; %ld seconds ago"), u_oldcount, _(msg), sec);
+    if (uhp == NULL)
+	*msgbuf = NUL;
+    else
+	u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
+
+    smsg((char_u *)_("%ld %s; #%ld  %s"), u_oldcount, _(msg),
+				      uhp == NULL ? 0L : uhp->uh_seq, msgbuf);
 }
 
 /*
@@ -1215,6 +1238,128 @@
 }
 
 /*
+ * ":undolist": List the leafs of the undo tree
+ */
+/*ARGSUSED*/
+    void
+ex_undolist(eap)
+    exarg_T *eap;
+{
+    garray_T	ga;
+    u_header_T	*uhp;
+    int		mark;
+    int		nomark;
+    int		changes = 1;
+    int		i;
+
+    /*
+     * 1: walk the tree to find all leafs, put the info in "ga".
+     * 2: sort the lines
+     * 3: display the list
+     */
+    mark = ++lastmark;
+    nomark = ++lastmark;
+    ga_init2(&ga, (int)sizeof(char *), 20);
+
+    uhp = curbuf->b_u_oldhead;
+    while (uhp != NULL)
+    {
+	if (uhp->uh_prev == NULL)
+	{
+	    if (ga_grow(&ga, 1) == FAIL)
+		break;
+	    vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld  ",
+							uhp->uh_seq, changes);
+	    u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
+								uhp->uh_time);
+	    ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
+	}
+
+	uhp->uh_walk = mark;
+
+	/* go down in the tree if we haven't been there */
+	if (uhp->uh_prev != NULL && uhp->uh_prev->uh_walk != nomark
+					 && uhp->uh_prev->uh_walk != mark)
+	{
+	    uhp = uhp->uh_prev;
+	    ++changes;
+	}
+
+	/* go to alternate branch if we haven't been there */
+	else if (uhp->uh_alt_next != NULL
+		&& uhp->uh_alt_next->uh_walk != nomark
+		&& uhp->uh_alt_next->uh_walk != mark)
+	    uhp = uhp->uh_alt_next;
+
+	/* go up in the tree if we haven't been there and we are at the
+	 * start of alternate branches */
+	else if (uhp->uh_next != NULL && uhp->uh_alt_prev == NULL
+		&& uhp->uh_next->uh_walk != nomark
+		&& uhp->uh_next->uh_walk != mark)
+	{
+	    uhp = uhp->uh_next;
+	    --changes;
+	}
+
+	else
+	{
+	    /* need to backtrack; mark this node as done */
+	    uhp->uh_walk = nomark;
+	    if (uhp->uh_alt_prev != NULL)
+		uhp = uhp->uh_alt_prev;
+	    else
+	    {
+		uhp = uhp->uh_next;
+		--changes;
+	    }
+	}
+    }
+
+    if (ga.ga_len == 0)
+	MSG(_("Nothing to undo"));
+    else
+    {
+	sort_strings((char_u **)ga.ga_data, ga.ga_len);
+
+	msg_start();
+	msg_puts_attr((char_u *)_("number changes  time"), hl_attr(HLF_T));
+	for (i = 0; i < ga.ga_len && !got_int; ++i)
+	{
+	    msg_putchar('\n');
+	    if (got_int)
+		break;
+	    msg_puts(((char_u **)ga.ga_data)[i]);
+	}
+	msg_end();
+
+	ga_clear_strings(&ga);
+    }
+}
+
+/*
+ * Put the timestamp of an undo header in "buf[buflen]" in a nice format.
+ */
+    static void
+u_add_time(buf, buflen, tt)
+    char_u	*buf;
+    size_t	buflen;
+    time_t	tt;
+{
+#ifdef HAVE_STRFTIME
+    struct tm	*curtime;
+
+    if (time(NULL) - tt >= 100)
+    {
+	curtime = localtime(&tt);
+	(void)strftime((char *)buf, buflen, "%T", curtime);
+    }
+    else
+#endif
+	vim_snprintf((char *)buf, buflen, "%ld seconds ago",
+						     (long)(time(NULL) - tt));
+}
+
+/*
  * ":undojoin": continue adding to the last entry list
  */
 /*ARGSUSED*/
diff --git a/src/version.h b/src/version.h
index 774222d..19333f2 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 15)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 15, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 16)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 16, compiled "