Commits

ZyX_I committed 76ecff4

Added [defaults] argument to :function

It serves same purpose as “emulate -L zsh” at the start of zsh functions: making
function less configuration-dependant.

  • Participants
  • Parent commits b89e2bd

Comments (0)

Files changed (5)

runtime/doc/eval.txt

 See |:verbose-cmd| for more information.
 
 							*E124* *E125* *E853*
-:fu[nction][!] {name}([arguments]) [range] [abort] [dict]
+:fu[nction][!] {name}([arguments]) [range] [abort] [dict] [defaults]
 			Define a new function by the name {name}.  The name
 			must be made of alphanumeric characters and '_', and
 			must start with a capital or "s:" (see above).
 			local variable "self" will then be set to the
 			dictionary.  See |Dictionary-function|.
 
+			When the [defaults] argument is added, some intrusive 
+			options are temporary reset to their default values in 
+			order to make scripting easier and less user 
+			configuration dependant: 'cpoptions', 'gdefault', 
+			'ignorecase', 'magic', 'remap', 'selection', 
+			'startofline', 'virtualedit', 'wrapscan'.
+
 						*function-search-undo*
 			The last used search pattern and the redo command "."
 			will not be changed by the function.  This also
 /* function flags */
 #define FC_ABORT    1		/* abort function on error */
 #define FC_RANGE    2		/* function accepts range */
-#define FC_DICT	    4		/* Dict function, uses "self" */
+#define FC_DICT     4		/* Dict function, uses "self" */
+#define FC_DEFAULTS 8		/* Should save and restore some options */
 
 /*
  * All user-defined functions are found in this hashtable.
     proftime_T	prof_child;	/* time spent in a child */
 #endif
     funccall_T	*caller;	/* calling function or NULL */
+    savopts_T	*savopts;	/* Values of saved options */
 };
 
 /*
 	    flags |= FC_ABORT;
 	    p += 5;
 	}
+	else if (STRNCMP(p, "defaults", 8) == 0)
+	{
+	    flags |= FC_DEFAULTS;
+	    p += 8;
+	}
 	else
 	    break;
     }
     /* Check if this function has a breakpoint. */
     fc->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
     fc->dbg_tick = debug_tick;
+    if (fp->uf_flags | FC_DEFAULTS)
+	save_and_set_options(&(fc->savopts));
+    else
+	fc->savopts = NULL;
 
     /*
      * Note about using fc->fixvar[]: This is an array of FIXVAR_CNT variables
     current_funccal = fc->caller;
     --depth;
 
+    if (fc->savopts != NULL)
+	restore_options(&(fc->savopts));
+
     /* If the a:000 list and the l: and a: dicts are not referenced we can
      * free the funccall_T and what's in it. */
     if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
 {
     return curbuf->b_p_sts < 0 ? get_sw_value() : curbuf->b_p_sts;
 }
