Skip to content

Preview project-wide refactorings before applying them - #595

Merged
bbatsov merged 1 commit into
masterfrom
refactoring-preview
Jul 12, 2026
Merged

bbatsov merged 1 commit into
masterfrom
refactoring-preview

Conversation

@bbatsov

@bbatsov bbatsov commented Jul 12, 2026

Copy link
Copy Markdown
Member

cljr-rename-symbol and cljr-change-function-signature rewrite files across the whole project, and until now they saved every file the moment you ran them - no chance to see what changed or take it back.

Now they gather all their edits in memory first, show them as a diff, and write nothing until you confirm. Decline and every touched buffer is reverted. There's also cljr-undo-last-refactoring to roll back the last applied one in a single step (bound to ur, and in the menu).

New cljr-preview-refactorings (default on) gates it; set it to nil for the old apply-immediately behavior.

A reviewer caught a couple of data-loss traps around buffers that already had unsaved edits, so there's care taken there: the snapshot records each buffer's modified state, apply/abort act only on files whose content actually changed, abort restores the original modified flag, and undo confirms before overwriting. So your unrelated unsaved work in a target file is never silently lost or written out.

Covers rename and change-signature (the two occurrence-rewriting commands); inline-symbol could follow. Validated live against a real refactor-nrepl connection - rename across two files, confirm applied both, decline left both untouched - plus buttercup coverage for apply/abort/undo/preview-off and the dirty-buffer case.

cljr-rename-symbol and cljr-change-function-signature rewrite files
across the whole project and used to save each one immediately, with no
way to see the changes first or take them back.

They now run through cljr--run-previewable-refactoring: the edits are
gathered in-memory (cljr--save-buffer defers the writes), diffed against
each file's pre-refactoring snapshot, and shown in a diff-mode preview
buffer. Nothing is written until you confirm; declining reverts every
touched buffer. Gated by the new cljr-preview-refactorings (default on).

cljr-undo-last-refactoring reverts every file changed by the last
applied refactoring in one step (bound to `ur', and in the menu).

Care is taken with buffers that already had unsaved edits: the snapshot
records their modified state, apply and abort act only on files whose
content actually changed, abort restores the original modified flag, and
undo confirms before overwriting - so a target buffer's unrelated
unsaved work is never silently lost or written out.

Validated live against a real refactor-nrepl connection (rename across
two files: confirm applied both, decline left both untouched).
@bbatsov
bbatsov merged commit d402285 into master Jul 12, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant