feat(editor): add :enew and :delete with real git-staging (v0.5 slice 3)
:enew <name> creates a new file (empty, dirty, added to the palette list); :delete unlinks the current file via a new Effect::Delete and switches to a parked buffer or scratch. Scope is read from the path (local/x, repo/x) rather than a modal prompt, and the /sd prefix is now optional in resolve_path. On-device testing showed deletions never reached the remote: add_all(["*"]) alone does not stage a removal on this libgit2, so the tree came back unchanged and the push was a silent no-op. stage_and_commit now runs add_all then update_all(["*"]) (git add -u) — together git add -A. The :delete snackbar now confirms the scoped file and flags that a Tracked file is local until :sync.
This commit is contained in:
@@ -308,6 +308,20 @@ impl Storage {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Unlink a file under `/sd` (`:delete`). Tolerates a missing target — an
|
||||
/// already-gone file is a success, so the call is idempotent. Also clears a
|
||||
/// stray `{path}.tmp` best-effort, so a crash-interrupted save can't leave the
|
||||
/// file half-present after a delete. For a Tracked file this leaves the
|
||||
/// working copy short one file; the next publish's `add --all` stages it.
|
||||
pub fn delete_path(&self, path: &str) -> Result<()> {
|
||||
let _ = fs::remove_file(format!("{path}.tmp"));
|
||||
match fs::remove_file(path) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
|
||||
Err(e) => Err(e).with_context(|| format!("unlink {path}")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Reconcile a leftover `notes.md.tmp` at boot. The save sequence is
|
||||
/// write-tmp → fsync → unlink-target → rename, so a lingering tmp means the
|
||||
/// last save was interrupted. Which way to recover depends on whether the
|
||||
|
||||
Reference in New Issue
Block a user