(str+)
string values across literals, template literals, concatenations, and string-valued property keys
clojure
(str+ val)Where:
- val: the string pattern to find *
Expanding into:
clojure
(:or (str \1)
(str* \1)
(tpl* \1)
(comp (str \1))
(comp (:ref (str \1)))
(obj (prop (:into (str \1)))))Matching:
- string literals, e.g.
"foo" - template literals, e.g.
`foo ${bar}` - string concatenations, e.g.
"foo" + bar - computed property access, e.g.
obj["foo"] - object property keys, e.g.
{ "foo": value }
Behavior
- Pseudo-evaluates templates and concatenations by joining literals and identifier names (e.g.,
errors.${timeout}is treated aserrors.timeout). - Does not match bare identifiers; use
(id ...)for that.
Examples
Normalize analytics event names that include userId even when constructed dynamically.
clojure
(str+ /userId/)Selects in lines { 1, 2 } but not in { 3, 4 }:
typescript
const event1 = `user_${userId}`
const event2 = "user_" + userId
const event3 = `user_${accountId}`
const event4 = "user_" + accountIdRename a request header key wherever it appears in literals and accessors.
clojure
(str+ "X-Request-ID")Selects in lines { 1 } but not in { 3 }:
typescript
const headers = { "X-Request-ID": reqId }
const header = req.headers["X-Request-ID"]
const wrong = req.headers["X-Request-Id"]
const other = { "X-Request-Id": reqId }Find timeout translation keys across maps and dynamic construction.
clojure
(str+ /errors\.timeout/)Selects in lines { 1, 2, 3 } but not in { 4, 0, 5 }:
typescript
const key1 = `errors.${timeout}`
const key2 = "errors." + timeout
const map = { "errors.timeout": "Request timed out" }
const other1 = `errors.${code}`
const other2 = { "warnings.timeout": "Check config" }Arguments
val
• Identifier • String • Pattern
Does NOT support: Composition — Free-form Selection — Refinement — Replacement