vim-patch:7.4.218

Problem:  It's not easy to remove duplicates from a list.

Solution: Add the uniq() function. (LCD)

https://code.google.com/p/vim/source/detail?r=ddc3f32a4b2191f829206322d46f0e9c7e365e22
This commit is contained in:
Marco Hinz 2014-04-13 20:26:17 +02:00 committed by Thiago de Arruda
parent 98b0a6ffb4
commit f54c050cf3
4 changed files with 95 additions and 37 deletions

View File

@ -758,6 +758,7 @@ static void f_trunc(typval_T *argvars, typval_T *rettv);
static void f_type(typval_T *argvars, typval_T *rettv); static void f_type(typval_T *argvars, typval_T *rettv);
static void f_undofile(typval_T *argvars, typval_T *rettv); static void f_undofile(typval_T *argvars, typval_T *rettv);
static void f_undotree(typval_T *argvars, typval_T *rettv); static void f_undotree(typval_T *argvars, typval_T *rettv);
static void f_uniq(typval_T *argvars, typval_T *rettv);
static void f_values(typval_T *argvars, typval_T *rettv); static void f_values(typval_T *argvars, typval_T *rettv);
static void f_virtcol(typval_T *argvars, typval_T *rettv); static void f_virtcol(typval_T *argvars, typval_T *rettv);
static void f_visualmode(typval_T *argvars, typval_T *rettv); static void f_visualmode(typval_T *argvars, typval_T *rettv);
@ -7074,6 +7075,7 @@ static struct fst {
{"type", 1, 1, f_type}, {"type", 1, 1, f_type},
{"undofile", 1, 1, f_undofile}, {"undofile", 1, 1, f_undofile},
{"undotree", 0, 0, f_undotree}, {"undotree", 0, 0, f_undotree},
{"uniq", 1, 3, f_uniq},
{"values", 1, 1, f_values}, {"values", 1, 1, f_values},
{"virtcol", 1, 1, f_virtcol}, {"virtcol", 1, 1, f_virtcol},
{"visualmode", 0, 1, f_visualmode}, {"visualmode", 0, 1, f_visualmode},
@ -13777,10 +13779,11 @@ static int item_compare_ic;
static char_u *item_compare_func; static char_u *item_compare_func;
static dict_T *item_compare_selfdict; static dict_T *item_compare_selfdict;
static int item_compare_func_err; static int item_compare_func_err;
static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort);
#define ITEM_COMPARE_FAIL 999 #define ITEM_COMPARE_FAIL 999
/* /*
* Compare functions for f_sort() below. * Compare functions for f_sort() and f_uniq() below.
*/ */
static int item_compare(const void *s1, const void *s2) static int item_compare(const void *s1, const void *s2)
{ {
@ -13841,7 +13844,7 @@ static int item_compare2(const void *s1, const void *s2)
/* /*
* "sort({list})" function * "sort({list})" function
*/ */
static void f_sort(typval_T *argvars, typval_T *rettv) static void do_sort_uniq(typval_T *argvars, typval_T *rettv, bool sort)
{ {
list_T *l; list_T *l;
listitem_T *li; listitem_T *li;
@ -13849,13 +13852,14 @@ static void f_sort(typval_T *argvars, typval_T *rettv)
long len; long len;
long i; long i;
if (argvars[0].v_type != VAR_LIST) if (argvars[0].v_type != VAR_LIST) {
EMSG2(_(e_listarg), "sort()"); EMSG2(_(e_listarg), sort ? "sort()" : "uniq()");
else { } else {
l = argvars[0].vval.v_list; l = argvars[0].vval.v_list;
if (l == NULL || tv_check_lock(l->lv_lock, if (l == NULL || tv_check_lock(l->lv_lock,
(char_u *)_("sort() argument"))) (char_u *)(sort ? _("sort() argument") : _("uniq() argument")))) {
return; return;
}
rettv->vval.v_list = l; rettv->vval.v_list = l;
rettv->v_type = VAR_LIST; rettv->v_type = VAR_LIST;
++l->lv_refcount; ++l->lv_refcount;
@ -13867,11 +13871,12 @@ static void f_sort(typval_T *argvars, typval_T *rettv)
item_compare_ic = FALSE; item_compare_ic = FALSE;
item_compare_func = NULL; item_compare_func = NULL;
item_compare_selfdict = NULL; item_compare_selfdict = NULL;
if (argvars[1].v_type != VAR_UNKNOWN) { if (argvars[1].v_type != VAR_UNKNOWN) {
/* optional second argument: {func} */ /* optional second argument: {func} */
if (argvars[1].v_type == VAR_FUNC) if (argvars[1].v_type == VAR_FUNC) {
item_compare_func = argvars[1].vval.v_string; item_compare_func = argvars[1].vval.v_string;
else { } else {
int error = FALSE; int error = FALSE;
i = get_tv_number_chk(&argvars[1], &error); i = get_tv_number_chk(&argvars[1], &error);
@ -13894,37 +13899,86 @@ static void f_sort(typval_T *argvars, typval_T *rettv)
} }
/* Make an array with each entry pointing to an item in the List. */ /* Make an array with each entry pointing to an item in the List. */
ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); ptrs = xmalloc((size_t)(len * sizeof (listitem_T *)));
if (ptrs == NULL)
return;
i = 0; i = 0;
for (li = l->lv_first; li != NULL; li = li->li_next) if (sort) {
// sort(): ptrs will be the list to sort.
for (li = l->lv_first; li != NULL; li = li->li_next) {
ptrs[i++] = li; ptrs[i++] = li;
}
item_compare_func_err = FALSE; item_compare_func_err = FALSE;
/* test the compare function */ // Test the compare function.
if (item_compare_func != NULL if (item_compare_func != NULL
&& item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) && item_compare2(&ptrs[0], &ptrs[1]) == ITEM_COMPARE_FAIL) {
== ITEM_COMPARE_FAIL)
EMSG(_("E702: Sort compare function failed")); EMSG(_("E702: Sort compare function failed"));
else { } else {
/* Sort the array with item pointers. */ // Sort the array with item pointers.
qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), qsort(ptrs, (size_t)len, sizeof (listitem_T *),
item_compare_func == NULL ? item_compare : item_compare2); item_compare_func == NULL ? item_compare : item_compare2);
if (!item_compare_func_err) { 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.
l->lv_first = l->lv_last = l->lv_idx_item = NULL; l->lv_first = NULL;
l->lv_last = NULL;
l->lv_idx_item = NULL;
l->lv_len = 0; l->lv_len = 0;
for (i = 0; i < len; ++i)
for (i = 0; i < len; i++) {
list_append(l, ptrs[i]); list_append(l, ptrs[i]);
} }
} }
}
} else {
int (*item_compare_func_ptr)(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(&li, &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--;
}
}
}
vim_free(ptrs); vim_free(ptrs);
} }
} }
/// "sort"({list})" function
static void f_sort(typval_T *argvars, typval_T *rettv)
{
do_sort_uniq(argvars, rettv, true);
}
/// "uniq({list})" function
static void f_uniq(typval_T *argvars, typval_T *rettv)
{
do_sort_uniq(argvars, rettv, false);
}
/* /*
* "soundfold({word})" function * "soundfold({word})" function
*/ */

