Summary
RangeLink auto-unbinds when a bound terminal is closed (onDidCloseTerminal) and when a bound editor is closed (onDidCloseTextDocument). But it does NOT detect file deletion. VS Code keeps editors open when the underlying file is deleted (strikethrough tab name), so the binding survives — any R-* command would try to paste into a non-existent file. This is inconsistent with the terminal behavior and is a bug.
Steps to Reproduce
- Open a file in the editor.
- Bind a destination to that text editor (R-D → select the editor).
- Delete the file from disk (e.g.,
rm file.ts in an external terminal).
- Observe: the editor tab shows the strikethrough filename, but the binding is still active.
- Run any R-* command — it attempts to paste into the now-deleted file, which either fails silently or writes to a non-existent path.
Expected Behavior
When a bound file is deleted from disk, RangeLink should auto-unbind with a plain status bar message (no checkmark), matching the existing terminal-close pattern.
Proposed Implementation
1. Add onDidDeleteFiles listener
Add a listener for vscode.workspace.onDidDeleteFiles (in PasteDestinationManager, or in BoundDestinationLifecycle if that extraction is complete). The listener should:
- Check if the bound destination is a text editor destination.
- Check if the deleted file URIs include the bound editor's URI.
- Call
unbind({ silent: true }).
- Show a single merged
setStatusBarMessage with plain style (no checkmark): "Unbound from Text Editor (name) — file deleted".
Follow the existing terminal-close pattern at PasteDestinationManager.ts lines 383-399.
2. New status bar message
Add a new message code (e.g., STATUS_BAR_DESTINATION_UNBOUND_FILE_DELETED) to the messages enum. Message text format: "Unbound from Text Editor (name) — file deleted". Plain style, no checkmark (mirrors STATUS_BAR_DESTINATION_UNBOUND_TERMINAL_CLOSED).
3. Test infrastructure: move cleanupFiles from teardown to setup
Currently, cleanupFiles runs during SsContextImpl teardown (line 91 of ssContext.ts). Adding an onDidDeleteFiles listener means fs.unlinkSync in teardown would fire the listener during the observation window, producing spurious status bar messages — the same Smell 1 pattern we fixed for terminals.
Fix: move cleanupFiles from teardown() to standardSuite setup (alongside disposeAllTerminals), so file deletions happen before beginTest() when nothing is bound. This makes file and terminal cleanup symmetrical — both happen in setup, after CMD_UNBIND_DESTINATION has already run.
4. Unit tests
- Test that
onDidDeleteFiles listener matches bound editor URI and calls unbind({ silent: true }).
- Test that
unbind({ silent: true }) is NOT called when a non-bound file is deleted.
- Test that listener is properly disposed when extension deactivates.
5. Integration tests
Add a new test case verifying:
- Bind a text editor destination.
- Delete the file from disk via
fs.unlinkSync (using fileHelpers).
- Verify status bar shows the correct unbind message.
- Verify the destination is no longer bound.
Dependencies
Related
The same gap may apply to file rename. onDidRenameFiles could auto-unbind with "Unbound from Text Editor (name) — file renamed". Lower priority than deletion.
Summary
RangeLink auto-unbinds when a bound terminal is closed (
onDidCloseTerminal) and when a bound editor is closed (onDidCloseTextDocument). But it does NOT detect file deletion. VS Code keeps editors open when the underlying file is deleted (strikethrough tab name), so the binding survives — any R-* command would try to paste into a non-existent file. This is inconsistent with the terminal behavior and is a bug.Steps to Reproduce
rm file.tsin an external terminal).Expected Behavior
When a bound file is deleted from disk, RangeLink should auto-unbind with a plain status bar message (no checkmark), matching the existing terminal-close pattern.
Proposed Implementation
1. Add
onDidDeleteFileslistenerAdd a listener for
vscode.workspace.onDidDeleteFiles(in PasteDestinationManager, or in BoundDestinationLifecycle if that extraction is complete). The listener should:unbind({ silent: true }).setStatusBarMessagewith plain style (no checkmark):"Unbound from Text Editor (name) — file deleted".Follow the existing terminal-close pattern at
PasteDestinationManager.tslines 383-399.2. New status bar message
Add a new message code (e.g.,
STATUS_BAR_DESTINATION_UNBOUND_FILE_DELETED) to the messages enum. Message text format: "Unbound from Text Editor (name) — file deleted". Plain style, no checkmark (mirrorsSTATUS_BAR_DESTINATION_UNBOUND_TERMINAL_CLOSED).3. Test infrastructure: move
cleanupFilesfrom teardown to setupCurrently,
cleanupFilesruns duringSsContextImplteardown (line 91 ofssContext.ts). Adding anonDidDeleteFileslistener meansfs.unlinkSyncin teardown would fire the listener during the observation window, producing spurious status bar messages — the same Smell 1 pattern we fixed for terminals.Fix: move
cleanupFilesfromteardown()tostandardSuitesetup (alongsidedisposeAllTerminals), so file deletions happen beforebeginTest()when nothing is bound. This makes file and terminal cleanup symmetrical — both happen in setup, afterCMD_UNBIND_DESTINATIONhas already run.4. Unit tests
onDidDeleteFileslistener matches bound editor URI and callsunbind({ silent: true }).unbind({ silent: true })is NOT called when a non-bound file is deleted.5. Integration tests
Add a new test case verifying:
fs.unlinkSync(usingfileHelpers).Dependencies
2.0.0release #249Related
The same gap may apply to file rename.
onDidRenameFilescould auto-unbind with "Unbound from Text Editor (name) — file renamed". Lower priority than deletion.