diff --git a/7.4.218 b/7.4.218 new file mode 100644 index 0000000..b878cb7 --- /dev/null +++ b/7.4.218 @@ -0,0 +1,578 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.4.218 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +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 -- Bram@Moolenaar.net -- 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 ///