Hi Ingo!

On Mo, 26 Mai 2014, Ingo Karkat wrote:

> Hello Vim developers,
> 
> I have a custom surround function that basically does this:
> 
>     let save_cursor = getpos('.')
>     execute "normal! eaXY\<Esc>"
>     call setpos('.', save_cursor)
> 
> And this correctly restores the cursor to the original position. But
> when I move down a line (with "j", same with "k" btw.) immediately after
> triggering this, the cursor jumps to the column of the last insert (the
> "Y" in the example above). This does not happen when:
> - a (no-op) move within the same line is performed (e.g. "l" followed by
> "h") before the "j"
> - cursor() is used instead of setpos('.')
> 
> I can reproduce this down to Vim version 7.0. Interestingly, in Vim
> 7.0.000, the cursor() function is also affected, but that starts working
> in Vim 7.1.000. I see this in the latest Vim 7.4.307 (HUGE build) on
> Linux/x64, as well as Vim 7.4.264 on Windows/x64.
> 
> You can reproduce this with the attached scriptlet:
> 
>     $ vim -N -u NONE -S bug-cursor-j.vim
> 
> Or by executing this in the middle of some text:
> 
>     let save_cursor = getpos('.')|execute "normal! eaXY\<Esc>"|call
> setpos('.', save_cursor)|normal! j
> 
> The problematic call incorrectly positions the cursor (represented by |)
> on the last insert column, instead of the column of the "B" where the
> function was triggered:
> 
> QuickBrownFoxJumpsOverMe |he he
> Quick|BrownFoxJumpsOverMe he he

This has been discussed before:
https://groups.google.com/d/msg/vim_dev/xTa0kHWkY_o/ZXDq-HCifWsJ
https://groups.google.com/d/msg/vim_dev/o9GRXaJMwHg/9g8INNnNB9YJ

As suggested by ZyX in one of the threads, here is a patch, that allows 
to explicitly set curswant by enhancing the winrestview() function call.

This means, you have to add an additional call to winrestview() like 
this:
    :call winrestview({'curswant':5})
to make Vim request to stay in column *6* on vertical movement. Yes, 
there is a difference between the column number getpos() and 
winsaveview() returns.

Best,
Christian
-- 

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -6395,6 +6395,16 @@ winrestcmd()	Returns a sequence of |:res
 winrestview({dict})
 		Uses the |Dictionary| returned by |winsaveview()| to restore
 		the view of the current window.
+		Note: The {dict} does not have to contain all values, that are
+		returned by |winsaveview()|. If values are missing, those
+		settings won't be restored. So you can use: >
+		    :call winrestview({'curswant': 4})
+<
+		This will only set the curswant value (the column the cursor
+		wants to move on vertical movements) of the cursor to column 5
+		(yes, that is 5), while all other settings will remain the
+		same. This is useful, if you set the cursor position manually.
+
 		If you have changed the values the result is unpredictable.
 		If the window size changed the result won't be the same.
 
@@ -6409,7 +6419,9 @@ winsaveview()	Returns a |Dictionary| tha
 		not opened when moving around.
 		The return value includes:
 			lnum		cursor line number
-			col		cursor column
+			col		cursor column (Note: the first column
+					zero, as opposed to what getpos()
+					returns)
 			coladd		cursor column offset for 'virtualedit'
 			curswant	column for vertical movement
 			topline		first line in the window
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -19229,20 +19229,30 @@ f_winrestview(argvars, rettv)
 	EMSG(_(e_invarg));
     else
     {
-	curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
-	curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
+	if (dict_find(dict, (char_u *)"lnum", -1) != NULL)
+	    curwin->w_cursor.lnum = get_dict_number(dict, (char_u *)"lnum");
+	if (dict_find(dict, (char_u *)"col", -1) != NULL)
+	    curwin->w_cursor.col = get_dict_number(dict, (char_u *)"col");
 #ifdef FEAT_VIRTUALEDIT
-	curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
-#endif
-	curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
-	curwin->w_set_curswant = FALSE;
-
-	set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
+	if (dict_find(dict, (char_u *)"coladd", -1) != NULL)
+	    curwin->w_cursor.coladd = get_dict_number(dict, (char_u *)"coladd");
+#endif
+	if (dict_find(dict, (char_u *)"curswant", -1) != NULL)
+	{
+	    curwin->w_curswant = get_dict_number(dict, (char_u *)"curswant");
+	    curwin->w_set_curswant = FALSE;
+	}
+
+	if (dict_find(dict, (char_u *)"topline", -1) != NULL)
+	    set_topline(curwin, get_dict_number(dict, (char_u *)"topline"));
 #ifdef FEAT_DIFF
-	curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
-#endif
-	curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
-	curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
+	if (dict_find(dict, (char_u *)"topfill", -1) != NULL)
+	    curwin->w_topfill = get_dict_number(dict, (char_u *)"topfill");
+#endif
+	if (dict_find(dict, (char_u *)"leftcol", -1) != NULL)
+	    curwin->w_leftcol = get_dict_number(dict, (char_u *)"leftcol");
+	if (dict_find(dict, (char_u *)"skipcol", -1) != NULL)
+	    curwin->w_skipcol = get_dict_number(dict, (char_u *)"skipcol");
 
 	check_cursor();
 	win_new_height(curwin, curwin->w_height);

Raspunde prin e-mail lui