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 <Bram@moolenaar.net>
+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    ///