updated for version 7.0077
diff --git a/src/eval.c b/src/eval.c
index d45a34e..108d93d 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -10071,7 +10071,7 @@
     }
     else if (p_verbose > 1)
     {
-	msg((char_u *)_("called inputrestore() more often than inputsave()"));
+	verb_msg((char_u *)_("called inputrestore() more often than inputsave()"));
 	rettv->vval.v_number = 1; /* Failed */
     }
 }
@@ -12786,7 +12786,8 @@
 		end = regmatch.startp[0];
 	    else
 		end = str + STRLEN(str);
-	    if (keepempty || end > str || (l->lv_len > 0 && *str != NUL))
+	    if (keepempty || end > str || (l->lv_len > 0 && *str != NUL
+					  && match && end < regmatch.endp[0]))
 	    {
 		ni = listitem_alloc();
 		if (ni == NULL)
@@ -16930,7 +16931,8 @@
 	if (p_verbose >= 12)
 	{
 	    ++no_wait_return;
-	    msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
+	    verbose_enter_scroll();
+
 	    smsg((char_u *)_("calling %s"), sourcing_name);
 	    if (p_verbose >= 14)
 	    {
@@ -16956,7 +16958,8 @@
 		msg_puts((char_u *)")");
 	    }
 	    msg_puts((char_u *)"\n");   /* don't overwrite this either */
-	    cmdline_row = msg_row;
+
+	    verbose_leave_scroll();
 	    --no_wait_return;
 	}
     }
@@ -17015,7 +17018,7 @@
     if (p_verbose >= 12)
     {
 	++no_wait_return;
-	msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
+	verbose_enter_scroll();
 
 	if (aborting())
 	    smsg((char_u *)_("%s aborted"), sourcing_name);
@@ -17037,7 +17040,8 @@
 	    vim_free(tofree);
 	}
 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
-	cmdline_row = msg_row;
+
+	verbose_leave_scroll();
 	--no_wait_return;
     }
 
@@ -17053,10 +17057,12 @@
     if (p_verbose >= 12 && sourcing_name != NULL)
     {
 	++no_wait_return;
-	msg_scroll = TRUE;	    /* always scroll up, don't overwrite */
+	verbose_enter_scroll();
+
 	smsg((char_u *)_("continuing in %s"), sourcing_name);
 	msg_puts((char_u *)"\n");   /* don't overwrite this either */
-	cmdline_row = msg_row;
+
+	verbose_leave_scroll();
 	--no_wait_return;
     }
 
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index a8083b3..2262794 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -266,6 +266,14 @@
 static char_u	*sortbuf;
 
 static int	sort_ic;		/* ignore case */
+static int	sort_nr;		/* sort on number */
+
+/* Struct to store info to be sorted. */
+typedef struct
+{
+    linenr_T	lnum;			/* line number */
+    long	col_nr;			/* column number or number */
+} sorti_T;
 
 static int
 #ifdef __BORLANDC__
@@ -281,14 +289,19 @@
     const void	*s1;
     const void	*s2;
 {
-    lpos_T	l1 = *(lpos_T *)s1;
-    lpos_T	l2 = *(lpos_T *)s2;
+    sorti_T	l1 = *(sorti_T *)s1;
+    sorti_T	l2 = *(sorti_T *)s2;
     char_u	*s;
 
+    /* When sorting numbers "col_nr" is the number, not the column number. */
+    if (sort_nr)
+	return l1.col_nr - l2.col_nr;
+
     /* We need to copy one line into "sortbuf", because there is no guarantee
      * that the first pointer becomes invalid when obtaining the second one. */
-    STRCPY(sortbuf, ml_get(l1.lnum) + l1.col);
-    s = ml_get(l2.lnum) + l2.col;
+    STRCPY(sortbuf, ml_get(l1.lnum) + l1.col_nr);
+    s = ml_get(l2.lnum) + l2.col_nr;
+
     return sort_ic ? STRICMP(sortbuf, s) : STRCMP(sortbuf, s);
 }
 