+
+static struct savoptsi_S
+{
+    int		si_cpo;
+    int		si_gd;
+    int		si_ic;
+    int		si_magic;
+    int		si_remap;
+    int		si_sel;
+    int		si_sol;
+    int		si_ve;
+    int		si_ws;
+} savopts_indicies;
+
+static int created_indicies = 0;
+
+    static void
+init_savopts_indicies(void)
+{
+    savopts_indicies.si_cpo   = findoption((char_u *) "cpoptions");
+    savopts_indicies.si_gd    = findoption((char_u *) "gdefault");
+    savopts_indicies.si_ic    = findoption((char_u *) "ignorecase");
+    savopts_indicies.si_magic = findoption((char_u *) "magic");
+    savopts_indicies.si_remap = findoption((char_u *) "remap");
+    savopts_indicies.si_sel   = findoption((char_u *) "selection");
+    savopts_indicies.si_sol   = findoption((char_u *) "startofline");
+    savopts_indicies.si_ve    = findoption((char_u *) "virtualedit");
+    savopts_indicies.si_ws    = findoption((char_u *) "wrapscan");
+
+    created_indicies = 1;
+}
+
+#define OPTION_IDX(o) savopts_indicies.si_##o
+#define OPTION_STRUCT(o) options[OPTION_IDX(o)]
+
+/*
+ * Save options to given savopts and set them to defaults
+ */
+    void
+save_and_set_options(so)
+    savopts_T	**so;
+{
+    if (!created_indicies)
+	init_savopts_indicies();
+
+    *so = (savopts_T *) alloc(sizeof(savopts_T));
+
+#ifdef FEAT_EVAL
+# define SAVE_SID(o) (*so)->so_##o##_id = OPTION_STRUCT(o).scriptID;
+#else
+# define SAVE_SID(o)
+#endif
+
+#define SAVE_AND_SET_OPTION(o) \
+		(*so)->so_##o = p_##o; \
+		SAVE_SID(o) \
+		set_option_default(OPTION_IDX(o), OPT_GLOBAL, p_cp)
+
+    SAVE_AND_SET_OPTION(cpo);
+    SAVE_AND_SET_OPTION(gd);
+    SAVE_AND_SET_OPTION(ic);
+    SAVE_AND_SET_OPTION(magic);
+    SAVE_AND_SET_OPTION(remap);
+    SAVE_AND_SET_OPTION(sel);
+    SAVE_AND_SET_OPTION(sol);
+    SAVE_AND_SET_OPTION(ve);
+    SAVE_AND_SET_OPTION(ws);
+}
+
+/*
+ * Set options to ones saved in given savopts, also free it
+ */
+    void
+restore_options(so)
+    savopts_T	**so;
+{
+#ifdef FEAT_EVAL
+# define RESTORE_SID(o) OPTION_STRUCT(o).scriptID = (*so)->so_##o##_id;
+#else
+# define RESTORE_SID(o)
+#endif
+
+#define RESTORE_STRING_OPTION(o) \
+	    set_string_option(OPTION_IDX(o), (*so)->so_##o, OPT_GLOBAL); \
+	    RESTORE_SID(o)
+    RESTORE_STRING_OPTION(cpo)
+    RESTORE_STRING_OPTION(sel)
+    RESTORE_STRING_OPTION(ve)
+
+    /* All options are global thus not using get_varp_scope */
+#define RESTORE_BOOL_OPTION(o) \
+	    set_bool_option(OPTION_IDX(o), \
+			    OPTION_STRUCT(o).var, \
+			    (*so)->so_##o, \
+			    OPT_GLOBAL); \
+	    RESTORE_SID(o)
+    RESTORE_BOOL_OPTION(gd)
+    RESTORE_BOOL_OPTION(ic)
+    RESTORE_BOOL_OPTION(magic)
+    RESTORE_BOOL_OPTION(remap)
+    RESTORE_BOOL_OPTION(sol)
+    RESTORE_BOOL_OPTION(ws)
+
+    vim_free(*so);
+    *so = NULL;
+}

src/proto/option.pro

 int check_ff_value __ARGS((char_u *p));
 long get_sw_value __ARGS((void));
 long get_sts_value __ARGS((void));
+void save_and_set_options __ARGS((savopts_T **so));
+void restore_options __ARGS((savopts_T **so));
 /* vim: set ft=c : */
   UINT32_T state[8];
   char_u   buffer[64];
 } context_sha256_T;
+
+/*
+ * Structure to hold values of options to restore them after function exits
+ */
+
+typedef struct savopts_S savopts_T;
+
+struct savopts_S
+{
+    char_u	*so_cpo;	/* 'cpoptions' */
+    int		 so_gd;		/* 'gdefault */
+    int		 so_ic;		/* 'ignorecase' */
+    int		 so_magic;	/* 'magic' */
+    int		 so_remap;	/* 'remap' */
+    char_u	*so_sel;	/* 'selection' */
+    int		 so_sol;	/* 'startofline' */
+    char_u	*so_ve;		/* 'virtualedit' */
+    int		 so_ws;		/* 'wrapscan' */
+#ifdef FEAT_EVAL
+    int		so_cpo_id;
+    int		so_gd_id;
+    int		so_ic_id;
+    int		so_magic_id;
+    int		so_remap_id;
+    int		so_sel_id;
+    int		so_sol_id;
+    int		so_ve_id;
+    int		so_ws_id;
+#endif
+};