8b9a1c
To: vim_dev@googlegroups.com
8b9a1c
Subject: Patch 7.4.073
8b9a1c
Fcc: outbox
8b9a1c
From: Bram Moolenaar <Bram@moolenaar.net>
8b9a1c
Mime-Version: 1.0
8b9a1c
Content-Type: text/plain; charset=UTF-8
8b9a1c
Content-Transfer-Encoding: 8bit
8b9a1c
------------
8b9a1c
8b9a1c
Patch 7.4.073
8b9a1c
Problem:    Setting undolevels for one buffer changes undo in another.
8b9a1c
Solution:   Make 'undolevels' a global-local option. (Christian Brabandt)
8b9a1c
Files:      runtime/doc/options.txt, src/buffer.c, src/option.c, src/option.h
8b9a1c
            src/structs.h, src/undo.c
8b9a1c
8b9a1c
8b9a1c
*** ../vim-7.4.072/runtime/doc/options.txt	2013-08-10 13:24:57.000000000 +0200
8b9a1c
--- runtime/doc/options.txt	2013-11-06 04:18:43.000000000 +0100
8b9a1c
***************
8b9a1c
*** 7594,7600 ****
8b9a1c
  						*'undolevels'* *'ul'*
8b9a1c
  'undolevels' 'ul'	number	(default 100, 1000 for Unix, VMS,
8b9a1c
  						Win32 and OS/2)
8b9a1c
! 			global
8b9a1c
  			{not in Vi}
8b9a1c
  	Maximum number of changes that can be undone.  Since undo information
8b9a1c
  	is kept in memory, higher numbers will cause more memory to be used
8b9a1c
--- 7594,7600 ----
8b9a1c
  						*'undolevels'* *'ul'*
8b9a1c
  'undolevels' 'ul'	number	(default 100, 1000 for Unix, VMS,
8b9a1c
  						Win32 and OS/2)
8b9a1c
! 			global or local to buffer |global-local|
8b9a1c
  			{not in Vi}
8b9a1c
  	Maximum number of changes that can be undone.  Since undo information
8b9a1c
  	is kept in memory, higher numbers will cause more memory to be used
8b9a1c
***************
8b9a1c
*** 7605,7612 ****
8b9a1c
  <	But you can also get Vi compatibility by including the 'u' flag in
8b9a1c
  	'cpoptions', and still be able to use CTRL-R to repeat undo.
8b9a1c
  	Also see |undo-two-ways|.
8b9a1c
! 	Set to a negative number for no undo at all: >
8b9a1c
! 		set ul=-1
8b9a1c
  <	This helps when you run out of memory for a single change.
8b9a1c
  	Also see |clear-undo|.
8b9a1c
  
8b9a1c
--- 7605,7613 ----
8b9a1c
  <	But you can also get Vi compatibility by including the 'u' flag in
8b9a1c
  	'cpoptions', and still be able to use CTRL-R to repeat undo.
8b9a1c
  	Also see |undo-two-ways|.
8b9a1c
! 	Set to -1 for no undo at all.  You might want to do this only for the
8b9a1c
! 	current buffer: >
8b9a1c
! 		setlocal ul=-1
8b9a1c
  <	This helps when you run out of memory for a single change.
8b9a1c
  	Also see |clear-undo|.
8b9a1c
  
8b9a1c
*** ../vim-7.4.072/src/buffer.c	2013-11-05 17:40:47.000000000 +0100
8b9a1c
--- src/buffer.c	2013-11-06 04:25:27.000000000 +0100
8b9a1c
***************
8b9a1c
*** 1949,1954 ****
8b9a1c
--- 1949,1955 ----
8b9a1c
      clear_string_option(&buf->b_p_qe);
8b9a1c
  #endif
8b9a1c
      buf->b_p_ar = -1;
8b9a1c
+     buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
8b9a1c
  }
8b9a1c
  
8b9a1c
  /*
8b9a1c
*** ../vim-7.4.072/src/option.c	2013-11-05 07:12:59.000000000 +0100
8b9a1c
--- src/option.c	2013-11-06 04:34:23.000000000 +0100
8b9a1c
***************
8b9a1c
*** 234,239 ****
8b9a1c
--- 234,240 ----
8b9a1c
  #ifdef FEAT_STL_OPT
8b9a1c
  # define PV_STL		OPT_BOTH(OPT_WIN(WV_STL))
8b9a1c
  #endif
8b9a1c
+ #define PV_UL		OPT_BOTH(OPT_BUF(BV_UL))
8b9a1c
  #ifdef FEAT_WINDOWS
8b9a1c
  # define PV_WFH		OPT_WIN(WV_WFH)
8b9a1c
  #endif
8b9a1c
***************
8b9a1c
*** 2683,2689 ****
8b9a1c
  #endif
8b9a1c
  			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
8b9a1c
      {"undolevels",  "ul",   P_NUM|P_VI_DEF,
8b9a1c
! 			    (char_u *)&p_ul, PV_NONE,
8b9a1c
  			    {
8b9a1c
  #if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS)
8b9a1c
  			    (char_u *)1000L,
8b9a1c
--- 2684,2690 ----
8b9a1c
  #endif
8b9a1c
  			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
8b9a1c
      {"undolevels",  "ul",   P_NUM|P_VI_DEF,
8b9a1c
! 			    (char_u *)&p_ul, PV_UL,
8b9a1c
  			    {
8b9a1c
  #if defined(UNIX) || defined(WIN3264) || defined(OS2) || defined(VMS)
8b9a1c
  			    (char_u *)1000L,
8b9a1c
***************
8b9a1c
*** 3313,3318 ****
8b9a1c
--- 3314,3320 ----
8b9a1c
  
8b9a1c
      curbuf->b_p_initialized = TRUE;
8b9a1c
      curbuf->b_p_ar = -1;	/* no local 'autoread' value */
8b9a1c
+     curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
8b9a1c
      check_buf_options(curbuf);
8b9a1c
      check_win_options(curwin);
8b9a1c
      check_options();
8b9a1c
***************
8b9a1c
*** 4512,4519 ****
8b9a1c
  						((flags & P_VI_DEF) || cp_val)
8b9a1c
  						 ?  VI_DEFAULT : VIM_DEFAULT];
8b9a1c
  			else if (nextchar == '<')
8b9a1c
! 			    value = *(long *)get_varp_scope(&(options[opt_idx]),
8b9a1c
! 								  OPT_GLOBAL);
8b9a1c
  			else if (((long *)varp == &p_wc
8b9a1c
  				    || (long *)varp == &p_wcm)
8b9a1c
  				&& (*arg == '<'
8b9a1c
--- 4514,4529 ----
8b9a1c
  						((flags & P_VI_DEF) || cp_val)
8b9a1c
  						 ?  VI_DEFAULT : VIM_DEFAULT];
8b9a1c
  			else if (nextchar == '<')
8b9a1c
! 			{
8b9a1c
! 			    /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to
8b9a1c
! 			     * use the global value. */
8b9a1c
! 			    if ((long *)varp == &curbuf->b_p_ul
8b9a1c
! 						    && opt_flags == OPT_LOCAL)
8b9a1c
! 				value = NO_LOCAL_UNDOLEVEL;
8b9a1c
! 			    else
8b9a1c
! 				value = *(long *)get_varp_scope(
8b9a1c
! 					     &(options[opt_idx]), OPT_GLOBAL);
8b9a1c
! 			}
8b9a1c
  			else if (((long *)varp == &p_wc
8b9a1c
  				    || (long *)varp == &p_wcm)
8b9a1c
  				&& (*arg == '<'
8b9a1c
***************
8b9a1c
*** 8487,8492 ****
8b9a1c
--- 8497,8509 ----
8b9a1c
  	u_sync(TRUE);
8b9a1c
  	p_ul = value;
8b9a1c
      }
8b9a1c
+     else if (pp == &curbuf->b_p_ul)
8b9a1c
+     {
8b9a1c
+ 	/* use the old value, otherwise u_sync() may not work properly */
8b9a1c
+ 	curbuf->b_p_ul = old_value;
8b9a1c
+ 	u_sync(TRUE);
8b9a1c
+ 	curbuf->b_p_ul = value;
8b9a1c
+     }
8b9a1c
  
8b9a1c
  #ifdef FEAT_LINEBREAK
8b9a1c
      /* 'numberwidth' must be positive */
8b9a1c
***************
8b9a1c
*** 9720,9726 ****
8b9a1c
  /*
8b9a1c
   * Unset local option value, similar to ":set opt<".
8b9a1c
   */
8b9a1c
- 
8b9a1c
      void
8b9a1c
  unset_global_local_option(name, from)
8b9a1c
      char_u	*name;
8b9a1c
--- 9737,9742 ----
8b9a1c
***************
8b9a1c
*** 9793,9798 ****
8b9a1c
--- 9809,9817 ----
8b9a1c
  	    clear_string_option(&((win_T *)from)->w_p_stl);
8b9a1c
  	    break;
8b9a1c
  #endif
8b9a1c
+ 	case PV_UL:
8b9a1c
+ 	    buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
8b9a1c
+ 	    break;
8b9a1c
      }
8b9a1c
  }