@@ -303,28 +316,39 @@
     int		len;
     linenr_T	lnum;
     long	maxlen = 0;
-    lpos_T	*nrs;
+    sorti_T	*nrs;
     size_t	count = eap->line2 - eap->line1 + 1;
-    int		i;
+    size_t	i;
     char_u	*p;
     char_u	*s;
     int		unique = FALSE;
     long	deleted;
+    colnr_T	col;
+    int		sort_oct;		/* sort on octal number */
+    int		sort_hex;		/* sort on hex number */
 
     if (u_save((linenr_T)(eap->line1 - 1), (linenr_T)(eap->line2 + 1)) == FAIL)
 	return;
     sortbuf = NULL;
     regmatch.regprog = NULL;
-    nrs = (lpos_T *)lalloc((long_u)(count * sizeof(lpos_T)), TRUE);
+    nrs = (sorti_T *)lalloc((long_u)(count * sizeof(sorti_T)), TRUE);
     if (nrs == NULL)
 	goto theend;
 
+    sort_ic = sort_nr = sort_oct = sort_hex = 0;
+
     for (p = eap->arg; *p != NUL; ++p)
     {
 	if (vim_iswhite(*p))
 	    ;
 	else if (*p == 'i')
 	    sort_ic = TRUE;
+	else if (*p == 'n')
+	    sort_nr = 2;
+	else if (*p == 'o')
+	    sort_oct = 2;
+	else if (*p == 'x')
+	    sort_hex = 2;
 	else if (*p == 'u')
 	    unique = TRUE;
 	else if (*p == '"')	/* comment start */
@@ -356,31 +380,60 @@
 	}
     }
 
+    /* Can only have one of 'n', 'o' and 'x'. */
+    if (sort_nr + sort_oct + sort_hex > 2)
+    {
+	EMSG(_(e_invarg));
+	goto theend;
+    }
+
+    /* From here on "sort_nr" is used as a flag for any number sorting. */
+    sort_nr += sort_oct + sort_hex;
+
     /*
-     * Make an array with all line numbers, so that we don't have to copy all
+     * Make an array with all line numbers.  This avoids having to copy all
      * the lines into allocated memory.
-     * Also get the longest line length.
+     * When sorting on strings "col_nr" is de offset in the line, for numbers
+     * sorting it's the number to sort on.  This means the pattern matching
+     * and number conversion only has to be done once per line.
+     * Also get the longest line length for allocating "sortbuf".
      */
     for (lnum = eap->line1; lnum <= eap->line2; ++lnum)
     {
-	nrs[lnum - eap->line1].lnum = lnum;
-	nrs[lnum - eap->line1].col = 0;
-
 	s = ml_get(lnum);
-	if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0))
-	    nrs[lnum - eap->line1].col = regmatch.endp[0] - s;
-
 	len = STRLEN(s);
 	if (maxlen < len)
 	    maxlen = len;
+
+	if (regmatch.regprog != NULL && vim_regexec(&regmatch, s, 0))
+	    col = regmatch.endp[0] - s;
+	else
+	    col = 0;
+
+	if (sort_nr)
+	{
+	    /* Sorting on number: Store the number itself. */
+	    if (sort_hex)
+		s = skiptohex(s + col);
+	    else
+		s = skiptodigit(s + col);
+	    vim_str2nr(s, NULL, NULL, sort_oct, sort_hex,
+					&nrs[lnum - eap->line1].col_nr, NULL);
+	}
+	else
+	    /* Store the column to sort at. */
+	    nrs[lnum - eap->line1].col_nr = col;
+
+	nrs[lnum - eap->line1].lnum = lnum;
     }
 
+    /* Allocate a buffer that can hold the longest line. */
     sortbuf = alloc((unsigned)maxlen + 1);
     if (sortbuf == NULL)
 	goto theend;
 
     /* sort the array of line numbers */
