changeset 5446:d0595545e98a v7.4.073

updated for version 7.4.073 Problem: Setting undolevels for one buffer changes undo in another. Solution: Make 'undolevels' a global-local option. (Christian Brabandt)
author Bram Moolenaar <bram@vim.org>
date Wed, 06 Nov 2013 05:26:15 +0100
parents 75c7eef1de70
children e3d25cf437c4
files runtime/doc/options.txt src/buffer.c src/option.c src/option.h src/structs.h src/undo.c src/version.c
diffstat 7 files changed, 59 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -7594,7 +7594,7 @@ A jump table for the options with a shor
 						*'undolevels'* *'ul'*
 'undolevels' 'ul'	number	(default 100, 1000 for Unix, VMS,
 						Win32 and OS/2)
-			global
+			global or local to buffer |global-local|
 			{not in Vi}
 	Maximum number of changes that can be undone.  Since undo information
 	is kept in memory, higher numbers will cause more memory to be used
@@ -7605,8 +7605,9 @@ A jump table for the options with a shor
 <	But you can also get Vi compatibility by including the 'u' flag in
 	'cpoptions', and still be able to use CTRL-R to repeat undo.
 	Also see |undo-two-ways|.
-	Set to a negative number for no undo at all: >
-		set ul=-1
+	Set to -1 for no undo at all.  You might want to do this only for the
+	current buffer: >
+		setlocal ul=-1
 <	This helps when you run out of memory for a single change.
 	Also see |clear-undo|.
 
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1949,6 +1949,7 @@ free_buf_options(buf, free_p_ff)
     clear_string_option(&buf->b_p_qe);
 #endif
     buf->b_p_ar = -1;
+    buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
 }
 
 /*
--- a/src/option.c
+++ b/src/option.c
@@ -234,6 +234,7 @@
 #ifdef FEAT_STL_OPT
 # define PV_STL		OPT_BOTH(OPT_WIN(WV_STL))
 #endif
+#define PV_UL		OPT_BOTH(OPT_BUF(BV_UL))
 #ifdef FEAT_WINDOWS
 # define PV_WFH		OPT_WIN(WV_WFH)
 #endif
@@ -2683,7 +2684,7 @@ static struct vimoption
 #endif
 			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
     {"undolevels",  "ul",   P_NUM|P_VI_DEF,
-			    (char_u *)&p_ul, PV_NONE,
+			    (char_u *)&p_ul, PV_UL,
 			    {
 #if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS)
 			    (char_u *)1000L,
@@ -3313,6 +3314,7 @@ set_init_1()
 
     curbuf->b_p_initialized = TRUE;
     curbuf->b_p_ar = -1;	/* no local 'autoread' value */
+    curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
     check_buf_options(curbuf);
     check_win_options(curwin);
     check_options();
@@ -4512,8 +4514,16 @@ do_set(arg, opt_flags)
 						((flags & P_VI_DEF) || cp_val)
 						 ?  VI_DEFAULT : VIM_DEFAULT];
 			else if (nextchar == '<')
-			    value = *(long *)get_varp_scope(&(options[opt_idx]),
-								  OPT_GLOBAL);
+			{
+			    /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to
+			     * use the global value. */
+			    if ((long *)varp == &curbuf->b_p_ul
+						    && opt_flags == OPT_LOCAL)
+				value = NO_LOCAL_UNDOLEVEL;
+			    else
+				value = *(long *)get_varp_scope(
+					     &(options[opt_idx]), OPT_GLOBAL);
+			}
 			else if (((long *)varp == &p_wc
 				    || (long *)varp == &p_wcm)
 				&& (*arg == '<'
@@ -8487,6 +8497,13 @@ set_num_option(opt_idx, varp, value, err
 	u_sync(TRUE);
 	p_ul = value;
     }
+    else if (pp == &curbuf->b_p_ul)
+    {
+	/* use the old value, otherwise u_sync() may not work properly */
+	curbuf->b_p_ul = old_value;
+	u_sync(TRUE);
+	curbuf->b_p_ul = value;
+    }
 
 #ifdef FEAT_LINEBREAK
     /* 'numberwidth' must be positive */
@@ -9720,7 +9737,6 @@ comp_col()
 /*
  * Unset local option value, similar to ":set opt<".
  */
-
     void
 unset_global_local_option(name, from)
     char_u	*name;
@@ -9793,6 +9809,9 @@ unset_global_local_option(name, from)
 	    clear_string_option(&((win_T *)from)->w_p_stl);
 	    break;
 #endif
+	case PV_UL:
+	    buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+	    break;
     }
 }
 
@@ -9841,6 +9860,7 @@ get_varp_scope(p, opt_flags)
 #ifdef FEAT_STL_OPT
 	    case PV_STL:  return (char_u *)&(curwin->w_p_stl);
 #endif
+	    case PV_UL:   return (char_u *)&(curbuf->b_p_ul);
 	}
 	return NULL; /* "cannot happen" */
     }
@@ -9905,6 +9925,8 @@ get_varp(p)
 	case PV_STL:	return *curwin->w_p_stl != NUL
 				    ? (char_u *)&(curwin->w_p_stl) : p->var;
 #endif
+	case PV_UL:	return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
+				    ? (char_u *)&(curbuf->b_p_ul) : p->var;
 
 #ifdef FEAT_ARABIC
 	case PV_ARAB:	return (char_u *)&(curwin->w_p_arab);
@@ -10445,6 +10467,7 @@ buf_copy_options(buf, flags)
 	    /* options that are normally global but also have a local value
 	     * are not copied, start using the global value */
 	    buf->b_p_ar = -1;
+	    buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
 #ifdef FEAT_QUICKFIX
 	    buf->b_p_gp = empty_option;
 	    buf->b_p_mp = empty_option;
--- a/src/option.h
+++ b/src/option.h
@@ -1031,6 +1031,7 @@ enum
     , BV_TW
     , BV_TX
     , BV_UDF
+    , BV_UL
     , BV_WM
     , BV_COUNT	    /* must be the last one */
 };
@@ -1109,3 +1110,6 @@ enum
     , WV_WRAP
     , WV_COUNT	    /* must be the last one */
 };
+
+/* Value for b_p_ul indicating the global value must be used. */
+#define NO_LOCAL_UNDOLEVEL -123456
--- a/src/structs.h
+++ b/src/structs.h
@@ -1627,6 +1627,7 @@ struct file_buffer
     char_u	*b_p_dict;	/* 'dictionary' local value */
     char_u	*b_p_tsr;	/* 'thesaurus' local value */
 #endif
+    long	b_p_ul;		/* 'undolevels' local value */
 #ifdef FEAT_PERSISTENT_UNDO
     int		b_p_udf;	/* 'undofile' */
 #endif
--- a/src/undo.c
+++ b/src/undo.c
@@ -83,6 +83,7 @@
 
 #include "vim.h"
 
+static long get_undolevel __ARGS((void));
 static void u_unch_branch __ARGS((u_header_T *uhp));
 static u_entry_T *u_get_headentry __ARGS((void));
 static void u_getbot __ARGS((void));
@@ -336,6 +337,17 @@ undo_allowed()
 }
 
 /*
+ * Get the undolevle value for the current buffer.
+ */
+    static long
+get_undolevel()
+{
+    if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
+	return p_ul;
+    return curbuf->b_p_ul;
+}
+
+/*
  * Common code for various ways to save text before a change.
  * "top" is the line above the first changed line.
  * "bot" is the line below the last changed line.
@@ -419,7 +431,7 @@ u_savecommon(top, bot, newbot, reload)
 	curbuf->b_new_change = TRUE;
 #endif
 
-	if (p_ul >= 0)
+	if (get_undolevel() >= 0)
 	{
 	    /*
 	     * Make a new header entry.  Do this first so that we don't mess
@@ -449,7 +461,8 @@ u_savecommon(top, bot, newbot, reload)
 	/*
 	 * free headers to keep the size right
 	 */
-	while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
+	while (curbuf->b_u_numhead > get_undolevel()
+					       && curbuf->b_u_oldhead != NULL)
 	{
 	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
 
@@ -530,7 +543,7 @@ u_savecommon(top, bot, newbot, reload)
     }
     else
     {
-	if (p_ul < 0)		/* no undo at all */
+	if (get_undolevel() < 0)	/* no undo at all */
 	    return OK;
 
 	/*
@@ -1972,7 +1985,7 @@ u_doit(startcount)
 	{
 	    if (curbuf->b_u_curhead == NULL)		/* first undo */
 		curbuf->b_u_curhead = curbuf->b_u_newhead;
-	    else if (p_ul > 0)				/* multi level undo */
+	    else if (get_undolevel() > 0)		/* multi level undo */
 		/* get next undo */
 		curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
 	    /* nothing to undo */
@@ -1993,7 +2006,7 @@ u_doit(startcount)
 	}
 	else
 	{
-	    if (curbuf->b_u_curhead == NULL || p_ul <= 0)
+	    if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0)
 	    {
 		beep_flush();	/* nothing to redo */
 		if (count == startcount - 1)
@@ -2751,7 +2764,7 @@ u_sync(force)
     if (im_is_preediting())
 	return;		    /* XIM is busy, don't break an undo sequence */
 #endif
-    if (p_ul < 0)
+    if (get_undolevel() < 0)
 	curbuf->b_u_synced = TRUE;  /* no entries, nothing to do */
     else
     {
@@ -2911,7 +2924,7 @@ ex_undojoin(eap)
     }
     if (!curbuf->b_u_synced)
 	return;		    /* already unsynced */
-    if (p_ul < 0)
+    if (get_undolevel() < 0)
 	return;		    /* no entries, nothing to do */
     else
     {
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    73,
+/**/
     72,
 /**/
     71,