8b9a1c
  
8b9a1c
***************
8b9a1c
*** 9841,9846 ****
8b9a1c
--- 9860,9866 ----
8b9a1c
  #ifdef FEAT_STL_OPT
8b9a1c
  	    case PV_STL:  return (char_u *)&(curwin->w_p_stl);
8b9a1c
  #endif
8b9a1c
+ 	    case PV_UL:   return (char_u *)&(curbuf->b_p_ul);
8b9a1c
  	}
8b9a1c
  	return NULL; /* "cannot happen" */
8b9a1c
      }
8b9a1c
***************
8b9a1c
*** 9905,9910 ****
8b9a1c
--- 9925,9932 ----
8b9a1c
  	case PV_STL:	return *curwin->w_p_stl != NUL
8b9a1c
  				    ? (char_u *)&(curwin->w_p_stl) : p->var;
8b9a1c
  #endif
8b9a1c
+ 	case PV_UL:	return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
8b9a1c
+ 				    ? (char_u *)&(curbuf->b_p_ul) : p->var;
8b9a1c
  
8b9a1c
  #ifdef FEAT_ARABIC
8b9a1c
  	case PV_ARAB:	return (char_u *)&(curwin->w_p_arab);
8b9a1c
***************
8b9a1c
*** 10445,10450 ****
8b9a1c
--- 10467,10473 ----
8b9a1c
  	    /* options that are normally global but also have a local value
8b9a1c
  	     * are not copied, start using the global value */
8b9a1c
  	    buf->b_p_ar = -1;
8b9a1c
+ 	    buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
8b9a1c
  #ifdef FEAT_QUICKFIX
8b9a1c
  	    buf->b_p_gp = empty_option;
8b9a1c
  	    buf->b_p_mp = empty_option;
8b9a1c
*** ../vim-7.4.072/src/option.h	2013-06-26 18:41:39.000000000 +0200
8b9a1c
--- src/option.h	2013-11-06 04:17:40.000000000 +0100
8b9a1c
***************
8b9a1c
*** 1031,1036 ****
8b9a1c
--- 1031,1037 ----
8b9a1c
      , BV_TW
8b9a1c
      , BV_TX
8b9a1c
      , BV_UDF
8b9a1c
+     , BV_UL
8b9a1c
      , BV_WM
8b9a1c
      , BV_COUNT	    /* must be the last one */
8b9a1c
  };
8b9a1c
***************
8b9a1c
*** 1109,1111 ****
8b9a1c
--- 1110,1115 ----
8b9a1c
      , WV_WRAP
8b9a1c
      , WV_COUNT	    /* must be the last one */
8b9a1c
  };
8b9a1c
+ 
8b9a1c
+ /* Value for b_p_ul indicating the global value must be used. */
8b9a1c
+ #define NO_LOCAL_UNDOLEVEL -123456
8b9a1c
*** ../vim-7.4.072/src/structs.h	2013-11-05 07:12:59.000000000 +0100
8b9a1c
--- src/structs.h	2013-11-06 04:26:17.000000000 +0100
8b9a1c
***************
8b9a1c
*** 1627,1632 ****
8b9a1c
--- 1627,1633 ----
8b9a1c
      char_u	*b_p_dict;	/* 'dictionary' local value */
