> Looks like you made a copy of f_sort() and modified it a bit.  That's a
> 
> lot of duplicate code.  Better move the common stuff into a function
> 
> that's used by both sort() and sortuniq().

Fixed

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
diff -r 5c956eeefc1b runtime/doc/change.txt
--- a/runtime/doc/change.txt    Tue Mar 18 23:36:13 2014 -0400
+++ b/runtime/doc/change.txt    Thu Mar 20 12:04:35 2014 +0700
@@ -1650,7 +1650,7 @@
 7. Sorting text                                                *sorting*
 
 Vim has a sorting function and a sorting command.  The sorting function can be
-found here: |sort()|.
+found here: |sort()|, |sortuniq()|.
 
                                                        *:sor* *:sort*
 :[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
diff -r 5c956eeefc1b runtime/doc/eval.txt
--- a/runtime/doc/eval.txt      Tue Mar 18 23:36:13 2014 -0400
+++ b/runtime/doc/eval.txt      Thu Mar 20 12:04:35 2014 +0700
@@ -326,6 +326,7 @@
 
 Changing the order of items in a list: >
        :call sort(list)                " sort a list alphabetically
+       :call sortuniq(list)            " sort a list and remove duplicates
        :call reverse(list)             " reverse the order of items
 
 
@@ -1956,6 +1957,8 @@
 sinh( {expr})                  Float   hyperbolic sine of {expr}
 sort( {list} [, {func} [, {dict}]])
                                List    sort {list}, using {func} to compare
+sortuniq( {list} [, {func} [, {dict}]])
+                               List    sort {list} and remove duplicates
 soundfold( {word})             String  sound-fold {word}
 spellbadword()                 String  badly spelled word at cursor
 spellsuggest( {word} [, {max} [, {capital}]])
@@ -5513,6 +5516,11 @@
                           return a:i1 - a:i2
                        endfunc
 <
+
+sortuniq({list} [, {func} [, {dict}]])                 *sortuniq()* *E702*
+               Sort the items in {list} as like |sort()| does and
+               remove duplicates.
+
                                                        *soundfold()*
 soundfold({word})
                Return the sound-folded equivalent of {word}.  Uses the first
diff -r 5c956eeefc1b runtime/doc/usr_41.txt
--- a/runtime/doc/usr_41.txt    Tue Mar 18 23:36:13 2014 -0400
+++ b/runtime/doc/usr_41.txt    Thu Mar 20 12:04:35 2014 +0700
@@ -622,6 +622,7 @@
        filter()                remove selected items from a List
        map()                   change each List item
        sort()                  sort a List
+       sortuniq()              sort a List and remove duplicate values
        reverse()               reverse the order of a List
        split()                 split a String into a List
        join()                  join List items into a String
diff -r 5c956eeefc1b runtime/doc/version7.txt
--- a/runtime/doc/version7.txt  Tue Mar 18 23:36:13 2014 -0400
+++ b/runtime/doc/version7.txt  Thu Mar 20 12:04:35 2014 +0700
@@ -927,6 +927,7 @@
 |setqflist()|          modify a quickfix list (Yegappan Lakshmanan)
 |settabwinvar()|       set variable in window of specified tab page
 |sort()|               sort a List
+|sortuniq()|           sort a List and remove duplicates
 |soundfold()|          get the sound-a-like equivalent of a word
 |spellbadword()|       get a badly spelled word
 |spellsuggest()|       get suggestions for correct spelling
diff -r 5c956eeefc1b src/eval.c
--- a/src/eval.c        Tue Mar 18 23:36:13 2014 -0400
+++ b/src/eval.c        Thu Mar 20 12:04:35 2014 +0700
@@ -93,6 +93,14 @@
     char_u     *ll_newkey;     /* New key for Dict in alloc. mem or NULL. */
 } lval_T;
 
+/*
+ * Structure used by sort_internal().
+ */
+typedef struct ulistitem_T
+{
+    listitem_T *ll_li;         /* list item */
+    int                is_duplicate;   /* TRUE, if item already in list */
+} ulistitem_T;
 
 static char *e_letunexp        = N_("E18: Unexpected characters in :let");
 static char *e_listidx = N_("E684: list index out of range: %ld");
@@ -695,6 +703,7 @@
 static void f_sinh __ARGS((typval_T *argvars, typval_T *rettv));
 #endif
 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_sortuniq __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv));
