I see erratic screen redraw (namely, curshor shown
past last line of file, or on wrong line (which is not line('.'))).
This vim 7.0.86 taken from svn today, including recent
fix to winrestcmd().

It happens after certain winrestview() when 'showcmd' is set.
This code works ok with 'noshowcmd'. (It took me a while to
track this down to 'showcmd' option specifically. The
context of this code is, I want to make "scrollfix" plugin which
locks cursor at Nth visual line, Nth line from top of screen).

To reproduce:

1. First, let's see how it works ok
 vim -u NONE -c 'so x.vim' x.vim
 press <Down> to end of file to see how it works ok.
 G gg G gg              " works ok

2. With 'showcmd', same code works very differently:

 vim -u NONE -c 'so x.vim' x.vim
 :set showcmd " this turns on the problem
 :set nu ruler statusline= laststatus=2    " this to watch the
                             " line number mismatch
  press <Down> repeatedly till eof
  BUG1: notice cursor draw past eof
  <Up>
  BUG2:  now notice the cursor is in line 25 but
              ':echo line(".")' shows line 26
  ggG
  BUG3: Now cursor is totally off-limits

Note that ':echo g:last' allows to see the dict
used in last winrestview() thanks to 'let g:last = dict'
line in x.vim.

Yakov
----------------------------- x.vim ----------------------------------
:let g:scroll_fix=5 " fix cursor fixed at fixed Nth visual line
:let so=0

aug scrollfix
   au!
   au CursorMoved * :call ScrollFix()
aug END

function! ScrollFix()
   if g:scroll_fix==0 | return | endif

   " keep cursor on fixed visual line of the window

   let dict = winsaveview()
   if dict['lnum'] <= g:scroll_fix | return | endif
   if dict['lnum'] - dict['topline'] + 1 == g:scroll_fix | return | endif
   let dict['topline'] = dict['lnum'] - g:scroll_fix + 1
   let g:last = dict " for debugging
   call winrestview(dict)
endfunction

Reply via email to