Christian Brabandt
unread,Nov 26, 2015, 5:00:16 PM11/26/15Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to vim...@vim.org
Bram,
there is a problem with getcurpos() and the matchparen plugin.
Consider this:
vim -u NONE -N -c 'ru plugin/matchparen.vim'
Type iaaaa{<enter>}<enter>aaaa
At this point, press CursorUp twice in insert mode. Note, the cursor
will be at column 2 instead of column 5.
The problem is the matchparen plugin:
,----
| fu! s:Highlight_Matching_Pair()
| if before > 0
| let has_getcurpos = exists("*getcurpos")
| if has_getcurpos
| " getcurpos() is more efficient but doesn't exist before 7.4.313.
| let save_cursor = getcurpos()
| else
| let save_cursor = winsaveview()
| endif
| call cursor(c_lnum, c_col - before)
| endif
| [...]
| if before > 0
| if has_getcurpos
| call setpos('.', save_cursor)
| else
| call winrestview(save_cursor)
| endif
| endif
| [...]
| endfu
`----
When the function finishes, the setpos() call will correctly set the
curwin->w_curswant column. Unfortunately, the cursor() function resets
the curwin->w_set_curswant flag to TRUE, so that in the next loop in
edit() curwin->w_curswant will be newly recalculated at edit() (Line 759
update_curswant()) and therefore invalidate the curswant argument from
the setpos() call.
Interestingly, this does not happen with older Vims, that do not have
the getcurpos() function. Because in that case the winrestview()
function will be called, which resets the curwin->w_set_curswant flag to
FALSE and then the problem does not occur.
I think, the setpos() function should also reset curwin->w_curswant, if
curswant argument has been given:
diff --git a/src/eval.c b/src/eval.c
--- a/src/eval.c
+++ b/src/eval.c
@@ -17375,7 +17375,10 @@ f_setpos(argvars, rettv)
{
curwin->w_cursor = pos;
if (curswant >= 0)
+ {
curwin->w_curswant = curswant - 1;
+ curwin->w_set_curswant = FALSE;
+ }
check_cursor();
rettv->vval.v_number = 0;
}
Alternatively, one could change the matchparen plugin like this:
--- matchparen.vim 2015-11-26 22:38:26.174851371 +0100
+++ matchparen.new.vim 2015-11-26 22:38:20.122775611 +0100
@@ -17,6 +17,7 @@
if !exists("g:matchparen_insert_timeout")
let g:matchparen_insert_timeout = 60
endif
+let s:has_getcurpos = exists("*getcurpos")
augroup matchparen
" Replace all matchparen autocommands
@@ -88,14 +89,17 @@
" Find the match. When it was just before the cursor move it there for a
" moment.
if before > 0
- let has_getcurpos = exists("*getcurpos")
- if has_getcurpos
+ " winrestview() uses 0-based col, while cursor() uses 1-based col
+ let col = c_col - before - s:has_getcurpos
+ if s:has_getcurpos
" getcurpos() is more efficient but doesn't exist before 7.4.313.
let save_cursor = getcurpos()
+ " use winrestview, which does not reset curwin->w_set_curswant
+ call winrestview({'lnum': c_lnum, 'col': col, 'curswant': save_cursor[4]})
else
let save_cursor = winsaveview()
+ call cursor(c_lnum, col)
endif
- call cursor(c_lnum, c_col - before)
endif
" Build an expression that detects whether the current cursor position is in
@@ -161,7 +165,7 @@
endtry
if before > 0
- if has_getcurpos
+ if s:has_getcurpos
call setpos('.', save_cursor)
else
call winrestview(save_cursor)
Best,
Christian
--
Der Teufelspakt des Wissenschaftlers ist seine Finanzierung durch
die Rüstungsindustrie.
-- Rolf Hochhuth