@@ -8101,6 +8110,7 @@
     {"sinh",           1, 1, f_sinh},
 #endif
     {"sort",           1, 3, f_sort},
+    {"sortuniq",       1, 3, f_sortuniq},
     {"soundfold",      1, 1, f_soundfold},
     {"spellbadword",   0, 1, f_spellbadword},
     {"spellsuggest",   1, 3, f_spellsuggest},
@@ -17027,6 +17037,11 @@
     _RTLENTRYF
 #endif
        item_compare2 __ARGS((const void *s1, const void *s2));
+static int
+#ifdef __BORLANDC__
+    _RTLENTRYF
+#endif
+       item_compare_uniq __ARGS((const void *s1, const void *s2));
 
 static int     item_compare_ic;
 static char_u  *item_compare_func;
@@ -17035,7 +17050,7 @@
 #define ITEM_COMPARE_FAIL 999
 
 /*
- * Compare functions for f_sort() below.
+ * Compare functions for f_sort() and f_sortuniq() below.
  */
     static int
 #ifdef __BORLANDC__
@@ -17045,14 +17060,18 @@
     const void *s1;
     const void *s2;
 {
+    ulistitem_T        *uli1, *uli2;
     char_u     *p1, *p2;
     char_u     *tofree1, *tofree2;
     int                res;
     char_u     numbuf1[NUMBUFLEN];
     char_u     numbuf2[NUMBUFLEN];
 
-    p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1, 0);
-    p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2, 0);
+    uli1 = (ulistitem_T *)s1;
+    uli2 = (ulistitem_T *)s2;
+
+    p1 = tv2string(&uli1->ll_li->li_tv, &tofree1, numbuf1, 0);
+    p2 = tv2string(&uli2->ll_li->li_tv, &tofree2, numbuf2, 0);
     if (p1 == NULL)
        p1 = (char_u *)"";
     if (p2 == NULL)
@@ -17074,19 +17093,23 @@
     const void *s1;
     const void *s2;
 {
+    ulistitem_T        *uli1, *uli2;
     int                res;
     typval_T   rettv;
     typval_T   argv[3];
     int                dummy;
 
+    uli1 = (ulistitem_T *)s1;
+    uli2 = (ulistitem_T *)s2;
+
     /* shortcut after failure in previous call; compare all items equal */
     if (item_compare_func_err)
        return 0;
 
     /* copy the values.  This is needed to be able to set v_lock to VAR_FIXED
      * in the copy without changing the original list items. */
-    copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]);
-    copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]);
+    copy_tv(&uli1->ll_li->li_tv, &argv[0]);
+    copy_tv(&uli2->ll_li->li_tv, &argv[1]);
 
     rettv.v_type = VAR_UNKNOWN;                /* clear_tv() uses this */
     res = call_func(item_compare_func, (int)STRLEN(item_compare_func),
@@ -17105,27 +17128,54 @@
     return res;
 }
 
