dotancohen
dotancohen

Reputation: 31471

VIM: Why is this function hanging VIM?

I have added the following fine function to my status bar to show which function is currently being edited in C-derived languages:

set statusline+=%{WhatFunctionAreWeIn()}
fun WhatFunctionAreWeIn()
    let strList = ["while", "foreach", "ifelse", "if else", "for", "if", "else", "try", "catch", "case"]
    let foundcontrol = 1
    let pos=getpos(".")          " This saves the cursor position
    let view=winsaveview()       " This saves the window view

    while (foundcontrol)

        let foundcontrol = 0

        " Go to the character before the last open {
        normal [{
        call search('\S','bW')

        " If the character is a ) then go to the character
        " preceding the () section
        let tempchar = getline(".")[col(".") - 1]
        if (match(tempchar, ")") >=0 )
            normal %
            call search('\S','bW')
        endif

        let tempstring = getline(".")

        for item in strList
            if( match(tempstring,item) >= 0 )
                let foundcontrol = 1
                break
            endif
        endfor

        if(foundcontrol == 0)
            call cursor(pos)
            call winrestview(view)
            return tempstring
        endif
    endwhile
    call cursor(pos)
    call winrestview(view)
    return tempstring
endfun

However, after a few minutes VIM hangs. Disabling the function prevents the hang, so I feel confident that this function is to blame. Is there anything in there that might hang VIM? Is there a better way to accomplish the task of showing the currently-edited function in the status bar?

Thanks.

Upvotes: 1

Views: 277

Answers (1)

David Pope
David Pope

Reputation: 6587

The issue is that your strategy for determining whether to keep moving to surrounding braces is too aggressive:

  • Suppose your cursor is on the f in a preprocessor directive #endif between two functions.
  • Since you're between two functions, there is no unmatched { for [{ to jump to, so the cursor doesn't move.
  • Your match() against strList hits the if in #endif, causing the loop to continue.
  • The loop never exits.

I suspect a ctags-based approach, like @Gowtham suggests, will work better, even if it requires some customization.

Upvotes: 1

Related Questions