View File

@ -323,13 +323,15 @@ let l = [0, 1, 2, 3]
: $put ='caught ' . v:exception : $put ='caught ' . v:exception
:endtry :endtry
:" :"
:" reverse() and sort() :" reverse(), sort(), uniq()
:let l = ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', [0, 1, 2], 'x8'] :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(l))
:$put =string(reverse(reverse(l))) :$put =string(reverse(reverse(l)))
:$put =string(sort(l)) :$put =string(sort(l))
:$put =string(reverse(sort(l))) :$put =string(reverse(sort(l)))
:$put =string(sort(reverse(sort(l)))) :$put =string(sort(reverse(sort(l))))
:$put =string(uniq(sort(l)))
:" :"
:" splitting a string to a List :" splitting a string to a List
:$put =string(split(' aa bb ')) :$put =string(split(' aa bb '))

View File

@ -94,11 +94,13 @@ caught a:000[0]
caught a:000[2] caught a:000[2]
caught a:000[3] caught a:000[3]
[1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}] [1, 2, [3, 9, 5, 6], {'a': 12, '5': 8}]
['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0'] ['-0', 'A11', 2, 'xaaa', 4, 'foo', 'foo6', 'foo', [0, 1, 2], 'x8', [0, 1, 2], 1.5]
['x8', [0, 1, 2], 'foo6', 'foo', 4, 'xaaa', 2, 'A11', '-0'] [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0']
['-0', 'A11', 'foo', 'foo6', 'x8', 'xaaa', 2, 4, [0, 1, 2]] [1.5, [0, 1, 2], 'x8', [0, 1, 2], 'foo', 'foo6', 'foo', 4, 'xaaa', 2, 2, 'A11', '-0']
[[0, 1, 2], 4, 2, 'xaaa', 'x8', 'foo6', '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', 2, 4, [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'] ['aa', 'bb']
['', 'aa', 'bb', ''] ['', 'aa', 'bb', '']

View File

@ -243,7 +243,7 @@ static int included_patches[] = {
//221, //221,
//220, //220,
219, 219,
//218, 218,
//217, //217,
//216, //216,
215, 215,