Liking cljdoc? Tell your friends :D

Changelog

Squint: Light-weight ClojureScript dialect

0.16.214

  • #1065: fix js-delete as the last expression of a function body emitting return return (@jasalt)
  • #1067: if with a keyword or non-empty string test, such as the :else of a cond, emits only the then branch instead of if ("else") and a dead return null (@staab)
  • #1069: every? and every-pred treat 0 and "" as truthy, and every-pred accepts keywords and collections
  • #1069: keep and keep-indexed keep false results, and the keep-indexed transducer accepts keywords and collections
  • #1069: assoc-in throws on a 0 or false level or root instead of replacing it, and assoc-in! creates a map for a nil level
  • #1069: assoc-in and assoc-in! create a map for a missing level under a vector root, e.g. (assoc-in [] [0 :a] 1) returns [{:a 1}]
  • #1069: into with a transducer keeps undefined values as nil and returns a vector for a nil target
  • #1069: memoize caches an undefined result
  • #1069: keys and vals of an empty map return null instead of undefined
  • #1069: clojure.string/join returns "" for an undefined coll and joins nil elements of a seq as ""
  • #1069: partition-by returns an empty seq for a nil or empty coll and compares keys with =
  • #1069: the filter transducer accepts a keyword or collection as pred
  • #1069: some-fn accepts keywords and collections
  • #1069: sort accepts a boolean comparator, e.g. (sort > [1 3 2])
  • #1069: clojure.string/replace and replace-first pass [match g1 g2 ...] to a replacement fn if the regex has groups
  • #1069: empty, conj and merge keep a sorted set or map sorted, with its comparator
  • #1069: clojure.set union, intersection, difference and select return a sorted set for a sorted set input
  • #1069: .forEach on a sorted set calls the function with each element in sorted order instead of throwing
  • #1069: .clear on a sorted set sets its size to 0
  • #1069: clojure.set functions treat a nil set as empty, map-invert returns {} for nil, and rename-keys accepts an empty key map
  • #1069: count of a map or record counts its entries instead of returning a :length or :size value

0.16.213

  • #1061: read tagged literals with reader functions from data_readers.cljc in :paths
  • #1059: defclass methods destructure their arguments
  • #594: support for await in doseq, with ^:await on a binding, (doseq [^:await x xs] ...), or on the binding vector for every binding (#1053, @shaunlebron)
  • #1052: squint run no longer prints a Running <file> banner, so a program's output is only its own (@shaunlebron)
  • compileStringEx errors carry data as a JS object, e.g. e.data.line
  • #1050: fix a catch binding that needs munging (e.g. abort-error) not being found in the catch body (@mskyan)
  • Playground: new layout with resizable panes, dark mode and a menu of built-in examples, each loadable with ?example=<name> (#1045, #1056, @paintparty)
  • Playground: mark compile and runtime errors at their source location in the editor (@paintparty)

0.15.212

  • #453: Add source maps for compiled files
  • squint watch writes source maps by default. Disable with --no-source-map or :source-map false in squint.edn
  • Optimize compiled output for core predicates such as even? and string? in if, and, or and not
  • Fix contains? to return a boolean for IAssociative types
  • Fix with_meta calls in output for ^:=> fns and for assoc and get on map literals

0.14.211

  • #1032: #html: escape attribute values from {:& m} (@mskyan)
  • #1031: #html: escape every string in a seq, not only the first one (@mskyan)

0.14.210

  • Add :used-core-vars to the result of compile*, with the munged core var names that the output references

0.14.209

  • Add eduction, implements? and keyword-identical?
  • Optimize compiled output for or, and and reify
  • Fix #1000: treat empty strings from str, subs or name as truthy in if
  • Allow locals to shadow core macros in call position
  • Fix map destructuring with a symbol key
  • Fix reduce-kv to stop on reduced and pass vector indices as keys
  • Fix with-meta to preserve protocol methods on deftype, defrecord and reify instances
  • Fix recur in protocol methods
  • Fix #994: JSX fragments with :jsx-runtime
  • Fix compilation of set!, js-in and js/typeof in expressions (#1011, #1002)
  • Fix eval as a var, local or parameter name
  • Fix #1008: and with recur after a boolean operand
  • Resolve qualified and dotted var names in the current or a required namespace
  • Fix regex literals on the JVM compiler path, including return values (#992)
  • Fix #998: cljs.test macros with a custom :resolve-ns
  • Preserve the type of deftype instances in assoc
  • Fix map?, object? and printing for reify instances
  • Preserve form metadata on reify
  • Make satisfies? and implements? consistently return booleans
  • Fix deftype with Object methods adding an undefined property
  • Playground: fix results after toggling REPL mode and stale errors and compiler state between runs (#990)
  • Playground: update layout, controls, panel scrolling and result font size (#989, @paintparty)

0.14.208

  • Fix #985: munge JS reserved words on the JVM compiler path
  • Fix core var references in macro expansions on the JVM compiler path
  • Fix let rename collisions in REPL output
  • Fix "invalid form" error for expanded call forms on the JVM compiler path
  • Fix repeated REPL require throwing on aliases from earlier evals
  • Fix REPL require of squint.core registering an unbound alias
  • Resolve core ns aliases to core vars
  • Use Symbol.for for protocol method dispatch, so pulling in multiple copies of squint.core (e.g. via http://esm.sh/) does not break protocol dispatch

0.14.207

  • Clojure 1.13 destructuring: :keys!/:syms!/:strs! for required keys, & inside them for keys required but not bound, :select, :all, :defaults, and :or by key. Adds req! and some-vals to core
  • Fix #975: & {:keys [...]} now destructures a map instead of the raw rest args, and a seq destructured as a map is read as kwargs. Both the kwargs and trailing-map call styles work, via seq-to-map-for-destructuring.
  • Fix #977: recur inside try no longer emits an illegal continue. A try in return position emits without the iife wrapper that cut the recur off from its loop
  • Fix #978: defclass now supports ^:get and ^:set methods
  • defmulti now defines the multimethod with defonce in REPL-mode, so a REPL or vite HMR module reload keeps the registered methods
  • Share the macro scan and macro lookup with cherry. A macro expansion calling another macro namespace's macro fully qualified now expands instead of compiling to a runtime call

0.14.206

  • Fix #960: the nREPL server no longer logs requests, responses and eval errors by default. Enable with --debug (CLI), :debug in squint.edn, or :debug (startServer)
  • DCE and performance optimizations in core lib

0.14.205

  • Fix #957: vite HMR: support ^:dev/after-load + ^:dev/before-load hooks similar to shadow-cljs
  • REPL mode: resolve local namespace aliases and refers through globalThis so redefined and hot-swapped code stays visible across namespaces. The REPL now expects :repl-compiled output.

0.14.204

  • Fix #955: cross-ns extend-type keys impl by protocol slot Symbol

0.14.203

Preparatory release before adding immutable + persistent collections in squint.immutable tl;dr: added a lot of protocols and made sure core functions work properly with them.

  • clojure.set dispatches through the collection protocols: results keep the input's type, membership tests against a protocol set are value-based, and rename-keys/map-invert no longer mutate a record
  • Add the IStack, IIndexed, IVector, IWriter and IPrintWithWriter protocols, write-all, and an ITransientVector -pop! slot; nth, peek, pop, pop!, subvec, vec, vector?, sequential?, set?, map?, seq, = and printing dispatch to custom collection types
  • Add equiv, hash, hash-ordered-coll, hash-unordered-coll and the IHash protocol. hash follows equiv: plain mutable objects and arrays hash by reference
  • Add the IEncodeJS protocol; clj->js dispatches through it so a custom type controls its own conversion
  • Add the IMeta and IWithMeta protocols; meta and with-meta dispatch through them and the internal meta symbol property is gone
  • Add :require-global and :refer-global to ns, binding globals loaded via a script tag to consts without emitting an import
  • The CLI reports the file, line and column of a compile error and exits non-zero, instead of dumping the raw exception
  • Support :as-alias in ns :require like CLJS: no runtime import, only a compile-time alias so a namespaced keyword such as ::alias/x resolves
  • Fix iterable to reject a class instance that has no native iterator or ISeqable, so reduce, into, remove and friends no longer expose an object's internal fields, matching seqable? and CLJS
  • Fix seq of a js/Map or sorted-map to return a non-map sequence of entries, like a plain map and like CLJS, instead of the map itself
  • A collection passed in function position is callable as a lookup only if it is a vector, map, set or a type implementing ILookup. A seq, list or opaque object now throws when called through juxt, comp and friends, like a non-IFn in CLJS
  • Fix descendants to throw on a constructor, like CLJS, instead of returning nil
  • Add ident?, simple-ident?, qualified-ident?, simple-symbol?, qualified-symbol?, num, byte and short
  • Add fnext, nfirst, nthnext, nthrest, parse-boolean, char, pop!, print-str, println-str, prn-str, random-sample, float?, reversible?, / as a value and associative? through the IAssociative protocol
  • Add the ISet, IEditableCollection, ITransientCollection, ITransientAssociative, ITransientMap and ITransientSet protocols. disj, transient, conj!, assoc!, dissoc!, disj! and persistent! dispatch to them on custom types
  • Records are JS-iterable over their entries and print readably in the Node console
  • Add defrecord, record? and the IRecord marker protocol. Records store their fields as own string-keyed properties and implement the map-facing protocols, so keyword lookup, keys, seq, assoc, conj and = work through the regular core functions. assoc keeps the record type, dissoc of a basis field gives a plain map, printing gives #TypeName{:a 1}
  • The generated record implementations are shared runtime functions in squint-cljs/src/squint/record.js, imported only by files that use defrecord: each defrecord emits one attach call instead of nine method bodies
  • Fix merge on a record or other -conj type without an empty representation
  • Fix merge, keys, vals, update-keys and update-vals to dispatch through the map protocols on custom types, instead of mutating copies or reading internal properties
  • Fix into to reduce through -conj on a type implementing ICollection instead of mutating a plain copy
  • Fix assoc-in and update-in to read intermediate levels through -lookup, so nested updates work on types implementing the map protocols
  • Add the ILookup, IAssociative, IMap, ICounted, IKVReduce, ICollection, IEmptyableCollection and IEquiv protocols. get, assoc, contains?, find, dissoc, count, reduce-kv, conj, empty and = dispatch to them on custom types. Plain objects and arrays keep their fast paths

0.14.202

  • Fix assoc and assoc! called without a value for the last key: throws at runtime, and at compile time for a literal call
  • Add get-validator and set-validator!
  • Fix a def or deftype inside a function being added to the module exports, which made the module fail to load
  • Fix take-nth to throw on a non-number step instead of looping forever
  • Fix empty to return nil on non-collections and class instances instead of throwing, like CLJS
  • Fix assoc! on a vector to validate the index like assoc, instead of writing a sparse array
  • Fix parents, ancestors and descendants to return nil on an invalid hierarchy instead of throwing

0.14.201

  • The built-in protocols can be extended to nil and to base types such as number and string via extend-type
  • BREAKING: deref, reset!, swap!, add-watch and remove-watch dispatch only through the protocols. The internal _deref and _reset_BANG_ props are no longer consulted: implement IDeref, IReset, ISwap or IWatchable instead
  • Add the IReset, ISwap and IWatchable protocols, satisfied by atoms. reset!, swap!, add-watch and remove-watch dispatch to them on custom types, so a reagent-style reactive atom can be a deftype
  • Fix multi-arity and variadic deftype methods to receive this, so protocol methods with more than one arity work
  • cljs.analyzer.api/resolve at compile time now sees vars of built-in library namespaces such as clojure.string, through an alias or fully qualified
  • Add clojure.string/escape
  • Fix clojure.string/blank? to return false on a non-string instead of throwing, like CLJS
  • Fix peek to throw on a non-stack such as a set or map, like CLJS
  • Fix = to compare regexes by identity, like CLJS, so two equal regex literals are not equal
  • Fix cons to throw eagerly on a non-seqable tail such as a number, like CLJS. seq throws the same is not ISeqable error on non-seqables such as a class instance without iterator
  • Add the ISeqable protocol with -seq: a type extended to it seqs through its -seq method in seq, vec, cons and everything built on them, and seqable? returns true for it
  • Fix some-fn to return the last predicate result such as false instead of nil, and to treat 0 and "" as truthy, like CLJS
  • Fix min-key and max-key to compare pairwise like CLJS, correcting the result when keys are NaN or equal
  • Fix merge with a non-collection first arg to return it or throw on more args, like CLJS, instead of failing to copy it
  • conj and merge on a map throw when a vector arg is not a pair, like CLJS
  • Fix nth to throw on a non-number index, pop to throw on a non-stack, keys and vals to throw on a non-map, and hash-map to throw on a missing value, like CLJS
  • Fix seq to throw on a function, (conj! coll) to return the coll unchanged, and conj on a map to accept only map entries or seqables of map entries, like CLJS
  • Fix disj to preserve metadata
  • take, drop, take-last and drop-last assert a number count, like CLJS
  • Add the IAtom marker protocol and the IDeref protocol with -deref, both satisfied by atoms. deref and @ dispatch to -deref on types extended via extend-type, like CLJS
  • Add missing-protocol and throw its clear error on every protocol dispatch miss, including custom protocols, like CLJS
  • Support the :meta and :validator options of atom, like CLJS. The validator runs on reset! and swap!, not at creation, matching current CLJS behavior
  • Fix reset! to return the new value
  • Fix assoc on a vector to validate the index, like CLJS: out of bounds or a non-number key throws, index count appends. assoc on false also throws: only nil puns to an empty map
  • Fix dissoc to throw on a non-map collection such as a vector, set or list, like CLJS
  • Fix get-in and select-keys to treat a nil path or key seq as empty, like CLJS, and select-keys to always return a map
  • Fix (cycle nil) and (cycle []) to give an empty seq instead of throwing or looping, cycle a map by its entries, and throw eagerly on a non-iterable, like CLJS
  • Fix NaN? to coerce its argument like CLJS js/isNaN, so (NaN? "foo") is true
  • Add hash-set, sorted?, char?, rseq, parse-uuid, force, clojure.string/reverse and the typed array constructors int-array, long-array, float-array, double-array and object-array
  • Fix random-uuid to return a UUID instance, so uuid? is true for it, like CLJS
  • uuid lowercases its argument, like CLJS
  • doall returns the realized seq itself instead of a vector, like CLJS
  • A dotted class ref like cljs.core.UUID resolves to the core module member, like in CLJS
  • Fix = to compare a plain object map and a js/Map by entries, so the two map reps are equal when their contents are
  • derive, underive, isa?, parents, ancestors and descendants accept a hierarchy written as a plain map, like {:parents {} :ancestors {} :descendants {}}
  • BREAKING: derive and underive with an explicit hierarchy throw on a malformed one, and the global-hierarchy derive requires a namespace-qualified tag and parent, like CLJS
  • cljs.analyzer.api/resolve at compile time now sees built-in macros such as and, when-let and bit-and, and user macros, returning :macro true for them, like CLJS. A name in :refer-clojure :exclude no longer resolves to core. A local binding shadows all of these and resolves with :local true

0.14.200

  • Fix assoc! regression on non-plain objects such as a class instance or a null-prototype object
  • .indexOf on a lazy seq now uses reference equality like a JS array, not value equality. This diverges from CLJS but keeps = out of any bundle that only builds lazy seqs, shrinking a conj bundle from 3801 to 2215 bytes
  • Add :squint/compile-time opt-in mechanism for macro/compile-time namespaces. See doc/compile-time.md.
  • Fix: a macro used in the namespace that defines it (self :require-macros) now expands: the macro's own def no longer shadows the macro lookup or triggers an alias-collision rename
  • A defmacro is compile-time only: no longer emitted to the runtime module, and :refering a macro no longer emits a runtime import for it, matching CLJS
  • Fix a sorted set to compare equal by elements to a hash set or another sorted set, and give it a count
  • Fix min and max to propagate NaN like CLJS, correcting a regression in 0.14.199 where the 2-arg comparison dropped it. Also stop inlining the 2-arg call, since CLJS does not inline min/max

0.14.199

  • Fix #886: let a var shadow a same-named core macro. :refer-clojure :exclude now suppresses the core macro, and declare registers a forward reference so a core-macro-named var such as exists? resolves to the var
  • Fix min and max to compare with </> and return one of the values, so nil acts like zero and NaN propagates, like CLJS, instead of Math.min/Math.max coercing nil to 0
  • Inline the 2-arg min/max call with simple operands to a comparison, like CLJS

0.14.198

These changes were all made to improve compatibility with dialect tests in clojure-test-suite.

  • Add sorted-map, sorted-map-by and sorted-set-by, keeping entries in sorted order
  • Make subvec throw on an out-of-bounds range, a nil index or a non-vector, and coerce indices to integers, like CLJS
  • Make pop throw on an empty vector or list, like Clojure and CLJS
  • Add hash-map and array-map, both building a plain map like a map literal
  • Make even? and odd? throw on a non-integer argument, like Clojure and CLJS
  • Fix take-last to return nil for an empty or nil collection, like CLJS
  • Fix sequential? to return false for sets, maps and strings, instead of treating every iterable as sequential
  • Fix seq on a string to return its characters and on a set to return its elements, like CLJS
  • Fix peek and pop on a list to use its front, like CLJS, and (pop nil) to return nil
  • Fix keys and vals to return nil for an empty or nil map, like CLJS
  • Fix merge to return nil when called with no maps or only nil maps, like CLJS
  • Fix (partition n step pad coll) to emit the final partial partition even when pad is empty or nil, like CLJS, and no longer throw on a nil pad
  • Fix add-watch and remove-watch to return the reference, like CLJS
  • Fix cat transducer appending a nil on completion, so transduce with cat or mapcat no longer adds a trailing nil
  • Fix (conj nil) to return nil, like CLJS, instead of an empty list
  • Fix contains? on a string to test integer indices, so (contains? "abc" 0) is true, like CLJS
  • Make every lazy seq an instance of LazySeq, so (instance? LazySeq (concat ...)) and similar return true
  • Support with-meta on a lazy seq or cons, attaching metadata without forcing realization
  • Fix boolean to coerce every value except nil and false to true
  • Fix fnil to replace only nil arguments and to use per-position defaults for higher arities
  • Fix cons to compare equal to vectors and lists and to print as a list
  • Make repeat return a lazy seq, so it compares equal to vectors and lists
  • Fix unary <, >, <=, >= to return true
  • Fix = to compare js/Date values, so distinct #inst literals are not equal
  • Route output through println in cljs.test
  • Support emojis as aliases
  • Add float and double core functions
  • Fix are to substitute bindings into the test form like CLJS, so assertions such as thrown? dispatch correctly
  • Fix emission of nullary (+) and (*) and unary (- x)
  • Map clojure.core and cljs.core to the core module so they can be required, including aliased fns and macros (c/inc, c/->)
  • Fix repeatedly to return an empty seq for count 0 and throw on a non-number count
  • Add realized? for delays and lazy seqs
  • Support #uuid literals with a UUID type
  • Support #inst literals as js/Date and add inst?
  • Support extending cljs.test/assert-expr with defmethod, like CLJS

0.14.197

  • Add clojure.string/replace-first
  • Fix: user-defined function named after JS reserved word (e.g. delete) now correctly shadows the special form
  • Fix conj + SortedSet DCE issue
  • Fix #771: DCE of varargs/multi-arity functions and optimize via ... spread
  • Improve DCE of defprotocol when no :extend-via-metadata is present
  • Speed up dissoc and conj!

0.14.196

  • Add squint.edn / clojure.edn, a minimal EDN reader in 300-ish lines of JS.
  • Add *print-fn*, *print-err-fn* and *print-newline* dynamic vars, similar to CLJS
  • BREAKING: println is no longer a synonym for console.log and now prints through *print-fn* like CLJS
  • Add double?, vary-meta, symbol core fns
  • Add with-out-str
  • Add print, pr
  • Fix: coll? returned true for functions. Use aset, aget for raw property access on non-objects.
  • Make core.js more suitable for treeshaking when only a few functions from it are used.
  • pr-str and prn no longer misreport a shared reference as circular. An object referenced from two places now prints in full at each occurrence, while genuine cycles still print as #object[circular].
  • Fix thrown? to work with :default like CLJS

0.13.195

  • Fix (vec (list ..)) edge case
  • Improve inference of collections, such that (let [x {:a 1}] (x :a)) works
  • Support .indexOf on lazy seqs, matching CLJS

0.13.194

  • Replicant support. See example.
  • Support :deps in squint.edn, resolved via clojure -Spath, added to :paths implicitly. Squint only supports :git/sha and :local/root libraries for now.
  • Lazy seqs are now cached. Previously squint did not cache results so if you consumed a seq twice its results would be computed twice. For performance seqs are chunked, same as CLJS.
  • Because lazy seqs are now cached, warn-on-lazy-reusae! now prints a deprecation warning and does nothing. It will be removed in the future.
  • = compares two lazy seqs of the same type element-wise instead of as plain objects, so e.g. (= (concat nil ["a"]) (concat nil ["a"])) is true
  • persistent! no longer freezes its argument, so persistent structures stay extensible for symbol-keyed metadata
  • vswap! and vreset! return the new value, like Clojure
  • nth on an out-of-bounds index without a default now throws, like Clojure
  • disj on nil returns nil instead of throwing
  • name now returns the part after the / for a namespaced keyword/symbol (e.g. (name :foo/bar) -> "bar"), consistent with namespace so they round-trip. Since keywords are strings in squint this also applies to slash-containing strings (differs from Clojure string name).
  • namespace uses the same / threshold as name, so a leading / yields a nil namespace instead of an empty string and (str (namespace x) "/" (name x)) round-trips.
  • Add var? (always false; squint has no first-class vars)
  • Support dynamic vars and binding. An earmuffed def (e.g. *foo*) compiles to a mutable box {value ...}; references read .value, set! assigns it, and binding saves/sets/restores it. Because only the box's property is mutated (never the import binding), this works across separately-compiled ESM modules.
  • Quoted symbols now compile to strings of their name (squint has no symbol type, like keywords)
  • Syntax-quote resolves symbols against the current ns and aliases (bare -> current ns, aliased -> full ns), matching Clojure
  • defprotocol: support the :extend-via-metadata option; protocol methods fall back to an impl on the receiver's metadata keyed by the fully-qualified method name
  • :require-macros accepts a bare symbol libspec (not only a vector)
  • Macros in a .cljc/.cljs namespace required via an :as alias (without :refer) now expand (alias resolves to the macro namespace)
  • Add keyword?, simple-keyword?, qualified-keyword? (keywords are strings in squint, so these are string-based) and unchecked-int
  • Add map-entry?; map entries are tagged so they are distinguishable from plain vectors
  • Add reify
  • Add keyword, symbol?, namespace, unchecked-inc-int, unchecked-dec-int, unchecked-add-int (keywords/symbols are strings in squint)
  • Fix qualified references to a namespace alias that is shadowed by a local binding or parameter of the same name (e.g. [x.y :as r] + (let [r ...] (r/f r))); they now resolve to the full-namespace import instead of the local
  • Fix = distinguishing null from undefined; both are nil in CLJS, so (= js/undefined nil) and e.g. (= (keys nil) nil) now return true.
  • Apply reader metadata (^:foo) on vector, map, set and fn literals as runtime metadata, matching CLJS ((meta ^:foo [1 2]) -> {:foo true}). Reader location keys, compiler directives (:tag/:async/:gen) and squint-internal keys are not included; edamame now records location under :line/:column.
  • Fix = not treating sequential collections of different concrete types as equal; (= '(1 2) [1 2]) and lazy-seq/vector comparisons now return true, matching CLJS. Equal-typed collections keep their existing fast paths.
  • Fix named variadic fn whose name munges (e.g. dispatch!) emitting an invalid self-reference (dispatch!.cljs$...) in its dispatcher; the munged name is now used.
  • Fix def/defn whose name shadows a :require alias or :refer producing colliding JS identifiers (import * as foo / import { foo } + var foo). The var is now renamed to a fresh gensym and exported under its real name; a bare foo is the var, foo/bar stays the alias.
  • Add clojure.walk (walk, prewalk, postwalk, prewalk-replace, postwalk-replace, keywordize-keys, stringify-keys, and the *-demo helpers)
  • empty, conj, assoc, into and other copy-based operations now carry metadata, matching Clojure (previously metadata was dropped on the freshly built structure); with-meta/copy now also support lists
  • #html now escapes literal string attributes
  • #html now does not emit true for a boolean-true attribute, but emits bare attribute
  • #html now gates CSS output on style attribute name
  • CLI: shell tab completion via babashka.cli's hidden org.babashka.cli/completions command. Print an install snippet with e.g. squint org.babashka.cli/completions snippet --shell zsh (bash, zsh, fish, powershell and nushell are supported)
  • CLI: --help/-h, argument validation and error messages are now provided by babashka.cli's dispatch (standard Usage/Commands/Options help, errors to stderr). Builds on #691 (@lread)

0.12.193

  • Fix #832: nREPL server hung on advertised ops. info/eldoc/lookup, complete (including js/ interop completion) and load-file are now implemented.
  • Fix parse-long returning out-of-range values instead of nil (the safe-integer upper bound was a no-op due to a chained comparison)
  • Fix select-keys dropping keys mapped to nil (loose != undefined matched null); nil-valued keys are now kept, matching Clojure
  • Fix clojure.string/split limit semantics: a positive limit now caps the number of splits and keeps the remainder (e.g. (str/split "a-b-c-d" #"-" 2) -> ["a" "b-c-d"]) instead of truncating like JS String.split; limit 0 discards trailing empties, negative keeps them
  • Fix compare throwing on booleans; (compare false true) -> -1 and (sort [true false]) no longer throws, matching CLJS
  • clojure.set/intersection and union now use .size (not .length) for their set-size optimization, which was previously dead code (undefined > undefined); results were already correct, this restores the intended performance
  • Fix seqable? returning false for maps; (seqable? {:a 1}) -> true, matching CLJS (seq already worked on objects)
  • Fix nth returning the not-found default for an in-bounds element that is undefined (e.g. sparse / object-array / JS-interop arrays); it now decides found-ness by the index bound, not the value
  • Fix parse-double not trimming leading/trailing whitespace ((parse-double " 3.14 ") -> 3.14); the whitespace character class in the regexes was double-escaped and matched literal backslashes instead of control chars
  • pr-str / prn now print Infinity, -Infinity and NaN as ##Inf, ##-Inf and ##NaN, matching CLJS (str is unchanged)

0.12.192

  • Add support for Vite 5-8

0.12.191

  • Add dedupe (seq and transducer arities)
  • Add distinct?, any?, ifn?, list*
  • Fix #819: macro changes not picked up in watch mode. The persistent compiler now re-evaluates a macro namespace when its source file changes (mtime + sha256 gate), instead of keeping the first-loaded definitions.
  • REPL: print promises as #<Promise 1> / #<Promise rejected ..> / #<Promise pending> instead of silently unwrapping them. Also surfaces a Promise wrapper in the playground (resolved value still inspectable).

0.12.190

  • Browser nREPL support. See docs
  • Fix #815: str wrapping known-numeric infix expressions in ??'', which esbuild flagged as suspicious-nullish-coalescing. (@willcohen)
  • Fix #820: :macros option silently ignored when passed to compileString / compileStringEx from JavaScript callers (string keys were keyword-ized by clj-ize-opts and no longer matched the symbol-keyed macro lookups in compile*). (@willcohen)

0.11.189

  • #809: add squint.compiler/compile* and squint.compiler/transpile* which accept either a string or a sequence of pre-parsed forms, skipping the forms -> string -> forms roundtrip for SSR use cases. The previous names compile-string* / transpile-string* are retained as deprecated aliases.
  • Fix #810: shorthand classes in #html / #jsx were erased when an attrs map was present without a :class key (e.g. [:div.myclass {}]).

0.11.188

  • Add multimethod support (#806): defmulti, defmethod, get-method, methods, remove-method, remove-all-methods, prefer-method, prefers, and hierarchy ops isa?, derive, underive, make-hierarchy, parents, ancestors, descendants.

  • cljs.test/report is now a multimethod, extensible via defmethod:

    (defmethod report [:cljs.test/default :begin-test-var] [m] ...)
    

    test-var now fires :begin-test-var / :end-test-var events.

0.11.187

  • Accept plain await in async functions, in anticipation of CLJS next. The legacy js-await and js/await forms continue to work as aliases for now and may be deprecated in a future version.
  • Add built-in cljs.test / clojure.test support: deftest, is, testing, are, use-fixtures, async, run-tests.
  • Fix with-meta now preserves callability when applied to a function
  • Fix #783: auto-load macros from .cljc files via :require (no need for :require-macros)
  • Fix #783: resolve qualified symbols from macro expansions
  • Fix #784: resolve transitive macro deps and auto-import runtime deps from macro expansion
  • Fix #786: resolve-macro-ns for cherry namespace resolution

v0.10.186 (2026-03-07)

  • Fix #799: forgot to add squint.math file to package.json

v0.10.185 (2026-01-26)

  • Fix emitting negative zero value (-0.0)
  • Add squint.math, also available as clojure.math namespace (a direct port of the original)

v0.9.184

  • Fix #792: prn js/undefined as nil
  • Fix #793: fix yield* IIFE (needs wrapping in parens)

v0.9.183

  • #779: Added compare-and-swap!, swap-vals! and reset-vals! (@tonsky)
  • #788: Fixed compilation of dotimes with _ binding (@tonsky)
  • #790: Fixed shuffle not working on lazy sequences (@tonsky)
  • Multiple :require-macros with :refer now accumulate instead of overwriting (@willcohen)

v0.9.182

  • Allow macro namespaces to load "node:fs", etc. to read config files for conditional compilation
  • Don't emit IIFE for top-level let so you can write let over defn to capture values.

v0.9.181

  • Fix js-yield and js-yield* in expression position
  • Implement some? as macro

v0.9.180

  • Fix #758: volatile!, vswap!, vreset!
  • pr-str, prn etc now print EDN (with the idea that you can paste it back into your program)
  • new #js/Map reader that reads a JavaScript Map from a Clojure map (maps are printed like this with pr-str too)

v0.9.178

  • Support passing keyword to mapv
  • #759: doseq can't be used in expression context
  • Fix #753: optimize output of dotimes
  • alength as macro

v0.9.177

  • Inline identical? calls
  • Clean up emissiong of paren wrapping
  • Add nat-int?, neg-int?, pos-int? (@eNotchy)
  • Add rand

v0.9.176

  • Fix rendering of null and undefined in #html

v0.9.175

  • #747: #html escape fix

v0.9.174

  • Optimize nested assoc calls, e.g. produced with ->
  • Avoid object spread when object isn't shared (auto-transient)

v0.9.173 (2025-10-19)

  • Optimize str even more

v0.9.172 (2025-10-19)

Remove debug output from compilation

v0.9.171 (2025-10-19)

  • Optimize =, and, and not= even more

v0.9.170 (2025-10-19)

  • not= on undefined and false should return true

v0.9.169 (2025-10-18)

  • Optimize code produced for assoc, assoc! and get when object argument can be inferred or is type hinted with ^object
  • Optimize str using macro that compiles into template strings + ?? '' for null/undefined
  • Fix #732: take-last should return nil or empty seq for negative numbers

v0.8.159 (2025-10-13)

  • #725: keys and vals should work on js/Map

v0.8.158 (2025-10-10)

  • Make map-indexed and keep-indexed lazy

v0.8.157 (2025-10-08)

  • Compile time optimization for = when using it on numbers, strings or keyword literals

News

Cljdoc chose squint for its small bundle sizes and easy migration off of TypeScript towards CLJS

v0.8.156 (2025-10-07)

  • Switch = to a deep-equals implementation that works on primitives, objects, Arrays, Maps and Sets

v0.8.155 (2025-10-02)

  • Fix #710: add parse-double
  • Fix #714: assoc-in on nil or undefined
  • Fix #714: dissoc on nil or undefined

v0.8.154 (2025-09-19)

  • Basic :import-maps support in squint.edn (just literal replacements, prefixes not supported yet)

v0.8.153 (2025-08-31)

  • Fix #704: while didn't compile correctly
  • Add clojure.string/includes?
  • Emit less code for varargs functions
  • Fix solidJS example
  • Documentation improvements (@lread)
  • Fix #697: ClassCastException in statement function when passed Code records

v0.8.152 (2025-07-18)

  • Fix #680: support import attributes using :with option in require, e.g. :with {:type :json}

v0.8.151 (2025-07-15)

  • Implement not= as function
  • Fix #684: JSX output

v0.8.150 (2025-07-09)

v0.8.149 (2025-06-19)

  • #671: Implement trampoline (@rafaeldelboni)
  • Fix #673: remove experimental atom as promise option since it causes unexpected behavior
  • Fix #672: alias may contain dots

v0.8.148 (2025-05-25)

  • Fix #669: munge refer-ed + renamed var

v0.8.147 (2025-05-09)

  • Fix #661: support throw in expression position
  • Fix #662: Fix extending protocol from other namespace to nil
  • Better solution for multiple expressions in return context in combination with pragmas
  • Add an ajv example

v0.8.146

  • #653: respect :context expr in compile-string
  • #657: respect :context expr in set! expression
  • #659: fix invalid code produced for REPL mode with respect to return

v0.8.145 (2025-04-11)

  • #651 Support :require + :rename + allow renamed value to be used in other :require clause

v0.8.144 (2025-04-09)

  • Fix #649: reset ns when compiling file and fix initial global object

v0.8.143 (2025-04-07)

  • Fix #647: emit explicit null when written in else branch of if

v0.8.142 (2025-03-19)

v0.8.141 (2025-03-10)

  • Fix #602: support hiccup-style shorthand for id and class attributes in #jsx and #html

v0.8.140 (2025-03-09)

v0.8.139 (2025-03-04)

  • defclass: elide constructor when not provided

v0.8.138 (2025-03-04)

  • Fix #603: don't emit multiple returns
  • Drop constructor requirement for defclass

v0.8.137 (2025-02-28)

  • Fix #626: Implement take-last
  • Fix #615: (zero? "0") should return false
  • Fix #617: deftype field name munging problem
  • Fix #618: Named multi-arity fn args don't get munged (@grayrest)
  • Fix #622: operator precendence issue with | and if
  • Add clojure.string functions lower-case, upper-case, capitalize (@plexus)

v0.8.136 (2024-02-21)

  • Fix #609: make remove return a transducer when no collection is provided
  • Fix #611: Implement the set? function (@jonasseglare)
  • Fix #613: Optimize aset

v0.8.134 (2024-02-11)

  • Fix #605: merge command line --paths with squint.edn config properly
  • Fix #607: make mapcat return a transducer if no collections are provided (@jonasseglare)

v0.8.132 (2024-12-29)

  • Fix #255: fn literal with rest args

v0.8.131 (2024-12-21)

  • #596: fix unary division to produce reciprocal

v0.8.129 (2024-12-03)

  • #592: fix clj->js to not process custom classes

v0.8.128 (2024-12-02)

  • #585: fix clj->js to realize lazy seqs into arrays

v0.8.127 (2024-11-29)

  • #586: support extending protocol to nil

v0.8.125 (2024-11-28)

  • #581: support docstring in defprotocol
  • #582: add extend-protocol

v0.8.124 (2024-11-20)

  • Add delay
  • Fix #575: map? should not return true for array
  • Fix #577: support $default + :refer

v0.8.123 (2024-11-05)

  • Fix #572: prevent vite page reload

v0.8.122 (2024-10-19)

  • Fix watcher and compiler not overriding squint.edn configurations with command line options, take 2

v0.8.121 (2024-10-18)

  • Fix watcher and compiler not overriding squint.edn configurations with command line options.

v0.8.120 (2024-10-18)

  • Fix watcher not being called

v0.8.119 (2024-10-18)

  • Allow passing --extension and --paths via CLI

v0.8.118 (2024-10-17)

  • Fix #563: prioritize refer over core built-in
  • Update chokidar to v4 which reduces the number of dependencies

v0.8.117 (2024-10-11)

  • BREAKING: Dynamic CSS in #html must now be explicitly passed as map literal: (let [m {:color :green}] #html [:div {:style {:& m}}]). Fixes issue when using lit-html in combination with classMap. See demo

v0.8.116 (2024-10-05)

  • #556: fix referring to var in other namespace via global object in REPL mode

v0.8.115 (2024-10-01)

  • Pass --repl opts to watch subcommand in CLI

v0.8.114 (2024-09-23)

  • #552: fix REPL output with hyphen in ns name

v0.8.113

  • #542: fix run on Windows

v0.8.112

  • #536: HTML is not escaped in dynamic expression

v0.7.111

  • #537: Fix not: wrap argument in parens
  • Return interop expression in function body

v0.7.110

  • Prefer value from props map over explicit value

v0.7.109

  • #html improvements, support :& for spreading props

v.0.7.108

  • #492: defclass static methods and fields
  • #526: Fix export of class name with dashes

v0.7.107

  • #517: Preserve state over REPL evals

v0.7.106 (2024-05-02)

  • #513: Fix shuffle core function random distribution and performances
  • #517: Fix re-definition of class with defclass in REPL
  • #522: fix nil #html rendering issue

v0.7.105 (2024-04-15)

  • #509: Optimization: use arrow fn for implicit IIFE when possible
  • Optimization: emit const in let expressions, which esbuild optimizes better

v0.7.104 (2024-04-05)

  • Don't wrap arrow function in parens, see this issue

v0.7.103 (2024-04-05)

  • Fix #499: add support for emitting arrow functions with ^:=> metadata

v0.7.102 (2024-04-03)

  • Fix #505: Support :rename in :require

v0.7.101 (2024-04-02)

  • Fix #490: render css maps in html mode
  • Fix #502: allow method names in defclass to override squint built-ins

v0.7.100 (2024-03-29)

  • Fix #496: don't wrap strings in another set of quotes

v0.7.99 (2024-03-29)

  • Fix rendering of attribute expressions in HTML (should be wrapped in quotes)

v0.7.98 (2024-03-25)

  • Compile destructured function args to JS destructuring when annotated with ^:js. This benefits working with vitest and playwright.

v0.7.97 (2024-03-25)

  • #481: BREAKING, squint no longer automatically copies all non-compiled files to the :output-dir. This behavior is now explicit with :copy-resources, see docs.

v0.7.96 (2024-03-14)

  • Add new #html reader for producing HTML literals using hiccup. See docs and playground example.
  • #483: Fix operator precedence problem

v0.6.95 (2024-02-26)

  • #472: Use consistent alias
  • #474: fix JSX fragment
  • #475: don't crash watcher on deleting file

v0.6.94 (2024-02-20)

  • Add simple-benchmark

v0.6.93 (2024-02-16)

  • #468: Keywords in JSX should render with hyphens

v0.6.92 (2024-02-15)

  • #466: Fix doseq expression with set! in function return position

v0.6.91 (2024-02-14)

  • #462: Add "exports" field to package.json
  • #460: escape < and > in JSX strings

v0.6.90 (2024-02-06)

  • #458: don't emit null in statement position

v0.6.89 (2024-02-01)

  • #455: don't export non-public vars

v0.6.88 (2024-01-10)

  • Fix infix operator in return position
  • Allow playground to use JSX in non-REPL mode

v0.6.87 (2024-01-06)

  • Add transducer arity to all existing core functions

v0.5.86 (2023-12-23)

  • Support ^:gen + js-yield + js-yield* to write JS generator functions. See playground
  • Add update-keys and update-vals
  • Add = as reified function

v0.4.85 (2023-12-20)

  • #449: fix issue with :refer

v0.4.84 (2023-12-19)

  • Add memoize, filter transducer arity, peek, pop
  • Export classes defined with defclass
  • Support ^:async Object method in defclass

v0.4.83 (2023-12-16)

  • Better support for pragmas and JSDoc via js* + // and /* */
  • Add rem, nnext, str/end-with?, str/index-of and str/last-index-of
  • Fix alias with hypen in REPL mode

v0.4.82 (2023-12-14)

  • Keep top level strings and comments (via js*) before imports (for JSDoc, Next.js "use client", etc)

v0.4.81 (2023-12-11)

  • Fix compileString in JS API

v0.4.80 (2023-12-11)

  • Optimization: sort largest set first for set/union, and smallest first for set/intersection
  • Add sorted-set, long, abs, keep-indexed transducer arity

v0.4.79 (2023-12-09)

  • The children function in tree-seq may return nil

v0.4.78 (2023-12-09)

  • Add clojure.set/join
  • Add tree-seq, flatten, seq? and sequential?

0.4.77 (2023-12-09)

  • Add clojure.set functions select, rename-keys, rename, project, and map-invert (@PEZ)
  • Fix reduce-kv with js/Map input

0.4.76 (2023-12-07)

  • Add more clojure.set functions: difference, union, subset?, and superset? (@PEZ)

0.4.75 (2023-12-07)

  • Let any object that has Symbol.iterable be destructureable even if it is not instance of Object

0.4.74 (2023-12-07)

  • Initial version of clojure.set
  • #418: Add reductions
  • Add bit-shift-left and more bit- related macros
  • Fix not with respect to truthiness
  • Fix reduce without initial value + empty coll, it should call f()
  • Add serve-playground bb task
  • Update playground with button for creating a blank AOC playground

0.4.73 (2023-12-05)

  • #407: fix conditional rendering
  • Add not-empty
  • Fix into + set + xform

0.4.72 (2023-12-04)

  • Allow JSX to be used in playground. See react example.
  • Add re-pattern (fixes #396)
  • Add zipmap

0.4.71 (2023-12-02)

  • More helpful error from JS when using unresolved symbol in REPL mode

0.4.70 (2023-12-02)

  • Allow >, < etc to be used as HOFs
  • Fix str/split with respect to trailing empty split elements

0.4.69 (2023-12-02)

  • Fix vararg functions in REPL mode

0.4.68 (2023-12-01)

  • #394: add int
  • #393: Math can be used without js/ prefix
  • Expose compiler state via compileStringEx for playground, preserves namespace transitions

0.4.67 (2023-11-28)

  • Restore backward compatibility with code that is compiled with older versions of squint

0.4.66 (2023-11-28)

  • Optimize various outputs for smaller size
  • Add js-in

0.4.65 (2023-11-28)

  • Support into + xform

0.4.64 (2023-11-27)

  • Support sort on strings

0.4.63 (2023-11-26)

  • #386: allow expression in value position in map literal

0.4.62 (2023-11-25)

  • Improvements with respect to laziness in mapcat and concat
  • Do not array mutate argument in reverse

0.4.61 (2023-11-25)

  • Escape JSX attribute vector value (and more)

0.4.60 (2023-11-24)

  • map + transduce support
  • Fix for in REPL mode
  • Throw when object is not iterable in for
  • Make next lazy when input is lazy
  • Fix playground shim (fixes issue in older versions of Safari)

0.4.59 (2023-11-23)

  • Add js-mod and quot

0.4.58 (2023-11-22)

  • #380: Don't emit space in between #jsx tags
  • Add re-find

0.4.57 (2023-11-21)

  • Add condp macro

0.4.56 (2023-11-20)

  • Use compare as default compare function in sort (which fixes numerical sorting)

0.4.55 (2023-11-20)

  • Allow assoc! to be called on arbitrary classes (regression)

0.4.54 (2023-11-19)

  • Improve get to call get method when present.

0.4.53 (2023-11-19)

  • False alarm, I was playing the pinball game in low power mode on my mobile 🤦

0.4.52 (2023-11-19)

  • Revert truthiness checks via funcall, negative impact on performance with pinball game on mobile

0.4.51 (2023-11-18)

  • Allow keywords and collections to be used as functions in HOFs
  • Make filter, etc aware of truthiness
  • Reduce code size for truthiness checks

0.4.50 (2023-11-18)

  • Add str/split-lines
  • Add partition-by
  • Add parse-long
  • Add sort-by

0.4.49 (2023-11-18)

  • Fix top level await

0.4.48 (2023-11-17)

  • Support multiple dimensions in aset
  • Add coercive-= as alias for ==
  • Add js-delete

0.4.47 (2023-11-17)

  • Fix min-key and max-key and improve tests

0.4.46 (2023-11-16)

  • Add min-key and max-key
  • Fix defonce in REPL-mode

0.4.45 (2023-11-16)

  • Fix doseq and for when binding name clashes with core var

0.4.44 (2023-11-15)

  • No-op release to hopefully fix caching issue with jspm

0.4.43 (2023-11-15)

0.4.42 (2023-11-13)

  • Allow alias name to be used as object in REPL mode

0.4.41 (2023-11-12)

  • Copy resources when using squint compile or squint watch

0.4.40 (2023-11-12)

  • Return map when select-keys is called with nil
  • nREPL server: print values through cljs.pprint (@PEZ)

0.4.39 (2023-11-10)

  • Initial (incomplete!) nREPL server on Node.js: npx squint nrepl-server :port 1888
  • Update/refactor threejs example

0.3.38 (2023-11-07)

  • #360: assoc-in! should not mutate objects in the middle if they already exist
  • Evaluate lazy-seq body just once
  • Avoid stackoverflow with min and max
  • #360: fix assoc-in! with immutable objects in the middle
  • Add mod, object?
  • Optimize get
  • Add threejs example

0.3.37 (2023-11-05)

  • #357: fix version in help text
  • Fix iterating over objects
  • Add clojure.string's triml, trimr, replace
  • Fix examples/vite-react by adding public/index.html
  • Add find, bounded-count, boolean?, merge-with, meta, with-meta, int?, ex-message, ex-cause, ex-info
  • Fix munging of reserved symbols in function arguments

0.3.36 (2023-10-31)

  • #350: js* should default to :context :expr
  • #352: fix zero? in return position
  • Add NaN? (@sher)

0.3.35 (2023-10-25)

  • #347: Add :pre and :post support in fn
  • Add number?
  • Support docstring in def

0.3.34 (2023-10-24)

  • Handle multipe source :paths in a more robust fashion

0.3.33 (2023-10-24)

  • #344: macros can't be used via aliases

0.3.32 (2023-10-17)

  • Add squint.edn support, see docs
  • Add watch subcommand to watch :paths from squint.edn
  • Make generated let variable names in JS more deterministic, which helps hot reloading in React
  • Added a vite + react example project.
  • Resolve symbolic namespaces (:require [foo.bar]) from :paths

0.2.31 (2023-10-09)

  • Add bit-and and bit-or

0.2.30 (2023-10-04)

  • Include lib/squint.core.umd.js which defines a global squint.core object (easy to use in browsers, see docs)

0.2.29 (2023-10-03)

  • Add subs, fn?, re-seq
  • Add squint.edn with :paths to resolve macros from (via :require-macros)

0.2.28 (2023-09-18)

  • Fix and and or with respect to CLJS truthiness

0.2.27 (2023-09-18)

  • Respect CLJS truth semantics: only null, undefined and false are non-truthy, 0 and "" are truthy.
  • Fix dotimes

0.2.26 (2023-09-17)

  • squint repl improvements

0.2.25 (2023-09-17)

  • Do not resolve binding in catch to core var
  • Fix reading .cljc files
  • Allow passing JS object as opts in JavaScript API's compileString

0.2.24 (2023-09-13)

  • Fix instance? in return position
  • to-array, str/starts-with?

0.1.23

  • Support next on non-arrays
  • Add compare

0.1.22

  • Fix #325: fix varargs destructuring
  • Fix #326: bun compatibility

0.1.21

  • Fix into-array

0.1.20

  • Add into-array, some-fn, keep-indexed
  • Fix for lazy-seq when body returns nil

0.1.19

  • Add max, min, every-pred

0.1.18

  • Add reduce-kv

0.1.17

  • #320: fix overriding core vars

0.1.16

  • Add rand-nth, aclone, add-watch, remove-watch

0.1.15

0.0.14

  • Drop cherry core from NPM package (cruft from porting cherry to squint)

0.0.13

  • Fix compilation of empty list
  • Fix and and or without arguments
  • #308: doseq in return position emits invalid code

0.0.12

  • Add js-obj

0.0.11

0.0.10

  • #289: support :as alias with hyphen in namespace require libspec

0.0.9

  • #286: make dissoc work with multiple keys

0.0.8

  • #284: fix undefined keys/values when passing objects and maps to conj

0.0.7

  • #274: fix logic precedence by wrapping in parens

0.0.6

Add preliminary Node.js API in node.js

0.0.5

  • Support {:& more :foo :bar} syntax in JSX to spread the more map into the props, inspired by helix

0.0.4

  • Add zero? pos? and neg? core functions

0.0.3

  • Fix boolean core function export

0.0.2

  • Escape boolean in JSX attribute
  • Add boolean core function

0.0.1

  • Fix + symbol import by bumping shadow-cljs
  • Move @babel/preset-react dependency to dev dependency

0.0.0-alpha.52

  • Fix async/await + variadiac arguments
  • Fix namespaced component in JSX

0.0.0-alpha.51

  • Change default extension back to .mjs. Use --extension js to change this to .js.

0.0.0-alpha.50

  • Fix rendering of number attributes in JSX

0.0.0-alpha.49

  • Support --extension option to set extension for JS files
  • Change default extension from .mjs to .js

Can you improve this documentation? These fine people already did:
Michiel Borkent, Peter Strömberg, jonasseglare, Rafael Delboni, mskyan, Jeremiah Coyle, Nikita Prokopov, Will Cohen, Phil Baker, shaun, Arne Brasseur, Brandon Stubbs, Karl Guertin, Clément, zachcp, Cora Sutton, hodlbod, Jack Rusher, Alex Davis & Jarkko Saltiola
Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close