8b9a1c
      char_u	*b_p_tsr;	/* 'thesaurus' local value */
8b9a1c
  #endif
8b9a1c
+     long	b_p_ul;		/* 'undolevels' local value */
8b9a1c
  #ifdef FEAT_PERSISTENT_UNDO
8b9a1c
      int		b_p_udf;	/* 'undofile' */
8b9a1c
  #endif
8b9a1c
*** ../vim-7.4.072/src/undo.c	2013-09-08 15:40:45.000000000 +0200
8b9a1c
--- src/undo.c	2013-11-06 04:33:12.000000000 +0100
8b9a1c
***************
8b9a1c
*** 83,88 ****
8b9a1c
--- 83,89 ----
8b9a1c
  
8b9a1c
  #include "vim.h"
8b9a1c
  
8b9a1c
+ static long get_undolevel __ARGS((void));
8b9a1c
  static void u_unch_branch __ARGS((u_header_T *uhp));
8b9a1c
  static u_entry_T *u_get_headentry __ARGS((void));
8b9a1c
  static void u_getbot __ARGS((void));
8b9a1c
***************
8b9a1c
*** 336,341 ****
8b9a1c
--- 337,353 ----
8b9a1c
  }
8b9a1c
  
8b9a1c
  /*
8b9a1c
+  * Get the undolevle value for the current buffer.
8b9a1c
+  */
8b9a1c
+     static long
8b9a1c
+ get_undolevel()
8b9a1c
+ {
8b9a1c
+     if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
8b9a1c
+ 	return p_ul;
8b9a1c
+     return curbuf->b_p_ul;
8b9a1c
+ }
8b9a1c
+ 
8b9a1c
+ /*
8b9a1c
   * Common code for various ways to save text before a change.
8b9a1c
   * "top" is the line above the first changed line.
8b9a1c
   * "bot" is the line below the last changed line.
8b9a1c
***************
8b9a1c
*** 419,425 ****
8b9a1c
  	curbuf->b_new_change = TRUE;
8b9a1c
  #endif
8b9a1c
  
8b9a1c
! 	if (p_ul >= 0)
8b9a1c
  	{
8b9a1c
  	    /*
8b9a1c
  	     * Make a new header entry.  Do this first so that we don't mess
8b9a1c
--- 431,437 ----
8b9a1c
  	curbuf->b_new_change = TRUE;
8b9a1c
  #endif
8b9a1c
  
8b9a1c
! 	if (get_undolevel() >= 0)
8b9a1c
  	{
8b9a1c
  	    /*
8b9a1c
  	     * Make a new header entry.  Do this first so that we don't mess
8b9a1c
***************
8b9a1c
*** 449,455 ****
8b9a1c
  	/*
8b9a1c
  	 * free headers to keep the size right
8b9a1c
  	 */
