Skip to content

Recover Unsaved Work

By the end of this chapter, you will know how to inspect an abandoned checkpoint, restore exact text and explicitly save or discard the recovered buffer. Recovery runs in both interaction profiles. It protects the last durably checkpointed revision; it does not save your source files or make every keystroke durable.

Prepare a Disposable Note

From the repository root, build the terminal and prepare a private exercise:

cargo build --locked -p rur-editor --bin rur-terminal-proof
recovery_editor="$PWD/target/debug/rur-terminal-proof"
recovery_demo=$(mktemp -d)
mkdir -m 700 "$recovery_demo/state"
printf 'seed\n' > "$recovery_demo/note.txt"
printf 'Demo directory: %s\n' "$recovery_demo"

Save this configuration as $recovery_demo/recovery.rb. These are the factory settings; the declaration makes the exercise's policy explicit:

Rur.configuration.recovery_policy({
  'enabled' => true,
  'strategy' => 'hybrid',
  'debounce_ms' => 300,
  'maximum_interval_ms' => 5000,
  'startup' => 'ask'
})

Start the disposable note. Choose modal instead of nonmodal to use that profile; enter Insert with i before typing there:

XDG_STATE_HOME="$recovery_demo/state" "$recovery_editor" --config "$recovery_demo/recovery.rb" --profile nonmodal --receipt "$recovery_demo/note.txt"

Insert some text and leave it unsaved. The status changes through Recovery pending to Recovery protected after the checkpoint completes. A timer becoming eligible alone does not establish protection. New edits can remain pending while an older durable revision is still protected. The note on disk still contains seed and its newline.

Return After an Unexpected Stop

After an unexpected stop, restart with the same state root. To rehearse with this disposable note, close only its terminal without choosing Save or Discard; a handled disconnect also retains the last durable checkpoint. Keep the printed demo directory so another shell can reuse it. Newer, uncheckpointed edits can be lost. Ordinary exit with explicit Discard intentionally retires recovery instead.

Use the same executable/configuration and omit the file argument to see the startup component and a nonblocking Unsaved recovery pending notice:

XDG_STATE_HOME="$recovery_demo/state" "$recovery_editor" --config "$recovery_demo/recovery.rb" --profile nonmodal --receipt

If using another shell, set recovery_demo and recovery_editor to the paths from the first shell. Recovery never searches source directories for work.

Press Alt-x, enter recover-unsaved-work, and press Enter. Live lineages owned by another editor are excluded. The list classifies each abandoned checkpoint:

RowMeaning
matchingThe complete current source matches the confirmed baseline.
changedThe source changed; preserve that source when recovering.
missingThe original source is absent.
unavailableThe source cannot be safely read or classified.
pathlessThe checkpoint came from an unassociated buffer.

Use Up/Down to select a row and PageDown to continue a bounded scan. Press Enter or i to inspect, or c to compare with a freshly read source. Views label the historical checkpoint and show escaped byte windows, including control bytes; n reads the next window and b returns to the list. Complete validation covers the payload, not just its visible window. Control-g cancels back to your prior editing or startup context. Inspection, comparison and cancellation leave the source and checkpoint pending.

Restore, Then Choose Its Outcome

Select the checkpoint and press s. Rur restores its complete exact text into a fresh, visibly unsaved buffer. Empty text, BOM, Unicode, NUL, mixed newline bytes and a missing final newline remain exact. Escaped inspection text is not what gets restored. Existing live buffers and their edits remain intact.

A freshly matching source can supply an association if no live buffer already owns that path. Conflicts, unavailable/missing sources and pathless work restore without an association; an origin hint does not permit a source write.

Press Ctrl-X Ctrl-S to Save. An unassociated recovered buffer asks for a new destination through the normal first-Save flow. Check the resulting file bytes; only this explicit Save changes its chosen destination. A durable Save of the exact recovered state retires its obsolete checkpoint. An older or uncertain Save keeps protection for text it has not proved obsolete.

To discard recovered text, run kill-buffer and choose Discard in the unsaved decision. Discard must durably retire its qualified recovery state before the buffer closes. If that fails, the buffer stays open. Cancel preserves it.

Control Recovery Deliberately

With an explicit launch file, ask scopes automatic review to that exact normalized path. inspect opens related review, and restore-matching restores only freshly matching related text. Unrelated and pathless candidates remain available through the global command. No-file startup keeps its notice instead of taking over the startup component.

For an invocation that must perform no recovery-store access, add --no-recovery; it overrides even an enabled configuration and later reloads:

XDG_STATE_HOME="$recovery_demo/state" "$recovery_editor" --config "$recovery_demo/recovery.rb" --profile nonmodal --no-recovery "$recovery_demo/note.txt"

Editing and explicit Save still work with recovery disabled. Disabling policy does not delete already stored checkpoints. Recovery unavailable or a full store means newer work may be unprotected; explicit Save remains independent. Storage is private local data, including source hints, not an encrypted backup.

See Recovery Policy and Outcomes for exact settings, limits and uncertainty, Recovery Review for controls, and Private Recovery Storage for ownership and retention.

Previous: Change Two Files Together | Part | User Guide | Next: Buffers and Panes