On Fri, 16 Mar 2012, Dotan Cohen wrote:
Hi all, I am having a real hard time with an indeterminate bug in a
VIM function. First, here is the function:
[...]
set statusline+=%{WhatFunctionAreWeIn()}
fun WhatFunctionAreWeIn()
[...]
This function displays the current PHP function name in the status
bar. It is derived from this gem:
http://vim.wikia.com/wiki/VimTip1296
Both the original function from the VIM wiki and my derived version
suffer an indeterminate bug. Sometimes when scrolling down with J the
cursor will "jump" to the wrong location. When this happens one can
simply `z to bring the cursor back to where it should be. I would say
that about one line in every 100 lines of PHP that I have triggers the
bug.
There are at least two things going on:
1. items in an 'stl' %{} group are expanded. So, if you ever return a
line that contains a '%', you'll have trouble. I worked around this by
renaming your function from WhatFunctionAreWeIn to
RawWhatFunctionAreWeIn, then creating:
fun! WhatFunctionAreWeIn()
let stl=RawWhatFunctionAreWeIn()
let stl=substitute(stl, '\t', ' ', 'g') " tabs don't show up right
let stl=substitute(stl, '%', '%%', 'g') " need to escape %'s
return stl
endfun
2. The :help for 'stl' states that you shouldn't change text or jump to
another window. (See :help textlock).
But, even more strongly, you *probably* shouldn't move the cursor in a
function called from 'stl'. When your function calls [{ to find the
prior block, it moves the displayed text. That's what causes the jump.
The problem is that the sequence of events for updating the displayed
text seems to vary for different types of movement. I was unable to
trigger the bug with <C-d> and <C-u> movement, for example. But, I
could pretty consistently trigger it (when viewing Vim help files) by
rapidly using 'k' to move up a single line.
Here's a much simpler function for what you're trying to do (also more
naïve, but it's a trade-off):
" still used in the same way:
" e.g.: set statusline+=%{WhatFunctionAreWeIn()}
fun! StatusLineSafe(txt)
let stl = a:txt
let stl = substitute(stl, '\t', ' ', 'g') " tabs don't show up right
let stl = substitute(stl, '%', '%%', 'g') " need to escape %'s
return stl
endfun
fun! WhatFunctionAreWeIn()
let strList = ['function', 'class']
let lnum = line('.') - 1
while lnum > 0
let line = getline(lnum)
let lnum -= 1
if line =~ '^\s*#' " simple improvement to skip comments
continue
endif
for item in strList
let position = match(line, '\<'.item.'\>')
if position >= 0
break
endif
endfor
if position >= 0
return StatusLineSafe("[line ".(lnum+1)."] ".line)
endif
endwhile
return '' " return empty string if it's unknown
endfun
--
Best,
Ben
--
You received this message from the "vim_use" 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