# HG changeset patch # User vimboss # Date 1142637578 0 # Node ID f664cc974a7a4037e8153481eade356938c24b32 # Parent 5a5a080c2776a85358c19fe319bce7246ce2344f updated for version 7.0227 diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 7.0aa. Last change: 2006 Mar 10 +*eval.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1510,6 +1510,7 @@ byte2line( {byte}) Number line number a byteidx( {expr}, {nr}) Number byte index of {nr}'th char in {expr} call( {func}, {arglist} [, {dict}]) any call {func} with arguments {arglist} +changenr() Number current change number char2nr( {expr}) Number ASCII value of first char in {expr} cindent( {lnum}) Number C indent for line {lnum} col( {expr}) Number column nr of cursor or mark @@ -1914,6 +1915,14 @@ call({func}, {arglist} [, {dict}]) *ca {dict} is for functions with the "dict" attribute. It will be used to set the local variable "self". |Dictionary-function| +changenr() *changenr()* + Return the number of the most recent change. This is the same + number as what is displayed with |:undolist| and can be used + with the |:undo| command. + When a change was made it is the number of that change. After + redo it is the number of the redone change. After undo it is + one less than the number of the undone change. + char2nr({expr}) *char2nr()* Return number value of the first char in {expr}. Examples: > char2nr(" ") returns 32 @@ -5574,9 +5583,11 @@ 7. Commands *expression-commands* :let {var-name} .. List the value of variable {var-name}. Multiple variable names may be given. Special names recognized here: *E738* - g: global variables. - b: local buffer variables. - w: local window variables. + g: global variables + b: local buffer variables + w: local window variables + s: script-local variables + l: local function variables v: Vim variables. :let List the values of all variables. The type of the diff --git a/runtime/doc/help.txt b/runtime/doc/help.txt --- a/runtime/doc/help.txt +++ b/runtime/doc/help.txt @@ -1,4 +1,4 @@ -*help.txt* For Vim version 7.0aa. Last change: 2006 Feb 27 +*help.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM - main help file k @@ -84,7 +84,7 @@ Making Vim Run ~ |usr_90.txt| Installing Vim -REFERENCE MANUAL: These files explain every detail of Vim. +REFERENCE MANUAL: These files explain every detail of Vim. *ref-toc* General subjects ~ |intro.txt| general introduction to Vim; notation used in help files @@ -194,6 +194,13 @@ Standard plugins ~ |pi_zip.txt| Zip archive explorer LOCAL ADDITIONS: *local-additions* +|cecutil.txt| DrChip's Utilities Jun 11, 2004 +|engspchk.txt| English Spelling Checker (v61) Mar 14, 2005 +|example.txt| Example for a locally added help file +|matchit.txt| Extended "%" matching +|test.txt| Testing the hélp cömmånd nôw +|typecorr.txt| Plugin for correcting typing mistakes +|helpp.txt| Dummy line to avoid an error message ------------------------------------------------------------------------------ *bars* Bars example diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt --- 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 16 +*options.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -2557,6 +2557,9 @@ A jump table for the options with a shor environment. This is the default value for 'encoding'. It is useful when 'encoding' is set to "utf-8" and your environment uses a non-latin1 encoding, such as Russian. + When 'encoding' is "utf-8" and a file contains an illegal byte + sequence it won't be recognized as UTF-8. You can use the |8g8| + command to find the illegal byte sequence. WRONG VALUES: WHAT'S WRONG: latin1,utf-8 "latin1" will always be used utf-8,ucs-bom,latin1 BOM won't be recognized in an utf-8 diff --git a/runtime/doc/tags b/runtime/doc/tags --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -1647,6 +1647,7 @@ 45.3 usr_45.txt /*45.3* 45.4 usr_45.txt /*45.4* 45.5 usr_45.txt /*45.5* 755 spell.txt /*755* +8g8 various.txt /*8g8* 90.1 usr_90.txt /*90.1* 90.2 usr_90.txt /*90.2* 90.3 usr_90.txt /*90.3* @@ -4602,6 +4603,7 @@ changed-6.3 version6.txt /*changed-6.3* changed-6.4 version6.txt /*changed-6.4* changelist motion.txt /*changelist* changelog.vim syntax.txt /*changelog.vim* +changenr() eval.txt /*changenr()* changetick eval.txt /*changetick* changing change.txt /*changing* char2nr() eval.txt /*char2nr()* @@ -6522,6 +6524,7 @@ recursive_mapping map.txt /*recursive_ma redo undo.txt /*redo* redo-register undo.txt /*redo-register* ref intro.txt /*ref* +ref-toc help.txt /*ref-toc* reference intro.txt /*reference* regexp pattern.txt /*regexp* regexp-changes-5.4 version5.txt /*regexp-changes-5.4* diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 7.0aa. Last change: 2006 Mar 16 +*todo.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -44,13 +44,9 @@ 8 Add patch from Muraoka Taro (Mar 16) EMBEDDING: Make it possible to run Vim inside a window of another program. For GTK Neil Bird has a patch to use Vim like a widget. -Win32: Patch for Korean IME. (Yusung, 2005 March 21) - Support ":set syntax=cpp.doxygen"? Suggested patch by Michael Geddes (9 Aug 2004). Should also work for 'filetype'. -Add command to search for illegal utf-8 byte sequence. - Add strtol() to avoid the problems with leading zero causing octal conversion. Add a 'tool' window: behaves like a preview window but there can be several. diff --git a/runtime/doc/usr_toc.txt b/runtime/doc/usr_toc.txt --- a/runtime/doc/usr_toc.txt +++ b/runtime/doc/usr_toc.txt @@ -1,4 +1,4 @@ -*usr_toc.txt* For Vim version 7.0aa. Last change: 2005 Feb 22 +*usr_toc.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM USER MANUAL - by Bram Moolenaar @@ -47,6 +47,8 @@ Making Vim Run |usr_90.txt| Installing Vim +More detailed information in the reference manual: |ref-toc| + The user manual is available as a single, ready to print HTML and PDF file here: http://vimdoc.sf.net diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -1,4 +1,4 @@ -*various.txt* For Vim version 7.0aa. Last change: 2006 Mar 05 +*various.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -66,7 +66,24 @@ g8 Print the hex values of the bytes u value of 'maxcombine' doesn't matter. Example of a character with two composing characters: e0 b8 81 + e0 b8 b9 + e0 b9 89 ~ - {not in Vi} + {not in Vi} {only when compiled with the |+multi_byte| + feature} + + *8g8* +8g8 Find an illegal UTF-8 byte sequence at or after the + cursor. This works in two situations: + 1. when 'encoding' is any 8-bit encoding + 2. when 'encoding' is "utf-8" and 'fileencoding' is + any 8-bit encoding + Thus it can be used when editing a file that was + supposed to be UTF-8 but was read as if it is an 8-bit + encoding because it contains illegal bytes. + Does not wrap around the end of the file. + Note that when the cursor is on an illegal byte or the + cursor is halfway a multi-byte character the command + won't move the cursor. + {not in Vi} {only when compiled with the |+multi_byte| + feature} *:p* *:pr* *:print* :[range]p[rint] [flags] diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -1,4 +1,4 @@ -*version7.txt* For Vim version 7.0aa. Last change: 2006 Mar 16 +*version7.txt* For Vim version 7.0aa. Last change: 2006 Mar 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -285,7 +285,8 @@ was about ten minutes earlier. The |:undolist| command can be used to get an idea of which undo branches exist. The |:undo| command now takes an argument to directly jump to a -specific position in this list. +specific position in this list. The |changenr()| function can be used to +obtain the change number. There is no graphical display of the tree with changes, navigation can be quite confusing. @@ -307,6 +308,8 @@ compile time. For pattern matching it is now possible to search for individual composing characters. |patterns-composing| +The |8g8| command searches for an illegal UTF-8 byte sequence. + More highlighting *new-more-highlighting* ----------------- @@ -2006,4 +2009,8 @@ E.g., when using ":match" to highlight a Added SOME_VALID: Redraw the whole window but also try to scroll to minimize redrawing. +Win32: When using Korean IME making it active didn't work properly. (Moon, +Yu-sung, 2005 March 21) + + vim:tw=78:ts=8:ft=help:norl: diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -1504,6 +1504,9 @@ EXTERN char bot_top_msg[] INIT(= N_("sea EXTERN int xsmp_icefd INIT(= -1); /* The actual connection */ #endif +/* For undo we need to know the lowest time possible. */ +EXTERN time_t starttime; + /* * Optional Farsi support. Include it here, so EXTERN and INIT are defined. */ diff --git a/src/gui_w32.c b/src/gui_w32.c --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -323,6 +323,7 @@ static BOOL (WINAPI *pImmGetCompositionF static BOOL (WINAPI *pImmSetCompositionFont)(HIMC, LPLOGFONTA); static BOOL (WINAPI *pImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM); static BOOL (WINAPI *pImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD); +static BOOL (WINAPI *pImmSetConversionStatus)(HIMC, DWORD, DWORD); static void dyn_imm_load(void); #else # define pImmGetCompositionStringA ImmGetCompositionStringA @@ -336,6 +337,7 @@ static void dyn_imm_load(void); # define pImmSetCompositionFont ImmSetCompositionFontA # define pImmSetCompositionWindow ImmSetCompositionWindow # define pImmGetConversionStatus ImmGetConversionStatus +# define pImmSetConversionStatus ImmSetConversionStatus #endif #ifndef ETO_IGNORELANGUAGE @@ -1714,6 +1716,39 @@ im_set_active(int active) hImc = pImmGetContext(s_hwnd); if (hImc) { + /* + * for Korean ime + */ + HKL hKL = GetKeyboardLayout(0); + + if (LOWORD(hKL) == MAKELANGID(LANG_KOREAN, SUBLANG_KOREAN)) + { + static DWORD dwConversionSaved = 0, dwSentenceSaved = 0; + static BOOL bSaved = FALSE; + + if (active) + { + /* if we have a saved conversion status, restore it */ + if (bSaved) + pImmSetConversionStatus(hImc, dwConversionSaved, + dwSentenceSaved); + bSaved = FALSE; + } + else + { + /* save conversion status and disable korean */ + if (pImmGetConversionStatus(hImc, &dwConversionSaved, + &dwSentenceSaved)) + { + bSaved = TRUE; + pImmSetConversionStatus(hImc, + dwConversionSaved & ~(IME_CMODE_NATIVE + | IME_CMODE_FULLSHAPE), + dwSentenceSaved); + } + } + } + pImmSetOpenStatus(hImc, active); pImmReleaseContext(s_hwnd, hImc); } @@ -1785,7 +1820,7 @@ latin9_to_ucs(char_u *text, int len, WCH { int c; - while (len-- >= 0) + while (--len >= 0) { c = *text++; switch (c) @@ -2021,28 +2056,28 @@ gui_mch_draw_string( { /* Output UTF-8 characters. Caller has already separated * composing characters. */ - int i = 0; - int clen; /* string length up to composing char */ + int i; + int wlen; /* string length in words */ + int clen; /* string length in characters */ int cells; /* cell width of string up to composing char */ int cw; /* width of current cell */ int c; - int xtra; - + + wlen = 0 + clen = 0; cells = 0; - for (clen = 0; i < len; ) + for (i = 0; i < len; ) { c = utf_ptr2char(text + i); if (c >= 0x10000) { /* Turn into UTF-16 encoding. */ - unicodebuf[clen] = ((c - 0x10000) >> 10) + 0xD800; - unicodebuf[clen + 1] = ((c - 0x10000) & 0x3ff) + 0xDC00; - xtra = 1; + unicodebuf[wlen++] = ((c - 0x10000) >> 10) + 0xD800; + unicodebuf[wlen++] = ((c - 0x10000) & 0x3ff) + 0xDC00; } else { - unicodebuf[clen] = c; - xtra = 0; + unicodebuf[wlen++] = c; } cw = utf_char2cells(c); if (cw > 2) /* don't use 4 for unprintable char */ @@ -2053,15 +2088,13 @@ gui_mch_draw_string( * when the font uses different widths (e.g., bold character * is wider). */ unicodepdy[clen] = cw * gui.char_width; - if (xtra == 1) - unicodepdy[clen + 1] = cw * gui.char_width; } cells += cw; i += utfc_ptr2len_len(text + i, len - i); - clen += xtra + 1; + ++clen; } ExtTextOutW(s_hdc, TEXT_X(col), TEXT_Y(row), - foptions, pcliprect, unicodebuf, clen, unicodepdy); + foptions, pcliprect, unicodebuf, wlen, unicodepdy); len = cells; /* used for underlining */ } else if ((enc_codepage > 0 && (int)GetACP() != enc_codepage) || enc_latin9) @@ -3894,6 +3927,8 @@ dyn_imm_load(void) = (void *)GetProcAddress(hLibImm, "ImmSetCompositionWindow"); pImmGetConversionStatus = (void *)GetProcAddress(hLibImm, "ImmGetConversionStatus"); + pImmSetConversionStatus + = (void *)GetProcAddress(hLibImm, "ImmSetConversionStatus"); if ( pImmGetCompositionStringA == NULL || pImmGetCompositionStringW == NULL @@ -3905,7 +3940,8 @@ dyn_imm_load(void) || pImmGetCompositionFont == NULL || pImmSetCompositionFont == NULL || pImmSetCompositionWindow == NULL - || pImmGetConversionStatus == NULL) + || pImmGetConversionStatus == NULL + || pImmSetConversionStatus == NULL) { FreeLibrary(hLibImm); hLibImm = NULL; diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -208,6 +208,7 @@ main time_fd = mch_fopen(STARTUPTIME, "a"); TIME_MSG("--- VIM STARTING ---"); #endif + starttime = time(NULL); #ifdef __EMX__ _wildcard(¶ms.argc, ¶ms.argv); diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -2147,9 +2147,9 @@ del_chars(count, fixpos) */ /*ARGSUSED*/ int -del_bytes(count, fixpos, use_delcombine) +del_bytes(count, fixpos_arg, use_delcombine) long count; - int fixpos; + int fixpos_arg; int use_delcombine; /* 'delcombine' option applies */ { char_u *oldp, *newp; @@ -2158,6 +2158,7 @@ del_bytes(count, fixpos, use_delcombine) colnr_T col = curwin->w_cursor.col; int was_alloced; long movelen; + int fixpos = fixpos_arg; oldp = ml_get(lnum); oldlen = (int)STRLEN(oldp); @@ -2201,9 +2202,14 @@ del_bytes(count, fixpos, use_delcombine) { /* * If we just took off the last character of a non-blank line, and - * fixpos is TRUE, we don't want to end up positioned at the NUL. + * fixpos is TRUE, we don't want to end up positioned at the NUL, + * unless "restart_edit" is set or 'virtualedit' contains "onemore". */ - if (col > 0 && fixpos) + if (col > 0 && fixpos && restart_edit == 0 +#ifdef FEAT_VIRTUALEDIT + && (ve_flags & VE_ONEMORE) == 0 +#endif + ) { --curwin->w_cursor.col; #ifdef FEAT_VIRTUALEDIT diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -1843,8 +1843,7 @@ op_delete(oap) curwin->w_cursor.coladd = 0; } #endif - (void)del_bytes((long)n, restart_edit == NUL && !virtual_op, - oap->op_type == OP_DELETE + (void)del_bytes((long)n, !virtual_op, oap->op_type == OP_DELETE #ifdef FEAT_VISUAL && !oap->is_VIsual #endif @@ -1868,8 +1867,7 @@ op_delete(oap) /* delete from start of line until op_end */ curwin->w_cursor.col = 0; (void)del_bytes((long)(oap->end.col + 1 - !oap->inclusive), - restart_edit == NUL && !virtual_op, - oap->op_type == OP_DELETE + !virtual_op, oap->op_type == OP_DELETE #ifdef FEAT_VISUAL && !oap->is_VIsual #endif diff --git a/src/proto/mbyte.pro b/src/proto/mbyte.pro --- a/src/proto/mbyte.pro +++ b/src/proto/mbyte.pro @@ -49,6 +49,7 @@ int utf_head_off __ARGS((char_u *base, c void mb_copy_char __ARGS((char_u **fp, char_u **tp)); int mb_off_next __ARGS((char_u *base, char_u *p)); int mb_tail_off __ARGS((char_u *base, char_u *p)); +void utf_find_illegal __ARGS((void)); int utf_valid_string __ARGS((char_u *s, char_u *end)); int dbcs_screen_tail_off __ARGS((char_u *base, char_u *p)); void mb_adjust_cursor __ARGS((void)); diff --git a/src/screen.c b/src/screen.c --- a/src/screen.c +++ b/src/screen.c @@ -4296,7 +4296,7 @@ win_line(wp, lnum, startrow, endrow, noc ScreenLinesUC[off] = 0; #endif ++col; - if (vcol == wp->w_virtcol) + if (vcol == (long)wp->w_virtcol) { ScreenAttrs[off] = hl_attr(HLF_CUC); break; @@ -4360,7 +4360,7 @@ win_line(wp, lnum, startrow, endrow, noc #ifdef FEAT_SYN_HL /* Highlight the cursor column if 'cursorcolumn' is set. But don't * highlight the cursor position itself. */ - if (wp->w_p_cuc && vcol == wp->w_virtcol + if (wp->w_p_cuc && vcol == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum && draw_state == WL_LINE) { diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1254,11 +1254,9 @@ struct file_buffer u_header_T *b_u_curhead; /* pointer to current header */ int b_u_numhead; /* current number of headers */ int b_u_synced; /* entry lists are synced */ - long b_u_seq_last; /* last used undo sequence number plus 1 */ - long b_u_seq_cur; /* undo sequence number of last header used - plus 1 */ - time_t b_u_seq_time; /* uh_time of the last header used plus 1 or - uh_time of current header */ + long b_u_seq_last; /* last used undo sequence number */ + long b_u_seq_cur; /* hu_seq of header below which we are now */ + time_t b_u_seq_time; /* uh_time of header below which we are now */ /* * variables for "U" command in undo.c diff --git a/src/undo.c b/src/undo.c --- a/src/undo.c +++ b/src/undo.c @@ -87,7 +87,7 @@ static void u_getbot __ARGS((void)); static int undo_allowed __ARGS((void)); 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_undoredo __ARGS((int undo)); 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)); @@ -350,8 +350,8 @@ u_savecommon(top, bot, newbot) if (curbuf->b_u_newhead != NULL) curbuf->b_u_newhead->uh_prev = uhp; - uhp->uh_seq = curbuf->b_u_seq_last++; - curbuf->b_u_seq_cur = curbuf->b_u_seq_last; + uhp->uh_seq = ++curbuf->b_u_seq_last; + curbuf->b_u_seq_cur = uhp->uh_seq; uhp->uh_time = time(NULL); curbuf->b_u_seq_time = uhp->uh_time + 1; @@ -579,9 +579,11 @@ u_redo(count) * Undo or redo, depending on 'undo_undoes', 'count' times. */ static void -u_doit(count) - int count; +u_doit(startcount) + int startcount; { + int count = startcount; + if (!undo_allowed()) return; @@ -604,22 +606,30 @@ u_doit(count) /* stick curbuf->b_u_curhead at end */ curbuf->b_u_curhead = curbuf->b_u_oldhead; beep_flush(); + if (count == startcount - 1) + { + MSG(_("Already at oldest change")); + return; + } break; } - u_undoredo(); + u_undoredo(TRUE); } else { if (curbuf->b_u_curhead == NULL || p_ul <= 0) { beep_flush(); /* nothing to redo */ + if (count == startcount - 1) + { + MSG(_("Already at newest change")); + return; + } break; } - u_undoredo(); - ++curbuf->b_u_seq_cur; - ++curbuf->b_u_seq_time; + u_undoredo(FALSE); /* Advance for next redo. Set "newhead" when at the end of the * redoable changes. */ @@ -652,7 +662,6 @@ undo_time(step, sec, absolute) long closest_start; long closest_seq = 0; long val; - long limit; u_header_T *uhp; u_header_T *last; int mark; @@ -670,43 +679,39 @@ undo_time(step, sec, absolute) if (curbuf->b_ml.ml_flags & ML_EMPTY) u_oldcount = -1; - /* "target" is the node below which we want to be. When going forward - * the current one also counts, thus do one less. */ + /* "target" is the node below which we want to be. + * Init "closest" to a value we can't reach. */ if (absolute) { target = step; - closest = -2; - } - else if (step < 0) - { - if (sec) - target = (long)curbuf->b_u_seq_time + step; - else - target = curbuf->b_u_seq_cur + step; - if (target < 0) - target = -1; - closest = -2; + closest = -1; } else { + /* When doing computations with time_t subtract starttime, because + * time_t converted to a long may result in a wrong number. */ if (sec) + target = (long)(curbuf->b_u_seq_time - starttime) + step; + else + target = curbuf->b_u_seq_cur + step; + if (step < 0) { - target = curbuf->b_u_seq_time + step - 1; - closest = time(NULL) + 1; + if (target < 0) + target = 0; + closest = -1; } else { - target = curbuf->b_u_seq_cur + step - 1; - closest = curbuf->b_u_seq_last + 1; + if (sec) + closest = time(NULL) - starttime + 1; + else + closest = curbuf->b_u_seq_last + 2; + if (target >= closest) + target = closest - 1; } - if (target >= closest) - target = closest - 1; } closest_start = closest; - if (sec) - limit = curbuf->b_u_seq_time + (step > 0 ? -1 : 1); - else - limit = curbuf->b_u_seq_cur; + closest_seq = curbuf->b_u_seq_cur; /* * May do this twice: @@ -733,27 +738,28 @@ undo_time(step, sec, absolute) while (uhp != NULL) { uhp->uh_walk = mark; - val = (dosec ? uhp->uh_time : uhp->uh_seq); + val = (dosec ? (uhp->uh_time - starttime) : uhp->uh_seq); if (round == 1) { /* Remember the header that is closest to the target. * It must be at least in the right direction (checked with - * "limit"). When the timestamp is equal find the + * "b_u_seq_cur"). When the timestamp is equal find the * highest/lowest sequence number. */ - if ((dosec && val == closest) - ? (step < 0 - ? uhp->uh_seq < closest_seq - : uhp->uh_seq > closest_seq) - : (step < 0 - ? (val < limit - && (closest > target - ? (val <= closest) - : (val >= closest))) - : (val > limit - && (closest < target - ? val >= closest - : val <= closest)))) + if ((step < 0 ? uhp->uh_seq <= curbuf->b_u_seq_cur + : uhp->uh_seq > curbuf->b_u_seq_cur) + && ((dosec && val == closest) + ? (step < 0 + ? uhp->uh_seq < closest_seq + : uhp->uh_seq > closest_seq) + : closest == closest_start + || (val > target + ? (closest > target + ? val - target <= closest - target + : val - target <= target - closest) + : (closest > target + ? target - val <= closest - target + : target - val <= target - closest)))) { closest = val; closest_seq = uhp->uh_seq; @@ -830,19 +836,12 @@ undo_time(step, sec, absolute) if (uhp == NULL) uhp = curbuf->b_u_newhead; else - { - while (uhp->uh_alt_prev != NULL - && uhp->uh_alt_prev->uh_walk == mark) - { - uhp->uh_walk = nomark; - uhp = uhp->uh_alt_prev; - } uhp = uhp->uh_next; - } - if (uhp == NULL || uhp->uh_walk != mark) + if (uhp == NULL || uhp->uh_walk != mark + || (uhp->uh_seq == target && !above)) break; curbuf->b_u_curhead = uhp; - u_undoredo(); + u_undoredo(TRUE); uhp->uh_walk = nomark; /* don't go back down here */ } @@ -850,7 +849,7 @@ undo_time(step, sec, absolute) * And now go down the tree (redo), branching off where needed. */ uhp = curbuf->b_u_curhead; - for (;;) + while (uhp != NULL) { /* Find the last branch with a mark, that's the one. */ last = uhp; @@ -869,10 +868,10 @@ undo_time(step, sec, absolute) uhp->uh_alt_prev = last; uhp = last; + if (uhp->uh_next != NULL) + uhp->uh_next->uh_prev = uhp; } curbuf->b_u_curhead = uhp; - curbuf->b_u_seq_cur = uhp->uh_seq; - curbuf->b_u_seq_time = uhp->uh_time; if (uhp->uh_walk != mark) break; /* must have reached the target */ @@ -882,9 +881,7 @@ undo_time(step, sec, absolute) if (uhp->uh_seq == target && above) break; - u_undoredo(); - ++curbuf->b_u_seq_cur; - ++curbuf->b_u_seq_time; + u_undoredo(FALSE); /* Advance "curhead" to below the header we last used. If it * becomes NULL then we need to set "newhead" to this leaf. */ @@ -898,6 +895,7 @@ undo_time(step, sec, absolute) uhp = uhp->uh_prev; if (uhp == NULL || uhp->uh_walk != mark) { + /* Need to redo more but can't find it... */ EMSG2(_(e_intern2), "undo_time()"); break; } @@ -912,9 +910,12 @@ undo_time(step, sec, absolute) * The lines in the file are replaced by the lines in the entry list at * curbuf->b_u_curhead. The replaced lines in the file are saved in the entry * list for the next undo/redo. + * + * When "undo" is TRUE we go up in the tree, when FALSE we go down. */ static void -u_undoredo() +u_undoredo(undo) + int undo; { char_u **newarray = NULL; linenr_T oldsize; @@ -1157,6 +1158,13 @@ u_undoredo() /* Remember where we are for "g-" and ":earlier 10s". */ curbuf->b_u_seq_cur = curhead->uh_seq; + if (undo) + /* We are below the previous undo. However, to make ":earlier 1s" + * work we compute this as being just above the just undone change. */ + --curbuf->b_u_seq_cur; + + /* The timestamp can be the same for multiple changes, just use the one of + * the undone/redone change. */ curbuf->b_u_seq_time = curhead->uh_time; } @@ -1212,8 +1220,9 @@ u_undo_end() else u_add_time(msgbuf, sizeof(msgbuf), uhp->uh_time); - smsg((char_u *)_("%ld %s; #%ld %s"), u_oldcount, _(msg), - uhp == NULL ? 0L : uhp->uh_seq, msgbuf); + smsg((char_u *)_("%ld %s; #%ld %s"), + u_oldcount < 0 ? -u_oldcount : u_oldcount, + _(msg), uhp == NULL ? 0L : uhp->uh_seq, msgbuf); } /* @@ -1264,7 +1273,8 @@ ex_undolist(eap) uhp = curbuf->b_u_oldhead; while (uhp != NULL) { - if (uhp->uh_prev == NULL) + if (uhp->uh_prev == NULL && uhp->uh_walk != nomark + && uhp->uh_walk != mark) { if (ga_grow(&ga, 1) == FAIL) break; diff --git a/src/version.h b/src/version.h --- 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 16)" -#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 16, compiled " +#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 17)" +#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Mar 17, compiled "