diff src/scriptfile.c @ 17922:4d63d47d87ef v8.1.1957

patch 8.1.1957: more code can be moved to evalvars.c Commit: https://github.com/vim/vim/commit/da6c03342117fb7f4a8110bd9e8627b612a05a64 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 1 16:01:30 2019 +0200 patch 8.1.1957: more code can be moved to evalvars.c Problem: More code can be moved to evalvars.c. Solution: Move code to where it fits better. (Yegappan Lakshmanan, closes #4883)
author Bram Moolenaar <Bram@vim.org>
date Sun, 01 Sep 2019 16:15:03 +0200
parents 0a5c615cd949
children 8f4cc259ed7a
line wrap: on
line diff
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -13,6 +13,11 @@
 
 #include "vim.h"
 
+#if defined(FEAT_EVAL) || defined(PROTO)
+// The names of packages that once were loaded are remembered.
+static garray_T		ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
+#endif
+
 /*
  * ":runtime [what] {name}"
  */
@@ -1334,6 +1339,12 @@ free_scriptnames(void)
 	vim_free(SCRIPT_ITEM(i).sn_name);
     ga_clear(&script_items);
 }
+
+    void
+free_autoload_scriptnames(void)
+{
+    ga_clear_strings(&ga_loaded);
+}
 # endif
 
 #endif
@@ -1690,4 +1701,76 @@ source_finished(
 	    && ((struct source_cookie *)getline_cookie(
 						fgetline, cookie))->finished);
 }
+
+/*
+ * Return the autoload script name for a function or variable name.
+ * Returns NULL when out of memory.
+ * Caller must make sure that "name" contains AUTOLOAD_CHAR.
+ */
+    char_u *
+autoload_name(char_u *name)
+{
+    char_u	*p, *q = NULL;
+    char_u	*scriptname;
+
+    // Get the script file name: replace '#' with '/', append ".vim".
+    scriptname = alloc(STRLEN(name) + 14);
+    if (scriptname == NULL)
+	return NULL;
+    STRCPY(scriptname, "autoload/");
+    STRCAT(scriptname, name);
+    for (p = scriptname + 9; (p = vim_strchr(p, AUTOLOAD_CHAR)) != NULL;
+								    q = p, ++p)
+	*p = '/';
+    STRCPY(q, ".vim");
+    return scriptname;
+}
+
+/*
+ * If "name" has a package name try autoloading the script for it.
+ * Return TRUE if a package was loaded.
+ */
+    int
+script_autoload(
+    char_u	*name,
+    int		reload)	    // load script again when already loaded
+{
+    char_u	*p;
+    char_u	*scriptname, *tofree;
+    int		ret = FALSE;
+    int		i;
+
+    // If there is no '#' after name[0] there is no package name.
+    p = vim_strchr(name, AUTOLOAD_CHAR);
+    if (p == NULL || p == name)
+	return FALSE;
+
+    tofree = scriptname = autoload_name(name);
+    if (scriptname == NULL)
+	return FALSE;
+
+    // Find the name in the list of previously loaded package names.  Skip
+    // "autoload/", it's always the same.
+    for (i = 0; i < ga_loaded.ga_len; ++i)
+	if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
+	    break;
+    if (!reload && i < ga_loaded.ga_len)
+	ret = FALSE;	    // was loaded already
+    else
+    {
+	// Remember the name if it wasn't loaded already.
+	if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
+	{
+	    ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
+	    tofree = NULL;
+	}
+
+	// Try loading the package from $VIMRUNTIME/autoload/<name>.vim
+	if (source_runtime(scriptname, 0) == OK)
+	    ret = TRUE;
+    }
+
+    vim_free(tofree);
+    return ret;
+}
 #endif