-    qsort((void *)nrs, count, sizeof(lpos_T), sort_compare);
+    qsort((void *)nrs, count, sizeof(sorti_T), sort_compare);
 
     /* Insert the lines in the sorted order below the last one. */
     lnum = eap->line2;
@@ -392,7 +445,8 @@
 	{
 	    if (ml_append(lnum++, s, (colnr_T)0, FALSE) == FAIL)
 		break;
-	    STRCPY(sortbuf, s);
+	    if (unique)
+		STRCPY(sortbuf, s);
 	}
     }
 
@@ -403,12 +457,14 @@
     else
 	count = 0;
 
+    /* Adjust marks for deleted (or added) lines and prepare for displaying. */
     deleted = count - (lnum - eap->line2);
     if (deleted > 0)
 	mark_adjust(eap->line2 - deleted, eap->line2, (long)MAXLNUM, -deleted);
     else if (deleted < 0)
 	mark_adjust(eap->line2, MAXLNUM, -deleted, 0L);
     changed_lines(eap->line1, 0, eap->line2 + 1, -deleted);
+
     curwin->w_cursor.lnum = eap->line1;
     beginline(BL_WHITE | BL_FIX);
 
@@ -1532,11 +1588,15 @@
     fp = mch_fopen((char *)fname, READBIN);
 
     if (p_verbose > 0)
+    {
+	verbose_enter();
 	smsg((char_u *)_("Reading viminfo file \"%s\"%s%s%s"),
 		fname,
 		want_info ? _(" info") : "",
 		want_marks ? _(" marks") : "",
 		fp == NULL ? _(" FAILED") : "");
+	verbose_leave();
+    }
 
     vim_free(fname);
     if (fp == NULL)
@@ -1760,7 +1820,11 @@
     }
 
     if (p_verbose > 0)
+    {
+	verbose_enter();
 	smsg((char_u *)_("Writing viminfo file \"%s\""), fname);
+	verbose_leave();
+    }
 
     viminfo_errcnt = 0;
     do_viminfo(fp_in, fp_out, !forceit, !forceit, FALSE);
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index c22414e..5ff0d40 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -2467,8 +2467,12 @@
     if (buf != NULL && rtp_copy != NULL)
     {
 	if (p_verbose > 1)
+	{
+	    verbose_enter();
 	    smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
 						 (char *)name, (char *)p_rtp);
+	    verbose_leave();
+	}
 
 	/* Loop over all entries in 'runtimepath'. */
 	rtp = rtp_copy;
@@ -2490,7 +2494,11 @@
 								       "\t ");
 
 		    if (p_verbose > 2)
+		    {
+			verbose_enter();
 			smsg((char_u *)_("Searching for \"%s\""), buf);
+			verbose_leave();
+		    }
 
 		    /* Expand wildcards, invoke the callback for each match. */
 		    if (gen_expand_wildcards(1, &buf, &num_files, &files,
@@ -2512,7 +2520,11 @@
     vim_free(buf);
     vim_free(rtp_copy);
     if (p_verbose > 0 && !did_one)
+    {
+	verbose_enter();
 	smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
+	verbose_leave();
+    }
 
 #ifdef AMIGA
     proc->pr_WindowPtr = save_winptr;
@@ -2759,11 +2771,13 @@
     {
 	if (p_verbose > 0)
 	{
+	    verbose_enter();
 	    if (sourcing_name == NULL)
 		smsg((char_u *)_("could not source \"%s\""), fname);
 	    else
 		smsg((char_u *)_("line %ld: could not source \"%s\""),
 							sourcing_lnum, fname);
+	    verbose_leave();
 	}
 	goto theend;
     }
@@ -2775,11 +2789,13 @@
      */
     if (p_verbose > 1)
     {
+	verbose_enter();
 	if (sourcing_name == NULL)
 	    smsg((char_u *)_("sourcing \"%s\""), fname);
 	else
 	    smsg((char_u *)_("line %ld: sourcing \"%s\""),
 							sourcing_lnum, fname);
+	verbose_leave();
     }
     if (is_vimrc)
 	vimrc_found();
@@ -2961,9 +2977,11 @@
     sourcing_lnum = save_sourcing_lnum;
     if (p_verbose > 1)
     {
+	verbose_enter();
 	smsg((char_u *)_("finished sourcing %s"), fname);
 	if (sourcing_name != NULL)
 	    smsg((char_u *)_("continuing in %s"), sourcing_name);
+	verbose_leave();
     }
 #ifdef STARTUPTIME
     vim_snprintf(IObuff, IOSIZE, "sourcing %s", fname);
diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c
index 819e3b4..37858dc 100644
--- a/src/gui_gtk_x11.c
+++ b/src/gui_gtk_x11.c
@@ -6132,7 +6132,11 @@
 	/* Got something */
 	clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd);
 	if (p_verbose > 0)
+	{
+	    verbose_enter();
 	    smsg((char_u *)_("Used CUT_BUFFER0 instead of empty selection"));
+	    verbose_leave();
+	}
     }
     if (buffer != NULL)
 	XFree(buffer);
diff --git a/src/main.c b/src/main.c
index eb9aa28..2bed192 100644
--- a/src/main.c
+++ b/src/main.c
@@ -813,6 +813,12 @@
 	    case 'V':		/* "-V{N}"	Verbose level */
 		/* default is 10: a little bit verbose */
 		p_verbose = get_number_arg((char_u *)argv[0], &argv_idx, 10);
+		if (argv[0][argv_idx] != NUL)
+		{
+		    set_option_value((char_u *)"verbosefile", 0L,
+					     (char_u *)argv[0] + argv_idx, 0);
+		    argv_idx = STRLEN(argv[0]);
+		}
 		break;
 
 	    case 'v':		/* "-v"  Vi-mode (as if called "vi") */
diff --git a/src/option.c b/src/option.c
index 1f4ce74..24b709e 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2259,6 +2259,9 @@
     {"verbose",	    "vbs",  P_NUM|P_VI_DEF,
 			    (char_u *)&p_verbose, PV_NONE,
 			    {(char_u *)0L, (char_u *)0L}},
+    {"verbosefile", "vfile", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
+			    (char_u *)&p_vfile, PV_NONE,
+			    {(char_u *)"", (char_u *)0L}},
     {"viewdir",     "vdir", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
 #ifdef FEAT_SESSION
 			    (char_u *)&p_vdir, PV_NONE,
@@ -3731,8 +3734,10 @@
 		    {
 			if (options[opt_idx].scriptID != 0)
 			{
+			    verbose_enter();
 			    MSG_PUTS(_("\n\tLast set from "));
 			    MSG_PUTS(get_scriptname(options[opt_idx].scriptID));
+			    verbose_leave();
 			}
 		    }
 #endif
@@ -5316,6 +5321,14 @@
     }
 #endif
 
+    /* 'verbosefile' */
+    else if (varp == &p_vfile)
+    {
+	verbose_stop();
+	if (*p_vfile != NUL && verbose_open() == FAIL)
+	    errmsg = e_invarg;
+    }
+
 #ifdef FEAT_VIMINFO
     /* 'viminfo' */
     else if (varp == &p_viminfo)
diff --git a/src/option.h b/src/option.h
index daeb366..d52f3c6 100644
--- a/src/option.h
+++ b/src/option.h
@@ -804,6 +804,7 @@
 # define VE_ALL		4
 #endif
 EXTERN long	p_verbose;	/* 'verbose' */
+EXTERN char_u	*p_vfile;	/* 'verbosefile' */
 EXTERN int	p_warn;		/* 'warn' */
 #ifdef FEAT_CMDL_COMPL
 EXTERN char_u	*p_wop;		/* 'wildoptions' */
diff --git a/src/proto/ex_cmds2.pro b/src/proto/ex_cmds2.pro
index 332229f..4914a44 100644
--- a/src/proto/ex_cmds2.pro
+++ b/src/proto/ex_cmds2.pro
@@ -54,7 +54,7 @@
 void ex_compiler __ARGS((exarg_T *eap));
 void ex_runtime __ARGS((exarg_T *eap));
 int cmd_runtime __ARGS((char_u *name, int all));
-int do_in_runtimepath __ARGS((char_u *name, int all, void (*callback)(char_u *fname, void *cookie), void *cookie));
+int do_in_runtimepath __ARGS((char_u *name, int all, void (*callback)(char_u *fname, void *ck), void *cookie));
 void ex_options __ARGS((exarg_T *eap));
 void ex_source __ARGS((exarg_T *eap));
 linenr_T *source_breakpoint __ARGS((void *cookie));
diff --git a/src/proto/hashtable.pro b/src/proto/hashtable.pro
index cacd7a3..e82f175 100644
--- a/src/proto/hashtable.pro
+++ b/src/proto/hashtable.pro
@@ -1,5 +1,4 @@
 /* hashtable.c */
-hashtab_T *hash_create __ARGS((void));
 void hash_init __ARGS((hashtab_T *ht));
 void hash_clear __ARGS((hashtab_T *ht));
 hashitem_T *hash_find __ARGS((hashtab_T *ht, char_u *key));
diff --git a/src/syntax.c b/src/syntax.c
index 3ac43d7..595befc 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -3127,8 +3127,8 @@
 {
     int i;
 
-    curbuf->b_syn_ic = FALSE;	    /* Use case, by default */
-    curbuf->b_syn_containedin = FALSE;
+    buf->b_syn_ic = FALSE;	    /* Use case, by default */
+    buf->b_syn_containedin = FALSE;
 
     /* free the keywords */
     clear_keywtab(&buf->b_keywtab);
diff --git a/src/testdir/Makefile b/src/testdir/Makefile
index fb35dcd..9901642 100644
--- a/src/testdir/Makefile
+++ b/src/testdir/Makefile
@@ -14,7 +14,7 @@
 		test38.out test39.out test40.out test41.out test42.out \
 		test43.out test44.out test45.out test46.out test47.out \
 		test48.out test49.out test51.out test52.out test53.out \
-		test54.out test55.out test56.out
+		test54.out test55.out test56.out test57.out
 
 SCRIPTS_GUI = test16.out
 
diff --git a/src/testdir/test55.in b/src/testdir/test55.in
index e25d6ca..5570c59 100644
--- a/src/testdir/test55.in
+++ b/src/testdir/test55.in
@@ -274,6 +274,8 @@
 :$put =string(split(':aa::bb:', ':', 0))
 :$put =string(split(':aa::bb:', ':', 1))
 :$put =string(split('aa,,bb, cc,', ',\s*', 1))
+:$put =string(split('abc', '\zs'))
+:$put =string(split('abc', '\zs', 1))
 :"
 :endfun
 :call Test(1, 2, [3, 4], {5: 6})  " This may take a while
diff --git a/src/ui.c b/src/ui.c
index 3506c48..89b5cd6 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -1696,7 +1696,13 @@
 #endif
 
 #ifdef FEAT_GUI
-    if (gui.in_use)
+    if (gui.in_use
+# ifdef NO_CONSOLE_INPUT
+    /* Don't use the GUI input when the window hasn't been opened yet.
+     * We get here from ui_inchar() when we should try reading from stdin. */
+	    && !no_console_input()
+# endif
+       )
     {
 	gui_mch_update();
 	return;
@@ -2140,7 +2146,7 @@
 	clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd);
 	XFree((void *)buffer);
 	if (p_verbose > 0)
-	    MSG(_("Used CUT_BUFFER0 instead of empty selection"));
+	    verb_msg((char_u *)_("Used CUT_BUFFER0 instead of empty selection"));
     }
 }