8b9a1c
! 	while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
8b9a1c
  	{
8b9a1c
  	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
8b9a1c
  
8b9a1c
--- 461,468 ----
8b9a1c
  	/*
8b9a1c
  	 * free headers to keep the size right
8b9a1c
  	 */
8b9a1c
! 	while (curbuf->b_u_numhead > get_undolevel()
8b9a1c
! 					       && curbuf->b_u_oldhead != NULL)
8b9a1c
  	{
8b9a1c
  	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
8b9a1c
  
8b9a1c
***************
8b9a1c
*** 530,536 ****
8b9a1c
      }
8b9a1c
      else
8b9a1c
      {
8b9a1c
! 	if (p_ul < 0)		/* no undo at all */
8b9a1c
  	    return OK;
8b9a1c
  
8b9a1c
  	/*
8b9a1c
--- 543,549 ----
8b9a1c
      }
8b9a1c
      else
8b9a1c
      {
8b9a1c
! 	if (get_undolevel() < 0)	/* no undo at all */
8b9a1c
  	    return OK;
8b9a1c
  
8b9a1c
  	/*
8b9a1c
***************
8b9a1c
*** 1972,1978 ****
8b9a1c
  	{
8b9a1c
  	    if (curbuf->b_u_curhead == NULL)		/* first undo */
8b9a1c
  		curbuf->b_u_curhead = curbuf->b_u_newhead;
8b9a1c
! 	    else if (p_ul > 0)				/* multi level undo */
8b9a1c
  		/* get next undo */
8b9a1c
  		curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
8b9a1c
  	    /* nothing to undo */
8b9a1c
--- 1985,1991 ----
8b9a1c
  	{
8b9a1c
  	    if (curbuf->b_u_curhead == NULL)		/* first undo */
8b9a1c
  		curbuf->b_u_curhead = curbuf->b_u_newhead;
8b9a1c
! 	    else if (get_undolevel() > 0)		/* multi level undo */
8b9a1c
  		/* get next undo */
8b9a1c
  		curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next.ptr;
8b9a1c
  	    /* nothing to undo */
8b9a1c
***************
8b9a1c
*** 1993,1999 ****
8b9a1c
  	}
8b9a1c
  	else
8b9a1c
  	{
8b9a1c
! 	    if (curbuf->b_u_curhead == NULL || p_ul <= 0)
8b9a1c
  	    {
8b9a1c
  		beep_flush();	/* nothing to redo */
8b9a1c
  		if (count == startcount - 1)
8b9a1c
--- 2006,2012 ----
8b9a1c
  	}
8b9a1c
  	else
8b9a1c
  	{
8b9a1c
! 	    if (curbuf->b_u_curhead == NULL || get_undolevel() <= 0)
8b9a1c
  	    {
8b9a1c
  		beep_flush();	/* nothing to redo */
8b9a1c
  		if (count == startcount - 1)
8b9a1c
***************
8b9a1c
*** 2751,2757 ****
8b9a1c
      if (im_is_preediting())
8b9a1c
  	return;		    /* XIM is busy, don't break an undo sequence */
8b9a1c
  #endif
8b9a1c
!     if (p_ul < 0)
8b9a1c
  	curbuf->b_u_synced = TRUE;  /* no entries, nothing to do */
8b9a1c
      else
8b9a1c
      {
8b9a1c
--- 2764,2770 ----
8b9a1c
      if (im_is_preediting())
8b9a1c
  	return;		    /* XIM is busy, don't break an undo sequence */
8b9a1c
  #endif
8b9a1c
!     if (get_undolevel() < 0)
8b9a1c
  	curbuf->b_u_synced = TRUE;  /* no entries, nothing to do */
8b9a1c
      else
8b9a1c
      {
8b9a1c
***************
8b9a1c
*** 2911,2917 ****
8b9a1c
      }
8b9a1c
      if (!curbuf->b_u_synced)
8b9a1c
  	return;		    /* already unsynced */
8b9a1c
!     if (p_ul < 0)
8b9a1c
  	return;		    /* no entries, nothing to do */
8b9a1c
      else
8b9a1c
      {
8b9a1c
--- 2924,2930 ----
8b9a1c
      }
8b9a1c
      if (!curbuf->b_u_synced)
8b9a1c
  	return;		    /* already unsynced */
8b9a1c
!     if (get_undolevel() < 0)
8b9a1c
  	return;		    /* no entries, nothing to do */
8b9a1c
      else
8b9a1c
      {
8b9a1c
*** ../vim-7.4.072/src/version.c	2013-11-06 04:04:29.000000000 +0100
8b9a1c
--- src/version.c	2013-11-06 05:21:43.000000000 +0100
8b9a1c
***************
8b9a1c
*** 740,741 ****
8b9a1c
--- 740,743 ----
8b9a1c
  {   /* Add new patch number below this line */
8b9a1c
+ /**/
8b9a1c
+     73,
8b9a1c
  /**/
8b9a1c
8b9a1c
-- 
8b9a1c
Living on Earth includes an annual free trip around the Sun.
8b9a1c
8b9a1c
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
8b9a1c
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
8b9a1c
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
8b9a1c
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///