Completion
July 24, 2026 · View on GitHub
Raven offers context-aware completions for R symbols, package exports, function parameters, and file paths. Completions respect the cross-file dependency graph and position-aware scope.
What's Offered
| Symbol source | Behavior |
|---|---|
| Local definitions | Symbols defined in the current file, above the cursor |
| Cross-file symbols | Symbols from sourced files, available after the source() call / # raven: source directive |
| Package exports | Functions and variables from loaded packages, with {pkg} attribution |
| Namespace-qualified exports | A package's exported symbols after pkg:: (e.g. dplyr::) |
| box imports | Static namespace aliases and attached/renamed exports; known exports after alias$, alias@, or literal alias[["…"]] access |
| import package bindings | Static selected, renamed, and known .all bindings from packages or literal script modules; named destinations contribute fallback names only |
| Function parameters | Parameter names when inside a function call |
| File paths | .R/.r files and directories inside source() strings and path directives |
| $ members | Known members after $ (from assignments and constructors) |
Position-Aware Filtering
Completions respect execution order. A symbol is only offered if it would be defined at the cursor's position at runtime:
# Before this line: only base symbols + earlier local definitions
library(dplyr)
# After the library() call: dplyr exports now available
source("utils.R")
# After the source() call: symbols from utils.R now available
Symbols defined below the cursor in the same file are not offered at the global level. Inside function bodies, global definitions are hoisted (see Global Symbol Hoisting).
Package Completions
When a package is loaded via library(), its exports appear in completions with {package} detail:
library(dplyr)
mut # Offers: mutate {dplyr}, mutate_all {dplyr}, ...
Package completions are position-aware — they only appear after the library() call. Packages loaded in parent files (before the source() call to the current file) are also available. They require package awareness (raven.packages.enabled, on by default); base-package symbols additionally wait until the package library has finished loading.
Namespace-Qualified Completions (pkg::)
After a :: namespace qualifier, Raven completes the package's exported symbols:
dplyr:: # Offers: mutate {dplyr}, filter {dplyr}, select {dplyr}, ...
Each item is attributed {package} and resolves to that topic's help, exactly like ordinary package completions, and covers the package's NAMESPACE exports. Non-syntactic exports — operators such as %>%, or exported names that are not valid bare identifiers — are inserted backtick-quoted (so accepting magrittr::%>% produces magrittr::`%>%`) and the accepted completion is valid R.
Unlike the position-aware completions above, pkg:: does not require a prior library(pkg) call: any installed package resolves on demand by reading its NAMESPACE (the same way pkg::name works in R without attaching the package). Writing pkg:: (or pkg:::) also warms pkg's metadata into the package cache in the background — exactly as a library(pkg) call would — so the two refinements below become available without an explicit attach. Crucially, this warming never attaches pkg to bare-name scope: it only populates metadata. Two refinements arrive once a package has been loaded (in the background, or by an earlier library()/pkg:: use in the session): exported datasets (which live in data/, not the NAMESPACE), and the complete export set for the ~6% of packages that export via exportPattern() — those offer their explicitly-exported names immediately.
Inside a pkg:: expression no other completions are offered (keywords, local symbols, and other packages are irrelevant there). Internal access via pkg::: (non-exported symbols) warms the package's metadata but is not completed and is never member-validated. Like the other package completions, this requires raven.packages.enabled. A pkg::member that a complete export set does not contain is flagged by the namespace-member-not-found diagnostic.
box Namespace and Attached Completions
A static box::use() import contributes only the bindings it requests. A namespace import offers known exported members after $ or @; a literal [["member"]] access resolves the same member for hover/navigation. Selective and renamed attachments appear as bare-name completions under their local names, and wildcard attachment expands the known export set.
box::use(./model, ./format[render, fmt = format_value])
model$ # Offers only known exports of ./model
rend # Can offer render
fmt # Can offer the renamed attachment
Private or merely transitive module names are never offered. Complete export metadata can prove a member absent; partial/unknown metadata contributes known positives without guessing the rest. Installed-package box imports use Raven's normal installed/frozen/downloaded package metadata, but do not attach the whole package as bare-name scope.
Function Parameter Completions
When the cursor is inside a function call, Raven offers parameter names:
read.csv( # Offers: file, header, sep, quote, ...
Trigger character ( activates parameter completions automatically (configurable via raven.completion.triggerOnOpenParen).
File Path Completions
Inside source() strings and path-taking directives, Raven completes file paths:
source("utils/ # Offers: utils/helpers.R, utils/config.R, ...
Path completion respects # raven: cd and workspace-root fallback rules for forward directives (# raven: source, # raven: run, # raven: include) and source() calls. Backward directives (# raven: sourced-by, # raven: run-by, # raven: included-by) still resolve relative to the file's directory.
In files under tests/testthat/ or tests/testit/, forward-path completion uses that test directory as its implicit working-directory anchor. For files nested below the anchor, Raven merges in entries from the file's own directory as a compatibility fallback; duplicate names appear once, with the anchor taking precedence. An explicit or inherited # raven: cd overrides these implicit completion bases.
$ Member Completions
After typing foo$, Raven offers known members of foo:
config <- list(host = "localhost", port = 8080)
config$ # Offers: host, port
Members are discovered from:
- Assignments:
foo$bar <- …,foo[["bar"]] <- … - Constructor literals: named arguments in
list(),data.frame(),tibble(), etc.
Non-syntactic member names are shown without quoting in the completion popup, but inserted with backticks so the resulting R code parses correctly:
df <- list(`alpha beta` = 1)
df$ # Offers: alpha beta; accepting inserts df$`alpha beta`
Member completion follows nested access at any depth, and $, @, and
[["lit"]] segments are interchangeable in the chain:
config <- list(db = list(host = "localhost", port = 8080))
config$db$ # Offers: host, port
config[["db"]]$ # Same — `[["db"]]` is equivalent to `$db`
Members reflect the value that is live at the cursor, so a whole reassignment of an intermediate value replaces its earlier members:
config$db <- list(url = "…") # whole-value rewrite
config$db$ # Offers: url (earlier host/port are replaced)
Because the container is resolved as a path, an unrelated top-level variable
that happens to share an intermediate name (a db elsewhere) never leaks its
members into config$db$.
Cross-File Completions
Symbols from sourced files appear with their source file indicated:
# main.R
source("utils.R")
help # Offers: helper_function — "from utils.R" as the item detail
R Markdown / Quarto
Inside .Rmd / .qmd documents, completions work inside R chunk bodies: local definitions, cross-file symbols, package exports, function parameters, and $ members all resolve across chunks as if the document were a single R program. On prose, YAML front matter, or non-R chunks, completion returns nothing rather than treating the line as R.
JAGS and Stan
For .stan, .jags, .bugs, and .bug files, Raven offers completions tailored to each language. JAGS suffixes are matched case-insensitively and mean strict JAGS dialect, not general OpenBUGS, WinBUGS, MultiBUGS, or NIMBLE compatibility:
| Language | What's offered |
|---|---|
| JAGS | Syntax keywords (var, data, model, for, in), contextual truncation/censoring forms (T, I), automatically available basemod/bugs distributions and callables (including aliases), and file-local symbols |
| Stan | Types (int, real, vector, …), block keywords (data, parameters, model, …), control flow (if, for, while, …), bare distribution names for sampling statements (normal, poisson, multi_normal, …), compiler-known callables including normalized and unnormalized probability variants (normal_lpdf, normal_lupdf, poisson_lpmf, poisson_lupmf, …), and file-local symbols |
JAGS completion, hover, and signature help share a generated catalog pinned to JAGS 4.3.2. It covers the basemod and bugs modules that JAGS loads automatically, including compiler-special length()/dim(), the pow() alias, distribution aliases, and the verified d/p/q/logdensity callables exposed by those modules. Optional modules are deliberately absent. A name that is both a callable and a distribution appears once. File-local symbols take precedence over a same-named catalog entry. The catalog is static and requires no local JAGS installation, subprocess, network request, or R analysis at runtime.
Stan's built-in callable and distribution catalogs are generated from the compiler metadata in Raven's pinned stanc3 npm dependency (package 2.39.1, bundled compiler 2.39.0). Unnormalized _lupdf and _lupmf aliases are included where the compiler exposes the corresponding normalized density or mass function. This avoids invalid combinations such as poisson_lpdf and keeps completions and Stan hover on the same versioned source of truth. These completions are static rather than context-sensitive: Raven offers the same built-in set throughout a Stan file. File-local symbols are discovered by scanning the current file for variable declarations and assignments. R-specific reserved words are excluded from JAGS completions to avoid noise.
Scope Rules Summary
- Local definitions: available after their definition line
- Cross-file symbols: available after the
source()call /# raven: sourcedirective - Package exports: available after the
library()call - Inside function bodies: global definitions are hoisted (all visible regardless of position)
rm()/remove()calls: removed symbols are excluded from completions