-/*
- * "sort({list})" function
- */
-    static void
-f_sort(argvars, rettv)
-    typval_T   *argvars;
-    typval_T   *rettv;
+    static int
+#ifdef __BORLANDC__
+_RTLENTRYF
+#endif
+item_compare_uniq(s1, s2)
+    const void *s1;
+    const void *s2;
+{
+    ulistitem_T        *uli2;
+    int                res;
+
+    uli2 = (ulistitem_T *)s2;
+
+    if (item_compare_func)
+       res = item_compare2((void *)s1, (void *)s2);
+    else
+       res = item_compare((void *)s1, (void *)s2);
+
+    if ( res == 0 )
+    {
+       uli2->is_duplicate = TRUE;
+    }
+    return res;
+}
+
+    static void
+sort_internal(argvars, rettv, uniq)
+    typval_T   *argvars;
+    typval_T   *rettv;
+    int                uniq;
 {
     list_T     *l;
     listitem_T *li;
-    listitem_T **ptrs;
+    ulistitem_T        *ptrs;
+    ulistitem_T        *p;
     long       len;
     long       i;
+    int                error = FALSE;
 
     if (argvars[0].v_type != VAR_LIST)
-       EMSG2(_(e_listarg), "sort()");
+       EMSG2(_(e_listarg), uniq ? "sortuniq()" : "sort()");
     else
     {
        l = argvars[0].vval.v_list;
-       if (l == NULL || tv_check_lock(l->lv_lock,
-                                            (char_u *)_("sort() argument")))
+       i = tv_check_lock(l->lv_lock,
+               (char_u *)_( uniq ? "sortuniq() argument" :
+                                   "sort() argument"));
+       if (l == NULL || i)
            return;
        rettv->vval.v_list = l;
        rettv->v_type = VAR_LIST;
@@ -17145,8 +17195,6 @@
                item_compare_func = argvars[1].vval.v_string;
            else
            {
-               int         error = FALSE;
-
                i = get_tv_number_chk(&argvars[1], &error);
                if (error)
                    return;             /* type error; errmsg already given */
@@ -17169,32 +17217,48 @@
        }
 
        /* Make an array with each entry pointing to an item in the List. */
-       ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
+       ptrs = (ulistitem_T *)alloc((int)(len * sizeof(*ptrs)));
        if (ptrs == NULL)
            return;
-       i = 0;
+       p = ptrs;
        for (li = l->lv_first; li != NULL; li = li->li_next)
-           ptrs[i++] = li;
+       {
+           p->ll_li = li;
+           p->is_duplicate = FALSE;
+           p++;
+       }
 
        item_compare_func_err = FALSE;
        /* test the compare function */
        if (item_compare_func != NULL
-               && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
+               && item_compare2((void *)&ptrs[0].ll_li, (void *)&ptrs[1].ll_li)
                                                         == 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);
+           qsort((void *)ptrs, (size_t)len, sizeof(*ptrs),
+                   uniq ? item_compare_uniq : item_compare_func ? 
item_compare2 : item_compare);
 
            if (!item_compare_func_err)
            {
-               /* Clear the List and append the items in the sorted order. */
+               /* Clear the List and append the items in the sorted order.
+                * If needed, remove duplicates. */
                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]);
+               p = ptrs;
+               for (i = 0; i < len; ++i, ++p)
+               {
+                   if (uniq && p->is_duplicate)
+                   {
+                       list_fix_watch( l, p->ll_li );
+                       listitem_free( p->ll_li );
+                   }
+                   else
+                   {
+                       list_append(l, p->ll_li);
+                   }
+               }
            }
        }
 
@@ -17203,6 +17267,28 @@
 }
 
 /*
+ * "sort({list})" function
+ */
+    static void
+f_sort(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    return sort_internal(argvars, rettv, FALSE);
+}
+
+/*
+ * "sortuniq({list})" function
+ */
+    static void
+f_sortuniq(argvars, rettv)
+    typval_T   *argvars;
+    typval_T   *rettv;
+{
+    return sort_internal(argvars, rettv, TRUE);
+}
+
+/*
  * "soundfold({word})" function
  */
     static void
diff -r 5c956eeefc1b src/testdir/test55.in
--- a/src/testdir/test55.in     Tue Mar 18 23:36:13 2014 -0400
+++ b/src/testdir/test55.in     Thu Mar 20 12:04:35 2014 +0700
@@ -323,13 +323,16 @@
 :  $put ='caught ' . v:exception
 :endtry
 :"
-:" reverse() and sort()
-:let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8']
+:" reverse(), sort(), sortuniq()
+:let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8', [0, 1, 
2], 2, 'foo', 1.5]
 :$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(sortuniq(l))
+:$put =string(reverse(sortuniq(l)))
+:$put =string(sortuniq(reverse(sortuniq(l))))
 :"
 :" splitting a string to a List
 :$put =string(split('  aa  bb '))
diff -r 5c956eeefc1b src/testdir/test55.ok
--- a/src/testdir/test55.ok     Tue Mar 18 23:36:13 2014 -0400
+++ b/src/testdir/test55.ok     Thu Mar 20 12:04:35 2014 +0700
@@ -94,11 +94,14 @@
 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]]
+[1.5, 'foo', 2, [0, 1, 2], 'x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 
'A11', '-0']
+[1.5, 'foo', 2, [0, 1, 2], 'x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 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]]
+[[0, 1, 2], 4, 2, 1.5, 'xaaa', 'x8', 'foo6', 'foo', 'A11', '-0']
+['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 1.5, 2, 4, [0, 1, 2]]
 ['aa', 'bb']
 ['aa', 'bb']
 ['', 'aa', 'bb', '']

Raspunde prin e-mail lui