updated for version 7.0049
diff --git a/src/eval.c b/src/eval.c
index 30d9b96..faea6b8 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -571,6 +571,8 @@
 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
 static ufunc_T *find_func __ARGS((char_u *name));
 static int function_exists __ARGS((char_u *name));
+static int builtin_function __ARGS((char_u *name));
+static int func_autoload __ARGS((char_u *name));
 static void func_free __ARGS((ufunc_T *fp));
 static void func_unref __ARGS((char_u *name));
 static void func_ref __ARGS((char_u *name));
@@ -2495,7 +2497,10 @@
 
     if (*startarg != '(')
     {
-	EMSG2(_("E107: Missing braces: %s"), name);
+	if (*name == K_SPECIAL)
+	    EMSG2(_("E107: Missing braces: <SNR>%s"), name + 3);
+	else
+	    EMSG2(_("E107: Missing braces: %s"), name);
 	goto end;
     }
 
@@ -2984,7 +2989,7 @@
     ht = &curwin->w_vars.dv_hashtab;
     if (wdone < ht->ht_used)
     {
-	if (bdone++ == 0)
+	if (wdone++ == 0)
 	    hi = ht->ht_array;
 	else
 	    ++hi;
@@ -6139,24 +6144,31 @@
 	rettv->v_type = VAR_NUMBER;	/* default is number rettv */
 	error = ERROR_UNKNOWN;
 
-	if (!ASCII_ISLOWER(fname[0]))
+	if (!builtin_function(fname))
 	{
 	    /*
 	     * User defined function.
 	     */
 	    fp = find_func(fname);
+
 #ifdef FEAT_AUTOCMD
-	    if (fp == NULL && apply_autocmds(EVENT_FUNCUNDEFINED,
-						    fname, fname, TRUE, NULL)
-#ifdef FEAT_EVAL
-		    && !aborting()
-#endif
-	       )
+	    /* Trigger FuncUndefined event, may load the function. */
+	    if (fp == NULL
+		    && apply_autocmds(EVENT_FUNCUNDEFINED,
+						     fname, fname, TRUE, NULL)
+		    && !aborting())
 	    {
-		/* executed an autocommand, search for function again */
+		/* executed an autocommand, search for the function again */
 		fp = find_func(fname);
 	    }
 #endif
+	    /* Try loading a package. */
+	    if (fp == NULL && func_autoload(fname) && !aborting())
+	    {
+		/* loaded a package, search for the function again */
+		fp = find_func(fname);
+	    }
+
 	    if (fp != NULL)
 	    {
 		if (fp->flags & FC_RANGE)
@@ -15375,10 +15387,9 @@
 	    lead += (int)STRLEN(sid_buf);
 	}
     }
-    else if (!(flags & TFN_INT) && !ASCII_ISUPPER(*lv.ll_name))
+    else if (!(flags & TFN_INT) && builtin_function(lv.ll_name))
     {
-	EMSG2(_("E128: Function name must start with a capital: %s"),
-								  lv.ll_name);
+	EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name);
 	goto theend;
     }
     name = alloc((unsigned)(len + lead + 1));
@@ -15496,15 +15507,62 @@
     p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL);
     if (p != NULL)
     {
-	if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL)
-	    n = (find_func(p) != NULL);
-	else if (ASCII_ISLOWER(*p))
+	if (builtin_function(p))
 	    n = (find_internal_func(p) >= 0);
+	else
+	    n = (find_func(p) != NULL);
 	vim_free(p);
     }
     return n;
 }
 
+/*
+ * Return TRUE if "name" looks like a builtin function name: starts with a
+ * lower case letter and doesn't contain a ':'.
+ */
+    static int
+builtin_function(name)
+    char_u *name;
+{
+    return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL;
+}
+
+/*
+ * If "name" has a package name try autoloading the script.
+ * Return TRUE if a package was loaded.
+ */
+    static int
+func_autoload(name)
+    char_u *name;
+{
+    char_u	*p;
+    char_u	*scriptname;
+    int		ret = FALSE;
+
+    /* If there is no colon after name[1] there is no package name. */
+    p = vim_strchr(name, ':');
+    if (p == NULL || p <= name + 2)
+	return FALSE;
+
+    /* Get the script file name: replace ':' with '/', append ".vim". */
+    scriptname = alloc((unsigned)(STRLEN(name) + 14));
+    if (scriptname == NULL)
+	return FALSE;
+    STRCPY(scriptname, "autoload/");
+    STRCAT(scriptname, name);
+    *vim_strrchr(scriptname, ':') = NUL;
+    STRCAT(scriptname, ".vim");
+    while ((p = vim_strchr(scriptname, ':')) != NULL)
+	*p = '/';
+
+    /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
+    if (cmd_runtime(scriptname, FALSE) == OK)
+	ret = TRUE;
+
+    vim_free(scriptname);
+    return ret;
+}
+
 #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
 
 /*
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index e363eb8..534bd80 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -3534,6 +3534,7 @@
     long	nmatch;		/* number of lines in match */
     linenr_T	sub_firstlnum;	/* nr of first sub line */
     char_u	*sub_firstline;	/* allocated copy of first sub line */
+    int		endcolumn;	/* put cursor in last column when done */
 
     cmd = eap->arg;
     if (!global_busy)
@@ -3623,6 +3624,10 @@
 	}
 	pat = NULL;		/* search_regcomp() will use previous pattern */
 	sub = old_sub;
+
+	/* Vi compatibility quirk: repeating with ":s" keeps the cursor in the
+	 * last column after using "$". */
+	endcolumn = (curwin->w_curswant == MAXCOL);
     }
 
     /*
@@ -4261,7 +4266,10 @@
 
 	if (!global_busy)
 	{
-	    beginline(BL_WHITE | BL_FIX);
+	    if (endcolumn)
+		coladvance((colnr_T)MAXCOL);
+	    else
+		beginline(BL_WHITE | BL_FIX);
 	    if (!do_sub_msg() && do_ask)
 		MSG("");
 	}