mirror of
https://github.com/vim/vim.git
synced 2025-09-04 21:33:48 -04:00
updated for version 7.4.218
Problem: It's not easy to remove duplicates from a list. Solution: Add the uniq() function. (LCD)
This commit is contained in:
parent
1a3eb8e1b5
commit
327aa02dda
@ -1650,7 +1650,7 @@ And a few warnings:
|
|||||||
7. Sorting text *sorting*
|
7. Sorting text *sorting*
|
||||||
|
|
||||||
Vim has a sorting function and a sorting command. The sorting function can be
|
Vim has a sorting function and a sorting command. The sorting function can be
|
||||||
found here: |sort()|.
|
found here: |sort()|, |uniq()|.
|
||||||
|
|
||||||
*:sor* *:sort*
|
*:sor* *:sort*
|
||||||
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
|
:[range]sor[t][!] [i][u][r][n][x][o] [/{pattern}/]
|
||||||
|
@ -327,6 +327,7 @@ examples: >
|
|||||||
Changing the order of items in a list: >
|
Changing the order of items in a list: >
|
||||||
:call sort(list) " sort a list alphabetically
|
:call sort(list) " sort a list alphabetically
|
||||||
:call reverse(list) " reverse the order of items
|
:call reverse(list) " reverse the order of items
|
||||||
|
:call uniq(sort(list)) " sort and remove duplicates
|
||||||
|
|
||||||
|
|
||||||
For loop ~
|
For loop ~
|
||||||
@ -2005,6 +2006,8 @@ trunc( {expr}) Float truncate Float {expr}
|
|||||||
type( {name}) Number type of variable {name}
|
type( {name}) Number type of variable {name}
|
||||||
undofile( {name}) String undo file name for {name}
|
undofile( {name}) String undo file name for {name}
|
||||||
undotree() List undo file tree
|
undotree() List undo file tree
|
||||||
|
uniq( {list} [, {func} [, {dict}]])
|
||||||
|
List remove adjacent duplicates from a list
|
||||||
values( {dict}) List values in {dict}
|
values( {dict}) List values in {dict}
|
||||||
virtcol( {expr}) Number screen column of cursor or mark
|
virtcol( {expr}) Number screen column of cursor or mark
|
||||||
visualmode( [expr]) String last visual mode used
|
visualmode( [expr]) String last visual mode used
|
||||||
@ -5488,20 +5491,26 @@ sinh({expr}) *sinh()*
|
|||||||
|
|
||||||
|
|
||||||
sort({list} [, {func} [, {dict}]]) *sort()* *E702*
|
sort({list} [, {func} [, {dict}]]) *sort()* *E702*
|
||||||
Sort the items in {list} in-place. Returns {list}. If you
|
Sort the items in {list} in-place. Returns {list}.
|
||||||
want a list to remain unmodified make a copy first: >
|
|
||||||
|
If you want a list to remain unmodified make a copy first: >
|
||||||
:let sortedlist = sort(copy(mylist))
|
:let sortedlist = sort(copy(mylist))
|
||||||
< Uses the string representation of each item to sort on.
|
< Uses the string representation of each item to sort on.
|
||||||
Numbers sort after Strings, |Lists| after Numbers.
|
Numbers sort after Strings, |Lists| after Numbers.
|
||||||
For sorting text in the current buffer use |:sort|.
|
For sorting text in the current buffer use |:sort|.
|
||||||
|
|
||||||
When {func} is given and it is one then case is ignored.
|
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
|
When {func} is a |Funcref| or a function name, this function
|
||||||
is called to compare items. The function is invoked with two
|
is called to compare items. The function is invoked with two
|
||||||
items as argument and must return zero if they are equal, 1 or
|
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
|
bigger if the first one sorts after the second one, -1 or
|
||||||
smaller if the first one sorts before the second one.
|
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: >
|
Example: >
|
||||||
func MyCompare(i1, i2)
|
func MyCompare(i1, i2)
|
||||||
return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
|
return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
|
||||||
@ -6169,6 +6178,14 @@ undotree() *undotree()*
|
|||||||
blocks. Each item may again have an "alt"
|
blocks. Each item may again have an "alt"
|
||||||
item.
|
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()*
|
values({dict}) *values()*
|
||||||
Return a |List| with all the values of {dict}. The |List| is
|
Return a |List| with all the values of {dict}. The |List| is
|
||||||
in arbitrary order.
|
in arbitrary order.
|
||||||
|
@ -942,6 +942,7 @@ New and extended functions: ~
|
|||||||
|tagfiles()| List with tags file names
|
|tagfiles()| List with tags file names
|
||||||
|taglist()| get list of matching tags (Yegappan Lakshmanan)
|
|taglist()| get list of matching tags (Yegappan Lakshmanan)
|
||||||
|tr()| translate characters (Ron Aaron)
|
|tr()| translate characters (Ron Aaron)
|
||||||
|
|uniq()| remove copies of repeated adjacent list items
|
||||||
|values()| get List of Dictionary values
|
|values()| get List of Dictionary values
|
||||||
|winnr()| takes an argument: what window to use
|
|winnr()| takes an argument: what window to use
|
||||||
|winrestview()| restore the view of the current window
|
|winrestview()| restore the view of the current window
|
||||||
|
109
src/eval.c
109
src/eval.c
@ -744,6 +744,7 @@ static void f_trunc __ARGS((typval_T *argvars, typval_T *rettv));
|
|||||||
static void f_type __ARGS((typval_T *argvars, typval_T *rettv));
|
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_undofile __ARGS((typval_T *argvars, typval_T *rettv));
|
||||||
static void f_undotree __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_values __ARGS((typval_T *argvars, typval_T *rettv));
|
||||||
static void f_virtcol __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));
|
static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv));
|
||||||
@ -8150,6 +8151,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},
|
||||||
@ -17023,10 +17025,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 __ARGS((typval_T *argvars, typval_T *rettv, int 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
|
static int
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
@ -17100,9 +17103,10 @@ item_compare2(s1, s2)
|
|||||||
* "sort({list})" function
|
* "sort({list})" function
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
f_sort(argvars, rettv)
|
do_sort_uniq(argvars, rettv, sort)
|
||||||
typval_T *argvars;
|
typval_T *argvars;
|
||||||
typval_T *rettv;
|
typval_T *rettv;
|
||||||
|
int sort;
|
||||||
{
|
{
|
||||||
list_T *l;
|
list_T *l;
|
||||||
listitem_T *li;
|
listitem_T *li;
|
||||||
@ -17111,12 +17115,12 @@ f_sort(argvars, rettv)
|
|||||||
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;
|
||||||
@ -17163,29 +17167,72 @@ f_sort(argvars, rettv)
|
|||||||
ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
|
ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *)));
|
||||||
if (ptrs == NULL)
|
if (ptrs == NULL)
|
||||||
return;
|
return;
|
||||||
i = 0;
|
|
||||||
for (li = l->lv_first; li != NULL; li = li->li_next)
|
|
||||||
ptrs[i++] = li;
|
|
||||||
|
|
||||||
item_compare_func_err = FALSE;
|
i = 0;
|
||||||
/* test the compare function */
|
if (sort)
|
||||||
if (item_compare_func != NULL
|
{
|
||||||
&& item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
|
/* 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)
|
== ITEM_COMPARE_FAIL)
|
||||||
EMSG(_("E702: Sort compare function failed"));
|
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
|
else
|
||||||
{
|
{
|
||||||
/* Sort the array with item pointers. */
|
int (*item_compare_func_ptr)__ARGS((const void *, const void *));
|
||||||
qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *),
|
|
||||||
item_compare_func == NULL ? item_compare : item_compare2);
|
/* 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)
|
if (!item_compare_func_err)
|
||||||
{
|
{
|
||||||
/* Clear the List and append the items in the sorted order. */
|
while (--i >= 0)
|
||||||
l->lv_first = l->lv_last = l->lv_idx_item = NULL;
|
{
|
||||||
l->lv_len = 0;
|
li = ptrs[i]->li_next;
|
||||||
for (i = 0; i < len; ++i)
|
ptrs[i]->li_next = li->li_next;
|
||||||
list_append(l, ptrs[i]);
|
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--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17193,6 +17240,28 @@ f_sort(argvars, rettv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "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
|
* "soundfold({word})" function
|
||||||
*/
|
*/
|
||||||
|
@ -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 '))
|
||||||
|
@ -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', '']
|
||||||
|
@ -734,6 +734,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
218,
|
||||||
/**/
|
/**/
|
||||||
217,
|
217,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user