Skip to content

Instantly share code, notes, and snippets.

@BenjaminWolfe
Last active June 19, 2022 22:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save BenjaminWolfe/fc00c480f8a7185779669d2895829069 to your computer and use it in GitHub Desktop.
Save BenjaminWolfe/fc00c480f8a7185779669d2895829069 to your computer and use it in GitHub Desktop.
# hacky but fun code to change the RStudio theme every (e.g.) 15 minutes,
# cycling through the themes in the {rsthemes} package.
# https://gist.github.com/BenjaminWolfe/fc00c480f8a7185779669d2895829069
#
# start is 9am on the day rstudio::conf(2021L) kicks off.
# applies the current theme, then starts a timer to change it periodically.
# to rotate less often (or more), adjust theme_period below.
# (fractional minutes may not work.)
# note that breaks are just based on lubridate::round_date logic.
#
# hacky b/c I use options() to give the functions a separate namespace.
# ideally I'd just do a pull request!
#
# I'd like to do some refactoring though first.
# a) how can the user set and share their own playlist / start / period?
# b) it would add lubridate as a suggests. is gadenbuie OK with that?
# c) do I want it to be savvy to daytime / nighttime?
#
# and then in an ideal world it would be fun to do a quick blog post about this.
#
# be sure to devtools::install("gadenbuie/rsthemes")
# and install.packages(c("later", "lubridate")) if needed.
# then file.edit("~/.Rprofile") and add this code, and restart R.
if (
interactive() &&
requireNamespace("rsthemes" , quietly = TRUE) &&
requireNamespace("later" , quietly = TRUE) &&
requireNamespace("lubridate", quietly = TRUE)
) {
later::later(function() {
options(
theme_period = lubridate::minutes(15),
theme_start = lubridate::ymd_h("2021-01-18 09", tz = "America/New_York"),
theme_playlist = rsthemes::list_rsthemes(),
# wait for the minute to turn (0 seconds)
wait_for_minute = function() {
this_second <- floor(lubridate::second(lubridate::now()))
if (this_second == 0) return(getOption("wait_for_loop")())
later::later(getOption("wait_for_minute"), delay = 1)
},
# wait for the next break (e.g. every 15 minutes)
wait_for_loop = function() {
breaks <- lubridate::minute(c(
lubridate::floor_date(lubridate::now(), getOption("theme_period")),
lubridate::ceiling_date(lubridate::now(), getOption("theme_period"))
))
if (lubridate::minute(lubridate::now()) %in% breaks) {
return(getOption("apply_theme")())
}
later::later(getOption("wait_for_loop"), delay = 60)
},
# apply the theme of the moment from {rsthemes}
apply_theme = function(delayed = TRUE) {
start <- getOption("theme_start")
period <- getOption("theme_period")
playlist <- getOption("theme_playlist")
current <- (lubridate::now() - start) / lubridate::as.duration(period)
this_theme <- playlist[floor(current %% length(playlist)) + 1]
message(
lubridate::now(), ":",
" changing theme to ", this_theme,
" until ", lubridate::ceiling_date(lubridate::now(), period)
)
rstudioapi::applyTheme(this_theme)
if (!isTRUE(delayed)) return(invisible())
later::later(getOption("apply_theme"), delay = as.numeric(period))
}
)
getOption("apply_theme")(delayed = FALSE)
getOption("wait_for_minute")()
}, delay = 1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment