A release with known breaking changes is marked with:
-
[breaking] you probably need to change your code
-
[minor breaking] you likely don’t need to change your code
-
bump
org.clojure/tools.reader
to version1.5.0
(@lread) -
sexpr
now better matches clojureread-string
for~
,@
and~@
#305 (@frenchy64)
-
bump
org.clojure/tools.reader
to version1.4.2
(@lread) -
sexpr
now 1) expands tag metadata to its long form 2) throws on invalid metadata #280 (@lread) -
Add support for Clojure 1.12 vector metadata (ex.
(^[double] String/valueOf 3)
) #279 (@lread) -
Add support for Clojure 1.12 array class syntax (ex.
byte/3
) #279 (@lread) -
rewrite-clj.paredit/barf-forward
on zipper created with:track-position? true
now correctly barfs when current node has children #245 (@lread, thanks for the issue @p4ulcristian!) -
docs
-
added new
rewrite-clj.zip
functionsof-string*
andof-file*
, these are versions ofof-string
andof-file
that do no auto-navigation #189 (@lread, thanks @mainej for the analysis work!) -
a lazy sequence now coerces to a rewrite-clj list node #180 (thanks @borkdude!)
-
exceptions thrown while reading now include
:row
and:col
keys inex-data
#181 (thanks @ferdinand-beyer) -
docs
-
a docstring typo fix #191 (thanks @bobbicodes!)
-
-
dropped the alpha status (@lread)
-
changed rewrite-clj library version scheme from commit-count to release-num #179 (@lread)
-
renamed zipper creation functions that take a rewrite-clj node as input. The old names did not reflect their purpose which led to confusion. Old functions will remain but are marked as deprecated. #178 (@lread)
-
rewrite-clj.zip/edn
→rewrite-clj.zip/of-node
-
rewrite-clj.zip/edn*
→rewrite-clj.zip/of-node*
-
-
now properly escaping inline double quotes for coerced strings #176 (@lread, thanks to @ivarref for raising the issue!
-
docs:
-
docstring fix, was missing
list-node
from toc (thanks @rfhayashi!)
-
-
update clojure tools.reader dependency to v1.3.6 (@lread)
-
a zipper created with both a custom
:auto-resolve
option and the:track-position?
true
option will now acknowledge and use the custom:auto-resolve
#159 (@lread) -
a Cons now coerces to a rewrite-clj list node #160 #161 (thanks @borkdude!)
-
internal rewrite-clj developer facing:
-
user guide and docstrings better explain
sexpr-able?
and what invalid code elements rewrite-clj parses #150 #151 (@lread) -
rewrite-clj now exports clj-kondo config for its public API #146 (@lread)
-
ClojureScript compiler should no longer emit invalid deprecated warnings #153 (@lread)
-
Internal rewrite-clj developer facing:
-
Switched from babashka scripts to babashka tasks, developer guide updated accordingly (@lread)
-
If you wish, you can read nitty gritty details on merging rewrite clj v0 and rewrite cljs. What follows is a summary of changes.
-
Minimum Clojure version bumped from v1.5.1 to v1.9
-
Minimum ClojureScript version (from whatever is was for rewrite-cljs) bumped to v1.10
-
Minimum Java version bumped from v7 to v8
-
Keyword node field
namespaced?
renamed toauto-resolved?
-
Now using
ex-info
for explicitly raised exceptions -
Rewrite-cljs positional support migrated to rewrite-clj’s positional support
-
Namespaced element support reworked
-
v1 changes do not affect node traversal of the namespaced map, number and order of children remain the same.
-
Namespace map prefix, is now stored in a namespaced map qualifier node.
-
Prior to v1, the prefix was parsed to a keyword-node.
-
Let’s look at what interesting node API functions will return for the prefix node in the following namespaced maps. Assume we have parsed the example and traversed down to the prefix node.
For example via:(→ "#:prefix{:a 1}" z/of-string z/down z/node)
.node API call rewrite-clj #:prefix{:a 1}
#::alias{:a 1}
#::{:a 1}
string
is unchangedv1
":prefix"
"::alias"
"::"
v0
-
throws on parse
tag
is differentv1
:map-qualifier
v0
:token
-
throws on parse
inner?
still indicates that the node is a leaf node and has no childrenv1
false
v0
false
-
throws on parse
sexpr
<read on below for discussion on sexpr>
-
-
-
Namespaced element
sexpr
support now relies on user specifiable auto-resolve function to resolve qualifiers-
Unlike rewrite-clj v0, the default auto-resolve behaviour never consults
*ns*
-
An sexpr for keyword node
::alias/foo
no longer returns:alias/foo
(this could be considered a bug fix, but if your code is expecting this, then you’ll need to make changes)
-
-
The following namespaced element
sexpr
examples assume:-
*ns*
is bound touser
namespace (important only for rewrite-clj v0): -
We are using the default auto-resolve function for rewrite-clj v1
-
That you will refer to the User Guide for more detailed examples of v1 behaviour
source sexpr rewrite-clj v1 sexpr rewrite-clj v0 sexpr rewrite-cljs qualified keyword
:prefix/foo
no change
current-ns qualified keyword
::foo
:?_current-ns_?/foo
:user/foo
-
throws on sexpr
ns-alias qualified keyword
::alias/foo
:??_alias_??/foo
:alias/foo
:alias/foo
qualified map
#:prefix{:a 1}
#:prefix{:a 1}
#:prefix{:a 1}
(read-string "#:prefix{:a 1}")
current-ns qualified map
#::{:b 2}
#:?_current-ns_?{:b 2}
-
throws on parse
-
throws on parse
ns-alias qualified map
#::alias{:c 3}
#:??_alias_??{:c 3}
-
throws unless namespace alias
alias
has been loaded in*ns*
-
if
alias
inns
resolves tomy.ns1
:
#:my.ns1{:c 3}
(read-string "#::alias{:c 3}")
-
-
Let’s dig into prefix and key sub-nodes of a namespaced map to explore v1 differences:
Description rewrite-clj v1 rewrite-clj v0 and rewrite-cljs prefix (aka qualifier)
qualified
(-> "#:prefix{:a 1}" z/of-string z/down z/sexpr)
prefix
:prefix
current-ns qualified
(-> "#::{:b 2}" z/of-string z/down z/sexpr)
?_current-ns_?
-
throws on parse
ns-alias qualified
(-> "#::alias{:c 2}" z/of-string z/down z/sexpr)
??_alias_??
:user/alias
-
rewrite-cljs throws
key
qualified
(-> "#:prefix{:a 1}" z/of-string z/down z/right z/down z/sexpr)
:prefix/a
:a
current-ns qualified
(-> "#::{:b 2}" z/of-string z/down z/right z/down z/sexpr)
:?current-ns?/b
-
throws on parse
ns-alias qualified
(-> "#::alias{:c 3}" z/of-string z/down z/right z/down z/sexpr)
:??_alias_??/c
:c
-
-
-
-
Potentially breaking
-
Some rewrite-cljs optimizations were dropped in favor of a single code base. If performance for rewrite-clj v1 for ClojureScript users is poor with today’s ClojureScript, we shall adapt.
-
Deleted redundant
rewrite-clj.parser.util
#93 (@lread). If you were using this internal namespace you can opt to switch to, the also internal,rewrite-clj.reader
namespace.
-
-
A new home under clj-commons. Thanks to @xsc, rewrite-clj will also retain its same maven coordinates on Clojars making for a seamless upgrade path for rewrite-clj v0 users.
-
Now supports ClojureScript, merging in rewrite-cljs specific functionality. Frustrations like not having namespace map support and differences from rewrite-clj, like whitespace parsing, should now be things of the past. Rewrite-cljs users migrating to rewrite-clj v1 are now at, and will remain at, feature parity with rewrite-clj.
-
Additions to the public API:
-
rewrite-clj.paredit
- carried over from rewrite-cljs, an API for structured editing of Clojure forms -
rewrite-clj.zip
-
Exposes the following (accidentally?) omitted functions:
-
append-child*
-
insert-newline-left
-
insert-newline-right
-
insert-space-left
-
insert-space-right
-
subzip
-
-
Adds functions from rewrite-cljs
-
find-last-by-pos
- navigate to node at row/col -
find-tag-by-pos
- navigate to node with tag at row/col -
position-span
- returns start and end row/col for a form -
remove-preserve-newline
- same as remove but preserves newlines
-
-
Adds namespaced element support functions
-
reapply-context
- reapplies (or removes) map qualifier node context from keywords and symbols -
zipper creation functions now optionally accept an auto-resolve function to support sexpr on namespaced element nodes
-
-
Other additions
-
sexpr-able?
- return true ifsexpr
is supported for current node
-
-
-
rewrite-clj.node
-
Additions:
-
keyword-node?
- returns true if form is a rewrite-clj keyword node -
map-qualifier-node
- to create a namespaced map’s map qualifier node manually -
map-context-apply
- apply map qualifier to keyword or symbol -
map-context-clear
- remove map qualifier from keyword or symbol -
node?
- returns true if a form is a rewrite-clj created node -
sexpr-able?
- return true ifsexpr
is supported for node -
symbol-node?
- return true if node is a rewrite-clj symbol node
-
-
Updates:
-
sexpr
,sepxrs
andchild-sexprs
- now optionally take an options argument to specify an auto-resolve function
-
-
-
-
Many updates to docs and docstrings
-
OS specific end of line variants in source now normalized consistently to
\newline
#93 (@lread) -
Postwalk on larger source file no longer throws StackOverflow #69 (@lread)
-
Correct and document prefix and suffix functions #91 (@lread)
-
Positional metadata added by the reader is elided on coercion #90 (@lread)
-
Ensure that all rewrite-clj nodes coerce to themselves (@lread)
-
Strings now coerce to string nodes (instead of to token nodes) #126 (@lread)
-
Regex node now:
-
Moved from potemkin import-vars to static template based version #98 (@lread):
-
Avoids frustration/mysteries of dynamic import-vars for users and maintainers
-
Argument names now correct in API docs (some were gensymed previously)
-
Also turfed use of custom version of potemkin defprotocol+ in favor of plain old defprotocol. Perhaps I missed something, but I did not see the benefit of defprotocol+ for rewrite-clj v1.
-
-
ClojureScript tests, in addition to being run under node, are now also run under chrome-headless, shadow-cljs, and for self-hosted ClojureScript, under planck. (@lread)
-
Now testing rewrite-clj compiled under GraalVM native-image in two variants (@lread):
-
In a pure form where library and tests are compiled
-
Via sci where a sci exposed rewrite-clj is compiled, then tests are interpreted.
-
-
Now automatically testing rewrite-clj against popular libs #124 (@lread)
-
Now linting source with clj-kondo (@lread)
-
Code coverage reports now generated for Clojure unit test run and sent to codecov.io (@lread)
-
Can now preview for cljdoc locally via
script/cljdoc_preview.clj
(@lread) -
API diffs for rewrite-clj v1 vs rewrite-clj v0 vs rewrite-cljs can be generated by
script/gen_api_diffs.clj
(@lread) -
Contributors are acknowledged in README and updated via
script/update_readme.clj
(@lread) -
Doc code blocks are automatically tested via
script/doc_tests.clj
#100 (@lread) -
Some tooling and tech replaced (@lread):
-
All scripts are written in Clojure and run via Babashka or Clojure.
-
Switched from leiningen
project.clj
to Clojure tools CLIdeps.edn
-
Moved from CommonMark to AsciiDoc for docs
-
Moved from publishing docs locally via codox to publishing to cljdoc
-
Now using CommonMark in docstrings (they render nicely in cljdoc)
-
Moved from TravisCI to GitHub Actions where, in addition to Linux, we also test under macOS and Windows
-
Adopted kaocha for Clojure testing, stuck with doo for regular ClojureScript testing, and added support for ClojureScript watch testing with figwheel main.
-
Potemkin dynamic import-vars replaced with static code generation solution
-
-
Added GitHub issue templates (@lread)
-
BREAKING: uses a dedicated node type for regular expressions. #49 (thanks @ChrisBlom)
-
fixes parsing of multi-line regular expressions. #51 (thanks @brian-dawn!)
-
BREAKING: commas will no longer be parsed into
:whitespace
nodes but:comma
. #44 (thanks @arrdem!) -
BREAKING:
position
will throw exception if not used on rewrite-clj custom zipper. #45 (@xsc) -
BREAKING: drops testing against JDK6.
-
DEPRECATED:
-
append-space
in favour ofinsert-space-right
-
prepend-space
in favour ofinsert-space-left
-
append-newline
in favour ofinsert-newline-right
-
prepend-newline
in favour ofinsert-newline-left
-
-
fix insertion of nodes in the presence of existing whitespace. #33, 34 (thanks @eraserhd!)
-
edn
andedn*
now take a:track-position?
option that activates a custom zipper implementation allowingposition
to be called on. #41, 45 (thanks @eraserhd!) -
fix serialization of `integer-node`s. #37 (thanks @eraserhd!)
-
adds
insert-left*
andinsert-right*
to facade.
Development has branched off, using the 0.4.x
branch
-
upgrades dependencies.
-
fixes a compatibility issue when running 'benedekfazekas/mranderson' on a project with both 'rewrite-clj' and 'potemkin'.
-
switch to Clojure 1.8.0 as base Clojure dependency; mark as "provided".
-
switch to MIT License.
-
drop support for JDK6.
-
fix
:fn
nodes (wereprintable-only?
but should actually create an s-sexpression). -
fix
assert-sexpr-count
to not actually create the s-expressions.
-
BREAKING
rewrite-clj.zip.indent
no longer usable. -
BREAKING node creation/edit has stricter preconditions (e.g.
:meta
has to contain exactly two non-whitespace forms). -
BREAKING moved to a type/protocol based implementation of nodes.
-
add node constructor functions.
-
add
child-sexprs
function.
-
drop tests for Clojure 1.4.0.
-
fix behaviour of
leftmost
. -
upgrade to fast-zip 0.5.2.
-
add
:uneval
element type (for#_form
elements). -
fix
estimate-length
for multi-line strings.
-
upgrade dependencies.
-
fix file parser (UTF-8 characters were not parsed correctly, see #24@xsc/lein-ancient).
-
added token type
:newline
to handle linebreak characters. -
rewrite-clj.zip/edn
wraps everything into[:forms …]
node, but the initial location is the node passed to it. -
new functions in
rewrite-clj.zip.core
:-
length
-
move-to-node
-
edit→>
,edit-node
-
subedit→
,subedit→>
,edit-children
-
leftmost?
,rightmost?
-
-
new functions in
rewrite-clj.zip.edit
:-
splice-or-remove
-
prefix
,suffix
(formerlyrewrite-clj.zip.utils
)
-
-
rewrite-clj.zip.edit/remove
now handles whitespace appropriately. -
indentation-aware modification functions in
rewrite-clj.zip.indent
:-
indent
-
indent-children
-
replace
-
edit
-
insert-left
-
insert-right
-
remove
-
splice
-
-
fast-zip utility functions in
rewrite-clj.zip.utils
-
added more expressive error handling to parser.
-
added multi-line string handling (node type:
:multi-line
) -
new functions in
rewrite-clj.printer
:-
→string
-
estimate-length
-
-
new functions in
rewrite-clj.zip
:-
of-string
,of-file
-
print
,print-root
-
→string
,→root-string
-
append-space
,prepend-space
-
append-newline
,prepend-newline
-
right*
,left*
, … (delegating tofast-zip.core/right
, …)
-
-
new token type
:forms
-
new functions in
rewrite-clj.parser
:-
parse-all
-
parse-string-all
-
parse-file-all
-
-
zipper utility functions in
rewrite-clj.zip.utils
(able to handle multi-line strings):-
prefix
-
suffix
-