Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

227 lines
7.8 KiB

5 years ago
  1. ### BREAKPOINTS
  2. .ESSBP. <- new.env()
  3. ### DEBUG/UNDEBUG
  4. .ess_find_funcs <- function(env) {
  5. objs <- ls(envir = env, all.names = TRUE)
  6. if (length(objs) > 0)
  7. objs <- objs[sapply(objs, exists, envir = env,
  8. mode = 'function', inherits = FALSE)]
  9. objs
  10. }
  11. .ess_all_functions <- function(packages = c(), env = NULL) {
  12. if(is.null(env))
  13. env <- parent.frame()
  14. empty <- emptyenv()
  15. coll <- list()
  16. for(p in packages){
  17. ## package might not be attached
  18. try(
  19. {
  20. objNS <- .ess_find_funcs(asNamespace(p))
  21. objPKG <- .ess_find_funcs(as.environment(paste0('package:', p)))
  22. objNS <- setdiff(objNS, objPKG)
  23. if(length(objPKG))
  24. coll[[length(coll) + 1]] <- paste0(p, ':::', objNS)
  25. }, silent = TRUE)
  26. }
  27. while(!identical(empty, env)){
  28. coll[[length(coll) + 1]] <- .ess_find_funcs(env)
  29. env <- parent.env(env)
  30. }
  31. grep('^\\.ess', unlist(coll, use.names = FALSE),
  32. invert = TRUE, value = TRUE)
  33. }
  34. .ess_dbg_flag_for_debuging <- function(fname){
  35. all <- utils::getAnywhere(fname)
  36. if(length(all$obj) == 0){
  37. msg <- sprintf("No functions names '%s' found", fname)
  38. } else {
  39. msg <- sprintf("Flagged '%s' for debugging", fname)
  40. tryCatch(lapply(all$obj, debug),
  41. error = function(e){
  42. msg <- paste0("Error: ", e$message)
  43. })
  44. }
  45. cat(msg)
  46. .ess_mpi_message(msg)
  47. }
  48. .ess_dbg_getTracedAndDebugged <- function()
  49. {
  50. packages <- base::.packages()
  51. tr_state <- tracingState(FALSE)
  52. on.exit(tracingState(tr_state))
  53. generics <- methods::getGenerics()
  54. all_traced <- c()
  55. for(i in seq_along(generics)){
  56. genf <- methods::getGeneric(generics[[i]],
  57. package=generics@package[[i]])
  58. if(!is.null(genf)){ ## might happen !! v.2.13
  59. menv <- methods::getMethodsForDispatch(genf)
  60. traced <- unlist(eapply(menv, is, 'traceable', all.names=TRUE))
  61. if(length(traced) && any(traced))
  62. all_traced <- c(paste(generics[[i]],':',
  63. names(traced)[traced],sep=''), all_traced)
  64. tfn <- getFunction(generics[[i]], mustFind=FALSE, where = .GlobalEnv)
  65. if(!is.null(tfn ) && is(tfn, 'traceable')) # if the default is traced, it does not appear in the menv :()
  66. all_traced <- c(generics[[i]], all_traced)
  67. }
  68. }
  69. debugged_pkg <- unlist(lapply(packages, function(pkgname){
  70. ns <- asNamespace(pkgname)
  71. funcs <- .ess_find_funcs(ns)
  72. dbged <- funcs[unlist(lapply(funcs,
  73. function(f){
  74. isdebugged(get(f, envir = ns, inherits = FALSE))
  75. }))]
  76. if(length(dbged))
  77. paste0(pkgname, ':::`', dbged, '`')
  78. }))
  79. env <- parent.frame()
  80. ## traced function don't appear here. Not realy needed and would affect performance.
  81. all <- .ess_all_functions(packages = packages, env = env)
  82. which_deb <- lapply(all, function(nm){
  83. ## if isdebugged is called with string it doess find
  84. tryCatch(isdebugged(get(nm, envir = env)),
  85. error = function(e) FALSE)
  86. ## try(eval(substitute(isdebugged(nm), list(nm = as.name(nm)))), silent = T)
  87. })
  88. debugged <- all[which(unlist(which_deb, recursive=FALSE, use.names=FALSE))]
  89. unique(c(debugged_pkg, debugged, all_traced))
  90. }
  91. .ess_dbg_UntraceOrUndebug <- function(name, env = parent.frame()) {
  92. tr_state <- tracingState(FALSE)
  93. on.exit(tracingState(tr_state))
  94. if( grepl('::', name) ){
  95. ## foo:::bar name
  96. eval(parse(text = sprintf('undebug(%s)', name)))
  97. }else{
  98. ## name is a name of a function to be undebugged or has a form
  99. ## name:Class1#Class2#Class3 for traced methods
  100. name <- strsplit(name, ':', fixed = TRUE)[[1]]
  101. if( length(name)>1 ){
  102. ## a method
  103. fun <- name[[1]]
  104. sig <- strsplit(paste(name[-1], collapse=''), '#', fixed=TRUE)[[1]]
  105. untrace(fun, signature = sig)
  106. }else{
  107. ## function
  108. if( is(getFunction(name, where = parent.frame()), 'traceable') )
  109. untrace(name)
  110. else if(grepl(":", name))
  111. undebug(name)
  112. else
  113. undebug(get(name, envir = env))
  114. }}
  115. }
  116. .ess_dbg_UndebugALL <- function(funcs)
  117. {
  118. tr_state <- tracingState(FALSE)
  119. on.exit(tracingState(tr_state))
  120. env <- parent.frame()
  121. invisible(lapply(funcs, function( nm ) {
  122. ## ugly tryCatch, but there might be several names pointing to the
  123. ## same function, like foo:::bar and bar. An alternative would be
  124. ## to call .ess_dbg_getTracedAndDebugged each time but that might
  125. ## be ery slow
  126. try(.ess_dbg_UntraceOrUndebug(nm, env = env), TRUE)
  127. }))
  128. }
  129. ### WATCH
  130. .ess_watch_expressions <- list()
  131. .ess_watch_eval <- function()
  132. {
  133. env <- as.environment("ESSR")
  134. exps <- get('.ess_watch_expressions', envir = env)
  135. if(length(exps) == 0) {
  136. ## using old style so this can be parsed by R 1.9.1 (e.g):
  137. cat('\n# Watch list is empty!\n',
  138. '# a append new expression',
  139. '# i insert new expression',
  140. '# k kill',
  141. '# e edit the expression',
  142. '# r rename',
  143. '# n/p navigate',
  144. '# u/d,U move the expression up/down',
  145. '# q kill the buffer',
  146. sep="\n")
  147. } else {
  148. .parent_frame <- parent.frame()
  149. .essWEnames <- allNames(exps)
  150. len0p <- !nzchar(.essWEnames)
  151. .essWEnames[len0p] <- seq_along(len0p)[len0p]
  152. for(i in seq_along(exps)) {
  153. cat('\n@---- ', .essWEnames[[i]], ' ',
  154. rep.int('-', max(0, 35 - nchar(.essWEnames[[i]]))), '-@\n', sep = '')
  155. cat(paste('@---:', deparse(exps[[i]][[1]])), ' \n', sep = '')
  156. tryCatch(print(eval(exps[[i]],
  157. envir = .parent_frame)),
  158. error = function(e) cat('Error:', e$message, '\n' ),
  159. warning = function(w) cat('warning: ', w$message, '\n' ))
  160. }
  161. }
  162. }
  163. .ess_watch_assign_expressions <- function(elist) {
  164. assign(".ess_watch_expressions", elist, envir = as.environment("ESSR"))
  165. }
  166. .ess_log_eval <- function(log_name) {
  167. env <- as.environment("ESSR")
  168. if(!exists(log_name, envir = env, inherits = FALSE))
  169. assign(log_name, list(), envir = env)
  170. log <- get(log_name, envir = env, inherits = FALSE)
  171. .essWEnames <- allNames(.ess_watch_expressions)
  172. cur_log <- list()
  173. .parent_frame <- parent.frame()
  174. for(i in seq_along(.ess_watch_expressions)) {
  175. capture.output( {
  176. cur_log[[i]] <-
  177. tryCatch(eval(.ess_watch_expressions[[i]]),
  178. envir = .parent_frame,
  179. error = function(e) paste('Error:', e$message, '\n'),
  180. warning = function(w) paste('warning: ', w$message, '\n'))
  181. if(is.null(cur_log[i][[1]]))
  182. cur_log[i] <- list(NULL)
  183. })
  184. }
  185. names(cur_log) <- .essWEnames
  186. assign(log_name, c(log, list(cur_log)), envir = env)
  187. invisible(NULL)
  188. }
  189. .ess_package_attached <- function(pack_name){
  190. as.logical(match(paste0("package:", pack_name), search()))
  191. }
  192. ## magrittr debug_pipe
  193. .ess_pipe_browser <- function(x){
  194. if(is.list(x))
  195. evalq({
  196. browser(skipCalls = 2)
  197. x
  198. }, envir = x)
  199. else if(is.environment(x))
  200. ## enclos argumentn has no effect for unclear reason, need to hack
  201. eval(bquote({
  202. x <- .(environment())
  203. browser(skipCalls = 2)
  204. x
  205. }), envir = x)
  206. else {
  207. browser(skipCalls = 0)
  208. x
  209. }
  210. }