]> granicus.if.org Git - vim/commitdiff
updated for version 7.0031
authorBram Moolenaar <Bram@vim.org>
Wed, 5 Jan 2005 22:16:17 +0000 (22:16 +0000)
committerBram Moolenaar <Bram@vim.org>
Wed, 5 Jan 2005 22:16:17 +0000 (22:16 +0000)
runtime/doc/eval.txt
runtime/doc/options.txt
runtime/doc/tags
src/edit.c
src/ex_eval.c
src/ex_getln.c
src/gui_kde.cc
src/gui_kde_x11.cc
src/proto/eval.pro
src/structs.h
src/version.h

index 5402a2cd41635567e52060451e85bbb115840b8a..e71380e0f15c28be7f0fae257a6ecd61cf0361af 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jan 04
+*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jan 05
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -2774,6 +2774,7 @@ string({expr})    Return {expr} converted to a String.
                        String          identical
                        Number          decimal representation
                        Funcref         name of the function
+                       List            "[item, item]" form
 
                                                        *strlen()*
 strlen({expr}) The result is a Number, which is the length of the String
@@ -3619,29 +3620,69 @@ This would call the function "my_func_whizz(parameter)".
                        as long as {expr1} evaluates to non-zero.
                        When an error is detected from a command inside the
                        loop, execution continues after the "endwhile".
-
+                       Example: >
+                               :let lnum = 1
+                               :while lnum <= line("$")
+                                  :call FixLine(lnum)
+                                  :let lnum = lnum + 1
+                               :endwhile
+<
                        NOTE: The ":append" and ":insert" commands don't work
-                       properly inside a ":while" loop.
+                       properly inside a :while" and ":for" loop.
 
+:for {var} in {list}                                   *:for*
+:endfo[r]                                              *:endfo* *:endfor*
+                       Repeat the commands between ":for" and ":endfor" for
+                       each item in {list}.  {var} is set to the value of the
+                       item.
+                       When an error is detected from a command inside the
+                       loop, execution continues after the "endfor".
+                       A copy of {list} is made, so that it cannot change
+                       while executing the commands.  Example (an inefficient
+                       way to make a list empty): >
+                               :for a in mylist
+                                  :call remove(mylist, 0)
+                               :endfor
+<                      Note that the type of each list item should be
+                       identical to avoid errors for the type of {var}
+                       changing.  Unlet the variable at the end of the loop
+                       to allow multiple item types.
+
+:for {var} in {string}
+:endfo[r]              Like ":for" above, but use each character in {string}
+                       as a list item.
+                       Composing characters are used as separate characters.
+                       A Number is first converted to a String.
+
+:for [{var1}, {var2}, ...] in {listlist}
+:endfo[r]
+                       Like ":for" above, but each item in {listlist} must be
+                       a list, of which each item is assigned to {var1},
+                       {var2}, etc.  Example: >
+                               :for [lnum, col] in [[1, 3], [2, 5], [3, 8]]
+                                  :echo getline(lnum)[col]
+                               :endfor
+<
                                                *:continue* *:con* *E586*
-:con[tinue]            When used inside a ":while", jumps back to the
-                       ":while".  If it is used after a |:try| inside the
-                       ":while" but before the matching |:finally| (if
-                       present), the commands following the ":finally" up to
-                       the matching |:endtry| are executed first.  This
-                       process applies to all nested ":try"s inside the
-                       ":while".  The outermost ":endtry" then jumps back to
-                       the ":while".
+:con[tinue]            When used inside a ":while" or ":for" loop, jumps back
+                       to the start of the loop.
+                       If it is used after a |:try| inside the loop but
+                       before the matching |:finally| (if present), the
+                       commands following the ":finally" up to the matching
+                       |:endtry| are executed first.  This process applies to
+                       all nested ":try"s inside the loop.  The outermost
+                       ":endtry" then jumps back to the start of the loop.
 
                                                *:break* *:brea* *E587*
-:brea[k]               When used inside a ":while", skips to the command
-                       after the matching ":endwhile".  If it is used after
-                       a |:try| inside the ":while" but before the matching
-                       |:finally| (if present), the commands following the
-                       ":finally" up to the matching |:endtry| are executed
-                       first.  This process applies to all nested ":try"s
-                       inside the ":while".  The outermost ":endtry" then
-                       jumps to the command after the ":endwhile".
+:brea[k]               When used inside a ":while" or ":for" loop, skips to
+                       the command after the matching ":endwhile" or
+                       ":endfor".
+                       If it is used after a |:try| inside the loop but
+                       before the matching |:finally| (if present), the
+                       commands following the ":finally" up to the matching
+                       |:endtry| are executed first.  This process applies to
+                       all nested ":try"s inside the loop.  The outermost
+                       ":endtry" then jumps to the command after the loop.
 
 :try                           *:try* *:endt* *:endtry* *E600* *E601* *E602*
 :endt[ry]              Change the error handling for the commands between
