dgkf / debugadapter

Debug Adapter Protocol implementation for R

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Effective immediately! Drop support for stable R :stuck_out_tongue_closed_eyes:

dgkf opened this issue · comments

This project hit a few constraints that made it mostly dead-on-arrival. Most notably, the lack of any hooks for interacting with an ongoing browser session.

Well that looks like it's unofficially been solved in bugs.r-project.org discussion.

We now have an experimental global option to add a browser "error handler", which allows us to hook into conditions intercepted by the browser.

I see this as almost an inevitability in the R world, so I'm willing to stake the project against the eventual inclusion of such a feature. Instead of even entertaining support for current versions of R and contorting the project to work in that scheme, I think it's better to throw all that out and use this much more direct mechanism of intercepting the debugger.

Note, this probably means the next stage of this project will only work on R-devel, compiled with the -DUSE_BROWSER_HOOK flag set. Because I build R from source ever few years -- leaving just enough time to completely forget what I'm doing -- I'm going to document my exact steps:

svn checkout https://svn.r-project.org/R/trunk R
cd R

# fetch recommended packages
./tools/rsync-recommended

# make a build target directory
mkdir target
cd target

# in my case, i'm on wayland with no x11
../configure --without-x CPPFLAGS=-DUSE_BROWSER_HOOK
make

# finally, launch our browser-hook-enabled R
bin/R

Taking some notes on Luke's browser hooks implementation. More of a "user acceptance testing" style feedback, with my own thoughts on this as an API for hooking into the browser:

Impressions

Overall, the design feels like it's at odds with itself. The hook is used to catch entering into the browser, automatically resets the hook, then to actually enter a browser while intercepting future browser steps you have to reintroduce the hook and call browser with a ignoreHook flag. My impulsive response to such a design is that it feels overly complicated for what it allows.

Further Questions / Suggestions

  • Like top-level callbacks, would prefer if this hook used a logical return value to decide whether to remove this hook for future calls or left it to the user to erase it from options() instead of forcibly removing it.

  • The hook "burns after reading". It automatically gets changed to NULL after being invoked, which is quite unintuitive. It also means the hook must accept hook as its first argument as a way of propagating itself.

  • browser getting an ignoreHook argument feels a bit heavy handed (and it is not included in the formals() in the R API). Would prefer to always use the hook, but allow developers to juggle what hook is set using options() and on.exit() (to restore a hook). This style of scope management feels more much idiomatic within R.

  • Instead of using finally to catch exits, would be preferred if browser() exited with a proper condition. Exiting with a ^C interrupt exits with a c("interrupt", "condition"), whereas exiting with a Browse[1]> Q seems to long-jump to the top level without a condition... at least in my tests using partial matching to try to catch anything that might be unofficially returned. it seems finally is the only way to catch a Q exit.

  • It would be nice if options(prompt) and options(continue) could be used within the Browse[1]> to make a custom debug REPL. Currently hard-coded, but with this hook becomes a useful design surface. Defaults could of course be set such that the current Browse[n]> prompt is shown, but it would be great if this was customizable.

  • Within a browser() session, is there a way to get the current debug at position? Ideally similar to utils::findLineNum? Trying to track expression location through a browser path would be redundant and error prone. Seems like this might be exposed through the C API?

  • Luke's example returns the output of browser()... does this ever return anything useful?

  • Interestingly, with this new code, calling browser(ignoreHook = TRUE) provides an interface for long-jumping to the topenv within R, forcing the early termination all the frames on the stack. Almost certainly not an intended feature, but an interesting one!


tagging @lionel- - maybe interesting to you if you're hoping to stabilize this feature for your DAP implementation

Cool to see it reviving 👍 Just for my understanding, is it supposed to currently work in its current state? I have tried to use it a couple of times without success.

is it supposed to currently work [within neovim] in its current state?

When I was working in this, neovim was what I used to test to see if it was working. There were quite a few very specific steps to get it working - I needed to use a fork of processx where I enabled intercepting of the stdin file handle and it would only work on unix-like platforms where processes can be forked.

This iteration will require a devel build of R with the -DUSE_BROWSER_HOOK flag, which is its own burden on the project, but it will be cross platform and less flaky.

As soon as I have a minimal example I’ll write up new config steps for neovim and hopefully helix.