vim plugin to show current Perl subroutine
- by Andrew
I'm trying to make a vim plugin that will split the window on load and simulate a info bar at the top of my terminal. I've got it sorta working but I think I've either reached limits of my knowledge of vim syntax or there's a logic problem in my code.
The desired effect would be to do a reverse search for any declaration of a Perl subroutine form my current location in the active buffer and display the line in the top buffer. I'm also trying to make it skip that buffer when I switch buffers with <C-R>. My attempt at that so far can be seen in the mess of nested if statements.
Anyway, here's the code. I would greatly appreciate feedback from anyone.  
(pastebin pastebin.com/8cuMPn1Q)
let s:current_function_bufname = 'Current\ Function\/Subroutine'
function! s:get_current_function_name(no_echo)
    let lnum = line(".")
    let col = col(".")
    if a:no_echo
        let s:current_function_name = getline(search("^[^s]sub .$", 'bW'))
    else
        echohl ModeMsg
        echo getline(search("^[^s]sub .$", 'bW'))
        "echo getline(search("^[^ \t#/]\{2}.[^:]\s$", 'bW'))
        echohl None
    endif
endfunction  
let s:previous_winbufnr = 1
let s:current_function_name = ''
let s:current_function_buffer_created = 0
let s:current_function_bufnr = 2
function! s:show_current_function()
    let total_buffers = winnr('$')
    let current_winbufnr = winnr()
    if s:previous_winbufnr != current_winbufnr
        if bufname(current_winbufnr) == s:current_function_bufname
            if s:previous_winbufnr < current_winbufnr
                let i = current_winbufnr + 1
                if i  total_buffers
                    let i = 1
                endif
                if i == s:current_function_bufnr
                    let i = i + 1
                endif
                if i  total buffers
                    let i = 1
                endif
                exec i.'wincmd w'
            else
                let i = current_winbufnr - 1
                if i < 1
                    let i = total_buffers
                endif
                if i == s:current_function_bufnr
                    let i = i - 1
                endif
                if i < 1
                    let i = total_buffers
                endif
                try
                    exec i.'wincmd w'
                finally
                    exec total_buffers.'wincmd w'
                endtry
            endif
        endif
        let s:previous_winbufnr = current_winbufnr
        return 1
    endif  
if s:current_function_buffer_created == 0  
    exec 'top 1 split '.s:current_function_bufname  
    call s:set_as_scratch_buffer()  
    let s:current_function_buffer_created = 1  
    let s:current_function_bufnr = winnr()  
endif  
call s:activate_buffer_by_name(s:current_function_bufname)  
setlocal modifiable  
call s:get_current_function_name(1)  
call setline(1, s:current_function_name)  
setlocal nomodifiable  
call s:activate_buffer_by_name(bufname(current_winbufnr))  
endfunction  
function! s:set_as_scratch_buffer()
   setlocal noswapfile
   setlocal nomodifiable
   setlocal bufhidden=delete
   setlocal buftype=nofile
   setlocal nobuflisted
   setlocal nonumber
   setlocal nowrap
   setlocal cursorline
endfunction  
function! s:activate_buffer_by_name(name)
   for i in range(1, winnr('$'))
      let name = bufname(winbufnr(i))
      let full_name = fnamemodify(bufname(winbufnr(i)), ':p')
      if name == a:name || full_name == a:name
         exec i.'wincmd w'
         return 1
      endif
   endfor
   return 0
endfunction  
set laststatus=2
autocmd! CursorMoved,CursorMovedI,BufWinEnter * call s:show_current_function()
(pastebin pastebin.com/8cuMPn1Q)
similar to VIM: display custom reference bar on top of window
and http://vim.wikia.com/wiki/Show_current_function_name_in_C_programs