index a43e24ee8e030d3afa4b8bff0669ca5e853ddbf3..01535c7b09d1ed71b03e0668bacb44aff62b408f 100644 (file)
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 7.0aa.  Last change: 2004 Dec 24
+*options.txt*  For Vim version 7.0aa.  Last change: 2005 Jan 05
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -5019,7 +5019,8 @@ A jump table for the options with a short description can be found at |Q_op|.
           folds        manually created folds, opened/closed folds and local
                        fold options
           globals      global variables that start with an uppercase letter
-                       and contain at least one lowercase letter.
+                       and contain at least one lowercase letter.  Only
+                       String and Number types are stored.
           help         the help window
           localoptions options and mappings local to a window or buffer (not
                        global values for local options)
@@ -6410,7 +6411,8 @@ A jump table for the options with a short description can be found at |Q_op|.
        !       When included, save and restore global variables that start
                with an uppercase letter, and don't contain a lowercase
                letter.  Thus "KEEPTHIS and "K_L_M" are stored, but "KeepThis"
-               and "_K_L_M" are not.
+               and "_K_L_M" are not.  Only String and Number types are
+               stored.
        "       Maximum number of lines saved for each register.  Old name of
                the '<' item, with the disadvantage that you need to put a
                backslash before the ", otherwise it will be recognized as the
index f680818fb6ee45f2d1dbb93b6638d2a83c264957..b6c0445ee2143a771e7a915cdb42419e76cf8167 100644 (file)
@@ -1883,6 +1883,8 @@ $VIMRUNTIME       starting.txt    /*$VIMRUNTIME*
 :emenu gui.txt /*:emenu*
 :en    eval.txt        /*:en*
 :endf  eval.txt        /*:endf*
+:endfo eval.txt        /*:endfo*
+:endfor        eval.txt        /*:endfor*
 :endfunction   eval.txt        /*:endfunction*
 :endif eval.txt        /*:endif*
 :endt  eval.txt        /*:endt*
@@ -1934,6 +1936,7 @@ $VIMRUNTIME       starting.txt    /*$VIMRUNTIME*
 :folddoopen    fold.txt        /*:folddoopen*
 :foldo fold.txt        /*:foldo*
 :foldopen      fold.txt        /*:foldopen*
+:for   eval.txt        /*:for*
 :fu    eval.txt        /*:fu*
 :function      eval.txt        /*:function*
 :g     repeat.txt      /*:g*
@@ -2039,6 +2042,7 @@ $VIMRUNTIME       starting.txt    /*$VIMRUNTIME*
 :let-option    eval.txt        /*:let-option*
 :let-register  eval.txt        /*:let-register*
 :let-star      eval.txt        /*:let-star*
+:let-unpack    eval.txt        /*:let-unpack*
 :list  various.txt     /*:list*
 :lm    map.txt /*:lm*
 :lmap  map.txt /*:lmap*
@@ -5298,6 +5302,7 @@ linewise  motion.txt      /*linewise*
 linewise-register      change.txt      /*linewise-register*
 linewise-visual        visual.txt      /*linewise-visual*
 lispindent()   eval.txt        /*lispindent()*
+list-index     eval.txt        /*list-index*
 list-repeat    windows.txt     /*list-repeat*
 lite-syntax    syntax.txt      /*lite-syntax*
 lite.vim       syntax.txt      /*lite.vim*
@@ -5871,6 +5876,7 @@ remote_foreground()       eval.txt        /*remote_foreground()*
 remote_peek()  eval.txt        /*remote_peek()*
 remote_read()  eval.txt        /*remote_read()*
 remote_send()  eval.txt        /*remote_send()*
+remove()       eval.txt        /*remove()*
 remove-filetype        filetype.txt    /*remove-filetype*
 remove-option-flags    options.txt     /*remove-option-flags*
 rename()       eval.txt        /*rename()*
index 15812c7ff4f885e8d4e86d9ac928f3f64b61d81e..9b3f442e5d3f3d7a1cfa981ec194732d7c32c3f2 100644 (file)
@@ -6236,9 +6236,11 @@ ins_esc(count, cmdchar)
     {
        /*
         * Don't append the ESC for "r<CR>" and "grx".
+        * When 'insertmode' is set only CTRL-L stops Insert mode.  Needed for
+        * when "count" is non-zero.
         */
        if (cmdchar != 'r' && cmdchar != 'v')
-           AppendToRedobuff(ESC_STR);
+           AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
 
        /*
         * Repeating insert may take a long time.  Check for
index 67f8b893e65681e860615d337490bbde6b932813..d2e4f3789fb6ba53fc7bd90dee0402646496b268 100644 (file)
@@ -17,6 +17,7 @@
 
 static void    free_msglist __ARGS((struct msglist *l));
 static int     throw_exception __ARGS((void *, int, char_u *));
+static char_u  *get_end_emsg __ARGS((struct condstack *cstack));
 static void    rewind_conditionals __ARGS((struct condstack *,
                                                            int, int, int *));
 
@@ -863,7 +864,7 @@ ex_endif(eap)
     did_endif = TRUE;
     if (eap->cstack->cs_idx < 0
            || (eap->cstack->cs_flags[eap->cstack->cs_idx] &
-               (CSF_WHILE | CSF_TRY)))
+               (CSF_WHILE | CSF_FOR | CSF_TRY)))
        eap->errmsg = (char_u *)N_("E580: :endif without :if");
     else
     {
@@ -904,7 +905,8 @@ ex_else(eap)
            && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
 
     if (cstack->cs_idx < 0
-           || (cstack->cs_flags[cstack->cs_idx] & (CSF_WHILE | CSF_TRY)))
+           || (cstack->cs_flags[cstack->cs_idx]
+                                          & (CSF_WHILE | CSF_FOR | CSF_TRY)))
     {
        if (eap->cmdidx == CMD_else)
        {
@@ -976,7 +978,7 @@ ex_else(eap)
 }
 
 /*
- * Handle ":while".
+ * Handle ":while" and ":for".
  */
     void
 ex_while(eap)
@@ -988,45 +990,87 @@ ex_while(eap)
     struct condstack   *cstack = eap->cstack;
 
     if (cstack->cs_idx == CSTACK_LEN - 1)
