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.

Reply via email to