xref: /vim-8.2.3635/src/undo.c (revision 00a927d6)
1 /* vi:set ts=8 sts=4 sw=4:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * undo.c: multi level undo facility
12  *
13  * The saved lines are stored in a list of lists (one for each buffer):
14  *
15  * b_u_oldhead------------------------------------------------+
16  *							      |
17  *							      V
18  *		  +--------------+    +--------------+	  +--------------+
19  * b_u_newhead--->| u_header	 |    | u_header     |	  | u_header	 |
20  *		  |	uh_next------>|     uh_next------>|	uh_next---->NULL
21  *	   NULL<--------uh_prev  |<---------uh_prev  |<---------uh_prev  |
22  *		  |	uh_entry |    |     uh_entry |	  |	uh_entry |
23  *		  +--------|-----+    +--------|-----+	  +--------|-----+
24  *			   |		       |		   |
25  *			   V		       V		   V
26  *		  +--------------+    +--------------+	  +--------------+
27  *		  | u_entry	 |    | u_entry      |	  | u_entry	 |
28  *		  |	ue_next  |    |     ue_next  |	  |	ue_next  |
29  *		  +--------|-----+    +--------|-----+	  +--------|-----+
30  *			   |		       |		   |
31  *			   V		       V		   V
32  *		  +--------------+	      NULL		  NULL
33  *		  | u_entry	 |
34  *		  |	ue_next  |
35  *		  +--------|-----+
36  *			   |
37  *			   V
38  *			  etc.
39  *
40  * Each u_entry list contains the information for one undo or redo.
41  * curbuf->b_u_curhead points to the header of the last undo (the next redo),
42  * or is NULL if nothing has been undone (end of the branch).
43  *
44  * For keeping alternate undo/redo branches the uh_alt field is used.  Thus at
45  * each point in the list a branch may appear for an alternate to redo.  The
46  * uh_seq field is numbered sequentially to be able to find a newer or older
47  * branch.
48  *
49  *		   +---------------+	+---------------+
50  * b_u_oldhead --->| u_header	   |	| u_header	|
51  *		   |   uh_alt_next ---->|   uh_alt_next ----> NULL
52  *	   NULL <----- uh_alt_prev |<------ uh_alt_prev |
53  *		   |   uh_prev	   |	|   uh_prev	|
54  *		   +-----|---------+	+-----|---------+
55  *			 |		      |
56  *			 V		      V
57  *		   +---------------+	+---------------+
58  *		   | u_header	   |	| u_header	|
59  *		   |   uh_alt_next |	|   uh_alt_next |
60  * b_u_newhead --->|   uh_alt_prev |	|   uh_alt_prev |
61  *		   |   uh_prev	   |	|   uh_prev	|
62  *		   +-----|---------+	+-----|---------+
63  *			 |		      |
64  *			 V		      V
65  *		       NULL		+---------------+    +---------------+
66  *					| u_header	|    | u_header      |
67  *					|   uh_alt_next ---->|	 uh_alt_next |
68  *					|   uh_alt_prev |<------ uh_alt_prev |
69  *					|   uh_prev	|    |	 uh_prev     |
70  *					+-----|---------+    +-----|---------+
71  *					      |			   |
72  *					     etc.		  etc.
73  *
74  *
75  * All data is allocated with U_ALLOC_LINE(), it will be freed as soon as the
76  * buffer is unloaded.
77  */
78 
79 /* Uncomment the next line for including the u_check() function.  This warns
80  * for errors in the debug information. */
81 /* #define U_DEBUG 1 */
82 #define UH_MAGIC 0x18dade	/* value for uh_magic when in use */
83 #define UE_MAGIC 0xabc123	/* value for ue_magic when in use */
84 
85 #include "vim.h"
86 
87 /* See below: use malloc()/free() for memory management. */
88 #define U_USE_MALLOC 1
89 
90 static void u_unch_branch __ARGS((u_header_T *uhp));
91 static u_entry_T *u_get_headentry __ARGS((void));
92 static void u_getbot __ARGS((void));
93 static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
94 static void u_doit __ARGS((int count));
95 static void u_undoredo __ARGS((int undo));
96 static void u_undo_end __ARGS((int did_undo, int absolute));
97 static void u_add_time __ARGS((char_u *buf, size_t buflen, time_t tt));
98 static void u_freeheader __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
99 static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
100 static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
101 static void u_freeentry __ARGS((u_entry_T *, long));
102 
103 #ifdef U_USE_MALLOC
104 # define U_FREE_LINE(ptr) vim_free(ptr)
105 # define U_ALLOC_LINE(size) lalloc((long_u)((size) + 1), FALSE)
106 #else
107 static void u_free_line __ARGS((char_u *ptr, int keep));
108 static char_u *u_alloc_line __ARGS((unsigned size));
109 # define U_FREE_LINE(ptr) u_free_line((ptr), FALSE)
110 # define U_ALLOC_LINE(size) u_alloc_line(size)
111 #endif
112 static char_u *u_save_line __ARGS((linenr_T));
113 
114 static long	u_newcount, u_oldcount;
115 
116 /*
117  * When 'u' flag included in 'cpoptions', we behave like vi.  Need to remember
118  * the action that "u" should do.
119  */
120 static int	undo_undoes = FALSE;
121 
122 #ifdef U_DEBUG
123 /*
124  * Check the undo structures for being valid.  Print a warning when something
125  * looks wrong.
126  */
127 static int seen_b_u_curhead;
128 static int seen_b_u_newhead;
129 static int header_count;
130 
131     static void
132 u_check_tree(u_header_T *uhp,
133 	u_header_T *exp_uh_next,
134 	u_header_T *exp_uh_alt_prev)
135 {
136     u_entry_T *uep;
137 
138     if (uhp == NULL)
139 	return;
140     ++header_count;
141     if (uhp == curbuf->b_u_curhead && ++seen_b_u_curhead > 1)
142     {
143 	EMSG("b_u_curhead found twice (looping?)");
144 	return;
145     }
146     if (uhp == curbuf->b_u_newhead && ++seen_b_u_newhead > 1)
147     {
148 	EMSG("b_u_newhead found twice (looping?)");
149 	return;
150     }
151 
152     if (uhp->uh_magic != UH_MAGIC)
153 	EMSG("uh_magic wrong (may be using freed memory)");
154     else
155     {
156 	/* Check pointers back are correct. */
157 	if (uhp->uh_next != exp_uh_next)
158 	{
159 	    EMSG("uh_next wrong");
160 	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
161 						   exp_uh_next, uhp->uh_next);
162 	}
163 	if (uhp->uh_alt_prev != exp_uh_alt_prev)
164 	{
165 	    EMSG("uh_alt_prev wrong");
166 	    smsg((char_u *)"expected: 0x%x, actual: 0x%x",
167 					   exp_uh_alt_prev, uhp->uh_alt_prev);
168 	}
169 
170 	/* Check the undo tree at this header. */
171 	for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next)
172 	{
173 	    if (uep->ue_magic != UE_MAGIC)
174 	    {
175 		EMSG("ue_magic wrong (may be using freed memory)");
176 		break;
177 	    }
178 	}
179 
180 	/* Check the next alt tree. */
181 	u_check_tree(uhp->uh_alt_next, uhp->uh_next, uhp);
182 
183 	/* Check the next header in this branch. */
184 	u_check_tree(uhp->uh_prev, uhp, NULL);
185     }
186 }
187 
188     void
189 u_check(int newhead_may_be_NULL)
190 {
191     seen_b_u_newhead = 0;
192     seen_b_u_curhead = 0;
193     header_count = 0;
194 
195     u_check_tree(curbuf->b_u_oldhead, NULL, NULL);
196 
197     if (seen_b_u_newhead == 0 && curbuf->b_u_oldhead != NULL
198 	    && !(newhead_may_be_NULL && curbuf->b_u_newhead == NULL))
199 	EMSGN("b_u_newhead invalid: 0x%x", curbuf->b_u_newhead);
200     if (curbuf->b_u_curhead != NULL && seen_b_u_curhead == 0)
201 	EMSGN("b_u_curhead invalid: 0x%x", curbuf->b_u_curhead);
202     if (header_count != curbuf->b_u_numhead)
203     {
204 	EMSG("b_u_numhead invalid");
205 	smsg((char_u *)"expected: %ld, actual: %ld",
206 			       (long)header_count, (long)curbuf->b_u_numhead);
207     }
208 }
209 #endif
210 
211 /*
212  * Save the current line for both the "u" and "U" command.
213  * Returns OK or FAIL.
214  */
215     int
216 u_save_cursor()
217 {
218     return (u_save((linenr_T)(curwin->w_cursor.lnum - 1),
219 				      (linenr_T)(curwin->w_cursor.lnum + 1)));
220 }
221 
222 /*
223  * Save the lines between "top" and "bot" for both the "u" and "U" command.
224  * "top" may be 0 and bot may be curbuf->b_ml.ml_line_count + 1.
225  * Returns FAIL when lines could not be saved, OK otherwise.
226  */
227     int
228 u_save(top, bot)
229     linenr_T top, bot;
230 {
231     if (undo_off)
232 	return OK;
233 
234     if (top > curbuf->b_ml.ml_line_count ||
235 			    top >= bot || bot > curbuf->b_ml.ml_line_count + 1)
236 	return FALSE;	/* rely on caller to do error messages */
237 
238     if (top + 2 == bot)
239 	u_saveline((linenr_T)(top + 1));
240 
241     return (u_savecommon(top, bot, (linenr_T)0));
242 }
243 
244 /*
245  * save the line "lnum" (used by ":s" and "~" command)
246  * The line is replaced, so the new bottom line is lnum + 1.
247  */
248     int
249 u_savesub(lnum)
250     linenr_T	lnum;
251 {
252     if (undo_off)
253 	return OK;
254 
255     return (u_savecommon(lnum - 1, lnum + 1, lnum + 1));
256 }
257 
258 /*
259  * a new line is inserted before line "lnum" (used by :s command)
260  * The line is inserted, so the new bottom line is lnum + 1.
261  */
262     int
263 u_inssub(lnum)
264     linenr_T	lnum;
265 {
266     if (undo_off)
267 	return OK;
268 
269     return (u_savecommon(lnum - 1, lnum, lnum + 1));
270 }
271 
272 /*
273  * save the lines "lnum" - "lnum" + nlines (used by delete command)
274  * The lines are deleted, so the new bottom line is lnum, unless the buffer
275  * becomes empty.
276  */
277     int
278 u_savedel(lnum, nlines)
279     linenr_T	lnum;
280     long	nlines;
281 {
282     if (undo_off)
283 	return OK;
284 
285     return (u_savecommon(lnum - 1, lnum + nlines,
286 			nlines == curbuf->b_ml.ml_line_count ? 2 : lnum));
287 }
288 
289 /*
290  * Return TRUE when undo is allowed.  Otherwise give an error message and
291  * return FALSE.
292  */
293     int
294 undo_allowed()
295 {
296     /* Don't allow changes when 'modifiable' is off.  */
297     if (!curbuf->b_p_ma)
298     {
299 	EMSG(_(e_modifiable));
300 	return FALSE;
301     }
302 
303 #ifdef HAVE_SANDBOX
304     /* In the sandbox it's not allowed to change the text. */
305     if (sandbox != 0)
306     {
307 	EMSG(_(e_sandbox));
308 	return FALSE;
309     }
310 #endif
311 
312     /* Don't allow changes in the buffer while editing the cmdline.  The
313      * caller of getcmdline() may get confused. */
314     if (textlock != 0)
315     {
316 	EMSG(_(e_secure));
317 	return FALSE;
318     }
319 
320     return TRUE;
321 }
322 
323     static int
324 u_savecommon(top, bot, newbot)
325     linenr_T	top, bot;
326     linenr_T	newbot;
327 {
328     linenr_T	lnum;
329     long	i;
330     u_header_T	*uhp;
331     u_header_T	*old_curhead;
332     u_entry_T	*uep;
333     u_entry_T	*prev_uep;
334     long	size;
335 
336     /* When making changes is not allowed return FAIL.  It's a crude way to
337      * make all change commands fail. */
338     if (!undo_allowed())
339 	return FAIL;
340 
341 #ifdef U_DEBUG
342     u_check(FALSE);
343 #endif
344 #ifdef FEAT_NETBEANS_INTG
345     /*
346      * Netbeans defines areas that cannot be modified.  Bail out here when
347      * trying to change text in a guarded area.
348      */
349     if (usingNetbeans)
350     {
351 	if (netbeans_is_guarded(top, bot))
352 	{
353 	    EMSG(_(e_guarded));
354 	    return FAIL;
355 	}
356 	if (curbuf->b_p_ro)
357 	{
358 	    EMSG(_(e_nbreadonly));
359 	    return FAIL;
360 	}
361     }
362 #endif
363 
364 #ifdef FEAT_AUTOCMD
365     /*
366      * Saving text for undo means we are going to make a change.  Give a
367      * warning for a read-only file before making the change, so that the
368      * FileChangedRO event can replace the buffer with a read-write version
369      * (e.g., obtained from a source control system).
370      */
371     change_warning(0);
372 #endif
373 
374     size = bot - top - 1;
375 
376     /*
377      * if curbuf->b_u_synced == TRUE make a new header
378      */
379     if (curbuf->b_u_synced)
380     {
381 #ifdef FEAT_JUMPLIST
382 	/* Need to create new entry in b_changelist. */
383 	curbuf->b_new_change = TRUE;
384 #endif
385 
386 	if (p_ul >= 0)
387 	{
388 	    /*
389 	     * Make a new header entry.  Do this first so that we don't mess
390 	     * up the undo info when out of memory.
391 	     */
392 	    uhp = (u_header_T *)U_ALLOC_LINE((unsigned)sizeof(u_header_T));
393 	    if (uhp == NULL)
394 		goto nomem;
395 #ifdef U_DEBUG
396 	    uhp->uh_magic = UH_MAGIC;
397 #endif
398 	}
399 	else
400 	    uhp = NULL;
401 
402 	/*
403 	 * If we undid more than we redid, move the entry lists before and
404 	 * including curbuf->b_u_curhead to an alternate branch.
405 	 */
406 	old_curhead = curbuf->b_u_curhead;
407 	if (old_curhead != NULL)
408 	{
409 	    curbuf->b_u_newhead = old_curhead->uh_next;
410 	    curbuf->b_u_curhead = NULL;
411 	}
412 
413 	/*
414 	 * free headers to keep the size right
415 	 */
416 	while (curbuf->b_u_numhead > p_ul && curbuf->b_u_oldhead != NULL)
417 	{
418 	    u_header_T	    *uhfree = curbuf->b_u_oldhead;
419 
420 	    if (uhfree == old_curhead)
421 		/* Can't reconnect the branch, delete all of it. */
422 		u_freebranch(curbuf, uhfree, &old_curhead);
423 	    else if (uhfree->uh_alt_next == NULL)
424 		/* There is no branch, only free one header. */
425 		u_freeheader(curbuf, uhfree, &old_curhead);
426 	    else
427 	    {
428 		/* Free the oldest alternate branch as a whole. */
429 		while (uhfree->uh_alt_next != NULL)
430 		    uhfree = uhfree->uh_alt_next;
431 		u_freebranch(curbuf, uhfree, &old_curhead);
432 	    }
433 #ifdef U_DEBUG
434 	    u_check(TRUE);
435 #endif
436 	}
437 
438 	if (uhp == NULL)		/* no undo at all */
439 	{
440 	    if (old_curhead != NULL)
441 		u_freebranch(curbuf, old_curhead, NULL);
442 	    curbuf->b_u_synced = FALSE;
443 	    return OK;
444 	}
445 
446 	uhp->uh_prev = NULL;
447 	uhp->uh_next = curbuf->b_u_newhead;
448 	uhp->uh_alt_next = old_curhead;
449 	if (old_curhead != NULL)
450 	{
451 	    uhp->uh_alt_prev = old_curhead->uh_alt_prev;
452 	    if (uhp->uh_alt_prev != NULL)
453 		uhp->uh_alt_prev->uh_alt_next = uhp;
454 	    old_curhead->uh_alt_prev = uhp;
455 	    if (curbuf->b_u_oldhead == old_curhead)
456 		curbuf->b_u_oldhead = uhp;
457 	}
458 	else
459 	    uhp->uh_alt_prev = NULL;
460 	if (curbuf->b_u_newhead != NULL)
461 	    curbuf->b_u_newhead->uh_prev = uhp;
462 
463 	uhp->uh_seq = ++curbuf->b_u_seq_last;
464 	curbuf->b_u_seq_cur = uhp->uh_seq;
465 	uhp->uh_time = time(NULL);
466 	curbuf->b_u_seq_time = uhp->uh_time + 1;
467 
468 	uhp->uh_walk = 0;
469 	uhp->uh_entry = NULL;
470 	uhp->uh_getbot_entry = NULL;
471 	uhp->uh_cursor = curwin->w_cursor;	/* save cursor pos. for undo */
472 #ifdef FEAT_VIRTUALEDIT
473 	if (virtual_active() && curwin->w_cursor.coladd > 0)
474 	    uhp->uh_cursor_vcol = getviscol();
475 	else
476 	    uhp->uh_cursor_vcol = -1;
477 #endif
478 
479 	/* save changed and buffer empty flag for undo */
480 	uhp->uh_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
481 		       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
482 
483 	/* save named marks and Visual marks for undo */
484 	mch_memmove(uhp->uh_namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
485 #ifdef FEAT_VISUAL
486 	uhp->uh_visual = curbuf->b_visual;
487 #endif
488 
489 	curbuf->b_u_newhead = uhp;
490 	if (curbuf->b_u_oldhead == NULL)
491 	    curbuf->b_u_oldhead = uhp;
492 	++curbuf->b_u_numhead;
493     }
494     else
495     {
496 	if (p_ul < 0)		/* no undo at all */
497 	    return OK;
498 
499 	/*
500 	 * When saving a single line, and it has been saved just before, it
501 	 * doesn't make sense saving it again.  Saves a lot of memory when
502 	 * making lots of changes inside the same line.
503 	 * This is only possible if the previous change didn't increase or
504 	 * decrease the number of lines.
505 	 * Check the ten last changes.  More doesn't make sense and takes too
506 	 * long.
507 	 */
508 	if (size == 1)
509 	{
510 	    uep = u_get_headentry();
511 	    prev_uep = NULL;
512 	    for (i = 0; i < 10; ++i)
513 	    {
514 		if (uep == NULL)
515 		    break;
516 
517 		/* If lines have been inserted/deleted we give up.
518 		 * Also when the line was included in a multi-line save. */
519 		if ((curbuf->b_u_newhead->uh_getbot_entry != uep
520 			    ? (uep->ue_top + uep->ue_size + 1
521 				!= (uep->ue_bot == 0
522 				    ? curbuf->b_ml.ml_line_count + 1
523 				    : uep->ue_bot))
524 			    : uep->ue_lcount != curbuf->b_ml.ml_line_count)
525 			|| (uep->ue_size > 1
526 			    && top >= uep->ue_top
527 			    && top + 2 <= uep->ue_top + uep->ue_size + 1))
528 		    break;
529 
530 		/* If it's the same line we can skip saving it again. */
531 		if (uep->ue_size == 1 && uep->ue_top == top)
532 		{
533 		    if (i > 0)
534 		    {
535 			/* It's not the last entry: get ue_bot for the last
536 			 * entry now.  Following deleted/inserted lines go to
537 			 * the re-used entry. */
538 			u_getbot();
539 			curbuf->b_u_synced = FALSE;
540 
541 			/* Move the found entry to become the last entry.  The
542 			 * order of undo/redo doesn't matter for the entries
543 			 * we move it over, since they don't change the line
544 			 * count and don't include this line.  It does matter
545 			 * for the found entry if the line count is changed by
546 			 * the executed command. */
547 			prev_uep->ue_next = uep->ue_next;
548 			uep->ue_next = curbuf->b_u_newhead->uh_entry;
549 			curbuf->b_u_newhead->uh_entry = uep;
550 		    }
551 
552 		    /* The executed command may change the line count. */
553 		    if (newbot != 0)
554 			uep->ue_bot = newbot;
555 		    else if (bot > curbuf->b_ml.ml_line_count)
556 			uep->ue_bot = 0;
557 		    else
558 		    {
559 			uep->ue_lcount = curbuf->b_ml.ml_line_count;
560 			curbuf->b_u_newhead->uh_getbot_entry = uep;
561 		    }
562 		    return OK;
563 		}
564 		prev_uep = uep;
565 		uep = uep->ue_next;
566 	    }
567 	}
568 
569 	/* find line number for ue_bot for previous u_save() */
570 	u_getbot();
571     }
572 
573 #if !defined(UNIX) && !defined(DJGPP) && !defined(WIN32) && !defined(__EMX__)
574 	/*
575 	 * With Amiga and MSDOS 16 bit we can't handle big undo's, because
576 	 * then u_alloc_line would have to allocate a block larger than 32K
577 	 */
578     if (size >= 8000)
579 	goto nomem;
580 #endif
581 
582     /*
583      * add lines in front of entry list
584      */
585     uep = (u_entry_T *)U_ALLOC_LINE((unsigned)sizeof(u_entry_T));
586     if (uep == NULL)
587 	goto nomem;
588 #ifdef U_DEBUG
589     uep->ue_magic = UE_MAGIC;
590 #endif
591 
592     uep->ue_size = size;
593     uep->ue_top = top;
594     if (newbot != 0)
595 	uep->ue_bot = newbot;
596     /*
597      * Use 0 for ue_bot if bot is below last line.
598      * Otherwise we have to compute ue_bot later.
599      */
600     else if (bot > curbuf->b_ml.ml_line_count)
601 	uep->ue_bot = 0;
602     else
603     {
604 	uep->ue_lcount = curbuf->b_ml.ml_line_count;
605 	curbuf->b_u_newhead->uh_getbot_entry = uep;
606     }
607 
608     if (size > 0)
609     {
610 	if ((uep->ue_array = (char_u **)U_ALLOC_LINE(
611 				(unsigned)(sizeof(char_u *) * size))) == NULL)
612 	{
613 	    u_freeentry(uep, 0L);
614 	    goto nomem;
615 	}
616 	for (i = 0, lnum = top + 1; i < size; ++i)
617 	{
618 	    fast_breakcheck();
619 	    if (got_int)
620 	    {
621 		u_freeentry(uep, i);
622 		return FAIL;
623 	    }
624 	    if ((uep->ue_array[i] = u_save_line(lnum++)) == NULL)
625 	    {
626 		u_freeentry(uep, i);
627 		goto nomem;
628 	    }
629 	}
630     }
631     else
632 	uep->ue_array = NULL;
633     uep->ue_next = curbuf->b_u_newhead->uh_entry;
634     curbuf->b_u_newhead->uh_entry = uep;
635     curbuf->b_u_synced = FALSE;
636     undo_undoes = FALSE;
637 
638 #ifdef U_DEBUG
639     u_check(FALSE);
640 #endif
641     return OK;
642 
643 nomem:
644     msg_silent = 0;	/* must display the prompt */
645     if (ask_yesno((char_u *)_("No undo possible; continue anyway"), TRUE)
646 								       == 'y')
647     {
648 	undo_off = TRUE;	    /* will be reset when character typed */
649 	return OK;
650     }
651     do_outofmem_msg((long_u)0);
652     return FAIL;
653 }
654 
655 /*
656  * If 'cpoptions' contains 'u': Undo the previous undo or redo (vi compatible).
657  * If 'cpoptions' does not contain 'u': Always undo.
658  */
659     void
660 u_undo(count)
661     int count;
662 {
663     /*
664      * If we get an undo command while executing a macro, we behave like the
665      * original vi. If this happens twice in one macro the result will not
666      * be compatible.
667      */
668     if (curbuf->b_u_synced == FALSE)
669     {
670 	u_sync(TRUE);
671 	count = 1;
672     }
673 
674     if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
675 	undo_undoes = TRUE;
676     else
677 	undo_undoes = !undo_undoes;
678     u_doit(count);
679 }
680 
681 /*
682  * If 'cpoptions' contains 'u': Repeat the previous undo or redo.
683  * If 'cpoptions' does not contain 'u': Always redo.
684  */
685     void
686 u_redo(count)
687     int count;
688 {
689     if (vim_strchr(p_cpo, CPO_UNDO) == NULL)
690 	undo_undoes = FALSE;
691     u_doit(count);
692 }
693 
694 /*
695  * Undo or redo, depending on 'undo_undoes', 'count' times.
696  */
697     static void
698 u_doit(startcount)
699     int startcount;
700 {
701     int count = startcount;
702 
703     if (!undo_allowed())
704 	return;
705 
706     u_newcount = 0;
707     u_oldcount = 0;
708     if (curbuf->b_ml.ml_flags & ML_EMPTY)
709 	u_oldcount = -1;
710     while (count--)
711     {
712 	if (undo_undoes)
713 	{
714 	    if (curbuf->b_u_curhead == NULL)		/* first undo */
715 		curbuf->b_u_curhead = curbuf->b_u_newhead;
716 	    else if (p_ul > 0)				/* multi level undo */
717 		/* get next undo */
718 		curbuf->b_u_curhead = curbuf->b_u_curhead->uh_next;
719 	    /* nothing to undo */
720 	    if (curbuf->b_u_numhead == 0 || curbuf->b_u_curhead == NULL)
721 	    {
722 		/* stick curbuf->b_u_curhead at end */
723 		curbuf->b_u_curhead = curbuf->b_u_oldhead;
724 		beep_flush();
725 		if (count == startcount - 1)
726 		{
727 		    MSG(_("Already at oldest change"));
728 		    return;
729 		}
730 		break;
731 	    }
732 
733 	    u_undoredo(TRUE);
734 	}
735 	else
736 	{
737 	    if (curbuf->b_u_curhead == NULL || p_ul <= 0)
738 	    {
739 		beep_flush();	/* nothing to redo */
740 		if (count == startcount - 1)
741 		{
742 		    MSG(_("Already at newest change"));
743 		    return;
744 		}
745 		break;
746 	    }
747 
748 	    u_undoredo(FALSE);
749 
750 	    /* Advance for next redo.  Set "newhead" when at the end of the
751 	     * redoable changes. */
752 	    if (curbuf->b_u_curhead->uh_prev == NULL)
753 		curbuf->b_u_newhead = curbuf->b_u_curhead;
754 	    curbuf->b_u_curhead = curbuf->b_u_curhead->uh_prev;
755 	}
756     }
757     u_undo_end(undo_undoes, FALSE);
758 }
759 
760 static int lastmark = 0;
761 
762 /*
763  * Undo or redo over the timeline.
764  * When "step" is negative go back in time, otherwise goes forward in time.
765  * When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
766  * seconds.
767  * When "absolute" is TRUE use "step" as the sequence number to jump to.
768  * "sec" must be FALSE then.
769  */
770     void
771 undo_time(step, sec, absolute)
772     long	step;
773     int		sec;
774     int		absolute;
775 {
776     long	    target;
777     long	    closest;
778     long	    closest_start;
779     long	    closest_seq = 0;
780     long	    val;
781     u_header_T	    *uhp;
782     u_header_T	    *last;
783     int		    mark;
784     int		    nomark;
785     int		    round;
786     int		    dosec = sec;
787     int		    above = FALSE;
788     int		    did_undo = TRUE;
789 
790     /* First make sure the current undoable change is synced. */
791     if (curbuf->b_u_synced == FALSE)
792 	u_sync(TRUE);
793 
794     u_newcount = 0;
795     u_oldcount = 0;
796     if (curbuf->b_ml.ml_flags & ML_EMPTY)
797 	u_oldcount = -1;
798 
799     /* "target" is the node below which we want to be.
800      * Init "closest" to a value we can't reach. */
801     if (absolute)
802     {
803 	target = step;
804 	closest = -1;
805     }
806     else
807     {
808 	/* When doing computations with time_t subtract starttime, because
809 	 * time_t converted to a long may result in a wrong number. */
810 	if (sec)
811 	    target = (long)(curbuf->b_u_seq_time - starttime) + step;
812 	else
813 	    target = curbuf->b_u_seq_cur + step;
814 	if (step < 0)
815 	{
816 	    if (target < 0)
817 		target = 0;
818 	    closest = -1;
819 	}
820 	else
821 	{
822 	    if (sec)
823 		closest = (long)(time(NULL) - starttime + 1);
824 	    else
825 		closest = curbuf->b_u_seq_last + 2;
826 	    if (target >= closest)
827 		target = closest - 1;
828 	}
829     }
830     closest_start = closest;
831     closest_seq = curbuf->b_u_seq_cur;
832 
833     /*
834      * May do this twice:
835      * 1. Search for "target", update "closest" to the best match found.
836      * 2. If "target" not found search for "closest".
837      *
838      * When using the closest time we use the sequence number in the second
839      * round, because there may be several entries with the same time.
840      */
841     for (round = 1; round <= 2; ++round)
842     {
843 	/* Find the path from the current state to where we want to go.  The
844 	 * desired state can be anywhere in the undo tree, need to go all over
845 	 * it.  We put "nomark" in uh_walk where we have been without success,
846 	 * "mark" where it could possibly be. */
847 	mark = ++lastmark;
848 	nomark = ++lastmark;
849 
850 	if (curbuf->b_u_curhead == NULL)	/* at leaf of the tree */
851 	    uhp = curbuf->b_u_newhead;
852 	else
853 	    uhp = curbuf->b_u_curhead;
854 
855 	while (uhp != NULL)
856 	{
857 	    uhp->uh_walk = mark;
858 	    val = (long)(dosec ? (uhp->uh_time - starttime) : uhp->uh_seq);
859 
860 	    if (round == 1)
861 	    {
862 		/* Remember the header that is closest to the target.
863 		 * It must be at least in the right direction (checked with
864 		 * "b_u_seq_cur").  When the timestamp is equal find the
865 		 * highest/lowest sequence number. */
866 		if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur
867 			      : uhp->uh_seq > curbuf->b_u_seq_cur)
868 			&& ((dosec && val == closest)
869 			    ? (step < 0
870 				? uhp->uh_seq < closest_seq
871 				: uhp->uh_seq > closest_seq)
872 			    : closest == closest_start
873 				|| (val > target
874 				    ? (closest > target
875 					? val - target <= closest - target
876 					: val - target <= target - closest)
877 				    : (closest > target
878 					? target - val <= closest - target
879 					: target - val <= target - closest))))
880 		{
881 		    closest = val;
882 		    closest_seq = uhp->uh_seq;
883 		}
884 	    }
885 
886 	    /* Quit searching when we found a match.  But when searching for a
887 	     * time we need to continue looking for the best uh_seq. */
888 	    if (target == val && !dosec)
889 		break;
890 
891 	    /* go down in the tree if we haven't been there */
892 	    if (uhp->uh_prev != NULL && uhp->uh_prev->uh_walk != nomark
893 					     && uhp->uh_prev->uh_walk != mark)
894 		uhp = uhp->uh_prev;
895 
896 	    /* go to alternate branch if we haven't been there */
897 	    else if (uhp->uh_alt_next != NULL
898 		    && uhp->uh_alt_next->uh_walk != nomark
899 		    && uhp->uh_alt_next->uh_walk != mark)
900 		uhp = uhp->uh_alt_next;
901 
902 	    /* go up in the tree if we haven't been there and we are at the
903 	     * start of alternate branches */
904 	    else if (uhp->uh_next != NULL && uhp->uh_alt_prev == NULL
905 		    && uhp->uh_next->uh_walk != nomark
906 		    && uhp->uh_next->uh_walk != mark)
907 	    {
908 		/* If still at the start we don't go through this change. */
909 		if (uhp == curbuf->b_u_curhead)
910 		    uhp->uh_walk = nomark;
911 		uhp = uhp->uh_next;
912 	    }
913 
914 	    else
915 	    {
916 		/* need to backtrack; mark this node as useless */
917 		uhp->uh_walk = nomark;
918 		if (uhp->uh_alt_prev != NULL)
919 		    uhp = uhp->uh_alt_prev;
920 		else
921 		    uhp = uhp->uh_next;
922 	    }
923 	}
924 
925 	if (uhp != NULL)    /* found it */
926 	    break;
927 
928 	if (absolute)
929 	{
930 	    EMSGN(_("Undo number %ld not found"), step);
931 	    return;
932 	}
933 
934 	if (closest == closest_start)
935 	{
936 	    if (step < 0)
937 		MSG(_("Already at oldest change"));
938 	    else
939 		MSG(_("Already at newest change"));
940 	    return;
941 	}
942 
943 	target = closest_seq;
944 	dosec = FALSE;
945 	if (step < 0)
946 	    above = TRUE;	/* stop above the header */
947     }
948 
949     /* If we found it: Follow the path to go to where we want to be. */
950     if (uhp != NULL)
951     {
952 	/*
953 	 * First go up the tree as much as needed.
954 	 */
955 	for (;;)
956 	{
957 	    uhp = curbuf->b_u_curhead;
958 	    if (uhp == NULL)
959 		uhp = curbuf->b_u_newhead;
960 	    else
961 		uhp = uhp->uh_next;
962 	    if (uhp == NULL || uhp->uh_walk != mark
963 					 || (uhp->uh_seq == target && !above))
964 		break;
965 	    curbuf->b_u_curhead = uhp;
966 	    u_undoredo(TRUE);
967 	    uhp->uh_walk = nomark;	/* don't go back down here */
968 	}
969 
970 	/*
971 	 * And now go down the tree (redo), branching off where needed.
972 	 */
973 	uhp = curbuf->b_u_curhead;
974 	while (uhp != NULL)
975 	{
976 	    /* Go back to the first branch with a mark. */
977 	    while (uhp->uh_alt_prev != NULL
978 					&& uhp->uh_alt_prev->uh_walk == mark)
979 		uhp = uhp->uh_alt_prev;
980 
981 	    /* Find the last branch with a mark, that's the one. */
982 	    last = uhp;
983 	    while (last->uh_alt_next != NULL
984 					&& last->uh_alt_next->uh_walk == mark)
985 		last = last->uh_alt_next;
986 	    if (last != uhp)
987 	    {
988 		/* Make the used branch the first entry in the list of
989 		 * alternatives to make "u" and CTRL-R take this branch. */
990 		while (uhp->uh_alt_prev != NULL)
991 		    uhp = uhp->uh_alt_prev;
992 		if (last->uh_alt_next != NULL)
993 		    last->uh_alt_next->uh_alt_prev = last->uh_alt_prev;
994 		last->uh_alt_prev->uh_alt_next = last->uh_alt_next;
995 		last->uh_alt_prev = NULL;
996 		last->uh_alt_next = uhp;
997 		uhp->uh_alt_prev = last;
998 
999 		uhp = last;
1000 		if (uhp->uh_next != NULL)
1001 		    uhp->uh_next->uh_prev = uhp;
1002 	    }
1003 	    curbuf->b_u_curhead = uhp;
1004 
1005 	    if (uhp->uh_walk != mark)
1006 		break;	    /* must have reached the target */
1007 
1008 	    /* Stop when going backwards in time and didn't find the exact
1009 	     * header we were looking for. */
1010 	    if (uhp->uh_seq == target && above)
1011 	    {
1012 		curbuf->b_u_seq_cur = target - 1;
1013 		break;
1014 	    }
1015 
1016 	    u_undoredo(FALSE);
1017 
1018 	    /* Advance "curhead" to below the header we last used.  If it
1019 	     * becomes NULL then we need to set "newhead" to this leaf. */
1020 	    if (uhp->uh_prev == NULL)
1021 		curbuf->b_u_newhead = uhp;
1022 	    curbuf->b_u_curhead = uhp->uh_prev;
1023 	    did_undo = FALSE;
1024 
1025 	    if (uhp->uh_seq == target)	/* found it! */
1026 		break;
1027 
1028 	    uhp = uhp->uh_prev;
1029 	    if (uhp == NULL || uhp->uh_walk != mark)
1030 	    {
1031 		/* Need to redo more but can't find it... */
1032 		EMSG2(_(e_intern2), "undo_time()");
1033 		break;
1034 	    }
1035 	}
1036     }
1037     u_undo_end(did_undo, absolute);
1038 }
1039 
1040 /*
1041  * u_undoredo: common code for undo and redo
1042  *
1043  * The lines in the file are replaced by the lines in the entry list at
1044  * curbuf->b_u_curhead. The replaced lines in the file are saved in the entry
1045  * list for the next undo/redo.
1046  *
1047  * When "undo" is TRUE we go up in the tree, when FALSE we go down.
1048  */
1049     static void
1050 u_undoredo(undo)
1051     int		undo;
1052 {
1053     char_u	**newarray = NULL;
1054     linenr_T	oldsize;
1055     linenr_T	newsize;
1056     linenr_T	top, bot;
1057     linenr_T	lnum;
1058     linenr_T	newlnum = MAXLNUM;
1059     long	i;
1060     u_entry_T	*uep, *nuep;
1061     u_entry_T	*newlist = NULL;
1062     int		old_flags;
1063     int		new_flags;
1064     pos_T	namedm[NMARKS];
1065 #ifdef FEAT_VISUAL
1066     visualinfo_T visualinfo;
1067 #endif
1068     int		empty_buffer;		    /* buffer became empty */
1069     u_header_T	*curhead = curbuf->b_u_curhead;
1070 
1071 #ifdef U_DEBUG
1072     u_check(FALSE);
1073 #endif
1074     old_flags = curhead->uh_flags;
1075     new_flags = (curbuf->b_changed ? UH_CHANGED : 0) +
1076 	       ((curbuf->b_ml.ml_flags & ML_EMPTY) ? UH_EMPTYBUF : 0);
1077     setpcmark();
1078 
1079     /*
1080      * save marks before undo/redo
1081      */
1082     mch_memmove(namedm, curbuf->b_namedm, sizeof(pos_T) * NMARKS);
1083 #ifdef FEAT_VISUAL
1084     visualinfo = curbuf->b_visual;
1085 #endif
1086     curbuf->b_op_start.lnum = curbuf->b_ml.ml_line_count;
1087     curbuf->b_op_start.col = 0;
1088     curbuf->b_op_end.lnum = 0;
1089     curbuf->b_op_end.col = 0;
1090 
1091     for (uep = curhead->uh_entry; uep != NULL; uep = nuep)
1092     {
1093 	top = uep->ue_top;
1094 	bot = uep->ue_bot;
1095 	if (bot == 0)
1096 	    bot = curbuf->b_ml.ml_line_count + 1;
1097 	if (top > curbuf->b_ml.ml_line_count || top >= bot
1098 				      || bot > curbuf->b_ml.ml_line_count + 1)
1099 	{
1100 	    EMSG(_("E438: u_undo: line numbers wrong"));
1101 	    changed();		/* don't want UNCHANGED now */
1102 	    return;
1103 	}
1104 
1105 	oldsize = bot - top - 1;    /* number of lines before undo */
1106 	newsize = uep->ue_size;	    /* number of lines after undo */
1107 
1108 	if (top < newlnum)
1109 	{
1110 	    /* If the saved cursor is somewhere in this undo block, move it to
1111 	     * the remembered position.  Makes "gwap" put the cursor back
1112 	     * where it was. */
1113 	    lnum = curhead->uh_cursor.lnum;
1114 	    if (lnum >= top && lnum <= top + newsize + 1)
1115 	    {
1116 		curwin->w_cursor = curhead->uh_cursor;
1117 		newlnum = curwin->w_cursor.lnum - 1;
1118 	    }
1119 	    else
1120 	    {
1121 		/* Use the first line that actually changed.  Avoids that
1122 		 * undoing auto-formatting puts the cursor in the previous
1123 		 * line. */
1124 		for (i = 0; i < newsize && i < oldsize; ++i)
1125 		    if (STRCMP(uep->ue_array[i], ml_get(top + 1 + i)) != 0)
1126 			break;
1127 		if (i == newsize && newlnum == MAXLNUM && uep->ue_next == NULL)
1128 		{
1129 		    newlnum = top;
1130 		    curwin->w_cursor.lnum = newlnum + 1;
1131 		}
1132 		else if (i < newsize)
1133 		{
1134 		    newlnum = top + i;
1135 		    curwin->w_cursor.lnum = newlnum + 1;
1136 		}
1137 	    }
1138 	}
1139 
1140 	empty_buffer = FALSE;
1141 
1142 	/* delete the lines between top and bot and save them in newarray */
1143 	if (oldsize > 0)
1144 	{
1145 	    if ((newarray = (char_u **)U_ALLOC_LINE(
1146 			    (unsigned)(sizeof(char_u *) * oldsize))) == NULL)
1147 	    {
1148 		do_outofmem_msg((long_u)(sizeof(char_u *) * oldsize));
1149 		/*
1150 		 * We have messed up the entry list, repair is impossible.
1151 		 * we have to free the rest of the list.
1152 		 */
1153 		while (uep != NULL)
1154 		{
1155 		    nuep = uep->ue_next;
1156 		    u_freeentry(uep, uep->ue_size);
1157 		    uep = nuep;
1158 		}
1159 		break;
1160 	    }
1161 	    /* delete backwards, it goes faster in most cases */
1162 	    for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum)
1163 	    {
1164 		/* what can we do when we run out of memory? */
1165 		if ((newarray[i] = u_save_line(lnum)) == NULL)
1166 		    do_outofmem_msg((long_u)0);
1167 		/* remember we deleted the last line in the buffer, and a
1168 		 * dummy empty line will be inserted */
1169 		if (curbuf->b_ml.ml_line_count == 1)
1170 		    empty_buffer = TRUE;
1171 		ml_delete(lnum, FALSE);
1172 	    }
1173 	}
1174 	else
1175 	    newarray = NULL;
1176 
1177 	/* insert the lines in u_array between top and bot */
1178 	if (newsize)
1179 	{
1180 	    for (lnum = top, i = 0; i < newsize; ++i, ++lnum)
1181 	    {
1182 		/*
1183 		 * If the file is empty, there is an empty line 1 that we
1184 		 * should get rid of, by replacing it with the new line
1185 		 */
1186 		if (empty_buffer && lnum == 0)
1187 		    ml_replace((linenr_T)1, uep->ue_array[i], TRUE);
1188 		else
1189 		    ml_append(lnum, uep->ue_array[i], (colnr_T)0, FALSE);
1190 		U_FREE_LINE(uep->ue_array[i]);
1191 	    }
1192 	    U_FREE_LINE((char_u *)uep->ue_array);
1193 	}
1194 
1195 	/* adjust marks */
1196 	if (oldsize != newsize)
1197 	{
1198 	    mark_adjust(top + 1, top + oldsize, (long)MAXLNUM,
1199 					       (long)newsize - (long)oldsize);
1200 	    if (curbuf->b_op_start.lnum > top + oldsize)
1201 		curbuf->b_op_start.lnum += newsize - oldsize;
1202 	    if (curbuf->b_op_end.lnum > top + oldsize)
1203 		curbuf->b_op_end.lnum += newsize - oldsize;
1204 	}
1205 
1206 	changed_lines(top + 1, 0, bot, newsize - oldsize);
1207 
1208 	/* set '[ and '] mark */
1209 	if (top + 1 < curbuf->b_op_start.lnum)
1210 	    curbuf->b_op_start.lnum = top + 1;
1211 	if (newsize == 0 && top + 1 > curbuf->b_op_end.lnum)
1212 	    curbuf->b_op_end.lnum = top + 1;
1213 	else if (top + newsize > curbuf->b_op_end.lnum)
1214 	    curbuf->b_op_end.lnum = top + newsize;
1215 
1216 	u_newcount += newsize;
1217 	u_oldcount += oldsize;
1218 	uep->ue_size = oldsize;
1219 	uep->ue_array = newarray;
1220 	uep->ue_bot = top + newsize + 1;
1221 
1222 	/*
1223 	 * insert this entry in front of the new entry list
1224 	 */
1225 	nuep = uep->ue_next;
1226 	uep->ue_next = newlist;
1227 	newlist = uep;
1228     }
1229 
1230     curhead->uh_entry = newlist;
1231     curhead->uh_flags = new_flags;
1232     if ((old_flags & UH_EMPTYBUF) && bufempty())
1233 	curbuf->b_ml.ml_flags |= ML_EMPTY;
1234     if (old_flags & UH_CHANGED)
1235 	changed();
1236     else
1237 #ifdef FEAT_NETBEANS_INTG
1238 	/* per netbeans undo rules, keep it as modified */
1239 	if (!isNetbeansModified(curbuf))
1240 #endif
1241 	unchanged(curbuf, FALSE);
1242 
1243     /*
1244      * restore marks from before undo/redo
1245      */
1246     for (i = 0; i < NMARKS; ++i)
1247 	if (curhead->uh_namedm[i].lnum != 0)
1248 	{
1249 	    curbuf->b_namedm[i] = curhead->uh_namedm[i];
1250 	    curhead->uh_namedm[i] = namedm[i];
1251 	}
1252 #ifdef FEAT_VISUAL
1253     if (curhead->uh_visual.vi_start.lnum != 0)
1254     {
1255 	curbuf->b_visual = curhead->uh_visual;
1256 	curhead->uh_visual = visualinfo;
1257     }
1258 #endif
1259 
1260     /*
1261      * If the cursor is only off by one line, put it at the same position as
1262      * before starting the change (for the "o" command).
1263      * Otherwise the cursor should go to the first undone line.
1264      */
1265     if (curhead->uh_cursor.lnum + 1 == curwin->w_cursor.lnum
1266 						 && curwin->w_cursor.lnum > 1)
1267 	--curwin->w_cursor.lnum;
1268     if (curhead->uh_cursor.lnum == curwin->w_cursor.lnum)
1269     {
1270 	curwin->w_cursor.col = curhead->uh_cursor.col;
1271 #ifdef FEAT_VIRTUALEDIT
1272 	if (virtual_active() && curhead->uh_cursor_vcol >= 0)
1273 	    coladvance((colnr_T)curhead->uh_cursor_vcol);
1274 	else
1275 	    curwin->w_cursor.coladd = 0;
1276 #endif
1277     }
1278     else if (curwin->w_cursor.lnum <= curbuf->b_ml.ml_line_count)
1279 	beginline(BL_SOL | BL_FIX);
1280     else
1281     {
1282 	/* We get here with the current cursor line being past the end (eg
1283 	 * after adding lines at the end of the file, and then undoing it).
1284 	 * check_cursor() will move the cursor to the last line.  Move it to
1285 	 * the first column here. */
1286 	curwin->w_cursor.col = 0;
1287 #ifdef FEAT_VIRTUALEDIT
1288 	curwin->w_cursor.coladd = 0;
1289 #endif
1290     }
1291 
1292     /* Make sure the cursor is on an existing line and column. */
1293     check_cursor();
1294 
1295     /* Remember where we are for "g-" and ":earlier 10s". */
1296     curbuf->b_u_seq_cur = curhead->uh_seq;
1297     if (undo)
1298 	/* We are below the previous undo.  However, to make ":earlier 1s"
1299 	 * work we compute this as being just above the just undone change. */
1300 	--curbuf->b_u_seq_cur;
1301 
1302     /* The timestamp can be the same for multiple changes, just use the one of
1303      * the undone/redone change. */
1304     curbuf->b_u_seq_time = curhead->uh_time;
1305 #ifdef U_DEBUG
1306     u_check(FALSE);
1307 #endif
1308 }
1309 
1310 /*
1311  * If we deleted or added lines, report the number of less/more lines.
1312  * Otherwise, report the number of changes (this may be incorrect
1313  * in some cases, but it's better than nothing).
1314  */
1315     static void
1316 u_undo_end(did_undo, absolute)
1317     int		did_undo;	/* just did an undo */
1318     int		absolute;	/* used ":undo N" */
1319 {
1320     char	*msgstr;
1321     u_header_T	*uhp;
1322     char_u	msgbuf[80];
1323 
1324 #ifdef FEAT_FOLDING
1325     if ((fdo_flags & FDO_UNDO) && KeyTyped)
1326 	foldOpenCursor();
1327 #endif
1328 
1329     if (global_busy	    /* no messages now, wait until global is finished */
1330 	    || !messaging())  /* 'lazyredraw' set, don't do messages now */
1331 	return;
1332 
1333     if (curbuf->b_ml.ml_flags & ML_EMPTY)
1334 	--u_newcount;
1335 
1336     u_oldcount -= u_newcount;
1337     if (u_oldcount == -1)
1338 	msgstr = N_("more line");
1339     else if (u_oldcount < 0)
1340 	msgstr = N_("more lines");
1341     else if (u_oldcount == 1)
1342 	msgstr = N_("line less");
1343     else if (u_oldcount > 1)
1344 	msgstr = N_("fewer lines");
1345     else
1346     {
1347 	u_oldcount = u_newcount;
1348 	if (u_newcount == 1)
1349 	    msgstr = N_("change");
1350 	else
1351 	    msgstr = N_("changes");
1352     }
1353 
1354     if (curbuf->b_u_curhead != NULL)
1355     {
1356 	/* For ":undo N" we prefer a "after #N" message. */
1357 	if (absolute && curbuf->b_u_curhead->uh_next != NULL)
1358 	{
1359 	    uhp = curbuf->b_u_curhead->uh_next;
1360 	    did_undo = FALSE;
1361 	}
1362 	else if (did_undo)
1363 	    uhp = curbuf->b_u_curhead;
1364 	else
1365 	    uhp = curbuf->b_u_curhead->uh_next;
1366     }
1367     else
1368 	uhp = curbuf->b_u_newhead;
1369 
1370     if (uhp == NULL)
1371 	*msgbuf = NUL;
1372     else
1373 	u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
1374 
1375     smsg((char_u *)_("%ld %s; %s #%ld  %s"),
1376 	    u_oldcount < 0 ? -u_oldcount : u_oldcount,
1377 	    _(msgstr),
1378 	    did_undo ? _("before") : _("after"),
1379 	    uhp == NULL ? 0L : uhp->uh_seq,
1380 	    msgbuf);
1381 }
1382 
1383 /*
1384  * u_sync: stop adding to the current entry list
1385  */
1386     void
1387 u_sync(force)
1388     int	    force;	/* Also sync when no_u_sync is set. */
1389 {
1390     /* Skip it when already synced or syncing is disabled. */
1391     if (curbuf->b_u_synced || (!force && no_u_sync > 0))
1392 	return;
1393 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
1394     if (im_is_preediting())
1395 	return;		    /* XIM is busy, don't break an undo sequence */
1396 #endif
1397     if (p_ul < 0)
1398 	curbuf->b_u_synced = TRUE;  /* no entries, nothing to do */
1399     else
1400     {
1401 	u_getbot();		    /* compute ue_bot of previous u_save */
1402 	curbuf->b_u_curhead = NULL;
1403     }
1404 }
1405 
1406 /*
1407  * ":undolist": List the leafs of the undo tree
1408  */
1409 /*ARGSUSED*/
1410     void
1411 ex_undolist(eap)
1412     exarg_T *eap;
1413 {
1414     garray_T	ga;
1415     u_header_T	*uhp;
1416     int		mark;
1417     int		nomark;
1418     int		changes = 1;
1419     int		i;
1420 
1421     /*
1422      * 1: walk the tree to find all leafs, put the info in "ga".
1423      * 2: sort the lines
1424      * 3: display the list
1425      */
1426     mark = ++lastmark;
1427     nomark = ++lastmark;
1428     ga_init2(&ga, (int)sizeof(char *), 20);
1429 
1430     uhp = curbuf->b_u_oldhead;
1431     while (uhp != NULL)
1432     {
1433 	if (uhp->uh_prev == NULL && uhp->uh_walk != nomark
1434 						      && uhp->uh_walk != mark)
1435 	{
1436 	    if (ga_grow(&ga, 1) == FAIL)
1437 		break;
1438 	    vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld  ",
1439 							uhp->uh_seq, changes);
1440 	    u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
1441 								uhp->uh_time);
1442 	    ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
1443 	}
1444 
1445 	uhp->uh_walk = mark;
1446 
1447 	/* go down in the tree if we haven't been there */
1448 	if (uhp->uh_prev != NULL && uhp->uh_prev->uh_walk != nomark
1449 					 && uhp->uh_prev->uh_walk != mark)
1450 	{
1451 	    uhp = uhp->uh_prev;
1452 	    ++changes;
1453 	}
1454 
1455 	/* go to alternate branch if we haven't been there */
1456 	else if (uhp->uh_alt_next != NULL
1457 		&& uhp->uh_alt_next->uh_walk != nomark
1458 		&& uhp->uh_alt_next->uh_walk != mark)
1459 	    uhp = uhp->uh_alt_next;
1460 
1461 	/* go up in the tree if we haven't been there and we are at the
1462 	 * start of alternate branches */
1463 	else if (uhp->uh_next != NULL && uhp->uh_alt_prev == NULL
1464 		&& uhp->uh_next->uh_walk != nomark
1465 		&& uhp->uh_next->uh_walk != mark)
1466 	{
1467 	    uhp = uhp->uh_next;
1468 	    --changes;
1469 	}
1470 
1471 	else
1472 	{
1473 	    /* need to backtrack; mark this node as done */
1474 	    uhp->uh_walk = nomark;
1475 	    if (uhp->uh_alt_prev != NULL)
1476 		uhp = uhp->uh_alt_prev;
1477 	    else
1478 	    {
1479 		uhp = uhp->uh_next;
1480 		--changes;
1481 	    }
1482 	}
1483     }
1484 
1485     if (ga.ga_len == 0)
1486 	MSG(_("Nothing to undo"));
1487     else
1488     {
1489 	sort_strings((char_u **)ga.ga_data, ga.ga_len);
1490 
1491 	msg_start();
1492 	msg_puts_attr((char_u *)_("number changes  time"), hl_attr(HLF_T));
1493 	for (i = 0; i < ga.ga_len && !got_int; ++i)
1494 	{
1495 	    msg_putchar('\n');
1496 	    if (got_int)
1497 		break;
1498 	    msg_puts(((char_u **)ga.ga_data)[i]);
1499 	}
1500 	msg_end();
1501 
1502 	ga_clear_strings(&ga);
1503     }
1504 }
1505 
1506 /*
1507  * Put the timestamp of an undo header in "buf[buflen]" in a nice format.
1508  */
1509     static void
1510 u_add_time(buf, buflen, tt)
1511     char_u	*buf;
1512     size_t	buflen;
1513     time_t	tt;
1514 {
1515 #ifdef HAVE_STRFTIME
1516     struct tm	*curtime;
1517 
1518     if (time(NULL) - tt >= 100)
1519     {
1520 	curtime = localtime(&tt);
1521 	(void)strftime((char *)buf, buflen, "%H:%M:%S", curtime);
1522     }
1523     else
1524 #endif
1525 	vim_snprintf((char *)buf, buflen, _("%ld seconds ago"),
1526 						     (long)(time(NULL) - tt));
1527 }
1528 
1529 /*
1530  * ":undojoin": continue adding to the last entry list
1531  */
1532 /*ARGSUSED*/
1533     void
1534 ex_undojoin(eap)
1535     exarg_T *eap;
1536 {
1537     if (curbuf->b_u_newhead == NULL)
1538 	return;		    /* nothing changed before */
1539     if (curbuf->b_u_curhead != NULL)
1540     {
1541 	EMSG(_("E790: undojoin is not allowed after undo"));
1542 	return;
1543     }
1544     if (!curbuf->b_u_synced)
1545 	return;		    /* already unsynced */
1546     if (p_ul < 0)
1547 	return;		    /* no entries, nothing to do */
1548     else
1549     {
1550 	/* Go back to the last entry */
1551 	curbuf->b_u_curhead = curbuf->b_u_newhead;
1552 	curbuf->b_u_synced = FALSE;  /* no entries, nothing to do */
1553     }
1554 }
1555 
1556 /*
1557  * Called after writing the file and setting b_changed to FALSE.
1558  * Now an undo means that the buffer is modified.
1559  */
1560     void
1561 u_unchanged(buf)
1562     buf_T	*buf;
1563 {
1564     u_unch_branch(buf->b_u_oldhead);
1565     buf->b_did_warn = FALSE;
1566 }
1567 
1568     static void
1569 u_unch_branch(uhp)
1570     u_header_T	*uhp;
1571 {
1572     u_header_T	*uh;
1573 
1574     for (uh = uhp; uh != NULL; uh = uh->uh_prev)
1575     {
1576 	uh->uh_flags |= UH_CHANGED;
1577 	if (uh->uh_alt_next != NULL)
1578 	    u_unch_branch(uh->uh_alt_next);	    /* recursive */
1579     }
1580 }
1581 
1582 /*
1583  * Get pointer to last added entry.
1584  * If it's not valid, give an error message and return NULL.
1585  */
1586     static u_entry_T *
1587 u_get_headentry()
1588 {
1589     if (curbuf->b_u_newhead == NULL || curbuf->b_u_newhead->uh_entry == NULL)
1590     {
1591 	EMSG(_("E439: undo list corrupt"));
1592 	return NULL;
1593     }
1594     return curbuf->b_u_newhead->uh_entry;
1595 }
1596 
1597 /*
1598  * u_getbot(): compute the line number of the previous u_save
1599  *		It is called only when b_u_synced is FALSE.
1600  */
1601     static void
1602 u_getbot()
1603 {
1604     u_entry_T	*uep;
1605     linenr_T	extra;
1606 
1607     uep = u_get_headentry();	/* check for corrupt undo list */
1608     if (uep == NULL)
1609 	return;
1610 
1611     uep = curbuf->b_u_newhead->uh_getbot_entry;
1612     if (uep != NULL)
1613     {
1614 	/*
1615 	 * the new ue_bot is computed from the number of lines that has been
1616 	 * inserted (0 - deleted) since calling u_save. This is equal to the
1617 	 * old line count subtracted from the current line count.
1618 	 */
1619 	extra = curbuf->b_ml.ml_line_count - uep->ue_lcount;
1620 	uep->ue_bot = uep->ue_top + uep->ue_size + 1 + extra;
1621 	if (uep->ue_bot < 1 || uep->ue_bot > curbuf->b_ml.ml_line_count)
1622 	{
1623 	    EMSG(_("E440: undo line missing"));
1624 	    uep->ue_bot = uep->ue_top + 1;  /* assume all lines deleted, will
1625 					     * get all the old lines back
1626 					     * without deleting the current
1627 					     * ones */
1628 	}
1629 
1630 	curbuf->b_u_newhead->uh_getbot_entry = NULL;
1631     }
1632 
1633     curbuf->b_u_synced = TRUE;
1634 }
1635 
1636 /*
1637  * Free one header "uhp" and its entry list and adjust the pointers.
1638  */
1639     static void
1640 u_freeheader(buf, uhp, uhpp)
1641     buf_T	    *buf;
1642     u_header_T	    *uhp;
1643     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
1644 {
1645     u_header_T	    *uhap;
1646 
1647     /* When there is an alternate redo list free that branch completely,
1648      * because we can never go there. */
1649     if (uhp->uh_alt_next != NULL)
1650 	u_freebranch(buf, uhp->uh_alt_next, uhpp);
1651 
1652     if (uhp->uh_alt_prev != NULL)
1653 	uhp->uh_alt_prev->uh_alt_next = NULL;
1654 
1655     /* Update the links in the list to remove the header. */
1656     if (uhp->uh_next == NULL)
1657 	buf->b_u_oldhead = uhp->uh_prev;
1658     else
1659 	uhp->uh_next->uh_prev = uhp->uh_prev;
1660 
1661     if (uhp->uh_prev == NULL)
1662 	buf->b_u_newhead = uhp->uh_next;
1663     else
1664 	for (uhap = uhp->uh_prev; uhap != NULL; uhap = uhap->uh_alt_next)
1665 	    uhap->uh_next = uhp->uh_next;
1666 
1667     u_freeentries(buf, uhp, uhpp);
1668 }
1669 
1670 /*
1671  * Free an alternate branch and any following alternate branches.
1672  */
1673     static void
1674 u_freebranch(buf, uhp, uhpp)
1675     buf_T	    *buf;
1676     u_header_T	    *uhp;
1677     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
1678 {
1679     u_header_T	    *tofree, *next;
1680 
1681     /* If this is the top branch we may need to use u_freeheader() to update
1682      * all the pointers. */
1683     if (uhp == buf->b_u_oldhead)
1684     {
1685 	u_freeheader(buf, uhp, uhpp);
1686 	return;
1687     }
1688 
1689     if (uhp->uh_alt_prev != NULL)
1690 	uhp->uh_alt_prev->uh_alt_next = NULL;
1691 
1692     next = uhp;
1693     while (next != NULL)
1694     {
1695 	tofree = next;
1696 	if (tofree->uh_alt_next != NULL)
1697 	    u_freebranch(buf, tofree->uh_alt_next, uhpp);   /* recursive */
1698 	next = tofree->uh_prev;
1699 	u_freeentries(buf, tofree, uhpp);
1700     }
1701 }
1702 
1703 /*
1704  * Free all the undo entries for one header and the header itself.
1705  * This means that "uhp" is invalid when returning.
1706  */
1707     static void
1708 u_freeentries(buf, uhp, uhpp)
1709     buf_T	    *buf;
1710     u_header_T	    *uhp;
1711     u_header_T	    **uhpp;	/* if not NULL reset when freeing this header */
1712 {
1713     u_entry_T	    *uep, *nuep;
1714 
1715     /* Check for pointers to the header that become invalid now. */
1716     if (buf->b_u_curhead == uhp)
1717 	buf->b_u_curhead = NULL;
1718     if (buf->b_u_newhead == uhp)
1719 	buf->b_u_newhead = NULL;  /* freeing the newest entry */
1720     if (uhpp != NULL && uhp == *uhpp)
1721 	*uhpp = NULL;
1722 
1723     for (uep = uhp->uh_entry; uep != NULL; uep = nuep)
1724     {
1725 	nuep = uep->ue_next;
1726 	u_freeentry(uep, uep->ue_size);
1727     }
1728 
1729 #ifdef U_DEBUG
1730     uhp->uh_magic = 0;
1731 #endif
1732     U_FREE_LINE((char_u *)uhp);
1733     --buf->b_u_numhead;
1734 }
1735 
1736 /*
1737  * free entry 'uep' and 'n' lines in uep->ue_array[]
1738  */
1739     static void
1740 u_freeentry(uep, n)
1741     u_entry_T	*uep;
1742     long	    n;
1743 {
1744     while (n > 0)
1745 	U_FREE_LINE(uep->ue_array[--n]);
1746     U_FREE_LINE((char_u *)uep->ue_array);
1747 #ifdef U_DEBUG
1748     uep->ue_magic = 0;
1749 #endif
1750     U_FREE_LINE((char_u *)uep);
1751 }
1752 
1753 /*
1754  * invalidate the undo buffer; called when storage has already been released
1755  */
1756     void
1757 u_clearall(buf)
1758     buf_T	*buf;
1759 {
1760     buf->b_u_newhead = buf->b_u_oldhead = buf->b_u_curhead = NULL;
1761     buf->b_u_synced = TRUE;
1762     buf->b_u_numhead = 0;
1763     buf->b_u_line_ptr = NULL;
1764     buf->b_u_line_lnum = 0;
1765 }
1766 
1767 /*
1768  * save the line "lnum" for the "U" command
1769  */
1770     void
1771 u_saveline(lnum)
1772     linenr_T lnum;
1773 {
1774     if (lnum == curbuf->b_u_line_lnum)	    /* line is already saved */
1775 	return;
1776     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) /* should never happen */
1777 	return;
1778     u_clearline();
1779     curbuf->b_u_line_lnum = lnum;
1780     if (curwin->w_cursor.lnum == lnum)
1781 	curbuf->b_u_line_colnr = curwin->w_cursor.col;
1782     else
1783 	curbuf->b_u_line_colnr = 0;
1784     if ((curbuf->b_u_line_ptr = u_save_line(lnum)) == NULL)
1785 	do_outofmem_msg((long_u)0);
1786 }
1787 
1788 /*
1789  * clear the line saved for the "U" command
1790  * (this is used externally for crossing a line while in insert mode)
1791  */
1792     void
1793 u_clearline()
1794 {
1795     if (curbuf->b_u_line_ptr != NULL)
1796     {
1797 	U_FREE_LINE(curbuf->b_u_line_ptr);
1798 	curbuf->b_u_line_ptr = NULL;
1799 	curbuf->b_u_line_lnum = 0;
1800     }
1801 }
1802 
1803 /*
1804  * Implementation of the "U" command.
1805  * Differentiation from vi: "U" can be undone with the next "U".
1806  * We also allow the cursor to be in another line.
1807  */
1808     void
1809 u_undoline()
1810 {
1811     colnr_T t;
1812     char_u  *oldp;
1813 
1814     if (undo_off)
1815 	return;
1816 
1817     if (curbuf->b_u_line_ptr == NULL
1818 			|| curbuf->b_u_line_lnum > curbuf->b_ml.ml_line_count)
1819     {
1820 	beep_flush();
1821 	return;
1822     }
1823 
1824     /* first save the line for the 'u' command */
1825     if (u_savecommon(curbuf->b_u_line_lnum - 1,
1826 				curbuf->b_u_line_lnum + 1, (linenr_T)0) == FAIL)
1827 	return;
1828     oldp = u_save_line(curbuf->b_u_line_lnum);
1829     if (oldp == NULL)
1830     {
1831 	do_outofmem_msg((long_u)0);
1832 	return;
1833     }
1834     ml_replace(curbuf->b_u_line_lnum, curbuf->b_u_line_ptr, TRUE);
1835     changed_bytes(curbuf->b_u_line_lnum, 0);
1836     U_FREE_LINE(curbuf->b_u_line_ptr);
1837     curbuf->b_u_line_ptr = oldp;
1838 
1839     t = curbuf->b_u_line_colnr;
1840     if (curwin->w_cursor.lnum == curbuf->b_u_line_lnum)
1841 	curbuf->b_u_line_colnr = curwin->w_cursor.col;
1842     curwin->w_cursor.col = t;
1843     curwin->w_cursor.lnum = curbuf->b_u_line_lnum;
1844     check_cursor_col();
1845 }
1846 
1847 /*
1848  * There are two implementations of the memory management for undo:
1849  * 1. Use the standard malloc()/free() functions.
1850  *    This should be fast for allocating memory, but when a buffer is
1851  *    abandoned every single allocated chunk must be freed, which may be slow.
1852  * 2. Allocate larger blocks of memory and keep track of chunks ourselves.
1853  *    This is fast for abandoning, but the use of linked lists is slow for
1854  *    finding a free chunk.  Esp. when a lot of lines are changed or deleted.
1855  * A bit of profiling showed that the first method is faster, especially when
1856  * making a large number of changes, under the condition that malloc()/free()
1857  * is implemented efficiently.
1858  */
1859 #ifdef U_USE_MALLOC
1860 /*
1861  * Version of undo memory allocation using malloc()/free()
1862  *
1863  * U_FREE_LINE() and U_ALLOC_LINE() are macros that invoke vim_free() and
1864  * lalloc() directly.
1865  */
1866 
1867 /*
1868  * Free all allocated memory blocks for the buffer 'buf'.
1869  */
1870     void
1871 u_blockfree(buf)
1872     buf_T	*buf;
1873 {
1874     while (buf->b_u_oldhead != NULL)
1875 	u_freeheader(buf, buf->b_u_oldhead, NULL);
1876     U_FREE_LINE(buf->b_u_line_ptr);
1877 }
1878 
1879 #else
1880 /*
1881  * Storage allocation for the undo lines and blocks of the current file.
1882  * Version where Vim keeps track of the available memory.
1883  */
1884 
1885 /*
1886  * Memory is allocated in relatively large blocks. These blocks are linked
1887  * in the allocated block list, headed by curbuf->b_block_head. They are all
1888  * freed when abandoning a file, so we don't have to free every single line.
1889  * The list is kept sorted on memory address.
1890  * block_alloc() allocates a block.
1891  * m_blockfree() frees all blocks.
1892  *
1893  * The available chunks of memory are kept in free chunk lists. There is
1894  * one free list for each block of allocated memory. The list is kept sorted
1895  * on memory address.
1896  * u_alloc_line() gets a chunk from the free lists.
1897  * u_free_line() returns a chunk to the free lists.
1898  * curbuf->b_m_search points to the chunk before the chunk that was
1899  * freed/allocated the last time.
1900  * curbuf->b_mb_current points to the b_head where curbuf->b_m_search
1901  * points into the free list.
1902  *
1903  *
1904  *  b_block_head     /---> block #1	/---> block #2
1905  *	 mb_next ---/	    mb_next ---/       mb_next ---> NULL
1906  *	 mb_info	    mb_info	       mb_info
1907  *	    |		       |		  |
1908  *	    V		       V		  V
1909  *	  NULL		free chunk #1.1      free chunk #2.1
1910  *			       |		  |
1911  *			       V		  V
1912  *			free chunk #1.2		 NULL
1913  *			       |
1914  *			       V
1915  *			      NULL
1916  *
1917  * When a single free chunk list would have been used, it could take a lot
1918  * of time in u_free_line() to find the correct place to insert a chunk in the
1919  * free list. The single free list would become very long when many lines are
1920  * changed (e.g. with :%s/^M$//).
1921  */
1922 
1923  /*
1924   * this blocksize is used when allocating new lines
1925   */
1926 #define MEMBLOCKSIZE 2044
1927 
1928 /*
1929  * The size field contains the size of the chunk, including the size field
1930  * itself.
1931  *
1932  * When the chunk is not in-use it is preceded with the m_info structure.
1933  * The m_next field links it in one of the free chunk lists.
1934  *
1935  * On most unix systems structures have to be longword (32 or 64 bit) aligned.
1936  * On most other systems they are short (16 bit) aligned.
1937  */
1938 
1939 /* the structure definitions are now in structs.h */
1940 
1941 #ifdef ALIGN_LONG
1942     /* size of m_size */
1943 # define M_OFFSET (sizeof(long_u))
1944 #else
1945     /* size of m_size */
1946 # define M_OFFSET (sizeof(short_u))
1947 #endif
1948 
1949 static char_u *u_blockalloc __ARGS((long_u));
1950 
1951 /*
1952  * Allocate a block of memory and link it in the allocated block list.
1953  */
1954     static char_u *
1955 u_blockalloc(size)
1956     long_u	size;
1957 {
1958     mblock_T	*p;
1959     mblock_T	*mp, *next;
1960 
1961     p = (mblock_T *)lalloc(size + sizeof(mblock_T), FALSE);
1962     if (p != NULL)
1963     {
1964 	 /* Insert the block into the allocated block list, keeping it
1965 		    sorted on address. */
1966 	for (mp = &curbuf->b_block_head;
1967 		(next = mp->mb_next) != NULL && next < p;
1968 			mp = next)
1969 	    ;
1970 	p->mb_next = next;		/* link in block list */
1971 	p->mb_size = size;
1972 	p->mb_maxsize = 0;		/* nothing free yet */
1973 	mp->mb_next = p;
1974 	p->mb_info.m_next = NULL;	/* clear free list */
1975 	p->mb_info.m_size = 0;
1976 	curbuf->b_mb_current = p;	/* remember current block */
1977 	curbuf->b_m_search = NULL;
1978 	p++;				/* return usable memory */
1979     }
1980     return (char_u *)p;
1981 }
1982 
1983 /*
1984  * free all allocated memory blocks for the buffer 'buf'
1985  */
1986     void
1987 u_blockfree(buf)
1988     buf_T	*buf;
1989 {
1990     mblock_T	*p, *np;
1991 
1992     for (p = buf->b_block_head.mb_next; p != NULL; p = np)
1993     {
1994 	np = p->mb_next;
1995 	vim_free(p);
1996     }
1997     buf->b_block_head.mb_next = NULL;
1998     buf->b_m_search = NULL;
1999     buf->b_mb_current = NULL;
2000 }
2001 
2002 /*
2003  * Free a chunk of memory for the current buffer.
2004  * Insert the chunk into the correct free list, keeping it sorted on address.
2005  */
2006     static void
2007 u_free_line(ptr, keep)
2008     char_u	*ptr;
2009     int		keep;	/* don't free the block when it's empty */
2010 {
2011     minfo_T	*next;
2012     minfo_T	*prev, *curr;
2013     minfo_T	*mp;
2014     mblock_T	*nextb;
2015     mblock_T	*prevb;
2016     long_u	maxsize;
2017 
2018     if (ptr == NULL || ptr == IObuff)
2019 	return;	/* illegal address can happen in out-of-memory situations */
2020 
2021     mp = (minfo_T *)(ptr - M_OFFSET);
2022 
2023     /* find block where chunk could be a part off */
2024     /* if we change curbuf->b_mb_current, curbuf->b_m_search is set to NULL */
2025     if (curbuf->b_mb_current == NULL || mp < (minfo_T *)curbuf->b_mb_current)
2026     {
2027 	curbuf->b_mb_current = curbuf->b_block_head.mb_next;
2028 	curbuf->b_m_search = NULL;
2029     }
2030     if ((nextb = curbuf->b_mb_current->mb_next) != NULL
2031 						     && (minfo_T *)nextb < mp)
2032     {
2033 	curbuf->b_mb_current = nextb;
2034 	curbuf->b_m_search = NULL;
2035     }
2036     while ((nextb = curbuf->b_mb_current->mb_next) != NULL
2037 						     && (minfo_T *)nextb < mp)
2038 	curbuf->b_mb_current = nextb;
2039 
2040     curr = NULL;
2041     /*
2042      * If mp is smaller than curbuf->b_m_search->m_next go to the start of
2043      * the free list
2044      */
2045     if (curbuf->b_m_search == NULL || mp < (curbuf->b_m_search->m_next))
2046 	next = &(curbuf->b_mb_current->mb_info);
2047     else
2048 	next = curbuf->b_m_search;
2049     /*
2050      * The following loop is executed very often.
2051      * Therefore it has been optimized at the cost of readability.
2052      * Keep it fast!
2053      */
2054 #ifdef SLOW_BUT_EASY_TO_READ
2055     do
2056     {
2057 	prev = curr;
2058 	curr = next;
2059 	next = next->m_next;
2060     }
2061     while (mp > next && next != NULL);
2062 #else
2063     do					    /* first, middle, last */
2064     {
2065 	prev = next->m_next;		    /* curr, next, prev */
2066 	if (prev == NULL || mp <= prev)
2067 	{
2068 	    prev = curr;
2069 	    curr = next;
2070 	    next = next->m_next;
2071 	    break;
2072 	}
2073 	curr = prev->m_next;		    /* next, prev, curr */
2074 	if (curr == NULL || mp <= curr)
2075 	{
2076 	    prev = next;
2077 	    curr = prev->m_next;
2078 	    next = curr->m_next;
2079 	    break;
2080 	}
2081 	next = curr->m_next;		    /* prev, curr, next */
2082     }
2083     while (mp > next && next != NULL);
2084 #endif
2085 
2086     /* if *mp and *next are concatenated, join them into one chunk */
2087     if ((char_u *)mp + mp->m_size == (char_u *)next)
2088     {
2089 	mp->m_size += next->m_size;
2090 	mp->m_next = next->m_next;
2091     }
2092     else
2093 	mp->m_next = next;
2094     maxsize = mp->m_size;
2095 
2096     /* if *curr and *mp are concatenated, join them */
2097     if (prev != NULL && (char_u *)curr + curr->m_size == (char_u *)mp)
2098     {
2099 	curr->m_size += mp->m_size;
2100 	maxsize = curr->m_size;
2101 	curr->m_next = mp->m_next;
2102 	curbuf->b_m_search = prev;
2103     }
2104     else
2105     {
2106 	curr->m_next = mp;
2107 	curbuf->b_m_search = curr;  /* put curbuf->b_m_search before freed
2108 				       chunk */
2109     }
2110 
2111     /*
2112      * If the block only contains free memory now, release it.
2113      */
2114     if (!keep && curbuf->b_mb_current->mb_size
2115 			      == curbuf->b_mb_current->mb_info.m_next->m_size)
2116     {
2117 	/* Find the block before the current one to be able to unlink it from
2118 	 * the list of blocks. */
2119 	prevb = &curbuf->b_block_head;
2120 	for (nextb = prevb->mb_next; nextb != curbuf->b_mb_current;
2121 						       nextb = nextb->mb_next)
2122 	    prevb = nextb;
2123 	prevb->mb_next = nextb->mb_next;
2124 	vim_free(nextb);
2125 	curbuf->b_mb_current = NULL;
2126 	curbuf->b_m_search = NULL;
2127     }
2128     else if (curbuf->b_mb_current->mb_maxsize < maxsize)
2129 	curbuf->b_mb_current->mb_maxsize = maxsize;
2130 }
2131 
2132 /*
2133  * Allocate and initialize a new line structure with room for at least
2134  * 'size' characters plus a terminating NUL.
2135  */
2136     static char_u *
2137 u_alloc_line(size)
2138     unsigned	size;
2139 {
2140     minfo_T	*mp, *mprev, *mp2;
2141     mblock_T	*mbp;
2142     int		size_align;
2143 
2144     /*
2145      * Add room for size field and trailing NUL byte.
2146      * Adjust for minimal size (must be able to store minfo_T
2147      * plus a trailing NUL, so the chunk can be released again)
2148      */
2149     size += M_OFFSET + 1;
2150     if (size < sizeof(minfo_T) + 1)
2151 	size = sizeof(minfo_T) + 1;
2152 
2153     /*
2154      * round size up for alignment
2155      */
2156     size_align = (size + ALIGN_MASK) & ~ALIGN_MASK;
2157 
2158     /*
2159      * If curbuf->b_m_search is NULL (uninitialized free list) start at
2160      * curbuf->b_block_head
2161      */
2162     if (curbuf->b_mb_current == NULL || curbuf->b_m_search == NULL)
2163     {
2164 	curbuf->b_mb_current = &curbuf->b_block_head;
2165 	curbuf->b_m_search = &(curbuf->b_block_head.mb_info);
2166     }
2167 
2168     /* Search for a block with enough space. */
2169     mbp = curbuf->b_mb_current;
2170     while (mbp->mb_maxsize < size_align)
2171     {
2172 	if (mbp->mb_next != NULL)
2173 	    mbp = mbp->mb_next;
2174 	else
2175 	    mbp = &curbuf->b_block_head;
2176 	if (mbp == curbuf->b_mb_current)
2177 	{
2178 	    int	n = (size_align > (MEMBLOCKSIZE / 4)
2179 					     ? size_align : MEMBLOCKSIZE);
2180 
2181 	    /* Back where we started in block list: need to add a new block
2182 	     * with enough space. */
2183 	    mp = (minfo_T *)u_blockalloc((long_u)n);
2184 	    if (mp == NULL)
2185 		return (NULL);
2186 	    mp->m_size = n;
2187 	    u_free_line((char_u *)mp + M_OFFSET, TRUE);
2188 	    mbp = curbuf->b_mb_current;
2189 	    break;
2190 	}
2191     }
2192     if (mbp != curbuf->b_mb_current)
2193 	curbuf->b_m_search = &(mbp->mb_info);
2194 
2195     /* In this block find a chunk with enough space. */
2196     mprev = curbuf->b_m_search;
2197     mp = curbuf->b_m_search->m_next;
2198     for (;;)
2199     {
2200 	if (mp == NULL)			    /* at end of the list */
2201 	    mp = &(mbp->mb_info);	    /* wrap around to begin */
2202 	if (mp->m_size >= size)
2203 	    break;
2204 	if (mp == curbuf->b_m_search)
2205 	{
2206 	    /* back where we started in free chunk list: "cannot happen" */
2207 	    EMSG2(_(e_intern2), "u_alloc_line()");
2208 	    return NULL;
2209 	}
2210 	mprev = mp;
2211 	mp = mp->m_next;
2212     }
2213 
2214     /* when using the largest chunk adjust mb_maxsize */
2215     if (mp->m_size >= mbp->mb_maxsize)
2216 	mbp->mb_maxsize = 0;
2217 
2218     /* if the chunk we found is large enough, split it up in two */
2219     if ((long)mp->m_size - size_align >= (long)(sizeof(minfo_T) + 1))
2220     {
2221 	mp2 = (minfo_T *)((char_u *)mp + size_align);
2222 	mp2->m_size = mp->m_size - size_align;
2223 	mp2->m_next = mp->m_next;
2224 	mprev->m_next = mp2;
2225 	mp->m_size = size_align;
2226     }
2227     else		    /* remove *mp from the free list */
2228     {
2229 	mprev->m_next = mp->m_next;
2230     }
2231     curbuf->b_m_search = mprev;
2232     curbuf->b_mb_current = mbp;
2233 
2234     /* If using the largest chunk need to find the new largest chunk */
2235     if (mbp->mb_maxsize == 0)
2236 	for (mp2 = &(mbp->mb_info); mp2 != NULL; mp2 = mp2->m_next)
2237 	    if (mbp->mb_maxsize < mp2->m_size)
2238 		mbp->mb_maxsize = mp2->m_size;
2239 
2240     mp = (minfo_T *)((char_u *)mp + M_OFFSET);
2241     *(char_u *)mp = NUL;		    /* set the first byte to NUL */
2242 
2243     return ((char_u *)mp);
2244 }
2245 #endif
2246 
2247 /*
2248  * u_save_line(): allocate memory with u_alloc_line() and copy line 'lnum'
2249  * into it.
2250  */
2251     static char_u *
2252 u_save_line(lnum)
2253     linenr_T	lnum;
2254 {
2255     char_u	*src;
2256     char_u	*dst;
2257     unsigned	len;
2258 
2259     src = ml_get(lnum);
2260     len = (unsigned)STRLEN(src);
2261     if ((dst = U_ALLOC_LINE(len)) != NULL)
2262 	mch_memmove(dst, src, (size_t)(len + 1));
2263     return (dst);
2264 }
2265 
2266 /*
2267  * Check if the 'modified' flag is set, or 'ff' has changed (only need to
2268  * check the first character, because it can only be "dos", "unix" or "mac").
2269  * "nofile" and "scratch" type buffers are considered to always be unchanged.
2270  */
2271     int
2272 bufIsChanged(buf)
2273     buf_T	*buf;
2274 {
2275     return
2276 #ifdef FEAT_QUICKFIX
2277 	    !bt_dontwrite(buf) &&
2278 #endif
2279 	    (buf->b_changed || file_ff_differs(buf));
2280 }
2281 
2282     int
2283 curbufIsChanged()
2284 {
2285     return
2286 #ifdef FEAT_QUICKFIX
2287 	!bt_dontwrite(curbuf) &&
2288 #endif
2289 	(curbuf->b_changed || file_ff_differs(curbuf));
2290 }
2291