-       eap->errmsg = (char_u *)N_("E585: :while nesting too deep");
+       eap->errmsg = (char_u *)N_("E585: :while/:for nesting too deep");
     else
     {
        /*
-        * cs_had_while is set when we have jumped back from the matching
-        * ":endwhile".  When not set, need to initialise this cstack entry.
+        * The loop flag is set when we have jumped back from the matching
+        * ":endwhile" or ":endfor".  When not set, need to initialise this
+        * cstack entry.
         */
-       if (!cstack->cs_had_while)
+       if ((cstack->cs_lflags & CSL_HAD_LOOP) == 0)
        {
            ++cstack->cs_idx;
-           ++cstack->cs_whilelevel;
+           ++cstack->cs_looplevel;
            cstack->cs_line[cstack->cs_idx] = -1;
        }
-       cstack->cs_flags[cstack->cs_idx] = CSF_WHILE;
+       cstack->cs_flags[cstack->cs_idx] =
+                              eap->cmdidx == CMD_while ? CSF_WHILE : CSF_FOR;
 
        /*
-        * Don't do something after an error, interrupt, or throw, or when there
-        * is a surrounding conditional and it was not active.
+        * Don't do something after an error, interrupt, or throw, or when
+        * there is a surrounding conditional and it was not active.
         */
        skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
                && !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
-       result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+       if (eap->cmdidx == CMD_while)
+       {
+           /*
+            * ":while bool-expr"
+            */
+           result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
+       }
+       else
+       {
+           void *fi;
+
+           /*
+            * ":for var in list-expr"
+            */
+           if ((cstack->cs_lflags & CSL_HAD_LOOP) != 0)
+           {
+               /* Jumping here from a ":continue" or ":endfor": use the
+                * previously evaluated list. */
+               fi = cstack->cs_fors[cstack->cs_idx];
+               error = FALSE;
+           }
+           else
+           {
+               /* Evaluate the argument and get the info in a structure. */
+               fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
+               cstack->cs_fors[cstack->cs_idx] = fi;
+           }
+
+           /* use the element at the start of the list and advance */
+           if (!error && fi != NULL && !skip)
+               result = next_for_item(fi, eap->arg);
+           else
+               result = FALSE;
+
+           if (!result)
+           {
+               free_for_info(fi);
+               cstack->cs_fors[cstack->cs_idx] = NULL;
+           }
+       }
 
        /*
-        * If this cstack entry was just initialised and is active, set
-        * cs_had_while flag, so do_cmdline() will set the line number
-        * in cs_line[].
+        * If this cstack entry was just initialised and is active, set the
+        * loop flag, so do_cmdline() will set the line number in cs_line[].
+        * If executing the command a second time, clear the loop flag.
         */
        if (!skip && !error && result)
        {
-           cstack->cs_flags[cstack->cs_idx] |= CSF_ACTIVE | CSF_TRUE;
-           cstack->cs_had_while = !cstack->cs_had_while;
+           cstack->cs_flags[cstack->cs_idx] |= (CSF_ACTIVE | CSF_TRUE);
+           cstack->cs_lflags ^= CSL_HAD_LOOP;
        }
        else
        {
-           cstack->cs_had_while = FALSE;
-           /* If the ":while" evaluates to FALSE, show the debug prompt at the
-            * ":endwhile" as if there was a ":break" in a ":while" evaluating
-            * to TRUE. */
+           cstack->cs_lflags &= ~CSL_HAD_LOOP;
+           /* If the ":while" evaluates to FALSE or ":for" is past the end of
+            * the list, show the debug prompt at the ":endwhile"/":endfor" as
+            * if there was a ":break" in a ":while"/":for" evaluating to
+            * TRUE. */
            if (!skip && !error)
                cstack->cs_flags[cstack->cs_idx] |= CSF_TRUE;
        }
@@ -1043,25 +1087,25 @@ ex_continue(eap)
     int                idx;
     struct condstack   *cstack = eap->cstack;
 
-    if (cstack->cs_whilelevel <= 0 || cstack->cs_idx < 0)
-       eap->errmsg = (char_u *)N_("E586: :continue without :while");
+    if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+       eap->errmsg = (char_u *)N_("E586: :continue without :while or :for");
     else
     {
        /* Try to find the matching ":while".  This might stop at a try
         * conditional not in its finally clause (which is then to be executed
         * next).  Therefor, inactivate all conditionals except the ":while"
         * itself (if reached). */
-       idx = cleanup_conditionals(cstack, CSF_WHILE, FALSE);
-       if ((cstack->cs_flags[idx] & CSF_WHILE))
+       idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
+       if ((cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
        {
            if (cstack->cs_idx > idx)
                rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
 
            /*
-            * Set cs_had_continue, so do_cmdline() will jump back to the
+            * Set CSL_HAD_CONT, so do_cmdline() will jump back to the
             * matching ":while".
             */
-           cstack->cs_had_continue = TRUE;     /* let do_cmdline() handle it */
+           cstack->cs_lflags |= CSL_HAD_CONT;  /* let do_cmdline() handle it */
        }
        else
        {
@@ -1083,16 +1127,16 @@ ex_break(eap)
     int                idx;
     struct condstack   *cstack = eap->cstack;
 
-    if (cstack->cs_whilelevel <= 0 || cstack->cs_idx < 0)
-       eap->errmsg = (char_u *)N_("E587: :break without :while");
+    if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+       eap->errmsg = (char_u *)N_("E587: :break without :while or :for");
     else
     {
        /* Inactivate conditionals until the matching ":while" or a try
         * conditional not in its finally clause (which is then to be
         * executed next) is found.  In the latter case, make the ":break"
         * pending for execution at the ":endtry". */
-       idx = cleanup_conditionals(cstack, CSF_WHILE, TRUE);
-       if (!(cstack->cs_flags[idx] & CSF_WHILE))
+       idx = cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, TRUE);
+       if (!(cstack->cs_flags[idx] & (CSF_WHILE | CSF_FOR)))
        {
            cstack->cs_pending[idx] = CSTP_BREAK;
            report_make_pending(CSTP_BREAK, NULL);
@@ -1101,53 +1145,72 @@ ex_break(eap)
 }
 
 /*
- * ":endwhile"
+ * ":endwhile" and ":endfor"
  */
     void
 ex_endwhile(eap)
     exarg_T    *eap;
 {
     struct condstack   *cstack = eap->cstack;
-    int                idx;
+    int                        idx;
+    char_u             *err;
+    int                        csf;
+    int                        fl;
+
+    if (eap->cmdidx == CMD_endwhile)
+    {
+       err = e_while;
+       csf = CSF_WHILE;
+    }
+    else
+    {
+       err = e_for;
+       csf = CSF_FOR;
+    }
 
-    if (cstack->cs_whilelevel <= 0 || cstack->cs_idx < 0)
-       eap->errmsg = e_while;
+    if (cstack->cs_looplevel <= 0 || cstack->cs_idx < 0)
+       eap->errmsg = err;
     else
     {
-       if (!(cstack->cs_flags[cstack->cs_idx] & CSF_WHILE))
+       fl =  cstack->cs_flags[cstack->cs_idx];
+       if (!(fl & csf))
        {
-           /* Try to find the matching ":while" and report what's missing. */
-           if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
+           if (fl & CSF_WHILE)
+               eap->errmsg = (char_u *)_("E999: Using :endfor with :while");
+           else if (fl & CSF_FOR)
+               eap->errmsg = (char_u *)_("E999: Using :endwhile with :for");
+           else if (!(fl & CSF_TRY))
                eap->errmsg = e_endif;
-           else if (cstack->cs_flags[cstack->cs_idx] & CSF_FINALLY)
+           else if (fl & CSF_FINALLY)
                eap->errmsg = e_endtry;
+           /* Try to find the matching ":while" and report what's missing. */
            for (idx = cstack->cs_idx; idx > 0; --idx)
            {
-               if ((cstack->cs_flags[idx] & CSF_TRY)
-                       && !(cstack->cs_flags[idx] & CSF_FINALLY))
+               fl =  cstack->cs_flags[idx];
+               if ((fl & CSF_TRY) && !(fl & CSF_FINALLY))
                {
                    /* Give up at a try conditional not in its finally clause.
-                    * Ignore the ":endwhile". */
-                   eap->errmsg = e_while;
+                    * Ignore the ":endwhile"/":endfor". */
+                   eap->errmsg = err;
                    return;
                }
-               if (cstack->cs_flags[idx] & CSF_WHILE)
+               if (fl & csf)
                    break;
            }
            /* Cleanup and rewind all contained (and unclosed) conditionals. */
-           (void)cleanup_conditionals(cstack, CSF_WHILE, FALSE);
+           (void)cleanup_conditionals(cstack, CSF_WHILE | CSF_FOR, FALSE);
            rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
        }
 
        /*
         * When debugging or a breakpoint was encountered, display the debug
         * prompt (if not already done).  This shows the user that an
-        * ":enwhile" is executed when the ":while" was not TRUE or after
-        * a ":break".  Handle a ">quit" debug command as if an interrupt
-        * had occurred before the ":endwhile".  That is, throw an interrupt
-        * exception if appropriate.  Doing this here prevents that an
-        * exception for a parsing error is discarded when throwing the
-        * interrupt exception later on.
+        * ":endwhile"/":endfor" is executed when the ":while" was not TRUE or
+        * after a ":break".  Handle a ">quit" debug command as if an
+        * interrupt had occurred before the ":endwhile"/":endfor".  That is,
+        * throw an interrupt exception if appropriate.  Doing this here
+        * prevents that an exception for a parsing error is discarded when
+        * throwing the interrupt exception later on.
         */
        else if (cstack->cs_flags[cstack->cs_idx] & CSF_TRUE
                && !(cstack->cs_flags[cstack->cs_idx] & CSF_ACTIVE)
@@ -1155,10 +1218,10 @@ ex_endwhile(eap)
            (void)do_intthrow(cstack);
 
        /*
-        * Set cs_had_endwhile, so do_cmdline() will jump back to the matching
-        * ":while".
+        * Set loop flag, so do_cmdline() will jump back to the matching
+        * ":while" or ":for".
         */
-       cstack->cs_had_endwhile = TRUE;
+       cstack->cs_lflags |= CSL_HAD_ENDLOOP;
     }
 }
 
@@ -1372,10 +1435,7 @@ ex_catch(eap)
        {
            /* Report what's missing if the matching ":try" is not in its
             * finally clause. */
-           if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
-               eap->errmsg = e_endwhile;
-           else
-               eap->errmsg = e_endif;
+           eap->errmsg = get_end_emsg(cstack);
            skip = TRUE;
        }
        for (idx = cstack->cs_idx; idx > 0; --idx)
@@ -1389,7 +1449,8 @@ ex_catch(eap)
            give_up = TRUE;
        }
        else if (cstack->cs_idx > idx)
-           rewind_conditionals(cstack, idx, CSF_WHILE, &cstack->cs_whilelevel);
+           rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+                                                      &cstack->cs_looplevel);
     }
 
     if (ends_excmd(*eap->arg)) /* no argument, catch all errors */
@@ -1523,11 +1584,7 @@ ex_finally(eap)
     {
        if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
        {
-           /* Find the matching ":try" and report what's missing. */
-           if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
-               eap->errmsg = e_endwhile;
-           else
-               eap->errmsg = e_endif;
+           eap->errmsg = get_end_emsg(cstack);
            for (idx = cstack->cs_idx - 1; idx > 0; --idx)
                if (cstack->cs_flags[idx] & CSF_TRY)
                    break;
@@ -1546,7 +1603,8 @@ ex_finally(eap)
            return;
        }
        if (cstack->cs_idx > idx)
-           rewind_conditionals(cstack, idx, CSF_WHILE, &cstack->cs_whilelevel);
+           rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+                                                      &cstack->cs_looplevel);
 
        /*
         * Don't do something when the corresponding try block never got active
@@ -1590,11 +1648,12 @@ ex_finally(eap)
             * got_int is set).  The pending values are restored by the
             * ":endtry", except if there is a new error, interrupt, exception,
             * ":continue", ":break", ":return", or ":finish" in the following
-            * finally clause.  A missing ":endwhile" or ":endif" detected here
-            * is treated as if did_emsg and did_throw had already been set,
-            * respectively in case that the error is not converted to an
-            * exception, did_throw had already been unset.  We must not set
-            * did_emsg here since that would suppress the error message.
+            * finally clause.  A missing ":endwhile", ":endfor" or ":endif"
+            * detected here is treated as if did_emsg and did_throw had
+            * already been set, respectively in case that the error is not
+            * converted to an exception, did_throw had already been unset.
+            * We must not set did_emsg here since that would suppress the
+            * error message.
             */
            if (pending == CSTP_ERROR || did_emsg || got_int || did_throw)
            {
@@ -1617,21 +1676,21 @@ ex_finally(eap)
                 * discarded if the finally clause is left by a ":continue",
                 * ":break", ":return", ":finish", error, interrupt, or another
                 * exception.  When emsg() is called for a missing ":endif" or
-                * a missing ":endwhile" detected here, the exception will be
-                * discarded. */
+                * a missing ":endwhile"/":endfor" detected here, the
+                * exception will be discarded. */
                if (did_throw && cstack->cs_exception[cstack->cs_idx] !=
                                                            current_exception)
                    EMSG(_(e_internal));
            }
 
            /*
-            * Set cs_had_finally, so do_cmdline() will reset did_emsg,
+            * Set CSL_HAD_FINA, so do_cmdline() will reset did_emsg,
             * got_int, and did_throw and make the finally clause active.
             * This will happen after emsg() has been called for a missing
-            * ":endif" or a missing ":endwhile" detected here, so that the
-            * following finally clause will be executed even then.
+            * ":endif" or a missing ":endwhile"/":endfor" detected here, so
+            * that the following finally clause will be executed even then.
             */
-           cstack->cs_had_finally = TRUE;
+           cstack->cs_lflags |= CSL_HAD_FINA;
        }
     }
 }
