Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Saving and changes on disk

n0te’s promise is that it never loses your words and never clobbers anyone else’s. This page is how it keeps it.

When n0te saves

There’s no save button to forget. n0te saves:

  • a second after you stop typing;
  • when you press esc to finish an edit;
  • when its window loses focus;
  • when you close the window, or leave the note for another;
  • for every open note, on n0 --quit. If one can’t be saved, the service doesn’t quit, and says which.

A note you only read is never written. (The exception is today’s daily note: --today, the palette’s Today’s daily note and -t create it from your template as soon as they need it.)

How it writes

  1. It checks the disk first. Just before writing, n0te reads the file again. If it changed since n0te last saw it, that change is merged first (see below), so nothing is ever overwritten blind.
  2. It changes only what you changed. The new text is your edited block spliced into the file as it is on disk. Every other block goes back byte for byte.
  3. It writes atomically. The text goes to a hidden temporary file next to the note (.NAME.n0te-PID~), which is flushed to disk, then renamed over the note. Readers see the old file or the new one, never half of one, and Obsidian sees one clean change.

It keeps the file’s permissions, follows symlinks (the file they point to is replaced, and the link stays), and keeps the line endings (LF or CRLF) and the final newline, or the lack of one.

In a folder you can’t write to, the temporary file can’t be made; a note there that you can write is saved in place instead.

When a save fails

No permission, a full disk, a missing folder: the status line turns red and says why (NOT SAVED · …). Your text stays in the window. Closing the window or leaving the note then takes a second try (do that again to discard your changes), and only that drops the change.

When the file changes on disk

n0te watches the file it shows. When something else writes to it (Obsidian, Obsidian Sync, Syncthing, git pull, a script) n0te waits until two reads in a row agree, so a file still being written isn’t taken half-done. Its own saves are recognised and ignored.

  • Nothing unsaved: the page reloads in place, without jumping, and the status line says Reloaded: changed on disk.
  • You’re editing: n0te merges. It compares three versions: the file as it was when you started, yours, and the one on disk now. Changes on either side are kept. Notes merge block by block, and then line by line inside a block; code merges line by line. Your edit stays open where it was. The status line says Merged changes from disk.
  • The same lines changed on both sides: in a note, n0te keeps both versions, yours first, saves, and says kept both versions, yours first. Tidy up whichever you don’t want.

Holds

A few situations are too risky to settle on its own. Then n0te holds: autosave pauses, the status line says why in red, and you decide.

Status lineWhat happenedWhat to do
CONFLICT MARKERS FROM A MERGEA merge in a code file hit lines changed on both sides, and n0te wrote git-style <<<<<<< markers into your copyFix them, then ctrl s
CHANGED ON DISK TOOBoth sides changed, and the file was too big to mergectrl s keeps yours. To take the disk’s, esc, then r twice
MOVED OR DELETED ON DISKThe file is gone from where it wasctrl s writes your unsaved changes back at the old path. With nothing unsaved, there’s nothing to keep: close the window
BINARY ON DISK NOWThe file on disk turned binary (NUL bytes)ctrl s keeps yours. To take the disk’s (read-only), r twice

ctrl s works while reading and while editing. r reloads only while reading, and during a hold the first press warns that your version will be dropped (do that again to discard your changes); a second press within five seconds does it.

A moved file isn’t silently recreated, because that would undo a deliberate move or delete. But two common cases need no hold:

  • A rename in Obsidian is followed: the window switches to the new name.
  • Vim and Emacs rename a file to a backup while saving it. n0te ignores that rename and stays on the file.

Undo across changes

u undoes your edits as merges, too: it takes out your change and keeps anything that changed on disk since. History is kept per file for as long as the service runs, so it survives closing and reopening a note, but not n0 --quit or a logout.

The updated: date

With Set updated: to today when saving on, a save that changes something also sets a plain updated: YYYY-MM-DD in the frontmatter to today. The new date is exactly as long as the old one, so nothing else moves. It’s skipped while you’re editing the frontmatter yourself, or the whole note as source.