2016-09-27 18:44 GMT+03:00 Luc Hermitte <vim-dev-git...@256bit.org>: > It'll be nice to have an official way to access the callstack from the > current function. I know for certain the information is somewhere as I've > found a very dirty trick to access it: I throw a dummy exception and I > decode v:throwproint. See: > https://github.com/LucHermitte/lh-vim-lib/blob/master/autoload/lh/exception.vim#L51 > and > https://github.com/LucHermitte/lh-vim-lib/blob/master/autoload/lh/log.vim#L250 > > Alas this approach is really clumsy and not always very robust as the exact > message produced may know small variations, it's locale dependent, and IIRC > changes may happen in the format from one vim version to the next. > > In an ideal world (as far as I'm concerned in order to avoid transforming > the information obtained), a callstack() function would return the list of > call information. Each information would contain: > > "script": filename of the vimscript where the function is defined > "pos": absolute line number in this script file > "fname": function name > "fstart": line where the function is defined in the script (not mandatory, > but a necessary step to deduce the 3 first information) > "offset": offset, from the start of the function, of the line the current > call is made. > > The 3 first information are what is really interesting to fill the quickfix > list. The 3rd and the 5th are what we have in v:throwpoint.
I like the idea, but with some modifications: 1. No 'script' or 'fstart', supply 'func' with funcref (as of funcref(), not function()) instead. Define `get()` arguments: - `get(fref, 'sid')`: script ID, number (additionally have sid2sfname and sfname2sid functions) - `get(fref, 'body')`: function body, list - `get(fref, 'signature')`: function signature: dictionary like `{'args': ['foo', 'bar'], 'varargs': v:true, 'dict': v:true, 'closure': v:true}` - `get(fref, 'sline')`: line where function is defined - `get(fref, 'slines')`: list of list of numbers, used to translate body indexes (what is returned by `get(fref, 'body')`) to real script line numbers. 2. `offset` should be in `get(fref, 'body')` indexes (function may be generated and created by a single `:execute` line, in this case `get(fref, 'slines')` will return something like `[[42], [42], [42]]`: each line in body corresponds to one and the same line in script file). 3. `args`: a: dictionary 4. `locals`: l: dictionary 5. `script_globals`: s: dictionary, may be absent. Alternatively: `sid2vars()` function Reasoning: your variant seems to be useful mostly for giving fancier error messages, which is good for offline remote debugging (I mean, debugging in case when bug occures only on user machine), but that’s all. My is targeted at debugging the problem myself: 1. sid2sfname/sfname2sid functions: I always wanted to make it easier to access <SID> which is used in a number of places: mostly for quirks like defining mappings with <SID> in another file (requires manual <SID> expansion). This is always possible to work around, but better have functions. 2. body: in addition to making it easier to print Python-style tracebacks with access to the function body this also makes it easier to serialize function when I have a list. And `:function` output parsing does not work in general: try defining function with control character inside and determine where you see literal `^[` and where there is escape. 3. signature: again, easier to serialize. Though this time `:function` parsing should work fine, it would be harder to use if signature is needed for something, but serializing (as an example: some plugin-defined callback which supplies funcref as much arguments as it can handle like with current `map()` situation). 4. sline+slines: Only for pretty tracebacks, I do not see other purposes yet. 5. args/locals/script_globals: needed for postmortem debugging. Also useful for offline remote debugging (i.e. you ask user to enable some “verbose” mode which will serialize and record all related variables and this can be sent to you). 6. For optimization purposes I sometimes write code that generates a function and then calls it, so `funcref()` and not function name: function names are useless in this case because most likely function is a dictionary one here and it may have vanished at the point Vim will check for the next character and I can do anything manually (i.e. after function which generates something optimized have finished executing). As a summary: my proposal is needed for - fancier error messages - postmortem debugging - remote offline debugging - function serialization --- Most of the above looks like something easy to implement: information is already there, just needs generating a VimL object without computing anything or any modifications to code not in `f_get` or (new) `f_callstack` (gets information about the currently processed point). (New) `f_throwstack` (callstack at the point where exception occures, for use in `:catch` block) should be harder (do not remember what information survives by the point Vim enters :catch, but pretty sure that something out of what is needed for throwstack() to work will be missing). `slines` AFAIK is not that easy to implement right, but I would not say it is useful enough to spend time on if it will be hard. Without throwstack() (which Luc Hermitte did not suggest, did he?) new changes will be useful only for `log.vim` or similar libraries’ users, limited to the cases when author did call logging function, throwstack() should be useful for debugging any plugin. > > — > You are receiving this because you are subscribed to this thread. > Reply to this email directly, view it on GitHub > > -- > -- > You received this message from the "vim_dev" 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 > > --- > You received this message because you are subscribed to the Google Groups > "vim_dev" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to vim_dev+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- -- You received this message from the "vim_dev" 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 --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.