Open hadley opened 4 years ago
When you are working on this again, I'd like to suggest to add an example of how you can wrap git + diffviewer to view your uncommited changes without having to go to the RStudio git pane.
view_change_between_current_and_uncommited_file <- function(uncommited_file, repo = ".") {
uncommited_file
uncommited_file <- fs::path_rel(
fs::path_real(uncommited_file),
fs::path_real(repo)
)
if (repo != ".") {
# change dir temporarily
withr::with_dir(repo, {
old_file_lines <- system(paste("git show HEAD:", uncommited_file), intern = TRUE)
})
} else {
old_file_lines <- system(paste0("git show HEAD:", uncommited_file, "\""), intern = TRUE)
}
tmp_dir <- withr::local_tempdir()
file_old <- fs::path(tmp_dir, paste0(fs::path_ext_remove(fs::path_file(uncommited_file)), "-uncommited"), ext = fs::path_ext(uncommited_file))
xfun::write_utf8(
con = file_old,
text = old_file_lines
)
diffviewer::visual_diff(
file_old = file_old,
file_new = uncommited_file,
height = 100
)
}
view_change_between_current_and_uncommited_file("DESCRIPTION")
My "final" version looks more like this. To allow showcasing never commited files too + allow to call without argument and defaulting on the currently open document.
visual_diff <- function(uncommited_file = reuseme::active_rs_doc(), repo = ".") {
rlang::check_installed(c("diffviewer", "gert", "xfun", "fs"))
if (is.null(uncommited_file)) {
cli::cli_abort("Not for unsaved documents.")
}
uncommited_file <- fs::path_rel(
fs::path_real(uncommited_file),
fs::path_real(repo)
)
if (stringr::str_detect(uncommited_file, "\\.\\./")) {
cli::cli_abort("uncommited file can't be outside repo.")
}
if (!fs::is_file(uncommited_file)) {
cli::cli_abort("{.arg uncommited file} must be an existing file.")
}
if (is.na(gert::git_stat_files(uncommited_file)$modified)) {
# Solution
cli::cli_inform("New (uncommited) file {.run [Click to delete])(fs::file_delete({as.character(uncommited_file)}))}.")
tmp_dir <- withr::local_tempdir()
empty_file <- fs::path(tmp_dir, uncommited_file)
xfun::write_utf8(
text = "",
empty_file
)
return(diffviewer::visual_diff(
file_old = empty_file,
file_new = uncommited_file,
height = 100
))
}
if (repo != ".") {
# change dir temporarily
withr::with_dir(repo, {
old_file_lines <- system(paste("git show HEAD:", uncommited_file), intern = TRUE)
})
} else {
old_file_lines <- system(paste0("git show HEAD:", uncommited_file, ""), intern = TRUE)
}
tmp_dir <- withr::local_tempdir()
file_old <- fs::path(tmp_dir, paste0(fs::path_ext_remove(fs::path_file(uncommited_file)), "-uncommited"), ext = fs::path_ext(uncommited_file))
xfun::write_utf8(
con = file_old,
text = old_file_lines
)
diffviewer::visual_diff(
file_old = file_old,
file_new = uncommited_file,
height = 100
)
I ended up not finding this very useful in practice because it doesn't resolve line copying problem (copying in the widget copies the line number, which is what I wanted to avoid with the git pane)
I use a function based on cli links that allows to easily copy content, and also navigate to the correct place (with cli links).
Using selection of examples from http://rpubs.com/jbkunst/diffviewer