]> granicus.if.org Git - vim/commitdiff
updated for version 7.0032
authorBram Moolenaar <Bram@vim.org>
Thu, 6 Jan 2005 23:24:37 +0000 (23:24 +0000)
committerBram Moolenaar <Bram@vim.org>
Thu, 6 Jan 2005 23:24:37 +0000 (23:24 +0000)
runtime/doc/eval.txt
src/ex_eval.c
src/structs.h
src/version.h

index e71380e0f15c28be7f0fae257a6ecd61cf0361af..7c6a1fdab25eaa4bddbcf7095651de2e635b7d4d 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jan 05
+*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jan 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -169,7 +169,10 @@ Expression syntax summary, from least to most significant:
        etc.                    As above, append ? for ignoring case, # for
                                matching case
 
-|expr5|        expr6 +  expr6 ..       number addition
+       expr5 is expr5          same List instance
+       expr5 isnot expr5       different List instance
+
+|expr5|        expr6 +  expr6 ..       number addition or list concatenation
        expr6 -  expr6 ..       number subtraction
        expr6 .  expr6 ..       string concatenation
 
@@ -282,6 +285,7 @@ if it evaluates to true.
                        *expr-<#*  *expr-<=#* *expr-=~#* *expr-!~#*
                        *expr-==?* *expr-!=?* *expr->?*  *expr->=?*
                        *expr-<?*  *expr-<=?* *expr-=~?* *expr-!~?*
+                       *expr-is*
                use 'ignorecase'    match case     ignore case ~
 equal                  ==              ==#             ==?
 not equal              !=              !=#             !=?
@@ -291,12 +295,28 @@ smaller than              <               <#              <?
 smaller than or equal  <=              <=#             <=?
 regexp matches         =~              =~#             =~?
 regexp doesn't match   !~              !~#             !~?
+same instance          is
+different instance     isnot
 
 Examples:
 "abc" ==# "Abc"          evaluates to 0
 "abc" ==? "Abc"          evaluates to 1
 "abc" == "Abc"   evaluates to 1 if 'ignorecase' is set, 0 otherwise
 
+A List can only be compared with a List and only "equal", "not equal" and "is"
+can be used.  This compares the values of the list, recursively.  Ignoring
+case means case is ignored when comparing item values.
+
+A Funcref can only be compared with a Funcref and only "equal" and "not equal"
+can be used.  Case is never ignored.
+
+When using "is" or "isnot" with a List this checks if the expressions are
+referring to the same List instance.  A copy of a List is different from the
+original List.  When using "is" without a List it is equivalent to using
+"equal", using "isnot" equivalent to using "not equal".  Except that a
+different type means the values are different.  "4 == '4'" is true, "4 is '4'"
+is false.
+
 When comparing a String with a Number, the String is converted to a Number,
 and the comparison is done on Numbers.  This means that "0 == 'x'" is TRUE,
 because 'x' converted to a Number is zero.
@@ -326,13 +346,16 @@ can be matched like an ordinary character.  Examples:
 
 expr5 and expr6                                                *expr5* *expr6*
 ---------------
-expr6 +         expr6 ..       number addition         *expr-+*
-expr6 -         expr6 ..       number subtraction      *expr--*
-expr6 .         expr6 ..       string concatenation    *expr-.*
+expr6 +         expr6 ..       Number addition or List concatenation   *expr-+*
+expr6 -         expr6 ..       Number subtraction                      *expr--*
+expr6 .         expr6 ..       String concatenation                    *expr-.*
+
+For Lists only "+" is possible and then both expr6 must be a list.  The result
+is a new list with the two lists Concatenated.
 
-expr7 *         expr7 ..       number multiplication   *expr-star*
-expr7 /         expr7 ..       number division         *expr-/*
-expr7 %         expr7 ..       number modulo           *expr-%*
+expr7 *         expr7 ..       number multiplication                   *expr-star*
+expr7 /         expr7 ..       number division                         *expr-/*
+expr7 %         expr7 ..       number modulo                           *expr-%*
 
 For all, except ".", Strings are converted to Numbers.
 
@@ -343,6 +366,8 @@ Note the difference between "+" and ".":
 When the righthand side of '/' is zero, the result is 0x7fffffff.
 When the righthand side of '%' is zero, the result is 0.
 
+None of these work for Funcrefs.
+
 
 expr7                                                  *expr7*
 -----
@@ -925,12 +950,14 @@ bufnr( {expr})                    Number  Number of the buffer {expr}
 bufwinnr( {expr})              Number  window number of buffer {expr}
 byte2line( {byte})             Number  line number at byte count {byte}
 byteidx( {expr}, {nr})         Number  byte index of {nr}'th char in {expr}
+call( {func}, {arglist})       any     call {func} with arguments {arglist}
 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
 confirm( {msg} [, {choices} [, {default} [, {type}]]])
                                Number  number of choice picked by user
 copy( {expr})                  any     make a shallow copy of {expr}
+count( {list}, {expr} [, {ic}])         Number  count how many {expr} are in {list}
 cscope_connection( [{num} , {dbpath} [, {prepend}]])
                                Number  checks existence of cscope connection
 cursor( {lnum}, {col})         Number  position cursor at {lnum}, {col}
@@ -985,6 +1012,7 @@ hlID( {name})                      Number  syntax ID of highlight group {name}
 hostname()                     String  name of the machine Vim is running on
 iconv( {expr}, {from}, {to})   String  convert encoding of {expr}
 indent( {lnum})                        Number  indent of line {lnum}
+index( {list}, {expr} [, {ic}]) Number index in {list} where {expr} appears
 input( {prompt} [, {text}])    String  get input from the user
 inputdialog( {p} [, {t} [, {c}]]) String  like input() but in a GUI dialog
 inputrestore()                 Number  restore typeahead
@@ -1019,7 +1047,7 @@ remote_peek( {serverid} [, {retvar}])
 remote_read( {serverid})       String  read reply string
 remote_send( {server}, {string} [, {idvar}])
                                String  send key sequence
-remove( {list}, {idx})         any     remove item {idx} from {list}
+remove( {list}, {idx} [, {end}])  any  remove items {idx}-{end} from {list}
 rename( {from}, {to})          Number  rename (move) file from {from} to {to}
 repeat( {expr}, {count})       String  repeat {expr} {count} times
 resolve( {filename})           String  get filename a shortcut points to
@@ -1235,6 +1263,13 @@ byteidx({expr}, {nr})                                    *byteidx()*
                If there are exactly {nr} characters the length of the string
                is returned.
 
+call({func}, {arglist})                                        *call()*
+               Call function {func} with the items in List {arglist} as
+               arguments.
+               {func} can either be a Funcref or the name of a function.
+               a:firstline and a:lastline are set to the cursor line.
+               Returns the return value of the called function.
+
 char2nr({expr})                                                *char2nr()*
                Return number value of the first char in {expr}.  Examples: >
                        char2nr(" ")            returns 32
@@ -1333,6 +1368,12 @@ copy({expr})     Make a copy of {expr}.  For Numbers and Strings this isn't
                changing an item changes the contents of both Lists.  Also see
                |deepcopy()|.
 
+count({list}, {expr} [, {ic}])                                 *count()*
+               Return the number of times an item with value {expr} appears
+               in List {list}.
+               When {ic} is given and it's non-zero then case is ignored.
+
+
                                                        *cscope_connection()*
 cscope_connection([{num} , {dbpath} [, {prepend}]])
                Checks for the existence of a |cscope| connection.  If no
@@ -1590,6 +1631,23 @@ expand({expr} [, {flag}])                                *expand()*
                See |glob()| for finding existing files.  See |system()| for
                getting the raw output of an external command.
 
+extend({list1}, {list2} [, {idx}])                     *extend()*
+               Append {list2} to {list1}.
+               If {idx} is given insert the items of {list2} before item
+               {idx} in {list1}.  When {idx} is zero insert before the first
+               item.  When {idx} is equal to len({list1}) {list2} is
+               appended.
+               {list1} is changed when {list2} is not empty.
+               {list2} remains unchanged.
+               {list1} and {list2} must be Lists.
+               Returns {list1}.
+               Examples: >
+                       :echo sort(extend(mylist, [7, 5]))
+                       :call extend(mylist, [2, 3], 1)
+<              Use |append()| to concatenate one item to a list.  To
+               concatenate two lists into a new list use the + operator: >
+                       :let newlist = [1, 2, 3] + [4, 5]
+
 filereadable({file})                                   *filereadable()*
                The result is a Number, which is TRUE when a file with the
                name {file} exists, and can be read.  If {file} doesn't exist,
@@ -2067,6 +2125,17 @@ indent({lnum})   The result is a Number, which is indent of line {lnum} in the
                |getline()|.
                When {lnum} is invalid -1 is returned.
 
+
+index({list}, {expr} [, {ic}])                         *index()*
+               Return the lowest index in List {list} where the item has a
+               value equal to {expr}.
+               When {ic} is given and it is non-zero, ignore case.  Otherwise
+               case must match.
+               -1 is returned when {expr} is not found in {list}.
+               Example: >
+                       :let idx = index(words, "the")
+
+
 input({prompt} [, {text}])                             *input()*
                The result is a String, which is whatever the user typed on
                the command-line.  The parameter is either a prompt string, or
@@ -2484,11 +2553,17 @@ remote_send({server}, {string} [, {idvar}])
                 \ 'server2client(expand("<client>"), "HELLO")<CR>')
 
 
-remove({list}, {idx})                                  *remove()*
-               Remove the item at {idx} from List {list} and return it.
-               See |list-index| for possible values of {idx}.
+remove({list}, {idx} [, {end}])                                *remove()*
+               Without {end}: Remove the item at {idx} from List {list} and
+               return it.
+               With {end}: Remove items from {idx} to {end} (inclusive) and
+               return a list with these items.  When {idx} points to the same
+               item as {end} a list with one item is returned.  When {end}
+               points to an item before {idx} this is an error.
+               See |list-index| for possible values of {idx} and {end}.
                Example: >
                        :echo "last item: " . remove(mylist, -1)
+                       :call remove(mylist, 0, 9)
 <              Use |delete()| to remove a file.
 
 rename({from}, {to})                                   *rename()*
@@ -2503,6 +2578,10 @@ repeat({expr}, {count})                                  *repeat()*
                result.  Example: >
                        :let seperator = repeat('-', 80)
 <              When {count} is zero or negative the result is empty.
+               When {expr} is a list the result is {expr} concatenated
+               {count} times. Example: >
+                       :let longlist = repeat(['a', 'b'], 3)
+<              Results in ['a', 'b', 'a', 'b', 'a', 'b'].
 
 resolve({filename})                                    *resolve()* *E655*
                On MS-Windows, when {filename} is a shortcut (a .lnk file),
@@ -3633,14 +3712,20 @@ This would call the function "my_func_whizz(parameter)".
 :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
+                       each item in {list}.  variable {var} is set to the
+                       value of each item.
+                       When an error is detected for 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
+                       Changing {list} affects what items are used.  Make a
+                       copy if this is unwanted: >
+                               :for item in copy(mylist)
+<                      When not making a copy, Vim stores a reference to the
+                       next item in the list, before executing the commands
+                       with the current item.  Thus the current item can be
+                       removed without effect.  Removing any later item means
+                       it will not be found.  Thus the following example
+                       works (an inefficient way to make a list empty): >
+                               :for item in mylist
                                   :call remove(mylist, 0)
                                :endfor
 <                      Note that the type of each list item should be
index d2e4f3789fb6ba53fc7bd90dee0402646496b268..38517e3e7f253ba99d7e9c4b09787ae6a4b1fd20 100644 (file)
@@ -18,8 +18,6 @@
 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 *));
 
 /*
  * Exception handling terms:
@@ -863,8 +861,8 @@ ex_endif(eap)
 {
     did_endif = TRUE;
     if (eap->cstack->cs_idx < 0
-           || (eap->cstack->cs_flags[eap->cstack->cs_idx] &
-               (CSF_WHILE | CSF_FOR | CSF_TRY)))
+           || (eap->cstack->cs_flags[eap->cstack->cs_idx]
+                                          & (CSF_WHILE | CSF_FOR | CSF_TRY)))
        eap->errmsg = (char_u *)N_("E580: :endif without :if");
     else
     {
@@ -1031,14 +1029,14 @@ ex_while(eap)
            {
                /* Jumping here from a ":continue" or ":endfor": use the
                 * previously evaluated list. */
-               fi = cstack->cs_fors[cstack->cs_idx];
+               fi = cstack->cs_forinfo[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;
+               cstack->cs_forinfo[cstack->cs_idx] = fi;
            }
 
            /* use the element at the start of the list and advance */
@@ -1050,7 +1048,7 @@ ex_while(eap)
            if (!result)
            {
                free_for_info(fi);
-               cstack->cs_fors[cstack->cs_idx] = NULL;
+               cstack->cs_forinfo[cstack->cs_idx] = NULL;
            }
        }
 
@@ -1098,8 +1096,7 @@ ex_continue(eap)
        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);
+           rewind_conditionals(cstack, idx, CSF_TRY, &cstack->cs_trylevel);
 
            /*
             * Set CSL_HAD_CONT, so do_cmdline() will jump back to the
@@ -1448,7 +1445,7 @@ ex_catch(eap)
            eap->errmsg = (char_u *)N_("E604: :catch after :finally");
            give_up = TRUE;
        }
-       else if (cstack->cs_idx > idx)
+       else
            rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
                                                       &cstack->cs_looplevel);
     }
@@ -1602,8 +1599,7 @@ ex_finally(eap)
            eap->errmsg = (char_u *)N_("E607: multiple :finally");
            return;
        }
-       if (cstack->cs_idx > idx)
-           rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
+       rewind_conditionals(cstack, idx, CSF_WHILE | CSF_FOR,
                                                       &cstack->cs_looplevel);
 
        /*
@@ -1678,8 +1674,8 @@ ex_finally(eap)
                 * exception.  When emsg() is called for a missing ":endif" or
                 * a missing ":endwhile"/":endfor" detected here, the
                 * exception will be discarded. */
-               if (did_throw && cstack->cs_exception[cstack->cs_idx] !=
-                                                           current_exception)
+               if (did_throw && cstack->cs_exception[cstack->cs_idx]
+                                                        != current_exception)
                    EMSG(_(e_internal));
            }
 
@@ -2033,8 +2029,9 @@ 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.
+ * 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 | 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
@@ -2186,8 +2183,9 @@ get_end_emsg(cstack)
  * "cond_level" specify a conditional type and the address of a level variable
  * which is to be decremented with each skipped conditional of the specified
  * type.
+ * Also free "for info" structures where needed.
  */
-    static void
+    void
 rewind_conditionals(cstack, idx, cond_type, cond_level)
     struct condstack   *cstack;
     int                idx;
@@ -2198,6 +2196,8 @@ rewind_conditionals(cstack, idx, cond_type, cond_level)
     {
        if (cstack->cs_flags[cstack->cs_idx] & cond_type)
            --*cond_level;
+       if (cstack->cs_flags[cstack->cs_idx] & CSF_FOR)
+           free_for_info(cstack->cs_forinfo[cstack->cs_idx]);
        --cstack->cs_idx;
     }
 }
index f49b80beb6abed15f3431c3bcb5586a226768d6a..4ceb0ce4fce5b534415c96ca94bdbcb81ba605de 100644 (file)
@@ -601,7 +601,7 @@ struct condstack
        void    *csp_rv[CSTACK_LEN];    /* return typeval for pending return */
        void    *csp_ex[CSTACK_LEN];    /* exception for pending throw */
     }          cs_pend;
-    void       *cs_fors[CSTACK_LEN];   /* info used by ":for" */
+    void       *cs_forinfo[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_looplevel;           /* nr of nested ":while"s and ":for"s */
@@ -612,6 +612,8 @@ struct condstack
 # define cs_rettv      cs_pend.csp_rv
 # define cs_exception  cs_pend.csp_ex
 
+/* There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
+ * was used. */
 # define CSF_TRUE      0x0001  /* condition was TRUE */
 # define CSF_ACTIVE    0x0002  /* current state is active */
 # define CSF_ELSE      0x0004  /* ":else" has been passed */
index 8348c0d00c46704ef979c81ee429051654c1e6cc..67ce20babc7a4488cf98c6a22a98fcb92ebd0714 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 5)"
-#define VIM_VERSION_LONG_DATE  "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 5, compiled "
+#define VIM_VERSION_LONG       "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 6)"
+#define VIM_VERSION_LONG_DATE  "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 6, compiled "