On May 31, 2011, at 5:23 PM, Thomas Friedrichsmeier wrote: > On Tuesday 31 May 2011, Simon Urbanek wrote: >> The history entries are somewhat in a grey area, because most GUIs use >> their own implementation of history (and thus they are irrelevant) and the >> *history() commands are documented to only use readline-backend. That >> said, they could be easily used by all GUIs if the Windows code is >> amended. > > Actually, I would suggest to use a different solution, though: This is not > really a problem that needs to be addressed on a low level of pointers to C > functions. Perhaps it would make more sense to allow to set some R > function(s) > to handle these via options() (or perhaps via a dedicated gui.options()). >
I suppose, yes, it's possible, but I see somewhat of an asymmetry if done that way : GUIs are like plug-ins in that there is a set of functions they have to implement to work properly. In the current state this is done using the C-level hooks, but they are incomplete in that some of the required hooks are not available on all platforms. However, if you introduce an additional layer of R function hooks, there will be two sets of competing ways for the GUI so register and some of them are simply not feasible on the R level (console handling, for example, which is why we have C-level hooks). It also makes the GUI unnecessary messy, since they will need to provide both C code and R code, where the R code essentially just points to C code, practically replicating what the C-level hooks would do (just more complicated as it requires embedded symbol registrations etc.). Currently I'm more inclined to make the hooks cross-platform (maybe conditional on the GUI type set to "custom" or something like that). But if someone wants to devise some nice way of customizing parts using R callback, I won't oppose it. >>> - utils::select.list() and utils::menu(): I want to show my own UI if >>> graphics==TRUE. Currently, select.list() has special code for windows, >>> "aqua" and tcltk; menu() essentially assumes the same code. Give me a >>> way to run register my own UI. >> >> ptr_do_selectlist provides the customization and could be extended to other >> platforms. > > See above. But yes, if at least it was cross-platform, that would be nice. > >>> - base::system(), base::system2(): As you will be aware, capturing the >>> output of system commands in a GUI is tricky on Unix. I do have a >>> solution for that, but I need to run synchronization code at the start >>> and end of system() and system2(), in order to get interleaving right. >>> Give me a hook, each, at the start and end of these functions. >> >> I'm not sure I understand your concern here. What exactly is your worry? >> Capturing output is trivial since it simply involves creating a pipe when >> you initialize R which you can read while R is running and the >> synchronization is provided by the OS, no magic involved. > > Is that pipe buffered? No (although you could buffer it if you wanted). > In my setup it is. And so consider code like this: > for (i in 1:10) { > print (i) > system (paste ("echo", i)) > } > How do you ensure that this results in > 1 > 1 > 2 > 2 > ... > rather than e.g. > 1 > 2 > 3 > 1 > 2 > 4 > 3 > 5 > 6 > ... > In R the output will be 1 1 2 2 by design - system() is synchronous, so stdout will arrive between the WriteConsole calls - try in the the R for Mac GUI and you'll see: > for (i in 1:10) { + print (i) + system (paste ("echo", i)) + } [1] 1 1 [1] 2 2 [1] 3 3 [1] 4 4 [1] 5 5 [1] 6 6 [1] 7 7 [1] 8 8 [1] 9 9 [1] 10 10 > Obviously, for wait=FALSE all bets are off. [Note: although the Mac GUI uses a hook for system, it is to run commands as root, not to do any special handling of I/O]. > I could not get it to work for RKWard without adding code to make sure the > "other" output is flushed. If you have issues with stdout buffer before the pipe, use can use setvbuf() to disable buffering. > (Note: I'm capturing regular R output via > R_WriteConsoleEx, since I am interested in the differentiation between output > types that this provides. So I cannot simply push that down the same pipe.). > >>> - graphics::plot.new(): I need a hook *before* the new plot is started, >>> in order to properly implement device-independent plot history. I would >>> appreciate not having to implement my own graphics device just to be >>> able to run some code at this point. >>> >>> - grDevices::dev.off(): I need a hook before the device is closed. Also >>> for plot history. >>> >>> - grDevices::dev.set(): I need a hook after the new device has been set. >>> Also for plot history. >>> >>> - grid::newpage(): See graphics::plot.new(). Of course, even better, I >>> would like to have a hook that is called every time before a new page / >>> frame is started on a device. >> >> For all of the above: all of them are already available a device callbacks >> (newPage, close, activate and newPage again). > > Quoting myself: I would appreciate not having to implement my own graphics > device just to be able to run some code at [these] point[s]. > Cautiously I would argue you have to the moment you're outside R, essentially since the built-in graphics devices are not guaranteed to work when embedded. In practice, I think if you write a GUI, you have to provide a GD - that is the only reasonable way you can seamlessly incorporate R graphics into your GUI. That said, there is a precedent for graphics hooks. The problem I see is the same that became apparent with grid last time we added hooks - there are potentially multiple ways to get to the same C level point, and they are either easily forgotten, or even hard to enumerate. For example, dev.set() is not the only way to activate a device - it can be activated from the menu and other means via selectDevice() which is at C level, so there is no R code involved at all, thus setting a hook on dev.set() is will work only in a subset of cases and thus you cannot expect consistency in your GUI. (Note: none of my comments are specific to RKWard, since it is not even available for OS X so I don't know anything about it) Cheers, Simon ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel