Skip to content

(str+)

string values across literals, template literals, concatenations, and string-valued property keys

clojure
(str+ val)

Where:

  1. 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:

  1. string literals, e.g. "foo"
  2. template literals, e.g. `foo ${bar}`
  3. string concatenations, e.g. "foo" + bar
  4. computed property access, e.g. obj["foo"]
  5. 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 as errors.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_" + accountId

Rename 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: CompositionFree-form SelectionRefinementReplacement

Copyright © 2022-present Semantic Works, Inc.