summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2006-03-16 21:41:35 +0000
committerBram Moolenaar <Bram@vim.org>2006-03-16 21:41:35 +0000
commitefd2bf158afeb2337dcb5a62c6198d6d2fb7cd5f (patch)
treeb1eedda1b33b2b2d3901094c20f4b10362ec2b83
parentd3667a2e2971a879194084f4b61b8ff7ff9765a2 (diff)
updated for version 7.0226
-rw-r--r--runtime/doc/change.txt3
-rw-r--r--runtime/doc/options.txt15
-rw-r--r--runtime/doc/tags3
-rw-r--r--runtime/doc/undo.txt19
-rwxr-xr-xsrc/auto/configure8
-rw-r--r--src/configure.in10
-rw-r--r--src/ex_getln.c66
-rw-r--r--src/misc2.c13
-rw-r--r--src/popupmenu.c15
-rw-r--r--src/regexp.c146
-rw-r--r--src/undo.c159
-rw-r--r--src/version.h4
12 files changed, 357 insertions, 104 deletions
diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt
index e4c5674fa3..408632291f 100644
--- a/runtime/doc/change.txt
+++ b/runtime/doc/change.txt
@@ -1,4 +1,4 @@
-*change.txt* For Vim version 7.0aa. Last change: 2006 Mar 06
+*change.txt* For Vim version 7.0aa. Last change: 2006 Mar 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -728,6 +728,7 @@ Examples: >
:s/\([abc]\)\([efg]\)/\2\1/g modifies "af fa bg" to "fa fa gb"
:s/abcde/abc^Mde/ modifies "abcde" to "abc", "de" (two lines)
:s/$/\^M/ modifies "abcde" to "abcde^M"
+ :s/\w\+/\u\0/g modifies "bla bla" to "Bla Bla"
Note: In previous versions CTRL-V was handled in a special way. Since this is
not Vi compatible, this was removed. Use a backslash instead.
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 7e10b85d46..0cc9b34fb1 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt* For Vim version 7.0aa. Last change: 2006 Mar 15
+*options.txt* For Vim version 7.0aa. Last change: 2006 Mar 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -3768,6 +3768,10 @@ A jump table for the options with a short description can be found at |Q_op|.
cursor to the match.
The highlighting can be set with the 'i' flag in 'highlight'.
See also: 'hlsearch'.
+ CTRL-L can be used to add one character from after the current match
+ to the command line.
+ CTRL-R CTRL-W can be used to add the word at the end of the current
+ match, excluding the characters that were already typed.
NOTE: This option is reset when 'compatible' is set.
*'indentexpr'* *'inde'*
@@ -7182,10 +7186,19 @@ A jump table for the options with a short description can be found at |Q_op|.
block Allow virtual editing in Visual block mode.
insert Allow virtual editing in Insert mode.
all Allow virtual editing in all modes.
+ onemore Allow the cursor to move just past the end of the line
Virtual editing means that the cursor can be positioned where there is
no actual character. This can be halfway into a Tab or beyond the end
of the line. Useful for selecting a rectangle in Visual mode and
editing a table.
+ "onemore" is not the same, it will only allow moving the cursor just
+ after the last character of the line. This makes some commands more
+ consistent. Previously the cursor was always past the end of the line
+ if the line was empty. But it is far from Vi compatible. It may also
+ break some plugins or Vim scripts. For example because |$| moves to a
+ different position. Use with care!
+ It doesn't make sense to combine "all" with "onemore", but you will
+ not get a warning for it.
*'visualbell'* *'vb'* *'novisualbell'* *'novb'* *beep*
'visualbell' 'vb' boolean (default off)
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 3b18a5b901..3734385fc5 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -2740,6 +2740,8 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
:undo undo.txt /*:undo*
:undoj undo.txt /*:undoj*
:undojoin undo.txt /*:undojoin*
+:undol undo.txt /*:undol*
+:undolist undo.txt /*:undolist*
:unh windows.txt /*:unh*
:unhide windows.txt /*:unhide*
:unl eval.txt /*:unl*
@@ -6247,6 +6249,7 @@ new-multi-lang version6.txt /*new-multi-lang*
new-netrw-explore version7.txt /*new-netrw-explore*
new-network-files version6.txt /*new-network-files*
new-omni-completion version7.txt /*new-omni-completion*
+new-onemore version7.txt /*new-onemore*
new-operator-mod version6.txt /*new-operator-mod*
new-options-5.2 version5.txt /*new-options-5.2*
new-options-5.4 version5.txt /*new-options-5.4*
diff --git a/runtime/doc/undo.txt b/runtime/doc/undo.txt
index fdfa71df60..e34d30d59b 100644
--- a/runtime/doc/undo.txt
+++ b/runtime/doc/undo.txt
@@ -1,4 +1,4 @@
-*undo.txt* For Vim version 7.0aa. Last change: 2006 Mar 14
+*undo.txt* For Vim version 7.0aa. Last change: 2006 Mar 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -23,6 +23,9 @@ u Undo [count] changes. {Vi: only one level}
*:u* *:un* *:undo*
:u[ndo] Undo one change. {Vi: only one level}
+:u[ndo] {N} Jump to after change number {N}. See |undo-branches|
+ for the meaning of {N}. {not in Vi}
+
*CTRL-R*
CTRL-R Redo [count] changes which were undone. {Vi: redraw
screen}
@@ -114,6 +117,19 @@ What matters here is the order in which the changes are made. Undo and redo
are not considered changes in this context. After each change you have a new
state of the text.
+ *:undol* *:undolist*
+:undol[ist] List the leafs in the tree of changes. Example:
+ number changes time ~
+ 4 10 10:34:11
+ 18 4 11:01:46
+
+ The "number" column is the change number. This number
+ continuously increases and can be used to identify a
+ specific undo-able change, see |:undo|.
+ The "changes" column is the number of changes to this
+ leaf from the root of the tree.
+ The "time" column is the time this change was made.
+
*g-*
g- Go to older text state. With a count repeat that many
times. {not in Vi}
@@ -132,6 +148,7 @@ g+ Go to newer text state. With a count repeat that many
:later {N}m Go to newer text state about {N} minutes later.
:later {N}h Go to newer text state about {N} hours later.
+
Note that text states will become unreachable when undo information is cleared
for 'undolevels'.
diff --git a/src/auto/configure b/src/auto/configure
index 13cb22610a..3dfa1b6015 100755
--- a/src/auto/configure
+++ b/src/auto/configure
@@ -2838,10 +2838,6 @@ if test "`(uname) 2>/dev/null`" = Darwin; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
- if test x$prefix = xNONE; then
- prefix=/Applications
- fi
-
echo "$as_me:$LINENO: checking --disable-darwin argument" >&5
echo $ECHO_N "checking --disable-darwin argument... $ECHO_C" >&6
# Check whether --enable-darwin or --disable-darwin was given.
@@ -3395,6 +3391,10 @@ fi
if test "x$CARBON" = "xyes"; then
if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk -a "X$enable_gui" != Xgtk2; then
with_x=no
+
+ if test x$prefix = xNONE; then
+ prefix=/Applications
+ fi
fi
fi
fi
diff --git a/src/configure.in b/src/configure.in
index 1797f69c41..3412b95d05 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -85,11 +85,6 @@ AC_MSG_CHECKING([for Darwin (Mac OS X)])
if test "`(uname) 2>/dev/null`" = Darwin; then
AC_MSG_RESULT(yes)
- dnl Default install directory is not /usr/local
- if test x$prefix = xNONE; then
- prefix=/Applications
- fi
-
AC_MSG_CHECKING(--disable-darwin argument)
AC_ARG_ENABLE(darwin,
[ --disable-darwin Disable Darwin (Mac OS X) support.],
@@ -165,6 +160,11 @@ if test "`(uname) 2>/dev/null`" = Darwin; then
if test "x$CARBON" = "xyes"; then
if test -z "$with_x" -a "X$enable_gui" != Xmotif -a "X$enable_gui" != Xathena -a "X$enable_gui" != Xgtk -a "X$enable_gui" != Xgtk2; then
with_x=no
+
+ dnl Default install directory is not /usr/local
+ if test x$prefix = xNONE; then
+ prefix=/Applications
+ fi
fi
fi
fi
diff --git a/src/ex_getln.c b/src/ex_getln.c
index e7fc0be87b..2af0e7ca6b 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -1377,7 +1377,23 @@ getcmdline(firstc, count, indent)
break;
goto cmdline_changed;
- case Ctrl_L: /* longest common part */
+ case Ctrl_L:
+#ifdef FEAT_SEARCH_EXTRA
+ if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
+ {
+ /* Add a character from under the cursor for 'incsearch' */
+ if (did_incsearch
+ && !equalpos(curwin->w_cursor, old_cursor))
+ {
+ c = gchar_cursor();
+ if (c != NUL)
+ break;
+ }
+ goto cmdline_not_changed;
+ }
+#endif
+
+ /* completion: longest common part */
if (nextwild(&xpc, WILD_LONGEST, 0) == FAIL)
break;
goto cmdline_changed;
@@ -1665,6 +1681,8 @@ cmdline_changed:
*/
if (p_is && !cmd_silent && (firstc == '/' || firstc == '?'))
{
+ pos_T end_pos;
+
/* if there is a character waiting, search and redraw later */
if (char_avail())
{
@@ -1696,7 +1714,7 @@ cmdline_changed:
/* cancelled searching because a char was typed */
incsearch_postponed = TRUE;
}
- if (i)
+ if (i != 0)
highlight_match = TRUE; /* highlight position */
else
highlight_match = FALSE; /* remove highlight */
@@ -1717,7 +1735,7 @@ cmdline_changed:
pos_T save_pos = curwin->w_cursor;
/*
- * First move cursor to end of match, then to start. This
+ * First move cursor to end of match, then to the start. This
* moves the whole match onto the screen when 'nowrap' is set.
*/
curwin->w_cursor.lnum += search_match_lines;
@@ -1728,14 +1746,20 @@ cmdline_changed:
coladvance((colnr_T)MAXCOL);
}
validate_cursor();
+ end_pos = curwin->w_cursor;
curwin->w_cursor = save_pos;
}
+
validate_cursor();
save_cmdline(&save_ccline);
update_screen(SOME_VALID);
restore_cmdline(&save_ccline);
+ /* Leave it at the end to make CTRL-R CTRL-W work. */
+ if (i != 0)
+ curwin->w_cursor = end_pos;
+
msg_starthere();
redrawcmdline();
did_incsearch = TRUE;
@@ -2813,6 +2837,7 @@ cmdline_paste(regname, literally)
{
long i;
char_u *arg;
+ char_u *p;
int allocated;
struct cmdline_info save_ccline;
@@ -2845,7 +2870,40 @@ cmdline_paste(regname, literally)
/* Got the value of a special register in "arg". */
if (arg == NULL)
return FAIL;
- cmdline_paste_str(arg, literally);
+
+ /* When 'incsearch' is set and CTRL-R CTRL-W used: skip the duplicate
+ * part of the word. */
+ p = arg;
+ if (p_is && regname == Ctrl_W)
+ {
+ char_u *w;
+ int len;
+
+ /* Locate start of last word in the cmd buffer. */
+ for (w = ccline.cmdbuff + ccline.cmdlen; w > ccline.cmdbuff; )
+ {
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ len = (*mb_head_off)(ccline.cmdbuff, w - 1) + 1;
+ if (!vim_iswordc(mb_ptr2char(w - len)))
+ break;
+ w -= len;
+ }
+ else
+#endif
+ {
+ if (!vim_iswordc(w[-1]))
+ break;
+ --w;
+ }
+ }
+ len = (ccline.cmdbuff + ccline.cmdlen) - w;
+ if (p_ic ? STRNICMP(w, arg, len) == 0 : STRNCMP(w, arg, len) == 0)
+ p += len;
+ }
+
+ cmdline_paste_str(p, literally);
if (allocated)
vim_free(arg);
return OK;
diff --git a/src/misc2.c b/src/misc2.c
index dece0d9680..9c84786a3b 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -151,11 +151,15 @@ coladvance2(pos, addspaces, finetune, wcol)
int head = 0;
#endif
- one_more = (State & INSERT) || restart_edit != NUL
+ one_more = (State & INSERT)
+ || restart_edit != NUL
#ifdef FEAT_VISUAL
- || (VIsual_active && *p_sel != 'o')
+ || (VIsual_active && *p_sel != 'o')
#endif
- ;
+#ifdef FEAT_VIRTUALEDIT
+ || (ve_flags & VE_ONEMORE)
+#endif
+ ;
line = ml_get_curline();
if (wcol >= MAXCOL)
@@ -5486,8 +5490,6 @@ qsort(base, elm_count, elm_size, cmp)
}
#endif
-#if defined(FEAT_EX_EXTRA) || defined(FEAT_CMDL_COMPL) \
- || (defined(FEAT_SYN_HL) && defined(FEAT_MBYTE)) || defined(PROTO)
/*
* Sort an array of strings.
*/
@@ -5515,7 +5517,6 @@ sort_strings(files, count)
{
qsort((void *)files, (size_t)count, sizeof(char_u *), sort_compare);
}
-#endif
#if !defined(NO_EXPANDPATH) || defined(PROTO)
/*
diff --git a/src/popupmenu.c b/src/popupmenu.c
index ca3547cb58..e8ff417320 100644
--- a/src/popupmenu.c
+++ b/src/popupmenu.c
@@ -58,6 +58,7 @@ pum_display(array, size, selected)
int row;
int height;
int col;
+ int above_row = cmdline_row;
redo:
def_width = PUM_DEF_WIDTH;
@@ -80,6 +81,12 @@ redo:
else
top_clear = 0;
+ /* When the preview window is at the bottom stop just above it. Also
+ * avoid drawing over the status line so that it's clear there is a window
+ * boundary. */
+ if (lastwin->w_p_pvw)
+ above_row -= lastwin->w_height + lastwin->w_status_height + 1;
+
/*
* Figure out the size and position of the pum.
*/
@@ -92,8 +99,8 @@ redo:
/* Put the pum below "row" if possible. If there are few lines decide on
* where there is more room. */
- if (row >= cmdline_row - pum_height
- && row > (cmdline_row - top_clear - height) / 2)
+ if (row >= above_row - pum_height
+ && row > (above_row - top_clear - height) / 2)
{
/* pum above "row" */
if (row >= size)
@@ -116,8 +123,8 @@ redo:
{
/* pum below "row" */
pum_row = row + height;
- if (size > cmdline_row - pum_row)
- pum_height = cmdline_row - pum_row;
+ if (size > above_row - pum_row)
+ pum_height = above_row - pum_row;
else
pum_height = size;
if (p_ph > 0 && pum_height > p_ph)
diff --git a/src/regexp.c b/src/regexp.c
index 2ff8ea333b..dd07ea734d 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -6531,53 +6531,53 @@ cstrchr(s, c)
* This is impossible, so we declare a pointer to a function returning a
* pointer to a function returning void. This should work for all compilers.
*/
-typedef void (*(*fptr) __ARGS((char_u *, int)))();
+typedef void (*(*fptr_T) __ARGS((int *, int)))();
-static fptr do_upper __ARGS((char_u *, int));
-static fptr do_Upper __ARGS((char_u *, int));
-static fptr do_lower __ARGS((char_u *, int));
-static fptr do_Lower __ARGS((char_u *, int));
+static fptr_T do_upper __ARGS((int *, int));
+static fptr_T do_Upper __ARGS((int *, int));
+static fptr_T do_lower __ARGS((int *, int));
+static fptr_T do_Lower __ARGS((int *, int));
static int vim_regsub_both __ARGS((char_u *source, char_u *dest, int copy, int magic, int backslash));
- static fptr
+ static fptr_T
do_upper(d, c)
- char_u *d;
- int c;
+ int *d;
+ int c;
{
- *d = TOUPPER_LOC(c);
+ *d = MB_TOUPPER(c);
- return (fptr)NULL;
+ return (fptr_T)NULL;
}
- static fptr
+ static fptr_T
do_Upper(d, c)
- char_u *d;
- int c;
+ int *d;
+ int c;
{
- *d = TOUPPER_LOC(c);
+ *d = MB_TOUPPER(c);
- return (fptr)do_Upper;
+ return (fptr_T)do_Upper;
}
- static fptr
+ static fptr_T
do_lower(d, c)
- char_u *d;
- int c;
+ int *d;
+ int c;
{
- *d = TOLOWER_LOC(c);
+ *d = MB_TOLOWER(c);
- return (fptr)NULL;
+ return (fptr_T)NULL;
}
- static fptr
+ static fptr_T
do_Lower(d, c)
- char_u *d;
+ int *d;
int c;
{
- *d = TOLOWER_LOC(c);
+ *d = MB_TOLOWER(c);
- return (fptr)do_Lower;
+ return (fptr_T)do_Lower;
}
/*
@@ -6587,7 +6587,8 @@ do_Lower(d, c)
* pattern. If that previous pattern also contains a ~ we should go back a
* step further... But we insert the previous pattern into the current one
* and remember that.
- * This still does not handle the case where "magic" changes. TODO?
+ * This still does not handle the case where "magic" changes. So require the
+ * user to keep his hands off of "magic".
*
* The tildes are parsed once before the first call to vim_regsub().
*/
@@ -6729,17 +6730,14 @@ vim_regsub_both(source, dest, copy, magic, backslash)
char_u *dst;
char_u *s;
int c;
+ int cc;
int no = -1;
- fptr func = (fptr)NULL;
+ fptr_T func = (fptr_T)NULL;
linenr_T clnum = 0; /* init for GCC */
int len = 0; /* init for GCC */
#ifdef FEAT_EVAL
static char_u *eval_result = NULL;
#endif
-#ifdef FEAT_MBYTE
- int l;
-#endif
-
/* Be paranoid... */
if (source == NULL || dest == NULL)
@@ -6840,16 +6838,16 @@ vim_regsub_both(source, dest, copy, magic, backslash)
{
switch (*src++)
{
- case 'u': func = (fptr)do_upper;
+ case 'u': func = (fptr_T)do_upper;
continue;
- case 'U': func = (fptr)do_Upper;
+ case 'U': func = (fptr_T)do_Upper;
continue;
- case 'l': func = (fptr)do_lower;
+ case 'l': func = (fptr_T)do_lower;
continue;
- case 'L': func = (fptr)do_Lower;
+ case 'L': func = (fptr_T)do_Lower;
continue;
case 'e':
- case 'E': func = (fptr)NULL;
+ case 'E': func = (fptr_T)NULL;
continue;
}
}
@@ -6882,28 +6880,28 @@ vim_regsub_both(source, dest, copy, magic, backslash)
/* Write to buffer, if copy is set. */
#ifdef FEAT_MBYTE
- if (has_mbyte && (l = (*mb_ptr2len)(src - 1)) > 1)
+ if (has_mbyte)
+ c = mb_ptr2char(src - 1);
+#endif
+
+ if (func == (fptr_T)NULL) /* just copy */
+ cc = c;
+ else
+ /* Turbo C complains without the typecast */
+ func = (fptr_T)(func(&cc, c));
+
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
{
- /* TODO: should use "func" here. */
+ src += mb_ptr2len(src - 1) - 1;
if (copy)
- mch_memmove(dst, src - 1, l);
- dst += l - 1;
- src += l - 1;
+ mb_char2bytes(cc, dst);
+ dst += mb_char2len(cc) - 1;
}
else
- {
#endif
if (copy)
- {
- if (func == (fptr)NULL) /* just copy */
- *dst = c;
- else /* change case */
- func = (fptr)(func(dst, c));
- /* Turbo C complains without the typecast */
- }
-#ifdef FEAT_MBYTE
- }
-#endif
+ *dst = cc;
dst++;
}
else
@@ -6976,29 +6974,39 @@ vim_regsub_both(source, dest, copy, magic, backslash)
}
dst += 2;
}
-#ifdef FEAT_MBYTE
- else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1)
- {
- /* TODO: should use "func" here. */
- if (copy)
- mch_memmove(dst, s, l);
- dst += l;
- s += l - 1;
- len -= l - 1;
- }
-#endif
else
{
- if (copy)
- {
- if (func == (fptr)NULL) /* just copy */
- *dst = *s;
- else /* change case */
- func = (fptr)(func(dst, *s));
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ c = mb_ptr2char(s);
+ else
+#endif
+ c = *s;
+
+ if (func == (fptr_T)NULL) /* just copy */
+ cc = c;
+ else
/* Turbo C complains without the typecast */
+ func = (fptr_T)(func(&cc, c));
+
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ int l = mb_ptr2len(s) - 1;
+
+ s += l;
+ len -= l;
+ if (copy)
+ mb_char2bytes(cc, dst);
+ dst += mb_char2len(cc) - 1;
}
- ++dst;
+ else
+#endif
+ if (copy)
+ *dst = cc;
+ dst++;
}
+
++s;
--len;
}
diff --git a/src/undo.c b/src/undo.c
index 27f04b92e5..330915df01 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -89,6 +89,7 @@ static int u_savecommon __ARGS((linenr_T, linenr_T, linenr_T));
static void u_doit __ARGS((int count));
static void u_undoredo __ARGS((void));
static void u_undo_end __ARGS((void));
+static void u_add_time __ARGS((char_u *buf, size_t buflen, time_t tt));
static void u_freeheader __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
static void u_freebranch __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
static void u_freeentries __ARGS((buf_T *buf, u_header_T *uhp, u_header_T **uhpp));
@@ -637,11 +638,14 @@ static int lastmark = 0;
* When "step" is negative go back in time, otherwise goes forward in time.
* When "sec" is FALSE make "step" steps, when "sec" is TRUE use "step" as
* seconds.
+ * When "absolute" is TRUE use "step" as the sequence number to jump to.
+ * "sec" must be FALSE then.
*/
void
-undo_time(step, sec)
+undo_time(step, sec, absolute)
long step;
int sec;
+ int absolute;
{
long target;
long closest;
@@ -668,7 +672,12 @@ undo_time(step, sec)
/* "target" is the node below which we want to be. When going forward
* the current one also counts, thus do one less. */
- if (step < 0)
+ if (absolute)
+ {
+ target = step;
+ closest = -2;
+ }
+ else if (step < 0)
{
if (sec)
target = (long)curbuf->b_u_seq_time + step;
@@ -787,6 +796,13 @@ undo_time(step, sec)
if (uhp != NULL) /* found it */
break;
+
+ if (absolute)
+ {
+ EMSGN(_("Undo number %ld not found"), step);
+ return;
+ }
+
if (closest == closest_start)
{
if (step < 0)
@@ -1152,8 +1168,9 @@ u_undoredo()
static void
u_undo_end()
{
- long sec;
char *msg;
+ u_header_T *uhp;
+ char_u msgbuf[80];
#ifdef FEAT_FOLDING
if ((fdo_flags & FDO_UNDO) && KeyTyped)
@@ -1185,12 +1202,18 @@ u_undo_end()
msg = N_("changes");
}
- if (curbuf->b_u_curhead == 0)
- sec = 0;
+ if (curbuf->b_u_curhead != NULL)
+ uhp = curbuf->b_u_curhead;
+ else
+ uhp = curbuf->b_u_newhead;
+
+ if (uhp == NULL)
+ *msgbuf = NUL;
else
- sec = time(NULL) - curbuf->b_u_curhead->uh_time;
+ u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time);
- smsg((char_u *)_("%ld %s; %ld seconds ago"), u_oldcount, _(msg), sec);
+ smsg((char_u *)_("%ld %s; #%ld %s"), u_oldcount, _(msg),
+ uhp == NULL ? 0L : uhp->uh_seq, msgbuf);
}
/*
@@ -1215,6 +1238,128 @@ u_sync()
}
/*
+ * ":undolist": List the leafs of the undo tree
+ */
+/*ARGSUSED*/
+ void
+ex_undolist(eap)
+ exarg_T *eap;
+{
+ garray_T ga;
+ u_header_T *uhp;
+ int mark;
+ int nomark;
+ int changes = 1;
+ int i;
+
+ /*
+ * 1: walk the tree to find all leafs, put the info in "ga".
+ * 2: sort the lines
+ * 3: display the list
+ */
+ mark = ++lastmark;
+ nomark = ++lastmark;
+ ga_init2(&ga, (int)sizeof(char *), 20);
+
+ uhp = curbuf->b_u_oldhead;
+ while (uhp != NULL)
+ {
+ if (uhp->uh_prev == NULL)
+ {
+ if (ga_grow(&ga, 1) == FAIL)
+ break;
+ vim_snprintf((char *)IObuff, IOSIZE, "%6ld %7ld ",
+ uhp->uh_seq, changes);
+ u_add_time(IObuff + STRLEN(IObuff), IOSIZE - STRLEN(IObuff),
+ uhp->uh_time);
+ ((char_u **)(ga.ga_data))[ga.ga_len++] = vim_strsave(IObuff);
+ }
+
+ uhp->uh_walk = mark;
+
+ /* go down in the tree if we haven't been there */
+ if (uhp->uh_prev != NULL && uhp->uh_prev->uh_walk != nomark
+ && uhp->uh_prev->uh_walk != mark)
+ {
+ uhp = uhp->uh_prev;
+ ++changes;
+ }
+
+ /* go to alternate branch if we haven't been there */
+ else if (uhp->uh_alt_next != NULL
+ && uhp->uh_alt_next->uh_walk != nomark
+ && uhp->uh_alt_next->uh_walk != mark)
+ uhp = uhp->uh_alt_next;
+
+ /* go up in the tree if we haven't been there and we are at the
+ * start of alternate branches */
+ else if (uhp->uh_next != NULL && uhp->uh_alt_prev == NULL
+ && uhp->uh_next->uh_walk != nomark
+ && uhp->uh_next->uh_walk != mark)
+ {
+ uhp = uhp->uh_next;
+ --changes;
+ }
+
+ else
+ {
+ /* need to backtrack; mark this node as done */
+ uhp->uh_walk = nomark;
+ if (uhp->uh_alt_prev != NULL)
+ uhp = uhp->uh_alt_prev;
+ else
+ {
+ uhp = uhp->uh_next;
+ --changes;
+ }
+ }
+ }
+
+ if (ga.ga_len == 0)
+ MSG(_("Nothing to undo"));
+ else
+ {
+ sort_strings((char_u **)ga.ga_data, ga.ga_len);
+
+ msg_start();
+ msg_puts_attr((char_u *)_("number changes time"), hl_attr(HLF_T));
+ for (i = 0; i < ga.ga_len && !got_int; ++i)
+ {
+ msg_putchar('\n');
+ if (got_int)
+ break;
+ msg_puts(((char_u **)ga.ga_data)[i]);
+ }
+ msg_end();
+
+ ga_clear_strings(&ga);
+ }
+}
+
+/*
+ * Put the timestamp of an undo header in "buf[buflen]" in a nice format.
+ */
+ static void
+u_add_time(buf, buflen, tt)
+ char_u *buf;
+ size_t buflen;
+ time_t tt;
+{
+#ifdef HAVE_STRFTIME
+ struct tm *curtime;
+
+ if (time(NULL) - tt >= 100)
+ {
+ curtime = localtime(&tt);
+ (void)strftime((char *)buf, buflen, "%T", curtime);
+ }
+ else
+#endif
+ vim_snprintf((char *)buf, buflen, "%ld seconds ago",
+ (long)(time(NULL) - tt));
+}
+
+/*
* ":undojoin": continue adding to the last entry list
*/
/*ARGSUSED*/
diff --git a/src/version.h b/src/version.h
index 774222d07d..19333f2379 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
#define VIM_VERSION_NODOT "vim70aa"
#define VIM_VERSION_SHORT "7.0aa"
#define VIM_VERSION_MEDIUM "7.0aa ALPHA"
-#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 15)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 15, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 16)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 16, compiled "