]> granicus.if.org Git - vim/commitdiff
updated for version 7.0227
authorBram Moolenaar <Bram@vim.org>
Fri, 17 Mar 2006 23:19:38 +0000 (23:19 +0000)
committerBram Moolenaar <Bram@vim.org>
Fri, 17 Mar 2006 23:19:38 +0000 (23:19 +0000)
18 files changed:
runtime/doc/eval.txt
runtime/doc/help.txt
runtime/doc/options.txt
runtime/doc/tags
runtime/doc/todo.txt
runtime/doc/usr_toc.txt
runtime/doc/various.txt
runtime/doc/version7.txt
src/globals.h
src/gui_w32.c
src/main.c
src/misc1.c
src/ops.c
src/proto/mbyte.pro
src/screen.c
src/structs.h
src/undo.c
src/version.h

index 9ca5d71a2cb8724cd340032ae0c69a5f4005f2dc..3171e96718d27ca4953ea0913a396a6a60bc094d 100644 (file)
@@ -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 at byte count {byte}
 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}])                       *call()* *E699*
                {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 @@ This would call the function "my_func_whizz(parameter)".
 :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
index 3192df56e21539d7d3e8199a84f29a8658dcbf0f..e6e3bfadb24c8243464610558b4db60982ac2be3 100644 (file)
@@ -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
index 0cc9b34fb1cece75dab5d64bdb2a77eaf8e7216c..822200c7e2761cf93f7e1ac31f4da3f5a747c4ef 100644 (file)
@@ -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 short description can be found at |Q_op|.
        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
index 3734385fc52ce6cc92d6aa6e549c28f149c27884..8457b13b14a16276d2ae82195d94773a9ca8e5c0 100644 (file)
@@ -1647,6 +1647,7 @@ $VIMRUNTIME       starting.txt    /*$VIMRUNTIME*
 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_mapping*
 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*
index 1948927ca1b9c879897e06bafdd943d6ae7e6eed..65e3c76506792c9b2afce022d4e6b7723ecc9526 100644 (file)
@@ -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 @@ Mac unicode patch (Da Woon Jung, Eckehard Berns):
 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.
index 554ab704e598ca8b001877db0bd742046f283fcd..924101fda1ded6224e07b8eeb497f214d91015d9 100644 (file)
@@ -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
index c16587f8f8bbca31a52c469cf9abe94f3f02a4eb..30a7a0ba02aa1040e93fd23200fa7e8c97401345 100644 (file)
@@ -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 used in the
                        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]
index 9a36fc65886dc625d896ff0712172042a2d9ae2f..8a7f018718dc3eeb6bd8ede84eb957f88b459953 100644 (file)
@@ -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 paren that the cursor landed on.
 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:
index 86d8ad9ca672802f040aa4c41806a80780af0cf5..b0523fc2ecbcf1986f3146de8f2c8900f4b10558 100644 (file)
@@ -1504,6 +1504,9 @@ EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
 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.
  */
index 46ca5468def85f49679950a7b39032a4c5974d6b..6e3608065d794a946ff93c759f20a0c308078ddd 100644 (file)
@@ -323,6 +323,7 @@ static BOOL (WINAPI *pImmGetCompositionFont)(HIMC, LPLOGFONTA);
 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, WCHAR *unicodebuf)
 {
     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;
index 3209183bae68bccfe7dc30e50e33c1276d30d978..aff8b3fb3f0ac00b044ddeca056e20124e9b2755 100644 (file)
@@ -208,6 +208,7 @@ main
     time_fd = mch_fopen(STARTUPTIME, "a");
     TIME_MSG("--- VIM STARTING ---");
 #endif
+    starttime = time(NULL);
 
 #ifdef __EMX__
     _wildcard(&params.argc, &params.argv);
index 873159cc7cdf7fcd3d6e31f548c4eaddd33f16fa..00921dc9b42a04d81f92a9b437dc54805b454f0f 100644 (file)
@@ -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
index fce995fd08f8d24a7ec223bb2f35ae010762ef73..a13cee76a7cf1f1d3b608db76dcec29b0ffbec17 100644 (file)
--- 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
index e5c9295fafdcdef26637a0063b0f4e393c0106ec..16a36c893db50a0fefa3b2b834d8bef06442b14a 100644 (file)
@@ -49,6 +49,7 @@ int utf_head_off __ARGS((char_u *base, char_u *p));
 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));
index 6de791d5b4afcd5b9bc8a89072039bb32b250fb0..fbc3fee5169ce8ba570fdbe7094d2fa72378a7c1 100644 (file)
@@ -4296,7 +4296,7 @@ win_line(wp, lnum, startrow, endrow, nochange)
                        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, nochange)
 #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)
        {
index 26fee9a65136d78d94c6f7affc537ce36892f3b7..1e66e6ff5535c6530ae4390a3ba6c6896c298f4e 100644 (file)
@@ -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
index 330915df01a11a83c397f2ec1f126288563e990c..555d9e5b1976ccfcbcb5ad86eecb496205c485fd 100644 (file)
@@ -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;
+       closest = -1;
     }
-    else if (step < 0)
+    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 + step;
+           target = (long)(curbuf->b_u_seq_time - starttime) + step;
        else
            target = curbuf->b_u_seq_cur + step;
-       if (target < 0)
-           target = -1;
-       closest = -2;
-    }
-    else
-    {
-       if (sec)
+       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;
index 19333f23794dcd196f4adfe5eec7cc8e5ae5d68e..92f741133a681b12cdeeacc91e0cdfbbb1129aa7 100644 (file)
@@ -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 "