Hello,

Would it be possible to have a custom prompt when browser()'ing.

I have made a simple implementation of this (which is attached), the basic idea is that instead of the hardcoded sprintf( "Browser[%d]> ", browselevel), a call to the getBrowsePrompt is made, and obviously the function is:

> getBrowsePrompt
function (level = 1, env = .GlobalEnv) {
   sprintf("Browse[%d]> ", level)
}
<environment: namespace:base>

> debug( rnorm )
> rnorm( 10 )
debugging in: rnorm(10)
debug: .Internal(rnorm(n, mean, sd))
Browse[1]>
exiting from: rnorm(10)
[1] -0.496598526 -0.006482431  1.491833990 -2.602605734 -0.275479145
[6] -1.143580117  0.146797854 -0.529420397  0.823817647 -0.256676050

but then it can be masked so that a more informative prompt is given, like this for example (showing the call stack)

> getBrowsePrompt
function( level = 1, env = .GlobalEnv){
calls <- sys.calls()
stack <- sapply( calls[-1], function(x) tryCatch(as.character(x[[1]]), error=function(e) "?") )
sprintf( "Browse[%d] %s > ", level, paste( stack, collapse = " -> ") )
}
> f()
debugging in: rnorm(10)
debug: .Internal(rnorm(n, mean, sd))
Browse[1] rnorm -> getBrowsePrompt >
exiting from: rnorm(10)
[1] -0.53854862 -1.42674850 -0.48391168 -0.23446819 -0.36863380  0.53803626
[7]  1.70176078  0.82984068  1.05101379 -0.03944557

Or this: printing the content of the environment we are browsing :

> getBrowsePrompt <- function( level = 1, env = .GlobalEnv ){
+   print( ls.str( envir = env) )
+   base:::getBrowsePrompt( level, env )
+ }
> f()
debugging in: rnorm(10)
debug: .Internal(rnorm(n, mean, sd))
mean :  num 0
n :  num 10
sd :  num 1
Browse[1]>
exiting from: rnorm(10)
[1]  1.1112007  0.4921306  0.1747196 -0.2518565 -0.9342039  0.5930085
[7] -0.5961234  0.1153541 -0.6189056  0.1670318

This probably should rely on an option instead of relying on masking functions. Also this opens a back door to the debugging system of R, but I am not sure this is entirely a bad thing. (see http://www.statistik.lmu.de/~eugster/soc09/#p5)

On the same note, what about having a function for the prompt, so that (for example) we could show the current working directory, the memory usage, ...


Romain

--
Romain Francois
Independent R Consultant
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr


Index: src/library/base/R/options.R
===================================================================
--- src/library/base/R/options.R	(revision 48377)
+++ src/library/base/R/options.R	(working copy)
@@ -18,3 +18,7 @@
 
 getOption <- function(x) options(x)[[1L]]
 
+getBrowsePrompt <- function( level = 1, env = .GlobalEnv){
+	sprintf( "Browse[%d]> ", level )
+}
+
Index: src/main/main.c
===================================================================
--- src/main/main.c	(revision 48377)
+++ src/main/main.c	(working copy)
@@ -116,20 +116,26 @@
 
 /* Read-Eval-Print loop with interactive input */
 static int prompt_type;
-static char BrowsePrompt[20];
 
-
-char *R_PromptString(int browselevel, int type)
+char *R_PromptString(int browselevel, int type, SEXP rho)
 {
     if (R_Slave) {
-	BrowsePrompt[0] = '\0';
-	return BrowsePrompt;
+	return "" ;
     }
     else {
 	if(type == 1) {
 	    if(browselevel) {
-		sprintf(BrowsePrompt, "Browse[%d]> ", browselevel);
-		return BrowsePrompt;
+		SEXP call ;
+		SEXP level ;
+		SEXP res ;
+		char* prompt ;
+		PROTECT( level = allocVector(INTSXP, 1) ) ;
+		INTEGER(level)[0] = browselevel ;
+		PROTECT( call = lang3( install("getBrowsePrompt"), level, rho  ) ) ;
+		PROTECT( res = eval( call, R_GlobalEnv ) );
+		prompt = (char *)CHAR(STRING_ELT(res, 0)) ;
+		UNPROTECT( 3 ) ;
+		return prompt ;
 	    }
 	    return (char *)CHAR(STRING_ELT(GetOption(install("prompt"),
 						     R_BaseEnv), 0));
@@ -202,7 +208,7 @@
 
     if(!*state->bufp) {
 	    R_Busy(0);
-	    if (R_ReadConsole(R_PromptString(browselevel, state->prompt_type),
+	    if (R_ReadConsole(R_PromptString(browselevel, state->prompt_type, rho),
 			      state->buf, CONSOLE_BUFFER_SIZE, 1) == 0)
 		return(-1);
 	    state->bufp = state->buf;
@@ -331,7 +337,7 @@
 
     if(!*DLLbufp) {
 	R_Busy(0);
-	if (R_ReadConsole(R_PromptString(0, prompt_type), DLLbuf,
+	if (R_ReadConsole(R_PromptString(0, prompt_type, R_GlobalEnv), DLLbuf,
 			  CONSOLE_BUFFER_SIZE, 1) == 0)
 	    return -1;
 	DLLbufp = DLLbuf;
______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to