Add support for Shiny app auto-loading - #1388
Conversation
|
AI generated review guide: Covers:
Related issues: posit-dev/positron#15144 and posit-dev/positron#14790. SetupUse a plain folder with no Section 6 tests experimental diagnostics. Enable them in {
"oak.diagnostics.experimental.enabled": true
}For each case, check resolution, goto-definition, find-references, and live updates after editing where applicable. 1. Non-package
|
| File | Required text |
|---|---|
app.R |
shinyApp |
ui.R |
shinyUI |
server.R |
shinyServer |
Filenames are matched case-insensitively. Marker detection is a plain text search, so comments and strings also count.
Basic support loading
ws/
app.R # shinyApp(ui, server)
global.R # cfg <- 1
R/
a.R # a_val <- 1
b.R # b_val <- 2
In app.R:
cfg,a_val, andb_valresolve.- Shiny exports such as
reactiveandfluidPageresolve withoutlibrary(shiny).
Entry-point top level sees all support files
# app.R
mod_ui() # resolves
shinyApp(ui, server)loadSupport() finishes before app.R starts, so top-level uses in the entry point see the full support set.
global.R runs first
# global.R
reactive(1) # resolves through the implicit shiny attach
a_val # unresolved because R/a.R has not runAn R/ support file can see bindings from global.R.
Non-recursive support directory
loadSupport() does not recurse. R/models/fit.R is not part of the app support set.
_disable_autoload.R
Adding R/_disable_autoload.R disables loading of the app's R/ directory but does not disable global.R.
ws/app.R # shinyApp(ui, server)
ws/global.R # cfg <- 1
ws/R/a.R # cfg and reactive should not resolve here
ws/R/_disable_autoload.R
The R/ files fall back to ordinary non-package collation and lose the implicit Shiny attach.
Split ui.R and server.R
Both entry points see the support set. They run in sibling environments, so they do not see bindings from each other.
Nested and packaged apps
R/app.Rinside an app remains a support file. It is not treated as another app root.- A package app under
inst/app/receives Shiny loading behavior. - A package's own
R/directory is never treated as Shiny support, even if the package root containsapp.R.
Live updates and cache stability
- Remove the
shinyAppmarker fromapp.R. - Confirm that
global.R, support-file visibility, and the implicit Shiny attach disappear. - Restore the marker and confirm that they return.
- Edit unrelated text in
app.R. Support files should not flicker or lose resolution.
5. Issue checks
posit-dev/positron#15144
Clone https://github.com/benzipperer/ctrl_click and check the three targets in main.R.
greet_localalready worked.greet_static_helperalready worked.greet_dynamic_helperstill does not resolve becauselapply(list.files("R"), source)requires dataflow analysis.
Replacing the dynamic loader with sourceDir("R") or tar_source() should make it resolve. Independently, files inside R/ should now resolve one another.
posit-dev/positron#14790
Functions spread across the workspace root, with no R/ directory and no source calls, are still unsupported. Confirm that goto-definition still reports no definition found.
6. Experimental diagnostics
These require oak.diagnostics.experimental.enabled.
6.1 source-cycle warning
# a.R
source("b.R")
# b.R
source("a.R")Expected:
- Both files report the cycle.
- Each diagnostic is anchored at the start of the file.
- The message says analysis is incomplete until the cycle is removed.
6.2 inherited-shadow information
This diagnostic reports a bare call whose NSE effect changes under inherited source context.
# a.R
source <- identity
base::source("b.R")
# b.R
source("c.R")
# c.R
foo <- 1Expected:
- The diagnostic appears in
b.Ronsource("c.R"). - It explains that standalone and inherited contexts resolve the call differently.
base::source("b.R") is required. A bare call would resolve to the local identity, removing both the source edge and the diagnostic.
The diagnostic should not appear when:
- The sourced file's own attach ordering explains the shadow.
- The sourcing file binds the name after the source call.
- Both winning definitions are plain functions with no NSE effect.
Only library, require, source, and tar_source callees are considered. NSE-only functions such as withr::defer() do not trigger this diagnostic.
7. Known gaps
lapply(list.files("R"), source)is not recognized.
c784e05 to
4479950
Compare
0003e80 to
0d7a8e0
Compare
0d7a8e0 to
35be7ff
Compare
Addresses posit-dev/positron#14790
Progress towards #1338
Shiny apps are now detected to inject a file loader in the workspace that implements Shiny auto-loading (https://shiny.posit.co/r/reference/shiny/1.7.5/loadsupport.html).
The detection follows RStudio: an
app.Rfile containingshinyApp, aui.Rfile containingshinyUI, or aserver.Rfile containingshinyServer.The entry point sees
global.Rand the wholeR/directory, plus an implicitshinyattach.global.Rloads first and doesn't seeR/. The autoload isn't recursive, unliketar_source()._disable_autoload.Rdrops the directory but keepsglobal.R.Shiny apps under
inst/app/are detected too, since package loading doesn't claiminst/files in the first place.An explicit
source()now replaces theR/auto-collation instead of adding to it: it contradicts the layout guess rather than describing a second execution. A detected loader like Shiny does, so it stays additive.Loader detection moves into a new
load_contextmodule, with per-package conventions underload_context/contrib/. Currently hastestthatandshinycontributions.Positron Release Notes
New Features
Bug Fixes