Patch 7.4.218
Problem:    It's not easy to remove duplicates from a list.
Solution:   Add the uniq() function. (LCD)
Files:      runtime/doc/change.txt, runtime/doc/eval.txt,
            runtime/doc/usr_41.txt, runtime/doc/version7.txt, src/eval.c,
            src/testdir/test55.in, src/testdir/test55.ok


*** ../vim-7.4.217/runtime/doc/change.txt       2013-09-22 15:23:38.000000000 
+0200
--- runtime/doc/change.txt      2014-03-25 17:32:29.510040841 +0100
***************
*** 1645,1651 ****
  7. Sorting text                                               *sorting*
  
  Vim has a sorting function and a sorting command.  The sorting function can be
! found here: |sort()|.
  
                                                        *:sor* *:sort*
  :[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
--- 1650,1656 ----
  7. Sorting text                                               *sorting*
  
  Vim has a sorting function and a sorting command.  The sorting function can be
! found here: |sort()|, |uniq()|.
  
                                                        *:sor* *:sort*
  :[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
*** ../vim-7.4.217/runtime/doc/eval.txt 2014-02-23 23:38:58.820760280 +0100
--- runtime/doc/eval.txt        2014-03-25 17:47:18.750054467 +0100
***************
*** 326,331 ****
--- 327,333 ----
  Changing the order of items in a list: >
        :call sort(list)                " sort a list alphabetically
        :call reverse(list)             " reverse the order of items
+       :call uniq(sort(list))          " sort and remove duplicates
  
  
  For loop ~
***************
*** 1518,1523 ****
--- 1520,1526 ----
                startup.  These are the files that Vim remembers marks for.
                The length of the List is limited by the ' argument of the
                'viminfo' option (default is 100).
+               When the |viminfo| file is not used the List is empty.
                Also see |:oldfiles| and |c_#<|.
                The List can be modified, but this has no effect on what is
                stored in the |viminfo| file later.  If you use values other
***************
*** 2003,2008 ****
--- 2006,2013 ----
  type( {name})                 Number  type of variable {name}
  undofile( {name})             String  undo file name for {name}
  undotree()                    List    undo file tree
+ uniq( {list} [, {func} [, {dict}]])
+                               List    remove adjacent duplicates from a list
  values( {dict})                       List    values in {dict}
  virtcol( {expr})              Number  screen column of cursor or mark
  visualmode( [expr])           String  last visual mode used
***************
*** 5474,5493 ****
  
  
  sort({list} [, {func} [, {dict}]])                    *sort()* *E702*
!               Sort the items in {list} in-place.  Returns {list}.  If you
!               want a list to remain unmodified make a copy first: >
                        :let sortedlist = sort(copy(mylist))
  <             Uses the string representation of each item to sort on.
                Numbers sort after Strings, |Lists| after Numbers.
                For sorting text in the current buffer use |:sort|.
                When {func} is given and it is one then case is ignored.
-               {dict} is for functions with the "dict" attribute.  It will be
-               used to set the local variable "self". |Dictionary-function|
                When {func} is a |Funcref| or a function name, this function
                is called to compare items.  The function is invoked with two
                items as argument and must return zero if they are equal, 1 or
                bigger if the first one sorts after the second one, -1 or
                smaller if the first one sorts before the second one.
                Example: >
                        func MyCompare(i1, i2)
                           return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
--- 5491,5516 ----
  
  
  sort({list} [, {func} [, {dict}]])                    *sort()* *E702*
!               Sort the items in {list} in-place.  Returns {list}.
!               
!               If you want a list to remain unmodified make a copy first: >
                        :let sortedlist = sort(copy(mylist))
  <             Uses the string representation of each item to sort on.
                Numbers sort after Strings, |Lists| after Numbers.
                For sorting text in the current buffer use |:sort|.
+ 
                When {func} is given and it is one then case is ignored.
                When {func} is a |Funcref| or a function name, this function
                is called to compare items.  The function is invoked with two
                items as argument and must return zero if they are equal, 1 or
                bigger if the first one sorts after the second one, -1 or
                smaller if the first one sorts before the second one.
+ 
+               {dict} is for functions with the "dict" attribute.  It will be
+               used to set the local variable "self". |Dictionary-function|
+ 
+               Also see |uniq()|.
+ 
                Example: >
                        func MyCompare(i1, i2)
                           return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
***************
*** 6155,6160 ****
--- 6178,6191 ----
                                blocks.  Each item may again have an "alt"
                                item.
  
+ uniq({list} [, {func} [, {dict}]])                    *uniq()* *E882*
+               Remove second and succeeding copies of repeated adjacent
+               {list} items in-place.  Returns {list}.  If you want a list
+               to remain unmodified make a copy first: >
+                       :let newlist = uniq(copy(mylist))
+ <             The default compare function uses the string representation of
+               each item.  For the use of {func} and {dict} see |sort()|.
+ 
  values({dict})                                                *values()*
                Return a |List| with all the values of {dict}.  The |List| is
                in arbitrary order.
*** ../vim-7.4.217/runtime/doc/usr_41.txt       2013-08-10 13:25:05.000000000 
+0200
--- runtime/doc/usr_41.txt      2014-03-25 17:32:29.518040841 +0100
***************
*** 1,4 ****
! *usr_41.txt*  For Vim version 7.4.  Last change: 2013 Feb 20
  
                     VIM USER MANUAL - by Bram Moolenaar
  
--- 1,4 ----
! *usr_41.txt*  For Vim version 7.4.  Last change: 2014 Jan 10
  
                     VIM USER MANUAL - by Bram Moolenaar
  
***************
*** 595,607 ****
        matchlist()             like matchstr() and also return submatches
        stridx()                first index of a short string in a long string
        strridx()               last index of a short string in a long string
!       strlen()                length of a string
        substitute()            substitute a pattern match with a string
        submatch()              get a specific match in ":s" and substitute()
        strpart()               get part of a string
        expand()                expand special keywords
        iconv()                 convert text from one encoding to another
        byteidx()               byte index of a character in a string
        repeat()                repeat a string multiple times
        eval()                  evaluate a string expression
  
--- 595,611 ----
        matchlist()             like matchstr() and also return submatches
        stridx()                first index of a short string in a long string
        strridx()               last index of a short string in a long string
!       strlen()                length of a string in bytes
!       strchars()              length of a string in characters
!       strwidth()              size of string when displayed
!       strdisplaywidth()       size of string when displayed, deals with tabs
        substitute()            substitute a pattern match with a string
        submatch()              get a specific match in ":s" and substitute()
        strpart()               get part of a string
        expand()                expand special keywords
        iconv()                 convert text from one encoding to another
        byteidx()               byte index of a character in a string
+       byteidxcomp()           like byteidx() but count composing characters
        repeat()                repeat a string multiple times
        eval()                  evaluate a string expression
  
***************
*** 619,624 ****
--- 623,629 ----
        map()                   change each List item
        sort()                  sort a List
        reverse()               reverse the order of a List
+       uniq()                  remove copies of repeated adjacent items
        split()                 split a String into a List
        join()                  join List items into a String
        range()                 return a List with a sequence of numbers
***************
*** 656,661 ****
--- 661,669 ----
        ceil()                  round up
        floor()                 round down
        trunc()                 remove value after decimal point
+       fmod()                  remainder of division
+       exp()                   exponential
+       log()                   natural logarithm (logarithm to base e)
        log10()                 logarithm to base 10
        pow()                   value of x to the exponent y
        sqrt()                  square root
***************
*** 675,680 ****
--- 683,689 ----
        invert()                bitwise invert
        or()                    bitwise OR
        xor()                   bitwise XOR
+       sha256()                SHA-256 hash
  
  Variables:                                            *var-functions*
        type()                  type of a variable
***************
*** 697,707 ****
--- 706,720 ----
        wincol()                window column number of the cursor
        winline()               window line number of the cursor
        cursor()                position the cursor at a line/column
+       screencol()             get screen column of the cursor
+       screenrow()             get screen row of the cursor
        getpos()                get position of cursor, mark, etc.
        setpos()                set position of cursor, mark, etc.
        byte2line()             get line number at a specific byte count
        line2byte()             byte count at a specific line
        diff_filler()           get the number of filler lines above a line
+       screenattr()            get attribute at a screen line/row
+       screenchar()            get character code at a screen line/row
  
  Working with text in the current buffer:              *text-functions*
        getline()               get a line or list of lines from the buffer
***************
*** 883,896 ****
--- 896,917 ----
        libcall()               call a function in an external library
        libcallnr()             idem, returning a number
  
+       undofile()              get the name of the undo file
+       undotree()              return the state of the undo tree
+ 
        getreg()                get contents of a register
        getregtype()            get type of a register
        setreg()                set contents and type of a register
  
+       shiftwidth()            effective value of 'shiftwidth'
+ 
        taglist()               get list of matching tags
        tagfiles()              get a list of tags files
  
+       luaeval()               evaluate Lua expression
        mzeval()                evaluate |MzScheme| expression
+       py3eval()               evaluate Python expression (|+python3|)
+       pyeval()                evaluate Python expression (|+python|)
  
  ==============================================================================
  *41.7*        Defining a function
*** ../vim-7.4.217/runtime/doc/version7.txt     2013-08-10 14:23:06.000000000 
+0200
--- runtime/doc/version7.txt    2014-03-25 17:32:29.518040841 +0100
***************
*** 942,947 ****
--- 942,948 ----
  |tagfiles()|          List with tags file names
  |taglist()|           get list of matching tags (Yegappan Lakshmanan)
  |tr()|                        translate characters (Ron Aaron)
+ |uniq()|              remove copies of repeated adjacent list items
  |values()|            get List of Dictionary values
  |winnr()|             takes an argument: what window to use
  |winrestview()|               restore the view of the current window
*** ../vim-7.4.217/src/eval.c   2014-03-23 15:12:29.915264336 +0100
--- src/eval.c  2014-03-25 17:52:09.554058923 +0100
***************
*** 744,749 ****
--- 744,750 ----
  static void f_type __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_undofile __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_undotree __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_uniq __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_values __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv));
  static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 8150,8155 ****
--- 8151,8157 ----
      {"type",          1, 1, f_type},
      {"undofile",      1, 1, f_undofile},
      {"undotree",      0, 0, f_undotree},
+     {"uniq",          1, 3, f_uniq},
      {"values",                1, 1, f_values},
      {"virtcol",               1, 1, f_virtcol},
      {"visualmode",    0, 1, f_visualmode},
***************
*** 17023,17032 ****
  static char_u *item_compare_func;
  static dict_T *item_compare_selfdict;
  static int    item_compare_func_err;
  #define ITEM_COMPARE_FAIL 999
  
  /*
!  * Compare functions for f_sort() below.
   */
      static int
  #ifdef __BORLANDC__
--- 17025,17035 ----
  static char_u *item_compare_func;
  static dict_T *item_compare_selfdict;
  static int    item_compare_func_err;
+ static void   do_sort_uniq __ARGS((typval_T *argvars, typval_T *rettv, int 
sort));
  #define ITEM_COMPARE_FAIL 999
  
  /*
!  * Compare functions for f_sort() and f_uniq() below.
   */
      static int
  #ifdef __BORLANDC__
***************
*** 17100,17108 ****
   * "sort({list})" function
   */
      static void
! f_sort(argvars, rettv)
      typval_T  *argvars;
      typval_T  *rettv;
  {
      list_T    *l;
      listitem_T        *li;
--- 17103,17112 ----
   * "sort({list})" function
   */
      static void
! do_sort_uniq(argvars, rettv, sort)
      typval_T  *argvars;
      typval_T  *rettv;
+     int               sort;
  {
      list_T    *l;
      listitem_T        *li;
***************
*** 17111,17122 ****
      long      i;
  
      if (argvars[0].v_type != VAR_LIST)
!       EMSG2(_(e_listarg), "sort()");
      else
      {
        l = argvars[0].vval.v_list;
        if (l == NULL || tv_check_lock(l->lv_lock,
!                                            (char_u *)_("sort() argument")))
            return;
        rettv->vval.v_list = l;
        rettv->v_type = VAR_LIST;
--- 17115,17126 ----
      long      i;
  
      if (argvars[0].v_type != VAR_LIST)
!       EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
      else
      {
        l = argvars[0].vval.v_list;
        if (l == NULL || tv_check_lock(l->lv_lock,
!              (char_u *)(sort ? _("sort() argument") : _("uniq() argument"))))
            return;
        rettv->vval.v_list = l;
        rettv->v_type = VAR_LIST;
***************
*** 17163,17191 ****
        ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
        if (ptrs == NULL)
            return;
-       i = 0;
-       for (li = l->lv_first; li != NULL; li = li->li_next)
-           ptrs[i++] = li;
  
!       item_compare_func_err = FALSE;
!       /* test the compare function */
!       if (item_compare_func != NULL
!               && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
                                                         == ITEM_COMPARE_FAIL)
!           EMSG(_("E702: Sort compare function failed"));
        else
        {
!           /* Sort the array with item pointers. */
!           qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
!                   item_compare_func == NULL ? item_compare : item_compare2);
  
            if (!item_compare_func_err)
            {
!               /* Clear the List and append the items in the sorted order. */
!               l->lv_first = l->lv_last = l->lv_idx_item = NULL;
!               l->lv_len = 0;
!               for (i = 0; i < len; ++i)
!                   list_append(l, ptrs[i]);
            }
        }
  
--- 17167,17238 ----
        ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
        if (ptrs == NULL)
            return;
  
!       i = 0;
!       if (sort)
!       {
!           /* sort(): ptrs will be the list to sort */
!           for (li = l->lv_first; li != NULL; li = li->li_next)
!               ptrs[i++] = li;
! 
!           item_compare_func_err = FALSE;
!           /* test the compare function */
!           if (item_compare_func != NULL
!                   && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
                                                         == ITEM_COMPARE_FAIL)
!               EMSG(_("E702: Sort compare function failed"));
!           else
!           {
!               /* Sort the array with item pointers. */
!               qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
!                   item_compare_func == NULL ? item_compare : item_compare2);
! 
!               if (!item_compare_func_err)
!               {
!                   /* Clear the List and append the items in sorted order. */
!                   l->lv_first = l->lv_last = l->lv_idx_item = NULL;
!                   l->lv_len = 0;
!                   for (i = 0; i < len; ++i)
!                       list_append(l, ptrs[i]);
!               }
!           }
!       }
        else
        {
!           int (*item_compare_func_ptr)__ARGS((const void *, const void *));
! 
!           /* f_uniq(): ptrs will be a stack of items to remove */
!           item_compare_func_err = FALSE;
!           item_compare_func_ptr = item_compare_func
!                                              ? item_compare2 : item_compare;
! 
!           for (li = l->lv_first; li != NULL && li->li_next != NULL;
!                                                            li = li->li_next)
!           {
!               if (item_compare_func_ptr((void *)&li, (void *)&li->li_next)
!                                                                        == 0)
!                   ptrs[i++] = li;
!               if (item_compare_func_err)
!               {
!                   EMSG(_("E882: Uniq compare function failed"));
!                   break;
!               }
!           }
  
            if (!item_compare_func_err)
            {
!               while (--i >= 0)
!               {
!                   li = ptrs[i]->li_next;
!                   ptrs[i]->li_next = li->li_next;
!                   if (li->li_next != NULL)
!                       li->li_next->li_prev = ptrs[i];
!                   else
!                       l->lv_last = ptrs[i];
!                   list_fix_watch(l, li);
!                   listitem_free(li);
!                   l->lv_len--;
!               }
            }
        }
  
***************
*** 17194,17199 ****
--- 17241,17268 ----
  }
  
  /*
+  * "sort({list})" function
+  */
+     static void
+ f_sort(argvars, rettv)
+     typval_T  *argvars;
+     typval_T  *rettv;
+ {
+     do_sort_uniq(argvars, rettv, TRUE);
+ }
+ 
+ /*
+  * "uniq({list})" function
+  */
+     static void
+ f_uniq(argvars, rettv)
+     typval_T  *argvars;
+     typval_T  *rettv;
+ {
+     do_sort_uniq(argvars, rettv, FALSE);
+ }
+ 
+ /*
   * "soundfold({word})" function
   */
      static void
*** ../vim-7.4.217/src/testdir/test55.in        2014-01-14 15:24:24.000000000 
+0100
--- src/testdir/test55.in       2014-03-25 17:32:29.522040841 +0100
***************
*** 323,335 ****
  :  $put ='caught ' . v:exception
  :endtry
  :"
! :" reverse() and sort()
! :let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8']
  :$put =string(reverse(l))
  :$put =string(reverse(reverse(l)))
  :$put =string(sort(l))
  :$put =string(reverse(sort(l)))
  :$put =string(sort(reverse(sort(l))))
  :"
  :" splitting a string to a List
  :$put =string(split('  aa  bb '))
--- 323,337 ----
  :  $put ='caught ' . v:exception
  :endtry
  :"
! :" reverse(), sort(), uniq()
! :let l = ['-0', 'A11', 2, 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 
'x8', [0, 1, 2], 1.5]
! :$put =string(uniq(copy(l)))
  :$put =string(reverse(l))
  :$put =string(reverse(reverse(l)))
  :$put =string(sort(l))
  :$put =string(reverse(sort(l)))
  :$put =string(sort(reverse(sort(l))))
+ :$put =string(uniq(sort(l)))
  :"
  :" splitting a string to a List
  :$put =string(split('  aa  bb '))
*** ../vim-7.4.217/src/testdir/test55.ok        2014-01-14 15:24:24.000000000 
+0100
--- src/testdir/test55.ok       2014-03-25 17:32:29.522040841 +0100
***************
*** 94,104 ****
  caught a:000[2]
  caught a:000[3]
  [1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]
! ['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
! ['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0']
! ['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
! [[0, 1, 2], 4, 2, 'xaaa', 'x8', 'foo6', 'foo', 'A11', '-0']
! ['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]]
  ['aa', 'bb']
  ['aa', 'bb']
  ['', 'aa', 'bb', '']
--- 94,106 ----
  caught a:000[2]
  caught a:000[3]
  [1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]
! ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 
1.5]
! [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 
'A11', '-0']
! [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 
'A11', '-0']
! ['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], 
[0, 1, 2]]
! [[0, 1, 2], [0, 1, 2], 4, 2, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'foo', 
'A11', '-0']
! ['-0', 'A11', 'foo', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 2, 4, [0, 1, 2], 
[0, 1, 2]]
! ['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]]
  ['aa', 'bb']
  ['aa', 'bb']
  ['', 'aa', 'bb', '']
*** ../vim-7.4.217/src/version.c        2014-03-25 18:05:45.242071421 +0100
--- src/version.c       2014-03-25 17:34:51.918043023 +0100
***************
*** 736,737 ****
--- 736,739 ----
  {   /* Add new patch number below this line */
+ /**/
+     218,
  /**/

-- 
Never under any circumstances take a sleeping pill
and a laxative on the same night.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui