views:

88

answers:

2

original (update follows)

I'm working with a lot of anonymous functions, ie functions declared as part of a dictionary, aka "methods". It's getting pretty painful to debug, because I can't tell what function the errors are happening in.

Vim's backtraces look like this:

Error detected while processing function NamedFunction..2111..2105:
line    1:
E730: using List as a String

This trace shows that the error occurred in the third level down the stack, on the first line of anonymous function #2105. IE NamedFunction called anonymous function #2111, which called anonymous function #2105. NamedFunction is one declared through the normal function NamedFunction() ... endfunction syntax; the others were declared using code like function dict.func() ... endfunction.

So obviously I'd like to find out which function has number 2105.

Assuming that it's still in scope, it's possible to find out what Dictionary entry references it by dumping all of the dictionary variables that might contain that reference. This is sort of awkward and it's difficult to be systematic about it, though I guess I could code up a function to search through all of the loaded dictionaries for a reference to that function, watching out for circular references. Although to be really thorough, it would have to search not only script-local and global dictionaries, but buffer-local dictionaries as well; is there a way to access another buffer's local variables?

Anyway I'm wondering if it's possible to dump the source code for the anonymous function instead. This would be a lot easier and probably more reliable.

update

I ended up asking about this a while back on the vim_use mailing list. Bram Moolenar, aka vim's BDFL, responded by saying that "You are not supposed to use the function number." However, a suitable alternative for this functionality has not been suggested, as of early September 2010. It's also not been explicitly mentioned whether or not this functionality will continue to work in subsequent vim releases. I've not tried to do this (or anything else, for that matter) in the recently released vim 7.3.

A: 

I use the following workaround: I have one plugin that does some stuff like creating commands, global functions for other plugins. It also registers all plugins, so I have a large dictionary with lots of stuff related to plugins. If I see a error I search for a function that produces it using function findnr:

"{{{3 stuf.findf:
function s:F.stuf.findf(nr, pos, d)
    if type(a:d)==2 && string(a:d)=~#"'".a:nr."'"
        return a:pos
    elseif type(a:d)==type({})
        for [key, Value] in items(a:d)
            let pos=s:F.stuf.findf(a:nr, a:pos."/".key, Value)
            unlet Value
            if type(pos)==type("")
                return pos
            endif
        endfor
    endif
    return 0
endfunction
"{{{3 stuf.findr:
function s:F.stuf.findnr(nr)
    for [key, value] in items(s:g.reg.registered)+[["load", {"F": s:F}]]
        let pos=s:F.stuf.findf(a:nr, "/".key, value.F)
        if type(pos)==type("")
            return pos
        endif
    endfor
    return 0
endfunction

Here I have this plugin functions in s:F.{key} dictionaries and other plugins' functions under s:g.reg.registered[plugname].F dictionary.

ZyX
+1  A: 

The :function command tries to stop you from specifying the numbered functions (their name is just a number) but you can trick it using the {...} dynamic function name feature, throw in some :verbose and you have a winner:

:verbose function {43}
  function 43()
      Last set from /home/peter/test.vim
1   throw "I am an exception"
  endfunction

This was not at all obvious in the help docs.

too much php
Beauty. Yeah, vim's documentation is . . . not entirely consistent. Did you just figure this out through trial and error, or is it documented somewhere?
intuited
Trial and error, I had to put a few pieces together. This solution is probably just exploiting a bug in the `:function` command.
too much php
I guess I could have read vim's source code. I forget about that sometimes.
intuited