@@ -1670,16 +1729,14 @@ ex_endtry(eap)
 
        if (!(cstack->cs_flags[cstack->cs_idx] & CSF_TRY))
        {
+           eap->errmsg = get_end_emsg(cstack);
            /* Find the matching ":try" and report what's missing. */
-           if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
-               eap->errmsg = e_endwhile;
-           else
-               eap->errmsg = e_endif;
            idx = cstack->cs_idx;
            do
                --idx;
            while (idx > 0 && !(cstack->cs_flags[idx] & CSF_TRY));
-           rewind_conditionals(cstack, idx, CSF_WHILE, &cstack->cs_whilelevel);
+           rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+                                                      &cstack->cs_looplevel);
            skip = TRUE;
 
            /*
@@ -1977,15 +2034,16 @@ leave_cleanup(csp)
  * Make conditionals inactive and discard what's pending in finally clauses
  * until the conditional type searched for or a try conditional not in its
  * finally clause is reached.  If this is in an active catch clause, finish the
- * caught exception.  Return the cstack index where the search stopped.  Values
- * used for "searched_cond" are CSF_WHILE or CSF_TRY or 0, the latter meaning
- * the innermost try conditional not in its finally clause.  "inclusive" tells
- * whether the conditional searched for should be made inactive itself (a try
- * conditional not in its finally claused possibly find before is always made
- * inactive).  If "inclusive" is TRUE and "searched_cond" is CSF_TRY|CSF_SILENT,
- * the saved former value of "emsg_silent", if reset when the try conditional
- * finally reached was entered, is restored (unsed by ex_endtry()).  This is
- * normally done only when such a try conditional is left.
+ * caught exception.  Return the cstack index where the search stopped.
+ * Values used for "searched_cond" are (CSF_WHILE | CSF_FOR) or CSF_TRY or 0,
+ * the latter meaning the innermost try conditional not in its finally clause.
+ * "inclusive" tells whether the conditional searched for should be made
+ * inactive itself (a try conditional not in its finally claused possibly find
+ * before is always made inactive).  If "inclusive" is TRUE and
+ * "searched_cond" is CSF_TRY|CSF_SILENT, the saved former value of
+ * "emsg_silent", if reset when the try conditional finally reached was
+ * entered, is restored (unsed by ex_endtry()).  This is normally done only
+ * when such a try conditional is left.
  */
     int
 cleanup_conditionals(cstack, searched_cond, inclusive)
@@ -2108,6 +2166,21 @@ cleanup_conditionals(cstack, searched_cond, inclusive)
     return idx;
 }
 
+/*
+ * Return an appropriate error message for a missing endwhile/endfor/endif.
+ */
+   static char_u *
+get_end_emsg(cstack)
+    struct condstack   *cstack;
+{
+    if (cstack->cs_flags[cstack->cs_idx] & CSF_WHILE)
+       return e_endwhile;
+    if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+       return e_endfor;
+    return e_endif;
+}
+
+
 /*
  * Rewind conditionals until index "idx" is reached.  "cond_type" and
  * "cond_level" specify a conditional type and the address of a level variable
@@ -2141,16 +2214,17 @@ ex_endfunction(eap)
 }
 
 /*
- * Return TRUE if the string "p" looks like a ":while" command.
+ * Return TRUE if the string "p" looks like a ":while" or ":for" command.
  */
     int
-has_while_cmd(p)
+has_loop_cmd(p)
     char_u     *p;
 {
     p = skipwhite(p);
     while (*p == ':')
        p = skipwhite(p + 1);
-    if (p[0] == 'w' && p[1] == 'h')
+    if ((p[0] == 'w' && p[1] == 'h')
+           || (p[0] == 'f' && p[1] == 'o' && p[2] == 'r'))
        return TRUE;
     return FALSE;
 }
