Structural edits
- ast_grep over search_files when syntax matters.
ast_grepwith a pattern likedbg!($X)orfn $NAME($$$ARGS)matches real code, not comments or string literals. Plain text search is fine for identifiers that appear nowhere else. Scope withpathto one directory when the change is local. - ast_edit over repeated edit_file when the same change repeats. One
pattern plus rewrite applies everywhere at once and returns a diff.
Three or more identical edits means ast_edit; one or two means edit_file.
Example: pattern
dbg!($X)with rewriteeprintln!("{:?}", $X)removes every debug print in the scope in one approval. - Metavariables carry the capture.
$Xcaptures a single node,$$$ARGScaptures a list. Reuse the same name in the rewrite; a name that appears only in the rewrite is an error, not an insertion. - Patterns must parse as the target language. A pattern that is not
valid syntax in the file's language matches nothing, silently. Write the
pattern in the language you are editing, and keep it narrow with context
(
$OBJ.foo($$$ARGS)rather thanfoo($$$ARGS)) so unrelated calls do not match. - Patterns exclude trailing semicolons. A pattern for
dbg!($X)matches the call, not the;after it. Do not put a semicolon in the pattern or the rewrite unless the statement itself is the target. - Run ast_grep first when unsure. A dry search with the same pattern shows exactly what ast_edit would touch, with no approval needed. If the match list surprises you, fix the pattern before rewriting.
- Read the diff at approval time. A too-broad pattern rewrites code you did not intend, and the diff is the only place you will see that. Every changed file goes through the same approval as edit_file; a Deny on one file stops the whole batch.