diff --git a/.Rbuildignore b/.Rbuildignore index ee7ab9907..1a6446795 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -24,5 +24,5 @@ ^internal$ ^revdep-cloud$ ^CRAN-SUBMISSION$ -^[\.]?air\.toml$ ^\.vscode$ +^[.]?air[.]toml$ diff --git a/.vscode/settings.json b/.vscode/settings.json index f2d0b79d6..a9f69fe41 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,9 @@ "[r]": { "editor.formatOnSave": true, "editor.defaultFormatter": "Posit.air-vscode" + }, + "[quarto]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "quarto.quarto" } } diff --git a/R/air.R b/R/air.R index aad1e2247..2555eae04 100644 --- a/R/air.R +++ b/R/air.R @@ -13,11 +13,12 @@ #' used by the Air extension installed through either VS Code or Positron, see #' the Installation section for more details. Specifically it: #' -#' - Sets `editor.formatOnSave = true` for R files to enable formatting on -#' every save. +#' - Sets `editor.formatOnSave = true` for R and Quarto files to enable +#' formatting on every save. #' #' - Sets `editor.defaultFormatter` to Air for R files to ensure that Air is -#' always selected as the formatter for this project. +#' always selected as the formatter for this project. Likewise, sets the +#' default formatter for Quarto. #' #' - Sets the Air extension as a "recommended" extension for this project, #' which triggers a notification for contributors coming to this project @@ -31,20 +32,21 @@ #' may prefer another editor. #' #' Note that `use_air()` does not actually invoke Air, it just configures your -#' project with the recommended settings. Consult the [editors +#' project with the recommended settings. Consult [Air's editors #' guide](https://posit-dev.github.io/air/editors.html) to learn how to invoke #' Air in your preferred editor. #' #' ## Installation #' -#' Note that this setup does not install an Air binary, so there is an +#' Note that this setup does not install an Air binary, so there may be an #' additional manual step you must take before using Air for the first time: #' #' - For RStudio, follow the [installation #' guide](https://posit-dev.github.io/air/editor-rstudio.html). #' -#' - For Positron, install the [OpenVSX -#' Extension](https://open-vsx.org/extension/posit/air-vscode). +#' - For Positron, the [Air extension](https://open-vsx.org/extension/posit/air-vscode) +#' is installed by default and that already includes the Air binary. A typical +#' Positron user does not need to do anything to install Air. #' #' - For VS Code, install the [VS Code #' Extension](https://marketplace.visualstudio.com/items?itemName=Posit.air-vscode). @@ -118,7 +120,7 @@ create_air_toml <- function(ignore = FALSE) { air_toml_regex <- function() { # Pre-escaped regex allowing both `air.toml` and `.air.toml` - "^[\\.]?air\\.toml$" + "^[.]?air[.]toml$" } create_vscode_json_file <- function(name) { @@ -142,20 +144,19 @@ create_vscode_json_file <- function(name) { } write_air_vscode_settings_json <- function(path) { - settings <- jsonlite::read_json(path) - settings_r <- settings[["[r]"]] - - if (is.null(settings_r)) { - # Mock it - settings_r <- set_names(list()) - } - - # Set these regardless of their previous values. Assume that calling - # `use_air()` is an explicit request to opt in to these settings. - settings_r[["editor.formatOnSave"]] <- TRUE - settings_r[["editor.defaultFormatter"]] <- "Posit.air-vscode" - - settings[["[r]"]] <- settings_r + settings <- jsonlite::read_json(path) %||% set_names(list()) + + patch <- list( + `[r]` = list( + "editor.formatOnSave" = TRUE, + "editor.defaultFormatter" = "Posit.air-vscode" + ), + `[quarto]` = list( + "editor.formatOnSave" = TRUE, + "editor.defaultFormatter" = "quarto.quarto" + ) + ) + settings <- utils::modifyList(settings, patch) write_vscode_json(x = settings, path = path) } diff --git a/man/use_air.Rd b/man/use_air.Rd index 14667c73f..b3774cc90 100644 --- a/man/use_air.Rd +++ b/man/use_air.Rd @@ -26,10 +26,11 @@ R package, \code{.Rbuildignore} is updated to ignore this file. used by the Air extension installed through either VS Code or Positron, see the Installation section for more details. Specifically it: \itemize{ -\item Sets \code{editor.formatOnSave = true} for R files to enable formatting on -every save. +\item Sets \code{editor.formatOnSave = true} for R and Quarto files to enable +formatting on every save. \item Sets \code{editor.defaultFormatter} to Air for R files to ensure that Air is -always selected as the formatter for this project. +always selected as the formatter for this project. Likewise, sets the +default formatter for Quarto. \item Sets the Air extension as a "recommended" extension for this project, which triggers a notification for contributors coming to this project that don't yet have the Air extension installed. @@ -43,15 +44,17 @@ may prefer another editor. } Note that \code{use_air()} does not actually invoke Air, it just configures your -project with the recommended settings. Consult the \href{https://posit-dev.github.io/air/editors.html}{editors guide} to learn how to invoke +project with the recommended settings. Consult \href{https://posit-dev.github.io/air/editors.html}{Air's editors guide} to learn how to invoke Air in your preferred editor. \subsection{Installation}{ -Note that this setup does not install an Air binary, so there is an +Note that this setup does not install an Air binary, so there may be an additional manual step you must take before using Air for the first time: \itemize{ \item For RStudio, follow the \href{https://posit-dev.github.io/air/editor-rstudio.html}{installation guide}. -\item For Positron, install the \href{https://open-vsx.org/extension/posit/air-vscode}{OpenVSX Extension}. +\item For Positron, the \href{https://open-vsx.org/extension/posit/air-vscode}{Air extension} +is installed by default and that already includes the Air binary. A typical +Positron user does not need to do anything about installing Air. \item For VS Code, install the \href{https://marketplace.visualstudio.com/items?itemName=Posit.air-vscode}{VS Code Extension}. \item For other editors, check to \href{https://posit-dev.github.io/air/editors.html}{see if that editor is supported} by Air. } diff --git a/tests/testthat/_snaps/air.md b/tests/testthat/_snaps/air.md index 0d0cb2b24..460f506d9 100644 --- a/tests/testthat/_snaps/air.md +++ b/tests/testthat/_snaps/air.md @@ -4,7 +4,7 @@ use_air() Message v Creating 'air.toml'. - v Adding "^[\\.]?air\\.toml$" to '.Rbuildignore'. + v Adding "^[.]?air[.]toml$" to '.Rbuildignore'. v Creating '.vscode/'. v Adding "^\\.vscode$" to '.Rbuildignore'. v Creating '.vscode/settings.json'. @@ -21,6 +21,10 @@ "[r]": { "editor.formatOnSave": true, "editor.defaultFormatter": "Posit.air-vscode" + }, + "[quarto]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "quarto.quarto" } } diff --git a/tests/testthat/test-air.R b/tests/testthat/test-air.R index df476c214..567392447 100644 --- a/tests/testthat/test-air.R +++ b/tests/testthat/test-air.R @@ -17,6 +17,11 @@ test_that("creates correct default package files", { settings[["[r]"]][["editor.defaultFormatter"]], "Posit.air-vscode" ) + expect_true(settings[["[quarto]"]][["editor.formatOnSave"]]) + expect_identical( + settings[["[quarto]"]][["editor.defaultFormatter"]], + "quarto.quarto" + ) settings <- jsonlite::read_json(proj_path(".vscode", "extensions.json")) recommendations <- settings[["recommendations"]] @@ -48,6 +53,11 @@ test_that("creates correct default project files", { settings[["[r]"]][["editor.defaultFormatter"]], "Posit.air-vscode" ) + expect_true(settings[["[quarto]"]][["editor.formatOnSave"]]) + expect_identical( + settings[["[quarto]"]][["editor.defaultFormatter"]], + "quarto.quarto" + ) settings <- jsonlite::read_json(proj_path(".vscode", "extensions.json")) recommendations <- settings[["recommendations"]] @@ -68,6 +78,9 @@ test_that("respects existing `settings.json`, but overwrites settings we own", { ), "[rust]" = list( "editor.formatOnSave" = FALSE + ), + "[quarto]" = list( + "editor.wordWrap" = "wordWrapColumn" ) ) @@ -76,11 +89,10 @@ test_that("respects existing `settings.json`, but overwrites settings we own", { use_air() # Here is all that should change - settings[["[r]"]] <- list( - # Overwrite both of these to Air's recommendations - "editor.formatOnSave" = TRUE, - "editor.defaultFormatter" = "Posit.air-vscode" - ) + settings[["[r]"]][["editor.formatOnSave"]] <- TRUE + settings[["[r]"]][["editor.defaultFormatter"]] <- "Posit.air-vscode" + settings[["[quarto]"]][["editor.formatOnSave"]] <- TRUE + settings[["[quarto]"]][["editor.defaultFormatter"]] <- "quarto.quarto" actual_settings <- jsonlite::read_json(path)