index 235e29e0b67b17ec3009a0837f47ad4f76cf133f..9122ab4918ac8fdae6d36cd9099b91b4409c0e68 100644 (file)
@@ -5459,7 +5459,7 @@ script_get(eap, cmd)
     {
        theline = eap->getline(
 #ifdef FEAT_EVAL
-           eap->cstack->cs_whilelevel > 0 ? -1 :
+           eap->cstack->cs_looplevel > 0 ? -1 :
 #endif
            NUL, eap->cookie, 0);
 
index bbe57f006730394f5fefe142f7f7ba8acf3a01a8..ffdb7f45ab1ba391df1527d91fc6937126bb612f 100644 (file)
@@ -241,12 +241,12 @@ gui_mch_add_menu(vimmenu_T *menu, int idx)//{{{
     {
        idx++; // for tearoffs to be first in menus
        me = new QPopupMenu(parent->widget, QSTR(menu->name));
-       parent->widget->insertItem(QSTR(menu->name), me, (int)me, idx);
+       parent->widget->insertItem(QSTR(menu->name), me, (long)me, idx);
     }
     else
     {
        me = new QPopupMenu(vmw->menuBar(), QSTR(menu->name));
-       vmw->menuBar()->insertItem(QSTR(menu->name), me, (int)me, idx);
+       vmw->menuBar()->insertItem(QSTR(menu->name), me, (long)me, idx);
     }
 
     me->setCaption((const char *)(menu->dname));
@@ -296,7 +296,7 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)//{{{
            return; // failed
        vmw->toolBar()->insertButton(
                pix,
-               (int)menu, // id
+               (long)menu, // id
                true,
                QSTR(menu->strings[MENU_INDEX_TIP]), // tooltip or text
                idx);
@@ -311,7 +311,7 @@ gui_mch_add_menu_item(vimmenu_T *menu, int idx)//{{{
        parent->widget->insertSeparator();
        return;
     }
-    parent->widget->insertItem(QSTR(menu->name), (int)menu, idx);
+    parent->widget->insertItem(QSTR(menu->name), (long)menu, idx);
 #endif
 }//}}}
 
@@ -390,12 +390,12 @@ gui_mch_destroy_menu(vimmenu_T *menu)//{{{
 #ifdef FEAT_TOOLBAR
     if (menu->parent && menu_is_toolbar(menu->parent->name))
     {
-       vmw->toolBar()->removeItem((int)menu);
+       vmw->toolBar()->removeItem((long)menu);
        return;
     }
 #endif
     if (menu->parent)
-       menu->parent->widget->removeItem((int)menu);
+       menu->parent->widget->removeItem((long)menu);
     if (menu->widget)
        delete menu->widget;
     menu->widget = 0;
index c8873ecb78365c89b40ee8291749acdd3e0ec502..32fb747a55f49e9d4f76711563924c5bf018d117 100644 (file)
@@ -1210,7 +1210,7 @@ gui_mch_menu_grey(vimmenu_T * menu, int grey)//{{{
 {
     if (!menu || !menu->parent || !menu->parent->widget)
        return;
-    menu->parent->widget->setItemEnabled((int)menu, !grey);
+    menu->parent->widget->setItemEnabled((long)menu, !grey);
     gui_mch_update();
 }//}}}
 
index 1cd2f8e05dfa6890d685bfc45e4cb21ff376c6cb..64fb62a524692e083f72f7441356aa1db342b600 100644 (file)
@@ -20,6 +20,9 @@ void *save_funccal __ARGS((void));
 void restore_funccal __ARGS((void *fc));
 int eval_foldexpr __ARGS((char_u *arg, int *cp));
 void ex_let __ARGS((exarg_T *eap));
+void *eval_for_line __ARGS((char_u *arg, int *errp, char_u **nextcmdp, int skip));
+int next_for_item __ARGS((void *fi_void, char_u *arg));
+void free_for_info __ARGS((void *fi_void));
 void set_context_for_expression __ARGS((expand_T *xp, char_u *arg, cmdidx_T cmdidx));
 void ex_call __ARGS((exarg_T *eap));
 void ex_unlet __ARGS((exarg_T *eap));
@@ -47,9 +50,9 @@ void ex_function __ARGS((exarg_T *eap));
 char_u *get_user_func_name __ARGS((expand_T *xp, int idx));
 void ex_delfunction __ARGS((exarg_T *eap));
 void ex_return __ARGS((exarg_T *eap));
-int do_return __ARGS((exarg_T *eap, int reanimate, int is_cmd, void *value));
-void discard_pending_return __ARGS((void *retvar));
-char_u *get_return_cmd __ARGS((void *retvar));
+int do_return __ARGS((exarg_T *eap, int reanimate, int is_cmd, void *rettv));
+void discard_pending_return __ARGS((void *rettv));
+char_u *get_return_cmd __ARGS((void *rettv));
 char_u *get_func_line __ARGS((int c, void *cookie, int indent));
 int func_has_ended __ARGS((void *cookie));
 int func_has_abort __ARGS((void *cookie));
index 0eba71f1afa391c8bd0a3e21338e4f2042088fc9..f49b80beb6abed15f3431c3bcb5586a226768d6a 100644 (file)
@@ -595,34 +595,34 @@ struct eslist_elem
 
 struct condstack
 {
-    char       cs_flags[CSTACK_LEN];   /* CSF_ flags */
+    short      cs_flags[CSTACK_LEN];   /* CSF_ flags */
     char       cs_pending[CSTACK_LEN]; /* CSTP_: what's pending in ":finally"*/
     union {
-       void   *cs_pend_rv[CSTACK_LEN]; /* return typeval for pending return */
-       void   *cs_pend_ex[CSTACK_LEN]; /* exception for pending throw */
+       void    *csp_rv[CSTACK_LEN];    /* return typeval for pending return */
+       void    *csp_ex[CSTACK_LEN];    /* exception for pending throw */
     }          cs_pend;
-    int                cs_line[CSTACK_LEN];    /* line number of ":while" line */
+    void       *cs_fors[CSTACK_LEN];   /* info used by ":for" */
+    int                cs_line[CSTACK_LEN];    /* line nr of ":while"/":for" line */
     int                cs_idx;                 /* current entry, or -1 if none */
-    int                cs_whilelevel;          /* number of nested ":while"s */
-    int                cs_trylevel;            /* number of nested ":try"s */
+    int                cs_looplevel;           /* nr of nested ":while"s and ":for"s */
+    int                cs_trylevel;            /* nr of nested ":try"s */
     eslist_T   *cs_emsg_silent_list;   /* saved values of "emsg_silent" */
-    char       cs_had_while;           /* just found ":while" */
-    char       cs_had_continue;        /* just found ":continue" */
-    char       cs_had_endwhile;        /* just found ":endwhile" */
-    char       cs_had_finally;         /* just found ":finally" */
+    char       cs_lflags;              /* loop flags: CSL_ flags */
 };
-# define cs_rettv      cs_pend.cs_pend_rv
-# define cs_exception  cs_pend.cs_pend_ex
-
-# define CSF_TRUE      1       /* condition was TRUE */
-# define CSF_ACTIVE    2       /* current state is active */
-# define CSF_ELSE      4       /* ":else" has been passed */
-# define CSF_WHILE     8       /* is a ":while" */
-# define CSF_TRY       16      /* is a ":try" */
-# define CSF_FINALLY   32      /* ":finally" has been passed */
-# define CSF_THROWN    64      /* exception thrown to this try conditional */
-# define CSF_CAUGHT    128     /* exception caught by this try conditional */
-# define CSF_SILENT    4       /* "emsg_silent" reset by ":try" */
+# define cs_rettv      cs_pend.csp_rv
+# define cs_exception  cs_pend.csp_ex
+
+# define CSF_TRUE      0x0001  /* condition was TRUE */
+# define CSF_ACTIVE    0x0002  /* current state is active */
+# define CSF_ELSE      0x0004  /* ":else" has been passed */
+# define CSF_WHILE     0x0008  /* is a ":while" */
+# define CSF_FOR       0x0010  /* is a ":for" */
+
+# define CSF_TRY       0x0100  /* is a ":try" */
+# define CSF_FINALLY   0x0200  /* ":finally" has been passed */
+# define CSF_THROWN    0x0400  /* exception thrown to this try conditional */
+# define CSF_CAUGHT    0x0800  /* exception caught by this try conditional */
+# define CSF_SILENT    0x1000  /* "emsg_silent" reset by ":try" */
 /* Note that CSF_ELSE is only used when CSF_TRY and CSF_WHILE are unset
  * (an ":if"), and CSF_SILENT is only used when CSF_TRY is set. */
 
@@ -639,6 +639,14 @@ struct condstack
 # define CSTP_RETURN   24      /* ":return" is pending */
 # define CSTP_FINISH   32      /* ":finish" is pending */
 
+/*
+ * Flags for the cs_lflags item in struct condstack.
+ */
+# define CSL_HAD_LOOP   1      /* just found ":while" or ":for" */
+# define CSL_HAD_ENDLOOP 2     /* just found ":endwhile" or ":endfor" */
+# define CSL_HAD_CONT   4      /* just found ":continue" */
+# define CSL_HAD_FINA   8      /* just found ":finally" */
+
 /*
  * A list of error messages that can be converted to an exception.  "throw_msg"
  * is only set in the first element of the list.  Usually, it points to the
index d543509bae8f5ecd2d2718775871c5fcc60715b8..8348c0d00c46704ef979c81ee429051654c1e6cc 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 (2004 Jan 4)"
-#define VIM_VERSION_LONG_DATE  "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 4, compiled "
+#define VIM_VERSION_LONG       "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 5)"
+#define VIM_VERSION_LONG_DATE  "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 5, compiled "