updated for version 7.4.310
Problem:    getpos()/setpos() don't include curswant.
Solution:   Add a fifth number when getting/setting the cursor.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 965c5b8..94cdf2b 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -2587,9 +2587,14 @@
 cursor({list})
 		Positions the cursor at the column (byte count) {col} in the
 		line {lnum}.  The first column is one.
+
 		When there is one argument {list} this is used as a |List|
-		with two or three items {lnum}, {col} and {off}.  This is like
-		the return value of |getpos()|, but without the first item.
+		with two, three or four item:
+			[{lnum}, {col}, {off}]
+			[{lnum}, {col}, {off}, {curswant}]
+		This is like the return value of |getpos()|, but without the
+		first item.
+
 		Does not change the jumplist.
 		If {lnum} is greater than the number of lines in the buffer,
 		the cursor will be positioned at the last line in the buffer.
@@ -4481,8 +4486,9 @@
 							*getpos()*
 getpos({expr})	Get the position for {expr}.  For possible values of {expr}
 		see |line()|.
-		The result is a |List| with four numbers:
+		The result is a |List| with four or five numbers:
 		    [bufnum, lnum, col, off]
+		    [bufnum, lnum, col, off, curswant]
 		"bufnum" is zero, unless a mark like '0 or 'A is used, then it
 		is the buffer number of the mark.
 		"lnum" and "col" are the position in the buffer.  The first
@@ -4491,6 +4497,8 @@
 		it is the offset in screen columns from the start of the
 		character.  E.g., a position within a <Tab> or after the last
 		character.
+		The "curswant" number is only added for getpos('.'), it is the
+		preferred column when moving the cursor vertically.
 		Note that for '< and '> Visual mode matters: when it is "V"
 		(visual line mode) the column of '< is zero and the column of
 		'> is a large number.
@@ -5298,8 +5306,9 @@
 			.	the cursor
 			'x	mark x
 
-		{list} must be a |List| with four numbers:
+		{list} must be a |List| with four or five numbers:
 		    [bufnum, lnum, col, off]
+		    [bufnum, lnum, col, off, curswant]
 
 		"bufnum" is the buffer number.	Zero can be used for the
 		current buffer.  Setting the cursor is only possible for
@@ -5317,6 +5326,12 @@
 		character.  E.g., a position within a <Tab> or after the last
 		character.
 
+		The "curswant" number is only used when setting the cursor
+		position.  It sets the preferred column for when moving the
+		cursor vertically.  When the "curswant" number is missing the
+		preferred column is not set.  When it is present and setting a
+		mark position it is not used.
+
 		Note that for '< and '> changing the line number may result in
 		the marks to be effectively be swapped, so that '< is always
 		before '>.
@@ -5327,7 +5342,10 @@
 		Also see |getpos()|
 
 		This does not restore the preferred column for moving
-		vertically.  See |winrestview()| for that.
+		vertically; if you set the cursor position with this, |j| and
+		|k| motions will jump to previous columns!  Use |cursor()| to
+		also set the preferred column.  Also see the "curswant" key in
+		|winrestview()|.
 
 
 setqflist({list} [, {action}])				*setqflist()*
diff --git a/src/eval.c b/src/eval.c
index 3d3c8b4..3d20d17 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -764,7 +764,7 @@
 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_xor __ARGS((typval_T *argvars, typval_T *rettv));
 
-static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump));
+static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump, colnr_T *curswantp));
 static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum));
 static int get_env_len __ARGS((char_u **arg));
 static int get_id_len __ARGS((char_u **arg));
@@ -9799,14 +9799,17 @@
     if (argvars[1].v_type == VAR_UNKNOWN)
     {
 	pos_T	    pos;
+	colnr_T	    curswant = -1;
 
-	if (list2fpos(argvars, &pos, NULL) == FAIL)
+	if (list2fpos(argvars, &pos, NULL, &curswant) == FAIL)
 	    return;
 	line = pos.lnum;
 	col = pos.col;
 #ifdef FEAT_VIRTUALEDIT
 	coladd = pos.coladd;
 #endif
+	if (curswant >= 0)
+	    curwin->w_curswant = curswant - 1;
     }
     else
     {
@@ -11770,6 +11773,8 @@
 				(fp != NULL) ? (varnumber_T)fp->coladd :
 #endif
 							      (varnumber_T)0);
+	if (fp == &curwin->w_cursor)
+	    list_append_number(l, (varnumber_T)curwin->w_curswant + 1);
     }
     else
 	rettv->vval.v_number = FALSE;
@@ -16751,12 +16756,13 @@
     pos_T	pos;
     int		fnum;
     char_u	*name;
+    colnr_T	curswant = -1;
 
     rettv->vval.v_number = -1;
     name = get_tv_string_chk(argvars);
     if (name != NULL)
     {
-	if (list2fpos(&argvars[1], &pos, &fnum) == OK)
+	if (list2fpos(&argvars[1], &pos, &fnum, &curswant) == OK)
 	{
 	    if (--pos.col < 0)
 		pos.col = 0;
@@ -16766,6 +16772,8 @@
 		if (fnum == curbuf->b_fnum)
 		{
 		    curwin->w_cursor = pos;
+		    if (curswant >= 0)
+			curwin->w_curswant = curswant - 1;
 		    check_cursor();
 		    rettv->vval.v_number = 0;
 		}
@@ -19532,21 +19540,22 @@
  * validity.
  */
     static int
-list2fpos(arg, posp, fnump)
+list2fpos(arg, posp, fnump, curswantp)
     typval_T	*arg;
     pos_T	*posp;
     int		*fnump;
+    colnr_T	*curswantp;
 {
     list_T	*l = arg->vval.v_list;
     long	i = 0;
     long	n;
 
-    /* List must be: [fnum, lnum, col, coladd], where "fnum" is only there
-     * when "fnump" isn't NULL and "coladd" is optional. */
+    /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only
+     * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */
     if (arg->v_type != VAR_LIST
 	    || l == NULL
 	    || l->lv_len < (fnump == NULL ? 2 : 3)
-	    || l->lv_len > (fnump == NULL ? 3 : 4))
+	    || l->lv_len > (fnump == NULL ? 4 : 5))
 	return FAIL;
 
     if (fnump != NULL)
@@ -19570,13 +19579,16 @@
     posp->col = n;
 
 #ifdef FEAT_VIRTUALEDIT
-    n = list_find_nr(l, i, NULL);
+    n = list_find_nr(l, i, NULL);	/* off */
     if (n < 0)
 	posp->coladd = 0;
     else
 	posp->coladd = n;
 #endif
 
+    if (curswantp != NULL)
+	*curswantp = list_find_nr(l, i + 1, NULL);  /* curswant */
+
     return OK;
 }
 
diff --git a/src/testdir/test_eval.in b/src/testdir/test_eval.in
index 11bc7e8..5a466d4 100644
--- a/src/testdir/test_eval.in
+++ b/src/testdir/test_eval.in
@@ -190,9 +190,18 @@
 :$put =v:exception
 :endtry
 :"
+:$put ='{{{1 setpos/getpos'
+/^012345678
+6l:let sp = getpos('.')
+0:call setpos('.', sp)
+jyl:$put
+:"
 :/^start:/+1,$wq! test.out
 :" vim: et ts=4 isk-=\: fmr=???,???
 :call getchar()
 ENDTEST
 
+012345678
+012345678
+
 start:
diff --git a/src/testdir/test_eval.ok b/src/testdir/test_eval.ok
index 313f39e..7bbce81 100644
--- a/src/testdir/test_eval.ok
+++ b/src/testdir/test_eval.ok
Binary files differ
diff --git a/src/version.c b/src/version.c
index 403a6e4..d817aa8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -735,6 +735,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    310,
+/**/
     309,
 /**/
     308,