diff --git a/NEWS-1.3.md b/NEWS-1.3.md index 5a0aae54e0c..42cfb23855b 100644 --- a/NEWS-1.3.md +++ b/NEWS-1.3.md @@ -128,6 +128,7 @@ * Enable wrap-around for previous/next source tab by default (#6139) * Provide full SHA in detail of Git commits (#6155) * File monitor now ignores Packrat, renv library folders (#3267) +* Make global source control commands rebindable (#6503) ### Bugfixes diff --git a/src/cpp/session/SessionDirs.cpp b/src/cpp/session/SessionDirs.cpp index 89f1fa2d313..c1080c4ad26 100644 --- a/src/cpp/session/SessionDirs.cpp +++ b/src/cpp/session/SessionDirs.cpp @@ -29,14 +29,21 @@ namespace dirs { FilePath getDefaultWorkingDirectory() { - // calculate using user settings - FilePath defaultWorkingDir = module_context::resolveAliasedPath( - prefs::userPrefs().initialWorkingDirectory()); + // see if the user has defined a default working directory in preferences + FilePath defaultWorkingDir; + std::string initialWorkingDir = prefs::userPrefs().initialWorkingDirectory(); + if (!initialWorkingDir.empty()) + { + // the user has defined a default; resolve the path + defaultWorkingDir = module_context::resolveAliasedPath(initialWorkingDir); + } + + // see if there's a working directory defined in the R session options (set by + // session-default-working-dir) FilePath sessionDefaultWorkingDir = FilePath(session::options().defaultWorkingDir()); - // return it if it exists, otherwise use the - // session specified value if it exists - // otherwise, use the default user home path + // return the first of these directories that is defined and exists, or the user home directory + // in the case that neither exists if (defaultWorkingDir.exists() && defaultWorkingDir.isDirectory()) return defaultWorkingDir; else if (sessionDefaultWorkingDir.exists() && sessionDefaultWorkingDir.isDirectory()) diff --git a/src/cpp/session/modules/SessionFind.cpp b/src/cpp/session/modules/SessionFind.cpp index e7df7171c9a..0e294b51dad 100644 --- a/src/cpp/session/modules/SessionFind.cpp +++ b/src/cpp/session/modules/SessionFind.cpp @@ -999,17 +999,27 @@ class GrepOperation : public boost::enable_shared_from_this matchOffs.push_back(matchOff); replaceMatchOns.push_back(replaceMatchOn); replaceMatchOffs.push_back(replaceMatchOff); - for (std::string newError : errorMessage) - errors.push_back(newError); + json::Array combinedErrors = json::toJsonArray(errorMessage); + errors.push_back(combinedErrors); recordsToProcess--; } } + // when doing a replace, we haven't completed the replace for the last file here if (findResults().replace() && !currentFile_.empty() && !findResults().preview()) { std::set errorMessage; completeFileReplace(&errorMessage); - for (std::string newError : errorMessage) - errors.push_back(json::Value(newError)); + + // it is unlikely there will be any errors if we've made it this far, + // but if so we must add them to the last array in errors + // if there is an error, there will only be one + if (!errorMessage.empty()) + { + json::Array lastErrors = errors.getBack().getArray(); + errors.erase(errors.end()); + lastErrors.push_back(json::Value(*errorMessage.begin())); + errors.push_back(lastErrors); + } } if (nextLineStart) diff --git a/src/cpp/session/modules/SessionRenv.R b/src/cpp/session/modules/SessionRenv.R index b07b978f402..bf896836c50 100644 --- a/src/cpp/session/modules/SessionRenv.R +++ b/src/cpp/session/modules/SessionRenv.R @@ -17,9 +17,25 @@ .rs.addJsonRpcHandler("renv_init", function(project) { - # ask renv not to restart since we'll do it ourselves - .rs.ensureDirectory(project) - renv::init(project = project, restart = FALSE) + # the project directory should already exist, but be extra careful + # and create it if necessary + dir.create(project, showWarnings = FALSE, recursive = TRUE) + owd <- setwd(project) + on.exit(setwd(owd), add = TRUE) + + # set library paths to be inherited by child process + libs <- paste(.libPaths(), collapse = .Platform$path.sep) + renv:::renv_scope_envvars(R_LIBS = libs) + + # form path to R + exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" + r <- file.path(R.home("bin"), exe) + + # form command line arguments + args <- c("--vanilla", "--slave", "-e", shQuote("renv::init()")) + + # invoke R + system2(r, args) }) .rs.addJsonRpcHandler("renv_actions", function(action) diff --git a/src/cpp/session/modules/SessionSource.R b/src/cpp/session/modules/SessionSource.R index 71da6934cc7..213f1eeb18c 100644 --- a/src/cpp/session/modules/SessionSource.R +++ b/src/cpp/session/modules/SessionSource.R @@ -184,8 +184,10 @@ if (length(args) > 0) { - for (ee in args) - freeVars <- c(freeVars, codetools:::walkCode(ee, w)) + # Needs to access the list via index in case of empty strings + # see https://github.com/rstudio/rstudio/issues/5285 + for (i in seq_along(args)) + freeVars <- c(freeVars, codetools:::walkCode(args[[i]], w)) } return(unique(freeVars)) })